Here is the linker.ld:
Code: Select all
OUTPUT_FORMAT(elf32-i386)
ENTRY(main)
SECTIONS
{
. = 0x9000;
.text : { *(.text.start) *(.text)}
.data : { *(.data) }
.bss : { *(.bss) *(COMMON) }
}
Code: Select all
nasm -f bin -o boot.bin boot.asm
nasm -f elf32 -o stage2.o stage2.asm
ld -melf_i386 -Ttext=0x1000 -nostdlib --nmagic -o stage2.elf stage2.o
objcopy -O binary stage2.elf stage2.bin
gcc -g -m32 -c -ffreestanding -o kernel.o kernel.c -lgcc
ld -melf_i386 -Tlinker.ld -nostdlib --nmagic -o kernel.elf kernel.o
objcopy -O binary kernel.elf kernel.bin
dd if=/dev/zero of=corn.img bs=512 count=2880
dd if=boot.bin of=corn.img bs=512 conv=notrunc
dd if=stage2.bin of=corn.img bs=512 conv=notrunc
dd if=kernel.bin of=corn.img bs=512 seek=1 conv=notrunc
Code: Select all
__asm__ (".pushsection .text.start\r\n" \
"jmp main\r\n" \
".popsection\r\n"
);
int main(){
while(1){}
return 0;
}
Code: Select all
bits 16
org 0x7c00
offset equ 0x1000
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov bp, sp
mov [BOOT_DRIVE], dl
cld
mov bx, msg
call print
load_stage2:
mov bx, offset
mov dh, 2
mov dl, [BOOT_DRIVE]
call load_disk
mov bx, 0x9000
mov dh, 17
mov dl, [BOOT_DRIVE]
call load_disk
jmp 0x0000:offset
jmp $
%include "load_disk.asm"
%include "print.asm"
%include "print_hex.asm"
BOOT_DRIVE db 0
msg db "Booting cornOS", 0
times 510 - ($-$$) db 0
dw 0xaa55
Code: Select all
bits 16
stage2:
mov ax, cs
mov ds, ax
mov es, ax
mov bx, stage2_called
call print
call enable_a20
call switch_to_pm
%include "a20.asm"
%include "switch_to_pm.asm"
%include "gdt.asm"
bits 32
BEGIN_PM:
mov ebx, pmode_msg
call print_pm
jmp CODE_SEG:0x9000
jmp $
%include "print32.asm"
stage2_called db "Stage two successfully called!", 0
pmode_msg db "Sucessfully entered protected mode", 0
gdt.asm
Code: Select all
gdt_start:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_desc:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
Code: Select all
bits 16
switch_to_pm:
cli
lgdt [gdt_desc]
mov eax, cr0
or al, 1
mov cr0, eax
jmp CODE_SEG:init_pm
bits 32
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call BEGIN_PM
Code: Select all
load_disk:
pusha
push dx
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov cl, 0x02
mov dh, 0x00
int 0x13
jc disk_error
pop dx
cmp al, dh
jne sectors_error
mov bx, read_disk_success
call print
popa
ret
disk_error:
mov bx, read_disk_failed
call print
mov dh, ah
call print_hex
jmp $
sectors_error:
mov bx, incorrect_sectors
call print
jmp $
read_disk_success db "Successfully read disk!", 0
read_disk_failed db "Failed to read disk", 0
incorrect_sectors db "Incorrect number of sectors read", 0
Code: Select all
bits 16
a20_success db "A20 gate sucessfully enabled!", 0
a20_failed db "A20 gate enable failed", 0
%include "print.asm"
check_a20:
pushf
push ds
push es
push di
push si
cli
xor ax, ax
mov es, ax
not ax
mov ds, ax
mov di, 0x0500
mov si, 0x0510
mov al, byte [es:di]
push ax
mov al, byte [ds:si]
push ax
mov byte [es:di], 0x00
mov byte [ds:si], 0xFF
cmp byte [es:di], 0xFF
pop ax
mov byte [ds:si], al
pop ax
mov byte [es:di], al
mov ax, 0
je check_a20__exit
mov ax, 1
check_a20__exit:
pop si
pop di
pop es
pop ds
popf
ret
enable_a20:
cli
call a20wait
mov al,0xAD
out 0x64,al
call a20wait
mov al,0xD0
out 0x64,al
call a20wait2
in al,0x60
push eax
call a20wait
mov al,0xD1
out 0x64,al
call a20wait
pop eax
or al,2
out 0x60,al
call a20wait
mov al,0xAE
out 0x64,al
call a20wait
sti
call check_a20
cmp ax, 0
jne a20_success_enable
mov bx, a20_failed
call print
ret
a20_success_enable:
mov bx, a20_success
call print
ret
a20wait:
in al,0x64
test al,2
jnz a20wait
ret
a20wait2:
in al,0x64
test al,1
jz a20wait2
ret