X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=geekos%2Fsrc%2Fgeekos%2Ffd_boot.asm;fp=geekos%2Fsrc%2Fgeekos%2Ffd_boot.asm;h=1250665d891944eadfadb128ac365289517f2c1e;hp=0000000000000000000000000000000000000000;hb=ddc16b0737cf58f7aa90a69c6652cdf4090aec51;hpb=626595465a2c6987606a6bc697df65130ad8c2d3 diff --git a/geekos/src/geekos/fd_boot.asm b/geekos/src/geekos/fd_boot.asm new file mode 100644 index 0000000..1250665 --- /dev/null +++ b/geekos/src/geekos/fd_boot.asm @@ -0,0 +1,422 @@ +; Boot sector for GeekOS +; Copyright (c) 2001,2004 David H. Hovemeyer +; Copyright (c) 2003, Jeffrey K. Hollingsworth +; Copyright (c) 2008, Jack Lange high copy table for the bios +; mov ax, word [bootsect_src_base] ; +; add ax, 512 +; mov dx,ax; +; call PrintHex +; adc byte [bootsect_src_base+2], 0 +; mov word [bootsect_src_base],ax + + mov ax, word [bootsect_dst_base] ; + add ax, 512 + adc byte [bootsect_dst_base+2], 0 + mov word [bootsect_dst_base],ax + + ; have we loaded all of the sectors? + + mov bx, word [max_sector] + cmp word [sec_count], bx + + +.stall +; jmp .skip + jl .again2 + +.skip + ; Now we've loaded the setup code and the kernel image. + ; Jump to setup code. + jmp SETUPSEG:0 + +; Read a sector from the floppy drive. +; This code (and the rest of this boot sector) will have to +; be re-written at some point so it reads more than one +; sector at a time. +; +; Parameters: +; - "logical" sector number [bp+8] +; - destination segment [bp+6] +; - destination offset [bp+4] +ReadSector: + push bp ; set up stack frame + mov bp, sp ; " + pusha ; save all registers + +%if 0 +; debug params + mov dx, [bp+8] + call PrintHex + call PrintNL + mov dx, [bp+6] + call PrintHex + call PrintNL + mov dx, [bp+4] + call PrintHex + call PrintNL +%endif + + ; Sector = log_sec % SECTORS_PER_TRACK + ; Head = (log_sec / SECTORS_PER_TRACK) % HEADS + mov ax, [bp+8] ; get logical sector number from stack + xor dx, dx ; dx is high part of dividend (== 0) + mov bx, SECTORS_PER_TRACK ; divisor + div bx ; do the division + mov [sec], dx ; sector is the remainder + and ax, 1 ; same as mod by HEADS==2 (slight hack) + mov [head], ax + + ; Track = log_sec / (SECTORS_PER_TRACK*HEADS) + mov ax, [bp+8] ; get logical sector number again + xor dx, dx ; dx is high part of dividend + mov bx, SECTORS_PER_TRACK*2 ; divisor + div bx ; do the division + mov [track], ax ; track is quotient + +%if 0 +; debugging code + mov dx, [sec] + call PrintHex + call PrintNL + mov dx, [head] + call PrintHex + call PrintNL + mov dx, [track] + call PrintHex + call PrintNL +%endif + + ; Now, try to actually read the sector from the floppy, + ; retrying up to 3 times. + + mov [num_retries], byte 0 + +.again: + mov ax, [bp+6] ; dest segment... + mov es, ax ; goes in es + mov ax, (0x02 << 8) | 1 ; function = 02h in ah, + ; # secs = 1 in al + mov bx, [track] ; track number... + mov ch, bl ; goes in ch + mov bx, [sec] ; sector number... + mov cl, bl ; goes in cl... + inc cl ; but it must be 1-based, not 0-based + mov bx, [head] ; head number... + mov dh, bl ; goes in dh + xor dl, dl ; hard code drive=0 + mov bx, [bp+4] ; offset goes in bx + ; (es:bx points to buffer) + ; Call the BIOS Read Diskette Sectors service + int 0x13 + + ; If the carry flag is NOT set, then there was no error + ; and we're done. + jnc .done + + ; Error - code stored in ah + mov dx, ax + call PrintHex + inc byte [num_retries] + cmp byte [num_retries], 3 + jne .again + + ; If we got here, we failed thrice, so we give up + mov dx, 0xdead + call PrintHex +.here: jmp .here + +.done: + popa ; restore all regisiters + pop bp ; leave stack frame + ret + +; Include utility routines: +;%include "util.asm" +; REPLACED WITH FOLLOWING WHICH MUST BE COMPILED 16 FOR USE IN THIS CODE +PrintHex: + pusha + mov cx, 4 ; 4 hex digits +.PrintDigit: + rol dx, 4 ; rotate so that lowest 4 bits are used + mov ax, 0E0Fh ; ah = request, al = mask for nybble + and al, dl + add al, 90h ; convert al to ascii hex (four instructions) + daa ; I've spent 1 hour to understand how it works.. + adc al, 40h + daa + int 10h + loop .PrintDigit + popa + ret + +; Print a newline. +PrintNL: ; print CR and NL + push ax + mov ax, 0E0Dh ; CR + int 10h + mov al, 0Ah ; LF + int 10h + pop ax + ret + + + +; ---------------------------------------------------------------------- +; Variables +; ---------------------------------------------------------------------- + +; These are used by ReadSector +head: dw 0 +track: dw 0 +sec: dw 0 +num_retries: db 0 + +; Used for loops reading sectors from floppy +sec_count: dw 0 +max_sector: dw 0 + + + + +bootsect_gdt: + dw 0,0,0,0 + dw 0,0,0,0 +bootsect_src: + dw 0xffff +bootsect_src_base: + db 0,0x20,0x08 ; ! base = 0x082000 + db 0x93 ; ! typbyte + dw 0 ; ! limit16,base24 =0 +bootsect_dst: + dw 0xffff +bootsect_dst_base: + db 0,0,0x10 ; ! base = 0x100000 + db 0x93 ; ! typbyte + dw 0 ; ! limit16,base24 =0 + dw 0,0,0,0 ; ! BIOS CS + dw 0,0,0,0 ; ! BIOS DS + + +; Padding to make the PFAT Boot Record sit just before the BIOS signature. +;Pad_From_Symbol PFAT_BOOT_RECORD_OFFSET, BeginText + +; PFAT boot record +; Describes how to load the setup program and kernel. +; The default values are appropriate for creating a boot +; floppy by concatenating the boot sector, setup program, +; and kernel image. The buildFat program will change +; these values if the boot floppy is formatted as a PFAT +; filesystem. + dw 0 + dw 0 + + dw 0 + dw 0 + + dw 0 + dw 0 + + dw 0 + dw 0 + + dw 0 + dw 0 + +;; part of pfat boot record +setupStart: + dw 1 ; by default, setup is at first sector + +;; part of pfat boot record +setupSize: + dw NUM_SETUP_SECTORS ; number of sectors in setup + +;; part of pfat boot record +kernelStart: + dw 1+NUM_SETUP_SECTORS ; default start sector for kernel + +;; part of pfat boot record +kernelSize: + dw NUM_KERN_SECTORS + + + + + ; Finish by writing the BIOS signature to mark this as +; a valid boot sector. +Pad_From_Symbol BIOS_SIGNATURE_OFFSET, BeginText +Signature dw 0xAA55 ; BIOS controls this to ensure this is a boot sector