small changes, part 2, rewriting bootloader partially, giving up on this branch

This commit is contained in:
Benji Dial 2019-12-24 00:16:05 -05:00
parent e520b52cd5
commit a947a7a143
5 changed files with 212 additions and 298 deletions

View file

@ -1,20 +1,17 @@
0x0000 - 0x03ff : interrupt vector table
0x0400 - 0x04ff : bios data area
0x0500 - 0x05ff : structure pointers
0x00 : fat
0x04 : root directory
0x08 : kernel
0x0c : file handle array
0x10 : process array
0x0600 - 0x1fff : not assigned
0x2000 - 0x3fff : memory map
for each word : 1 page
0x0000 = free
0x0001 = unavailable
0x0002 = kernel
other = process number
0x4000 - 0x6fff : not assigned
0x0500 - 0x05ff : global info
0x00 dword : fat pointer
0x04 dword : root directory pointer
0x08 word : usable memory from 0 to 1MiB in kiB
0x0a word : usable memory from 1MiB to 16MiB in kiB
0x0c dword : bootloader:
lower word: low memory usage by bootloader in kiB,
upper word: kernel image length in kiB
kernel:
file handle array pointer
0x10 dword : process array pointer
0x14 word : usable memory from 16MiB up in 64s of kiB
0x0600 - 0x6fff : not assigned
0x7000 - 0x7bff : bootloader scratch
0x7000 : memory map bios buffer
0x7c00 - 0x7fff : bootloader

View file

@ -9,8 +9,13 @@ floppy: bootloader fs
bootloader: obj
nasm src/bootloader.asm -o obj/bootloader.bin
kernel: fs
gcc src/kernel/*.c -o out/fs/kernel.sys -ffreestanding -nostdlib -m32 -T src/kernel/link.ld
kernel: obj fs
gcc src/kernel/*.c -o obj/kernel.elf -ffreestanding -nostdlib -m32 -fno-asynchronous-unwind-tables
ld obj/kernel.elf -o obj/kernel-stripped.elf -T src/kernel/link.ld -s --orphan-handling=discard -m elf_i386
objcopy obj/kernel-stripped.elf out/fs/kernel.sys -O binary
clean:
rm -r obj out
fs: out
mkdir -p out/fs

View file

@ -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
kload equ 0x0010_0000
fat_header:
.oem_name equ 0x7c03;mkfs.fat - ignored
.bytes_per_sector equ 0x7c0b;0x0200 - assumed
.sectors_per_cluster equ 0x7c0d;0x01 - assumed
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
;Get available low memory
int 0x12
mov word [global_info.low_mem], ax
mov word [global_info.mem_used], 0x0020
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 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
mov eax, dword [ebx + 0x1c]
dec eax
shr eax, 9
inc eax
;Save sector number for later
mov cx, [ebx + 26]
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
;find 1kiB buffer
mov ax, 2
mov byte [load_low.ret_with_segment], 0xc3;ret
call load_low
shl ebx, 4
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
load_low:
;ax in : number of sectors
;qword [dap.start] in : starting sector
;Store length in DAP
mov word [dap.length], ax
;Calculate kiB used
dec ax
shr ax, 1
inc ax
mov dx, ax
add ax, word [global_info.mem_usage]
;Fail if not enough is available
jc insufficient_memory
cmp ax, word [global_info.low_mem]
jg insufficient_memory
;Check if address will fit in DAP
test ah, ah
jnz insufficient_memory
;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
bad_fat_header:
mov dl, error_codes.bad_fat_header
jmp error
xor edx, edx
mov dx, word [ebx + 1]
shl edx, 8
mov dl, byte [ebx]
insufficient_memory:
mov dl, error_codes.insufficient_memory
jmp error
add word [dap.segment], 0x0020
jc halt
mov ecx, edx
and ecx, 0x0ff8
test ecx, 0x0ff8
jne .loop
mov ebx, dword [pointers.kernel]
;TODO
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
.start dq 0x0000_0000_0000_0001
;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
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

View file

@ -1,11 +1,13 @@
OUTPUT_FORMAT(binary)
MEMORY {
kload : ORIGIN = 0x01000000, LENGTH = 0x01000000
}
SECTIONS {
. = 0x01000000;
.text : {
main = .;
_start = .;
*(.text)
}
.rodata : { *(.rodata) }
.data : { *(.data) }
.bss : { *(.bss) }
} >kload
.rodata : { *(.rodata) } >kload
.data : { *(.data) *(.bss) } >kload
}

View file

@ -23,7 +23,7 @@ OF THIS SOFTWARE.
#include "proc.h"
#include "misc.h"
void main(void) {
void _start(void) {
*(uint16_t *)0x0000200e = 0x0000;
*(uint32_t *)0x0000050c = (uint32_t)allocate_pages(16 * sizeof(struct file_handle_info), 2);