diff options
Diffstat (limited to 'src/bootloader.asm')
-rw-r--r-- | src/bootloader.asm | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/bootloader.asm b/src/bootloader.asm new file mode 100644 index 0000000..e8ab91b --- /dev/null +++ b/src/bootloader.asm @@ -0,0 +1,246 @@ +;Copyright 2019 Benji Dial + +;Permission to use, copy, modify, and/or distribute this +;software for any purpose with or without fee is hereby +;granted, provided that the above copyright notice and this +;permission notice appear in all copies. + +;THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +;ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +;EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +;INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +;WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +;WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +;TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +;USE OR PERFORMANCE OF THIS SOFTWARE. + +pointers: +.fat equ 0x0500 + +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 +.n_fats equ 0x7c10;0x01 - assumed +.directory_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 +.long_sectors equ 0x7c20;0x0000_0000 - assumed +.drive_number equ 0x7c24; - ignored, used as scratch +.flags equ 0x7c25; - ignored +.signature equ 0x7c26;0x29 - halts on other values +.id equ 0x7c27; - ignored +.label equ 0x7c2b;PORTLAND OS - assumed +.fs_type equ 0x7c36;FAT12 - assumed + +org 0x7c3e +bits 16 + + in al, 0x92 + or al, 0x02 + out 0x92, al + + mov ah, 0x42 + mov si, dap + int 0x13 + + mov byte [fat_header.drive_number], dl + +memory: + mov bx, 0x2010 + mov eax, 0x0001_0001 +.clear: + mov dword [bx], eax + add bx, 4 + test bx, 0x4000 + jne .clear + + xor ax, ax + mov es, ax + mov si, 0x7000 + xor ebx, ebx + +.loop: + mov eax, 0x0000_e820 + mov ecx, 24 + mov edx, 0x534d_4150 + int 0x15 + jc .done + + test cl, 24 + jne .not_24 + + test byte [0x7014], 0x01 + jz .loop + +.not_24: + test dword [0x7010], 1 + jne .loop + + test byte [0x7003], 0 + jne .loop + + test dword [0x7004], 0 + jne .loop + + test dword [0x700c], 0 + je .check_lower + + mov dword [0x7008], 0xffff_ffff + +.check_lower: + test dword [0x7008], 0 + je .loop + + mov edx, ebx + mov ebx, dword [0x7000] + mov eax, ebx + add eax, dword [0x7008] + jnc .pagify + mov eax, 0xffff_ffff + +.pagify: + dec ebx + shr ebx, 12 + inc ebx + shr eax, 12 + dec eax + + test eax, 0xffff_f000 + jz .maxed + mov eax, 0x0000_0fff + +.maxed: + inc eax + test eax, ebx + je .next + + shl ebx, 1 + or ebx, 0x2000 + shl eax, 1 + add eax, 0x2000 + mov ecx, eax + + xor ax, ax +.free_loop: + mov word [ebx], ax + add ebx, 2 + test ebx, ecx + jne .free_loop + +.next: + mov ebx, edx + jmp .loop + +.done: + mov dword [0x2000], 0x0002_0002 + mov dword [0x2004], 0x0002_0002 + mov dword [0x2008], 0x0002_0002 + mov dword [0x200c], 0x0002_0002 + + test byte [fat_header.signature], 0x29 + jne halt + + mov ax, word [fat_header.sectors_per_fat] + mov word [dap.length], ax + + dec ax + shr ax, 3 + inc ax + +fat_allocate: + mov bx, 0x200e + xor cx, cx + mov dx, 0x2200 + +.loop: + add bx, 2 + test bx, dx + je halt + + test word [bx], 0x0000 + je .eq + + xor cx, cx + jmp .loop + +.eq: + inc cx + test cx, ax + jne .loop + + dec ax + shl ax, 1 + sub bx, ax + mov dx, bx + + mov ax, 0x0002 +.mark_loop: + mov word [bx], ax + loop .mark_loop + + mov bx, dx + 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 + + 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 + +allocate: + ;TODO + ret + +halt: + cli +.hlt: + hlt + jmp .hlt + +bits 32 +pmode: + |