Succesful ELF kernel boot!
This commit is contained in:
parent
a9985ea925
commit
bc3165eeb8
1 changed files with 75 additions and 11 deletions
|
@ -1,12 +1,12 @@
|
||||||
DISK_ID EQU 0x81
|
DISK_ID EQU 0x81
|
||||||
|
|
||||||
|
KERNEL_START EQU 0x100000
|
||||||
|
|
||||||
|
ELF_START EQU 0x8000
|
||||||
|
|
||||||
org 0x7C00
|
org 0x7C00
|
||||||
bits 16
|
bits 16
|
||||||
|
|
||||||
; memory layout:
|
|
||||||
; 0x8000 -> ... = ELF file, unparsed
|
|
||||||
; 0x100000 -> ... = actual kernel
|
|
||||||
|
|
||||||
jmp .start
|
jmp .start
|
||||||
|
|
||||||
[bits 16]
|
[bits 16]
|
||||||
|
@ -154,7 +154,7 @@ call puthex
|
||||||
.reset_disk_no_error:
|
.reset_disk_no_error:
|
||||||
|
|
||||||
mov cx, 1 ; start at sector 1
|
mov cx, 1 ; start at sector 1
|
||||||
mov bx, 0x8000 ; write to 0x8000
|
mov bx, ELF_START ; write to ELF_START
|
||||||
push bx
|
push bx
|
||||||
push cx
|
push cx
|
||||||
.read_disk_loop:
|
.read_disk_loop:
|
||||||
|
@ -223,16 +223,80 @@ mov ss, ax
|
||||||
; set up stack
|
; set up stack
|
||||||
mov esp, 0x090000
|
mov esp, 0x090000
|
||||||
|
|
||||||
; parse ELF file to 0x10000
|
; parse elf file at ELF_START to KERNEL_START
|
||||||
|
|
||||||
; load memory position from ELF file
|
; verify ELF header
|
||||||
mov eax, [ds:0x8018]
|
mov esi, ELF_START
|
||||||
|
cmp dword [esi], 464C457Fh ; ELF magic
|
||||||
|
jne .invalid_elf
|
||||||
|
cmp word [esi+4], 0101h ; lsb 32 bit, little endian
|
||||||
|
jne .invalid_elf
|
||||||
|
cmp word [esi+18], 03 ; x86 architecture
|
||||||
|
jne .invalid_elf
|
||||||
|
|
||||||
jmp eax
|
; read the entrypoint and store it
|
||||||
|
mov eax, dword [esi+0x18] ; program entry position
|
||||||
|
mov dword [.entrypoint], eax
|
||||||
|
|
||||||
|
mov cx, word [esi+0x2C] ; read phnum (number of program headers)
|
||||||
|
mov eax, dword [esi+0x1C] ; read phoff (offset of program header)
|
||||||
|
|
||||||
|
; ebx is now ELF_START, esi jumps to the start of the program header
|
||||||
|
mov ebx, esi
|
||||||
|
add esi, eax
|
||||||
|
|
||||||
|
; set up for loop
|
||||||
|
sub esi, 0x20
|
||||||
|
inc cx
|
||||||
|
|
||||||
|
.elf_ph_loop:
|
||||||
|
add esi, 0x20
|
||||||
|
dec cx
|
||||||
|
jz .invalid_elf ; there is no valid code block
|
||||||
|
cmp word [esi], 1 ; check if p_type is loadable
|
||||||
|
jne .elf_ph_loop
|
||||||
|
|
||||||
|
; add offset to ebx (ebx = pointer to code)
|
||||||
|
add ebx, dword [esi+0x04]
|
||||||
|
|
||||||
|
; store p_filesz (ecx = size of the segment)
|
||||||
|
mov ecx, dword [esi+0x10]
|
||||||
|
|
||||||
|
; calculate size of bss (edx = size of bss)
|
||||||
|
mov edx, dword [esi+0x14]
|
||||||
|
sub edx, ecx
|
||||||
|
|
||||||
|
; check if ecx is zero
|
||||||
|
or ecx, ecx
|
||||||
|
jz .invalid_elf
|
||||||
|
|
||||||
|
; set source
|
||||||
|
mov esi, ebx
|
||||||
|
|
||||||
|
; set destination
|
||||||
|
mov edi, KERNEL_START
|
||||||
|
|
||||||
|
; repeat ecx/4 times (because it moves 4 bytes at a time)
|
||||||
|
shr ecx, 2
|
||||||
|
|
||||||
|
; copy
|
||||||
|
repnz movsd
|
||||||
|
|
||||||
|
; jump to start of kernel
|
||||||
|
jmp [.entrypoint]
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
jmp .end
|
jmp .end
|
||||||
|
|
||||||
|
.invalid_elf:
|
||||||
|
mov byte [ds:0x0B8000], 'E'
|
||||||
|
mov byte [ds:0x0B8001], 0x40
|
||||||
|
mov byte [ds:0x0B8002], 'L'
|
||||||
|
mov byte [ds:0x0B8003], 0x40
|
||||||
|
mov byte [ds:0x0B8004], 'F'
|
||||||
|
mov byte [ds:0x0B8005], 0x40
|
||||||
|
jmp .end
|
||||||
|
|
||||||
.data:
|
.data:
|
||||||
.str_no_A20:
|
.str_no_A20:
|
||||||
db "A20 not enabled"
|
db "A20 not enabled"
|
||||||
|
@ -258,12 +322,12 @@ db 11001111b
|
||||||
db 0
|
db 0
|
||||||
.gdt_end:
|
.gdt_end:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.gdt_desc:
|
.gdt_desc:
|
||||||
dw .gdt_end - .gdt - 1
|
dw .gdt_end - .gdt - 1
|
||||||
dd .gdt
|
dd .gdt
|
||||||
|
|
||||||
|
.entrypoint: dd 0
|
||||||
|
|
||||||
; print padding nullbytes
|
; print padding nullbytes
|
||||||
times 510 - ($ - $$) db 0
|
times 510 - ($ - $$) db 0
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue