diff options
Diffstat (limited to 'src/bootloader.asm')
-rw-r--r-- | src/bootloader.asm | 213 |
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: - |