summaryrefslogtreecommitdiff
path: root/src/bootloader.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootloader.asm')
-rw-r--r--src/bootloader.asm213
1 files changed, 165 insertions, 48 deletions
diff --git a/src/bootloader.asm b/src/bootloader.asm
index e8ab91b..08d1daf 100644
--- a/src/bootloader.asm
+++ b/src/bootloader.asm
@@ -17,20 +17,22 @@
pointers:
.fat equ 0x0500
+.root_dir equ 0x0504
+.kernel equ 0x0508
fat_header:
.oem_name equ 0x7c03;mkfs.fat - ignored
.bytes_per_sector equ 0x7c0b;0x0200 - assumed
.sectors_per_cluster equ 0x7c0d;0x01 - assumed
-.reserved_sectors equ 0x7c0e;0x0002 - other values handled
+.reserved_sectors equ 0x7c0e;0x0004 - other values handled
.n_fats equ 0x7c10;0x01 - assumed
-.directory_entries equ 0x7c11; -
+.root_dir_entries equ 0x7c11; -
.n_sectors equ 0x7c13;0x0b40 -
.media_type equ 0x7c15; -
.sectors_per_fat equ 0x7c16; - handled
.sectors_per_track equ 0x7c18;0x0012 -
.sides equ 0x7c1a;0x0002 -
-.hidden_sectors equ 0x7c1c;0x0000_0000 - assumed
+.hidden_sectors equ 0x7c1c;0x0000_0000 - assumed, top half used as scratch for sector number of cluster 0
.long_sectors equ 0x7c20;0x0000_0000 - assumed
.drive_number equ 0x7c24; - ignored, used as scratch
.flags equ 0x7c25; - ignored
@@ -148,13 +150,165 @@ memory:
jne halt
mov ax, word [fat_header.sectors_per_fat]
+ xor ecx, ecx
+ mov cx, word [fat_header.reserved_sectors]
+
+ call allocate_and_load
+
+ mov dword [pointers.fat], ebx
+
+ mov ax, word [fat_header.root_dir_entries]
+ dec ax
+ shr ax, 4
+ inc ax
+
+ xor ecx, ecx
+ mov cx, word [fat_header.reserved_sectors]
+ add cx, word [fat_header.sectors_per_fat]
+ jnc .no_carry
+ or ecx, 0x0001_0000
+.no_carry:
+
+ call allocate_and_load
+
+ mov dword [pointers.root_dir], ebx
+
+ xor edx, edx
+ mov dx, word [fat_header.root_dir_entries]
+ shl edx, 5
+ add edx, ebx
+
+find_kernel:
+ mov eax, 0x6e_72_65_6b;kern
+ mov ecx, 0x20_20_6c_65;el
+ mov ebx, dword [pointers.root_dir]
+
+.loop:
+ test dword [ebx], eax
+ jne .next
+ test dword [ebx + 4], ecx
+ jne .next
+ test word [ebx + 8], 0x79_73;sy
+ jne .next
+ test byte [ebx + 10], 0x73;s
+ je .found
+
+.next:
+ add ebx, 32
+ test ebx, edx
+ jne .loop
+ jmp halt
+
+.found:
+ mov byte [allocate_and_load.load], 0xc3;ret
+
+ mov eax, dword [ebx + 0x1c]
+ dec eax
+ shr eax, 9
+ inc eax
+
+ test eax, 0xffff_0000
+ jnz halt
+
+ push word [ebx + 0x1a]
+
+ call allocate_and_load
+
+ mov dword [pointers.kernel], ebx
+
+ mov ax, word [fat_header.root_dir_entries]
+ dec ax
+ shr ax, 4
+ dec ax
+ add ax, word [fat_header.reserved_sectors]
+ jc halt
+ add ax, word [fat_header.sectors_per_fat]
+ jc halt
+ mov word [fat_header.hidden_sectors + 2], ax
+
+load_kernel:
+ mov word [dap.length], 0x0001
+ mov word [dap.offset], bx
+ xor bx, bx
+ shr ebx, 4
+ test ebx, 0xffff_0000
+ jnz halt
+ mov word [dap.segment], bx
+
+ xor edx, edx
+ pop dx
+ mov word [dap.start + 2], 0x0000
+ mov ah, 0x42
+ mov si, dap
+.loop:
+ mov cx, dx
+ add cx, word [fat_header.hidden_sectors + 2]
+ jc halt
+
+ mov word [dap.start], cx
+
+ int 0x13
+
+ mov ebx, dword [pointers.fat]
+ add ebx, edx
+ add ebx, edx
+ add ebx, edx
+
+ xor edx, edx
+ mov dx, word [ebx + 1]
+ shl edx, 8
+ mov dl, byte [ebx]
+
+ add word [dap.segment], 0x0020
+ jc halt
+
+ mov ecx, edx
+ and ecx, 0x0ff8
+ test ecx, 0x0ff8
+ jne .loop
+
+ mov ebx, dword [pointers.kernel]
+
+ ;Parse kernel executable header,
+ ;Go through relocation tables,
+ ;Get kernel_start.
+
+ cli
+
+ lgdt [gdt]
+ mov eax, cr0
+ or al, 0x01
+ mov cr0, eax
+ jmp 0x08:kernel_start;get start from file header
+
+gdt:
+dw 0x28
+dd gdt + 6
+dq 0x0000_0000_0000_0000
+dq 0x0040_9a00_0000_7fff;0x000000 - 0x007fff
+dq 0x0040_9200_0000_7fff
+dq 0x00c0_9a00_8000_0ff7;0x008000 - 0xffffff
+dq 0x00c0_9200_8000_0ff7
+
+dap:
+dw 0x0010
+.length dw 0x0003
+.offset dw 0x7e00
+.segment dw 0x0000
+.start dd 0x0000_0001
+.start_h dd 0x0000_0000
+
+;ecx = sector
+;ax = sector count
+;bx out = address of start
+allocate_and_load:
mov word [dap.length], ax
+ mov dword [dap.start], ecx
dec ax
shr ax, 3
inc ax
-fat_allocate:
mov bx, 0x200e
xor cx, cx
mov dx, 0x2200
@@ -189,50 +343,17 @@ fat_allocate:
and ebx, 0x0000_dfff
shl ebx, 12
- mov dword [pointers.fat], ebx
-
- mov dl, byte [fat_header.drive_number]
- mov ax, word [fat_header.reserved_sectors]
- mov word [dap.start], ax
- mov word [dap.offset], bx
- shr ebx, 16
- and bx, 0xf000
- mov word [dap.segment], bx
+.load:
+ mov eax, ebx
+ mov word [dap.offset], ax
+ shr eax, 4
+ and ax, 0xf000
+ mov word [dap.segment], ax
mov ah, 0x42
mov si, dap
- int 0x15
-
- mov ebx, dword [pointers.fat]
-
- ;fat loaded - load kernel
-
- cli
-
- lgdt [gdt]
- mov eax, cr0
- or al, 0x01
- mov cr0, eax
- jmp 0x08:pmode
-
-gdt:
-dw 0x28
-dd gdt + 6
-dq 0x0000_0000_0000_0000
-dq 0x0040_9a00_0000_7fff;0x000000 - 0x007fff
-dq 0x0040_9200_0000_7fff
-dq 0x00c0_9a00_8000_0ff7;0x008000 - 0xffffff
-dq 0x00c0_9200_8000_0ff7
-
-dap:
-dw 0x0010
-.length dw 0x0001
-.offset dw 0x7e00
-.segment dw 0x0000
-.start dq 1
+ int 0x13
-allocate:
- ;TODO
ret
halt:
@@ -240,7 +361,3 @@ halt:
.hlt:
hlt
jmp .hlt
-
-bits 32
-pmode:
-