%include "bootdef.inc" [bits 16] org 0x7c00 jmp short start ; -------------------------------------------------- ; data portion of the "DOS BOOT RECORD" ; ---------------------------------------------------------------------- brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B brBPS DW 512 ; 000Bh - Bytes per sector brSPC DB 1 ; 000Dh - Sector per cluster brSc_b4_fat DW 1 ; 000Eh - Reserved sectors brFATs DB 2 ; 0010h - FAT copies brRootEntries DW 0E0H ; 0011h - Root directory entries brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB brMedia DB 240 ; 0015h - Media descriptor brSPF DW 9 ; 0016h - Sectors per FAT brSc_p_trk DW 18 ; 0018h - Sectors per head/track brHPC DW 2 ; 001Ah - Heads per cylinder brSc_b4_prt DD 0 ; 001Ch - Hidden sectors brSectors DD 0 ; 0020h - Total number of sectors brDrive DB 0 ; 0024h - Physical drive no. DB 0 ; 0025h - Reserved (FAT32) DB 29H ; 0026h - Extended boot record sig (FAT32) brSerialNum DD 404418EAH ; 0027h - Volume serial number brLabel DB 'HOS 0.1.1 ' ; 002Bh - Volume label brFSID DB 'FAT12 ' ; 0036h - File System ID ;------------------------------------------------------------------------ start: jmp 0:jmphere ;ensure that cs=0 and ip=0x7c... jmphere: ;dl=drive number, save it! xor ax, ax mov ds, ax mov [brDrive], dl cli mov ss, ax mov sp, 0x7Bfe ;right under boot sector sti mov ax, 0xb800 mov ds, ax mov es, ax xor di, di mov ax, 0x0700 mov cx, 2000 cls: stosw loop cls enable_a20: in al, 0x64 test al, 2 jnz enable_a20 mov al, 0xD1 out 0x64, al ea20_2: in al, 0x64 and ax, byte 2 jnz ea20_2 mov al, 0xDF out 0x60, al unreal: xor ax, ax mov es, ax mov ds, ax lgdt [gdtr] ;load gdt cli push es push ds ;save segment values mov ebx, cr0 inc bl mov cr0, ebx ;pmode! mov ax, KERNEL_DATA mov es, ax mov ds, ax ;load segment limits dec bl mov cr0, ebx ;back to real mode! pop ds pop es ;segments back, with 4gb limits! sti ;now lets read in the FAT and root directory so we can search for the kernel file... mov ax, 0x0209 ;FAT1 mov cx, 0x0002 xor dh, dh mov dl, [brDrive] mov bx, BOOT_FAT_SEG mov es, bx xor bx, bx int 0x13 mov ax, 0x020E ;root directory mov cx, 0x0002 ;cyl/sect mov dh, 0x01 ;head mov dl, [brDrive] ;drive mov bx, BOOT_ROOT_SEG mov es, bx xor bx, bx int 0x13 ;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, stage2 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 add si, 32 loop loop_compare error: jmp $ ;halt! no kernel file found! found_file: ;ds:si points to root dir entry xor ax, ax mov gs, ax mov ax, BOOT_STAGE2_SEG mov es, ax mov ax, [ds:si+26] mov bx, BOOT_FAT_SEG mov ds, bx ;ds points to beginning of FAT xor di, di readstage2_loop: cmp ax, 0xff7 jg readstage2_done inc di push ax call getCHSfromCluster mov ax, 0x0201 mov dl, [gs:BOOT_DRIVE] xor bx, bx int 0x13 mov bx, es add bx, 0x0020 mov es, bx 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 readstage2_loop readstage2_done: jmp 0:BOOT_STAGE2_ADD ;------------------------------------------------------ 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_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: stage2: db "STAGE2 BIN" times 510-($-$$) db 0 db 0x55, 0xaa