%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 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"