471 lines
7.7 KiB
NASM
471 lines
7.7 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+177
|
|
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: ;done with ram disk, on to vesa info...
|
|
xor ax, ax
|
|
mov gs, ax
|
|
mov ds, ax
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov di, 160
|
|
mov cx, 2000-80
|
|
mov ax, 0x0700
|
|
cls_vesa_loop:
|
|
stosw
|
|
loop cls_vesa_loop
|
|
mov si, txt_vesa
|
|
mov di, 160*1
|
|
mov ah, 7
|
|
call puts
|
|
|
|
push di
|
|
mov ax, 0x0100
|
|
mov es, ax
|
|
xor di, di
|
|
mov dword [es:si], "2EBV"
|
|
mov ax, 0x4F00
|
|
|
|
int 0x10
|
|
pop di
|
|
cmp ax, 0x004F
|
|
jz vesa_good
|
|
mov si, txt_novesa
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov ah, 7
|
|
call puts
|
|
mov ax, BOOT_DATA_SEG
|
|
mov ds, ax
|
|
mov word [ds:BOOT_VESA], 0
|
|
jmp vesa_done
|
|
vesa_good:
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
mov ax, 0x0100
|
|
mov ds, ax
|
|
xor si, si
|
|
mov bx, [4]
|
|
mov al, bh
|
|
call puthex
|
|
mov al, '.'
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
mov al, bl
|
|
call puthex
|
|
add di, 4
|
|
cmp bh, 2
|
|
jge vesa_good2
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_vesaold
|
|
mov ah, 7
|
|
call puts
|
|
mov ax, BOOT_DATA_SEG
|
|
mov ds, ax
|
|
mov word [ds:BOOT_VESA], 0
|
|
jmp vesa_done
|
|
vesa_good2:
|
|
mov ebx, [6] ;something like 0x00000E60
|
|
mov edx, [14]
|
|
mov si, bx
|
|
shr ebx, 16
|
|
mov ds, bx ;ds:si points to null-terminated OEM identification string
|
|
mov ah, 2
|
|
push si
|
|
call puts
|
|
pop si
|
|
mov ax, BOOT_DATA_SEG
|
|
mov es, ax
|
|
mov di, BOOT_VESA_OEM
|
|
vesa_copyoem:
|
|
lodsb
|
|
stosb
|
|
or al, al
|
|
jnz vesa_copyoem
|
|
mov ax, 0x0100
|
|
mov ds, ax
|
|
xor si, si
|
|
mov di, BOOT_VESA_VBE
|
|
mov cx, 512
|
|
vesa_copyvbe:
|
|
lodsb
|
|
stosb
|
|
loop vesa_copyvbe
|
|
|
|
mov si, dx
|
|
shr edx, 16
|
|
mov ds, dx ;ds:si points to video mode list
|
|
|
|
|
|
|
|
;------------------------------------------------------
|
|
vesa_done:
|
|
|
|
xor ax, ax ;wait for keypress...
|
|
int 0x16
|
|
|
|
jmp go_pm
|
|
|
|
puts:
|
|
lodsb
|
|
or al, al
|
|
jz puts_done
|
|
stosb
|
|
mov al, ah
|
|
stosb
|
|
jmp puts
|
|
puts_done:
|
|
ret
|
|
|
|
checkvesa:
|
|
cmp ax, 0x004F
|
|
jnz vesaerror
|
|
ret
|
|
vesaerror:
|
|
mov ax, 0xb800
|
|
mov es, ax
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov si, txt_vesaerror
|
|
mov di, 160*24
|
|
mov ah, 4
|
|
call puts
|
|
cli
|
|
hlt
|
|
|
|
;------------------------------------------------------
|
|
puthex:
|
|
;es:di points to video memory
|
|
;al holds hex value
|
|
|
|
push ax
|
|
mov ah, al
|
|
shr ax, 4
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex_goon1
|
|
add al, 'A'-'9'-1
|
|
puthex_goon1:
|
|
cmp al, '0'
|
|
jz puthex_skipzero
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
puthex_skipzero:
|
|
pop ax
|
|
push ax
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex_goon2
|
|
add al, 'A'-'9'-1
|
|
puthex_goon2:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
ret
|
|
|
|
puthex2:
|
|
;es:di points to video memory, always displays 2 characters!
|
|
;al holds hex value
|
|
|
|
push ax
|
|
mov ah, al
|
|
shr ax, 4
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex2_goon1
|
|
add al, 'A'-'9'-1
|
|
puthex2_goon1:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
push ax
|
|
and al, 0x0F
|
|
add al, '0'
|
|
cmp al, '9'
|
|
jle puthex2_goon2
|
|
add al, 'A'-'9'-1
|
|
puthex2_goon2:
|
|
stosb
|
|
mov al, 7
|
|
stosb
|
|
pop ax
|
|
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
|
|
txt_vesaerror: db "VESA function call error! Halting system!", 0
|
|
txt_novesa: db "VESA not found. Starting in console mode...", 0
|
|
txt_vesaold: db "VESA version 2.0 required. Starting in console mode...", 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"
|
|
|
|
|