small changes, part 2, rewriting bootloader partially, giving up on this branch
This commit is contained in:
parent
e520b52cd5
commit
a947a7a143
5 changed files with 212 additions and 298 deletions
|
@ -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
|
9
makefile
9
makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
load_low:
|
||||
;ax in : number of sectors
|
||||
;qword [dap.start] in : starting sector
|
||||
|
||||
.over_sig:
|
||||
test ebx, 0xffff_0000
|
||||
jnz halt
|
||||
;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
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
|
|
Reference in a new issue