160 lines
2.6 KiB
NASM
160 lines
2.6 KiB
NASM
|
|
%include "bootdef.inc"
|
|
|
|
[bits 16]
|
|
|
|
org BOOT_STAGE2_ADD
|
|
|
|
|
|
;k now read root directory
|
|
mov bx, BOOT_ROOT_SEG
|
|
mov ds, bx
|
|
xor si, si ;k now ds:si points to beginning of root directory
|
|
mov es, si
|
|
mov cx, 224 ;max root entries
|
|
loop_compare:
|
|
mov di, kernel
|
|
push cx
|
|
push si ;save pointer to root dir entry
|
|
mov cx, 11
|
|
loop_name:
|
|
cmpsb
|
|
loopz loop_name
|
|
jnz goon ;cx didn't get to zero, bad file
|
|
pop si
|
|
pop cx
|
|
jmp found_file ;good file, ds:si points to start of root directory entry
|
|
goon:
|
|
pop si
|
|
pop cx
|
|
loop loop_compare
|
|
|
|
error:
|
|
jmp $ ;halt! no kernel file found!
|
|
|
|
found_file: ;ds:si points to root dir entry of kernel file
|
|
mov ax, [ds:si+26]
|
|
mov bx, BOOT_FAT_SEG
|
|
mov ds, bx ;ds points to beginning of FAT
|
|
mov edi, BOOT_KERNEL_ADD
|
|
|
|
readkernel_loop:
|
|
cmp ax, 0xff7
|
|
jg readkernel_done
|
|
push ax
|
|
call getCHSfromCluster
|
|
mov ax, 0x0201
|
|
mov dl, 0 ;[brDrive]
|
|
mov bx, BOOT_KERNEL_SEG
|
|
mov es, bx
|
|
xor bx, bx
|
|
int 0x13
|
|
mov cx, 256
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov esi, BOOT_KERNEL_SEG*16
|
|
copykernel_loop:
|
|
mov ax, [es:esi]
|
|
mov [es:edi], ax
|
|
inc esi
|
|
inc esi
|
|
inc edi
|
|
inc edi
|
|
loop copykernel_loop
|
|
|
|
pop ax ;current logical cluster #
|
|
|
|
mov cx, ax ;cx=logical cluster
|
|
mov dx, 3
|
|
mul dx
|
|
shr ax, 1 ;ax=logical cluster * 3 / 2
|
|
mov si, ax
|
|
test cl, 1 ;is bit0 set?
|
|
jnz odd_cluster
|
|
even_cluster:
|
|
lodsw
|
|
and ax, 0x0fff
|
|
jmp got_cluster
|
|
odd_cluster:
|
|
lodsw
|
|
shr ax, 4
|
|
got_cluster:
|
|
jmp readkernel_loop
|
|
|
|
readkernel_done:
|
|
|
|
jmp go_pm
|
|
|
|
;------------------------------------------------------
|
|
getCHSfromCluster:
|
|
;input: ax=lba of sector on floppy (0-2879)
|
|
add ax, 31 ;convert logical cluster# to lba#
|
|
xor dx, dx ;lba->chs
|
|
mov bx, 18
|
|
div bx
|
|
inc dx
|
|
mov cl, dl ;sector# (1-18)
|
|
xor dx, dx
|
|
mov bx, 2
|
|
div bx
|
|
mov ch, al ;cylinder# (0-79)
|
|
mov dh, dl ;head# (0-1)
|
|
ret
|
|
|
|
|
|
;-------------------------------------------------------
|
|
gdtr:
|
|
dw gdt_end-gdt-1
|
|
dd gdt
|
|
gdt:
|
|
dd 0
|
|
dd 0
|
|
|
|
KERNEL_CODE equ $-gdt
|
|
db 0xff ;limit 7:0
|
|
db 0xff ;limit 15:8
|
|
db 0x00 ;base 7:0
|
|
db 0x00 ;base 15:8
|
|
db 0x00 ;base 23:16
|
|
db 0x9a ;access
|
|
db 0xcf ;flags / limit 19:16
|
|
db 0x00 ;base 31:24
|
|
|
|
KERNEL_DATA equ $-gdt
|
|
db 0xff ;segment 16 = 4gb data
|
|
db 0xff
|
|
db 0x00
|
|
db 0x00
|
|
db 0x00
|
|
db 0x92
|
|
db 0xcf ;cf
|
|
db 0x00
|
|
|
|
gdt_end:
|
|
|
|
go_pm:
|
|
xor ax, ax
|
|
mov ds, ax
|
|
lgdt [gdtr]
|
|
cli
|
|
mov eax, cr0
|
|
inc eax
|
|
mov cr0, eax
|
|
|
|
jmp KERNEL_CODE:pmode
|
|
|
|
bits 32
|
|
pmode:
|
|
mov ax, KERNEL_DATA
|
|
mov es, ax
|
|
mov ds, ax
|
|
jmp KERNEL_CODE:BOOT_KERNEL_ADD
|
|
|
|
kernel: db "KERNEL BIN"
|
|
k_count: dw 0
|
|
|
|
times 510-($-$$) db 0
|
|
|
|
db 0x55, 0xaa
|
|
|