summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootloader.asm246
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:
+