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

View file

@ -9,8 +9,13 @@ floppy: bootloader fs
bootloader: obj bootloader: obj
nasm src/bootloader.asm -o obj/bootloader.bin nasm src/bootloader.asm -o obj/bootloader.bin
kernel: fs kernel: obj fs
gcc src/kernel/*.c -o out/fs/kernel.sys -ffreestanding -nostdlib -m32 -T src/kernel/link.ld 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 fs: out
mkdir -p out/fs mkdir -p out/fs

View file

@ -15,275 +15,245 @@
;TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE ;TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
;USE OR PERFORMANCE OF THIS SOFTWARE. ;USE OR PERFORMANCE OF THIS SOFTWARE.
pointers: kload equ 0x0010_0000
.fat equ 0x0500
.root_dir equ 0x0504
.kernel equ 0x0508
fat_header: global_info:;0x0500 - 0x05ff (0x0515)
.oem_name equ 0x7c03;mkfs.fat - ignored .fat equ 0x0500;dword - pointer
.bytes_per_sector equ 0x7c0b;0x0200 - assumed .root_dir equ 0x0504;dword - pointer
.sectors_per_cluster equ 0x7c0d;0x01 - assumed .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 .reserved_sectors equ 0x7c0e;0x0002 - handled
.n_fats equ 0x7c10;0x01 - assumed .n_fats equ 0x7c10;0x01 -
.root_dir_entries equ 0x7c11; - .root_dir_entries equ 0x7c11; -
.n_sectors equ 0x7c13;0x0b40 - .n_sectors equ 0x7c13;0x0b40 -
.media_type equ 0x7c15; - .media_type equ 0x7c15; -
.sectors_per_fat equ 0x7c16; - handled .sectors_per_fat equ 0x7c16; - handled
.sectors_per_track equ 0x7c18;0x0012 - .sectors_per_track equ 0x7c18;0x0012 -
.sides equ 0x7c1a;0x0002 - .sides equ 0x7c1a;0x0002 -
.hidden_sectors equ 0x7c1c;0x0000_0000 - assumed, top half used as scratch for sector number of cluster 0 .hidden_sectors equ 0x7c1c;0x0000_0000 -
.long_sectors equ 0x7c20;0x0000_0000 - assumed .long_sectors equ 0x7c20;0x0000_0000 -
.drive_number equ 0x7c24; - ignored, used as scratch .drive_number equ 0x7c24; - ignored, used as scratch for real drive number
.flags equ 0x7c25; - ignored .flags equ 0x7c25; -
.signature equ 0x7c26;0x29 - halts on other values .signature equ 0x7c26;0x29 - errors on other values
.id equ 0x7c27; - ignored .id equ 0x7c27; -
.label equ 0x7c2b;PORTLAND OS - assumed .label equ 0x7c2b;PORTLAND OS -
.fs_type equ 0x7c36;FAT12 - assumed .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 org 0x7c3e
bits 16 bits 16
;Enable A20 line
in al, 0x92 in al, 0x92
or al, 0x02 or al, 0x02
out 0x92, al out 0x92, al
;Load second sector of bootloader
mov ah, 0x42 mov ah, 0x42
mov si, dap mov si, dap
int 0x13 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 mov byte [fat_header.drive_number], dl
memory: memory:
mov bx, 0x2010 ;Get available low memory
mov eax, 0x0001_0001 int 0x12
.clear: mov word [global_info.low_mem], ax
mov dword [bx], eax mov word [global_info.mem_used], 0x0020
add bx, 4
test bx, 0x4000
jne .clear
xor ax, ax ;Get available mid and high memory
mov es, ax xor dx, dx
mov si, 0x7000 mov ax, 0xe801
xor ebx, ebx
.loop:
mov eax, 0x0000_e820
mov ecx, 24
mov edx, 0x534d_4150
int 0x15 int 0x15
jc .done test dx, dx
jnz .got
test cl, 24 mov cx, ax
jne .not_24 mov dx, bx
.got:
test byte [0x7014], 0x01 mov word [global_info.mid_mem], cx
jz .loop mov word [global_info.high_mem], dx
.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
;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] mov ax, word [fat_header.sectors_per_fat]
xor ecx, ecx call load_low
mov cx, word [fat_header.reserved_sectors] mov dword [global_info.fat], ebx
call allocate_and_load
mov dword [pointers.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] mov ax, word [fat_header.root_dir_entries]
dec ax
shr ax, 4 shr ax, 4
inc ax call load_low
mov dword [global_info.root_dir], ebx
;Calculate end of root directory
xor ecx, ecx xor ecx, ecx
mov cx, word [fat_header.reserved_sectors] mov cx, word [fat_header.root_dir_entries]
add cx, word [fat_header.sectors_per_fat] shl ecx, 5
jnc .no_carry add ecx, ebx
or ecx, 0x0001_0000 jc insufficient_memory
.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: find_kernel:
mov eax, 0x6e_72_65_6b;kern mov eax, 0x6e72_656b;kern
mov ecx, 0x20_20_6c_65;el mov edx, 0x2020_6c65;el
mov ebx, dword [pointers.root_dir]
.loop: .loop:
;Check name
test dword [ebx], eax test dword [ebx], eax
jne .next jne .next
test dword [ebx + 4], ecx test dword [ebx + 4], edx
jne .next jne .next
test word [ebx + 8], 0x79_73;sy test word [ebx + 8], 0x7973;sy
jne .next jne .next
test byte [ebx + 10], 0x73;s test byte [ebx + 10], 0x73;s
je .found je .found
.next: .next:
;Next record
add ebx, 32 add ebx, 32
test ebx, edx test ebx, ecx
jne .loop 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: .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] ;Save sector number for later
dec eax mov cx, [ebx + 26]
shr eax, 9
inc eax
test eax, 0xffff_0000 ;find 1kiB buffer
jnz halt mov ax, 2
mov byte [load_low.ret_with_segment], 0xc3;ret
push word [ebx + 0x1a] call load_low
shl ebx, 4
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: 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 load_low:
dw 0xaa55 ;ax in : number of sectors
;qword [dap.start] in : starting sector
.over_sig: ;Store length in DAP
test ebx, 0xffff_0000 mov word [dap.length], ax
jnz halt
;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.segment], bx
mov word [dap.offset], 0x0000
.ret_with_segment:
xor edx, edx ;Load from disk
pop dx
mov word [dap.start + 2], 0x0000
mov ah, 0x42
mov si, dap mov si, dap
.loop: mov ah, 0x42
mov cx, dx
add cx, word [fat_header.hidden_sectors + 2]
jc halt
mov word [dap.start], cx
int 0x13 int 0x13
shl ebx, 4
ret
mov ebx, dword [pointers.fat] bad_fat_header:
add ebx, edx mov dl, error_codes.bad_fat_header
add ebx, edx jmp error
add ebx, edx
xor edx, edx insufficient_memory:
mov dx, word [ebx + 1] mov dl, error_codes.insufficient_memory
shl edx, 8 jmp error
mov dl, byte [ebx]
add word [dap.segment], 0x0020 error:
jc halt ;Print error code (in octal)
mov ax, 0xb800
mov ecx, edx mov ds, ax
and ecx, 0x0ff8 mov word [0], 0x0f72;E
test ecx, 0x0ff8 mov ax, 0x0f00
jne .loop mov al, dl
and al, 0x07
mov ebx, dword [pointers.kernel] or al, 0x30
mov word [6], ax;bottom digit
;TODO 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 cli
.halt:
lgdt [gdt] hlt
mov eax, cr0 jmp .halt
or al, 0x01
mov cr0, eax
jmp 0x08:kernel_start;get start from file header
gdt: gdt:
dw 0x28 dw 0x28
@ -299,69 +269,9 @@ dw 0x0010
.length dw 0x0001 .length dw 0x0001
.offset dw 0x7e00 .offset dw 0x7e00
.segment dw 0x0000 .segment dw 0x0000
.start dd 0x0000_0001 .start dq 0x0000_0000_0000_0001
.start_h dd 0x0000_0000
;ecx = sector memory_usage:
;ax = sector count .low dw ;word - used memory from 0 to 1MiB in kiB
;bx out = address of start .mid dw 0x0000;word - used memory from 1MiB to 16MiB in kiB
allocate_and_load: .high dw 0x0000;word - used memory from 16MiB up in 64s of kiB
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

View file

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

View file

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