summaryrefslogtreecommitdiff
path: root/src/bootloader.asm
diff options
context:
space:
mode:
authorBenji Dial <Benji3.141@gmail.com>2019-12-24 00:16:05 -0500
committerBenji Dial <Benji3.141@gmail.com>2019-12-24 00:16:05 -0500
commita947a7a143029ee8ef5cb4a4232d7439b8a79670 (patch)
tree69ee1c58837efee95091781b12456a09f820357c /src/bootloader.asm
parente520b52cd58f70af9a17f330fe1ce98ce059762c (diff)
downloadportland-os-a947a7a143029ee8ef5cb4a4232d7439b8a79670.tar.gz
small changes, part 2, rewriting bootloader partially, giving up on this branch
Diffstat (limited to 'src/bootloader.asm')
-rw-r--r--src/bootloader.asm464
1 files changed, 187 insertions, 277 deletions
diff --git a/src/bootloader.asm b/src/bootloader.asm
index 583c169..f18750c 100644
--- a/src/bootloader.asm
+++ b/src/bootloader.asm
@@ -15,275 +15,245 @@
;TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
;USE OR PERFORMANCE OF THIS SOFTWARE.
-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
+kload equ 0x0010_0000
+
+global_info:;0x0500 - 0x05ff (0x0515)
+.fat equ 0x0500;dword - pointer
+.root_dir equ 0x0504;dword - pointer
+.low_mem equ 0x0508;word - usable memory from 0 to 1MiB in kiB
+.mid_mem equ 0x050a;word - usable memory from 1MiB to 16MiB in kiB
+.mem_used equ 0x050c;word - used memory from 0 to 1MiB in kiB
+.kernel_s equ 0x050e;word - kernel image length in kiB
+ ;dword - kernel use
+.high_mem equ 0x0514;word - usable memory from 16MiB up in 64s of kiB
+
+fat_header:;0x7c03 - 0x7c3d
+.oem_name equ 0x7c03;mkfs.fat -
+.bytes_per_sector equ 0x7c0b;0x0200 -
+.sectors_per_cluster equ 0x7c0d;0x01 -
.reserved_sectors equ 0x7c0e;0x0002 - handled
-.n_fats equ 0x7c10;0x01 - assumed
+.n_fats equ 0x7c10;0x01 -
.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, 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
-.signature equ 0x7c26;0x29 - halts on other values
-.id equ 0x7c27; - ignored
-.label equ 0x7c2b;PORTLAND OS - assumed
-.fs_type equ 0x7c36;FAT12 - assumed
+.hidden_sectors equ 0x7c1c;0x0000_0000 -
+.long_sectors equ 0x7c20;0x0000_0000 -
+.drive_number equ 0x7c24; - ignored, used as scratch for real drive number
+.flags equ 0x7c25; -
+.signature equ 0x7c26;0x29 - errors on other values
+.id equ 0x7c27; -
+.label equ 0x7c2b;PORTLAND OS -
+.fs_type equ 0x7c36;FAT12 - errors on other values
+
+error_codes:
+.bad_fat_header equ 0o000
+.insufficient_memory equ 0o001
+.no_kernel equ 0o002
+.kernel_too_big equ 0o003
org 0x7c3e
bits 16
+ ;Enable A20 line
in al, 0x92
or al, 0x02
out 0x92, al
+ ;Load second sector of bootloader
mov ah, 0x42
mov si, dap
int 0x13
+ ;Check FAT signature
+ test byte [fat_header.signature], 0x29
+ jne bad_fat_header
+ test word [fat_header.fs_type], 0x4146;FA
+ jne bad_fat_header
+ test word [fat_header.fs_type + 2], 0x3154;T1
+ jne bad_fat_header
+ test word [fat_header.fs_type + 4], 0x2032;2
+ jne bad_fat_header
+ test word [fat_header.fs_type + 6], 0x2020;
+ jne bad_fat_header
+
+ ;Store boot drive ID for later
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
+ ;Get available low memory
+ int 0x12
+ mov word [global_info.low_mem], ax
+ mov word [global_info.mem_used], 0x0020
+
+ ;Get available mid and high memory
+ xor dx, dx
+ mov ax, 0xe801
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
-
+ test dx, dx
+ jnz .got
+ mov cx, ax
+ mov dx, bx
+.got:
+ mov word [global_info.mid_mem], cx
+ mov word [global_info.high_mem], dx
+
+ ;Load FAT
+ mov ax, word [fat_header.reserved_sectors]
+ mov word [dap.start], ax
+ xor eax, eax
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
+ call load_low
+ mov dword [global_info.fat], ebx
+load_root:
+ ;Load root directory
+ mov ax, word [fat_header.sectors_per_fat]
+ xor dh, dh
+ mov dl, word [fat_header.n_fats]
+ mul dx
+ add ax, [fat_header.reserved_sectors]
+ jnc .no_inc
+ inc dx
+.no_inc:
+ mov word [dap.start], ax
+ mov word [dap.start + 2], dx
mov ax, word [fat_header.root_dir_entries]
- dec ax
shr ax, 4
- inc ax
+ call load_low
+ mov dword [global_info.root_dir], ebx
+ ;Calculate end of root directory
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
+ mov cx, word [fat_header.root_dir_entries]
+ shl ecx, 5
+ add ecx, ebx
+ jc insufficient_memory
find_kernel:
- mov eax, 0x6e_72_65_6b;kern
- mov ecx, 0x20_20_6c_65;el
- mov ebx, dword [pointers.root_dir]
-
+ mov eax, 0x6e72_656b;kern
+ mov edx, 0x2020_6c65;el
.loop:
+ ;Check name
test dword [ebx], eax
jne .next
- test dword [ebx + 4], ecx
+ test dword [ebx + 4], edx
jne .next
- test word [ebx + 8], 0x79_73;sy
+ test word [ebx + 8], 0x7973;sy
jne .next
test byte [ebx + 10], 0x73;s
je .found
-
.next:
+ ;Next record
add ebx, 32
- test ebx, edx
+ test ebx, ecx
jne .loop
- jmp halt
+ ;Got to end of directory
+ mov dl, error_codes.no_kernel
+ jmp error
+
+ ;ebx is pointer to entry
+ ;word [ebx + 26] is first cluster
+ ;dword [ebx + 28] is size
.found:
- mov byte [allocate_and_load.load], 0xc3;ret
+ ;Save size for later
+ mov eax, dword [ebx + 28]
+ shr eax, 10
+ test eax, 0x003f_0000
+ jz .store_size
+ mov dl, error_codes.kernel_too_big
+ jmp error
+.store_size:
+ mov word [global_info.kernel_s], ax
+
+ ;Save sector number for later
+ mov cx, [ebx + 26]
+
+ ;find 1kiB buffer
+ mov ax, 2
+ mov byte [load_low.ret_with_segment], 0xc3;ret
+ call load_low
+ shl ebx, 4
- mov eax, dword [ebx + 0x1c]
- dec eax
- shr eax, 9
- inc eax
+load_kernel:
+
- test eax, 0xffff_0000
- jnz halt
+load_low:
+ ;ax in : number of sectors
+ ;qword [dap.start] in : starting sector
- push word [ebx + 0x1a]
+ ;Store length in DAP
+ mov word [dap.length], ax
- call allocate_and_load
+ ;Calculate kiB used
+ dec ax
+ shr ax, 1
+ inc ax
+ mov dx, ax
+ add ax, word [global_info.mem_usage]
- mov dword [pointers.kernel], ebx
+ ;Fail if not enough is available
+ jc insufficient_memory
+ cmp ax, word [global_info.low_mem]
+ jg insufficient_memory
- 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
+ ;Check if address will fit in DAP
+ test ah, ah
+ jnz insufficient_memory
-load_kernel:
- mov word [dap.length], 0x0001
- mov word [dap.offset], bx
- xor bx, bx
- shr ebx, 4
- jmp .over_sig
-
-times $$ + 0x01fe - $ db 0
-dw 0xaa55
-
-.over_sig:
- test ebx, 0xffff_0000
- jnz halt
+ ;Commit usage
+ mov word [global_info.low_mem_usage], ax
+
+ ;Put address into DAP
+ xor ebx, ebx
+ mov bh, al
+ shr bx, 2
mov word [dap.segment], bx
+ mov word [dap.offset], 0x0000
+.ret_with_segment:
- xor edx, edx
- pop dx
- mov word [dap.start + 2], 0x0000
- mov ah, 0x42
+ ;Load from disk
mov si, dap
-.loop:
- mov cx, dx
- add cx, word [fat_header.hidden_sectors + 2]
- jc halt
-
- mov word [dap.start], cx
-
+ mov ah, 0x42
int 0x13
+ shl ebx, 4
+ ret
- 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]
-
- ;TODO
+bad_fat_header:
+ mov dl, error_codes.bad_fat_header
+ jmp error
+
+insufficient_memory:
+ mov dl, error_codes.insufficient_memory
+ jmp error
+
+error:
+ ;Print error code (in octal)
+ mov ax, 0xb800
+ mov ds, ax
+ mov word [0], 0x0f72;E
+ mov ax, 0x0f00
+ mov al, dl
+ and al, 0x07
+ or al, 0x30
+ mov word [6], ax;bottom digit
+ shr dl, 3
+ mov al, dl
+ and al, 0x07
+ or al, 0x30
+ mov word [4], ax;middle digit
+ shr dl, 3
+ mov al, dl
+ or al, 0x30
+ mov word [2], ax;top digit
cli
-
- lgdt [gdt]
- mov eax, cr0
- or al, 0x01
- mov cr0, eax
- jmp 0x08:kernel_start;get start from file header
+.halt:
+ hlt
+ jmp .halt
gdt:
dw 0x28
@@ -299,69 +269,9 @@ dw 0x0010
.length dw 0x0001
.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
+.start dq 0x0000_0000_0000_0001
- 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
-
-.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 0x13
-
- ret
-
-halt:
- cli
-.hlt:
- hlt
- jmp .hlt
+memory_usage:
+.low dw ;word - used memory from 0 to 1MiB in kiB
+.mid dw 0x0000;word - used memory from 1MiB to 16MiB in kiB
+.high dw 0x0000;word - used memory from 16MiB up in 64s of kiB \ No newline at end of file