296 lines
4.8 KiB
NASM
296 lines
4.8 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
|
|
xor ax, ax
|
|
mov gs, ax
|
|
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, [gs:BOOT_DRIVE]
|
|
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: ;-------------put more real mode init stuff here!
|
|
;----ask to load RD from floppy
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
xor ax, ax
|
|
mov ds, ax
|
|
xor di, di
|
|
mov cx, 2000
|
|
mov ax, 0x0700
|
|
cls_loop:
|
|
stosw
|
|
loop cls_loop
|
|
|
|
mov dx, 0x3d4 ;move cursor off screen...
|
|
mov al, 0x0e
|
|
out dx, al
|
|
inc dx
|
|
mov al, 0xff
|
|
out dx, al
|
|
dec dx
|
|
mov al, 0x0f
|
|
out dx, al
|
|
inc dx
|
|
out dx, al
|
|
|
|
xor di, di
|
|
mov si, txt_welcome
|
|
mov ah, 0x1f
|
|
call puts
|
|
|
|
mov di, 160
|
|
mov si, txt_rd1
|
|
mov ah, 7
|
|
call puts
|
|
|
|
mov si, txt_rd2
|
|
mov di, 160*2
|
|
call puts
|
|
|
|
mov di, 160*3
|
|
mov si, txt_input
|
|
call puts
|
|
|
|
get_rd:
|
|
xor ax, ax
|
|
int 0x16
|
|
cmp al, '1'
|
|
jz got_rd
|
|
cmp al, '2'
|
|
jnz get_rd
|
|
got_rd:
|
|
stosb
|
|
sub al, '1'
|
|
push ds
|
|
mov bx, BOOT_DATA_SEG ;segment for data to send kernel
|
|
mov ds, bx
|
|
mov [ds:BOOT_HASRD], al
|
|
pop ds ;ds=0
|
|
cmp al, 0 ;dont load rd
|
|
jz no_rd
|
|
|
|
mov cx, 80
|
|
mov edi, 0xb8000+160*4
|
|
filler_loop:
|
|
mov word [ds:edi], 0x0400+176
|
|
inc edi
|
|
inc edi
|
|
loop filler_loop
|
|
mov cx, 80 ;80 cylinders to read
|
|
xor si, si
|
|
mov edi, BOOT_RD_ADD ;ram disk address
|
|
read_cylinder:
|
|
push cx
|
|
mov bx, 0x0100
|
|
mov es, bx
|
|
xor bx, bx
|
|
mov ax, 0x0224
|
|
mov cx, si
|
|
mov ch, cl
|
|
mov cl, 1
|
|
xor dx, dx
|
|
mov dl, [gs:BOOT_DRIVE]
|
|
int 0x13
|
|
|
|
mov ebx, 0xb8000
|
|
add bx, si
|
|
shl bl, 1
|
|
mov word [ds:ebx+160*4], 0x0200+219
|
|
|
|
push si
|
|
mov esi, 0x1000
|
|
mov cx, 0x2400
|
|
copydisk_loop:
|
|
mov ax, [ds:esi]
|
|
inc esi
|
|
inc esi
|
|
mov [ds:edi], ax
|
|
inc edi
|
|
inc edi
|
|
loop copydisk_loop
|
|
|
|
pop si ;what cylinder# we are on...
|
|
inc si
|
|
pop cx
|
|
loop read_cylinder
|
|
|
|
no_rd:
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov si, txt_vesa
|
|
mov di, 160*5
|
|
mov ah, 7
|
|
call puts
|
|
|
|
|
|
xor ax, ax
|
|
int 0x16
|
|
|
|
jmp go_pm
|
|
|
|
puts:
|
|
lodsb
|
|
or al, al
|
|
jz puts_done
|
|
stosb
|
|
mov al, ah
|
|
stosb
|
|
jmp puts
|
|
puts_done:
|
|
ret
|
|
|
|
txt_welcome: db " Welcome to HOS v", VERSION, "! ", 0
|
|
txt_rd1: db "1. Do not load an initial ram disk", 0
|
|
txt_rd2: db "2. Load initial ram disk from floppy", 0
|
|
txt_input: db "Enter your selection: ", 0
|
|
txt_vesa: db "VESA version: ", 0
|
|
|
|
;------------------------------------------------------
|
|
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
|
|
mov fs, ax
|
|
mov gs, ax
|
|
jmp KERNEL_CODE:BOOT_KERNEL_ADD
|
|
|
|
kernel: db "KERNEL BIN"
|
|
|
|
|