Just to update.. the idea with this boot-loader (stage1) is for it to be able to work from a floppy/hdd/cdrom or usb in a single unified way. From what I understand the BIOS emulates a HD when booting from usb or cdrom? the 2nd stage loader will always be under 16 sectors (8kb?) I'm assuming at boot time all devices would present 512 byte sectors (usb/hd/cd) via bios 13h 02h? - in which case i can avoid lba2chs or anything else in the stage1 loader.
I'm not worried about supporting partitions/mbr really for what i'm doing and i don't want to use a ready-made loader like grub etc seing as it's for fun and one might as well write it all to learn.
Here is the full code with regards to the previous post, perhaps someone can see a major flaw .. I've tried to combine what i've read and seen from various loaders to support FD/HD/USB ..
Any thoughts as to why this thing loads sectors for the 2nd stage with out any errors but the data is all just 0.
Code: Select all
.386p
code segment para public use16 'code'
assume cs:code, ds:code
;--------------------------------------------------------------------------------
; Ensure the assembler generates 0 relative offsets for our later CS correction.
; -> Some BIOSes will load the boot sector code to 0000:7c00 while others
; -> will load it to 07c0:0000. We move it to this in either event for
; -> simplicity and to ensure we can re-locate the code to a different segment
; -> without affecting the offsets.
;--------------------------------------------------------------------------------
org 0h
start:
jmp short begin ; This 2 byte jump will always be the first part of our MBR.
;-----------------------------------------------------------------------------------
; MDB (Master Disk Block) = 32bytes.
;-----------------------------------------------------------------------------------
m_filesystem db "VXFS" ; File System Type in Use on Logical Disk.
m_volume db "UNTITLED" ; Drive Volume Name.
m_heads dw 2 ; Heads per Disk (Physical).
m_cylinders dw 80 ; Cylinders Per Head (Physical).
m_sectors dd 18 ; Sectors Per Track (Physical).
m_sectorsize dw 512 ; Size in bytes of a sector (Physical).
m_driveNo db 00h ; 0 = fdd0 / 80h = hdd0.
m_mode dw 0 ; 1 = CHS / 0 = LBA.
m_first_sec dd 0 ; First Sector Of File System.
padding db 0
;###############################################################################################################
; BOOT LOADER CODE BEGINS HERE.
;###############################################################################################################
begin:
db 0eah ; Hard-coded long jump to seg:ofs as specified.
dw offset cs_correction, 07c0h
cs_correction:
cli ; Disable any interrupts.
xor ax,ax
mov es,ax
dec ax
mov sp,ax
mov ax,9000h
mov ss,ax ; Setup stack at 9000:ffff (common place).
mov ax,07c0h
mov ds,ax ; Ensure DS = CS (07c0:0000).
mov m_driveNo,dl ; Store the Boot Drive Number (BIOS will start us with this in DL).
xor si,si ; DS:SI = begin of original bootloader.
mov di,600h ; ES:DI = begin of new bootloader.
mov cx,100h ; Copy 256 words (512 bytes).
rep movsw ; Copy bootloader.
db 0eah ; Hardcode force far jmp.
dw offset bootloader_exc0,0060h ; new code addr = (0060:bootloader_exc0).
;=============================================================================================================
; Bootloader will commence from here at new address.
; -> All offsets need to be adjusted manually from here on due
; -> to self-modified execution address 600h.
; -> eg (offset Print_Msg-7c00h)+600h
; -> short IP relative jmps are fine.
; -> THIS IS NOW FIXED BY USING ORG 0h and seg:0000...!!!!
; -> Just out of interest 0600h happens to be the address DOS 1.x loaded to..
;=============================================================================================================
bootloader_exc0:
mov ax,060h ; Reset Seg Registers.
mov ds,ax ; CS and DS = 0060h.
;--------------------------------------------------------------------------------
; If we get this far, we can display the startup message and
; start doing some useful setup.
; -> Traditionally we'd want to check for a 386+ machine, but these days?
;--------------------------------------------------------------------------------
mov ax,03h ; Reset 80x25 text mode.
int 10h
mov si,offset msg0 ; Display Start Message.
call printstr
mov si,offset msg1 ; Display Boot Drive Number.
call printstr
mov al,m_driveNo
call printbyte
; The Interrupt Vector Table (IVT) occupies the first 1024 bytes of low memory and
; contains 256 4-byte entries. Each entry is an address to an Interrupt routine.
; The INT 1E vector (Diskette Configuration pointer) is at 0000:0078 and contains
; the address to the Diskette Parameter Table (DPT). (78h/4 = 1Eh)
;-----------------------------------------------------------------------------------
; -> Reset FDC Param Tables (apparently some BIOS have too low max sector
; count (7).. we need 36 for max 2.88 disks, this messes up multi-sector
; reads greater than the BIOS value. Too high is safe, too low not...
;-----------------------------------------------------------------------------------
push ds
mov bx,078h ; ES:BX = FDC BIOS Param Table Ptr.
lds si,es:[bx] ; DS:SI points to Param Table.
mov byte ptr ds:[si+4],36 ; Kludge Sector Per Track Count (36 = 2.88 disk). We try 63?
mov byte ptr ds:[si+9],0fh ; Reset Head Bounce Time.
pop ds ; Updates INT 1E table.
mov dl,m_driveNo
xor ax,ax
int 13h ; Reset Controller for booted drive.
;--------------------------------------------------------------------------------
; Did we get booted from a floppy, harddisk, usb or cdrom?
; -> USB will emulate a HDD boot (80h).
;--------------------------------------------------------------------------------
cmp m_driveNo,80h
jae skip_not_floppy
;====================================================================================
; FLOPPY DISK BOOT SOURCE.
;====================================================================================
mov m_heads,2 ; All floppies have 2 heads(?)
mov m_sectorsize,512 ; All floppies have 512 byte sectors.
mov m_cylinders,80 ; All floppies have 80 cylinders.
mov m_mode,1 ; All floppies have CHS addressing.
;-----------------------------------------------------------------------------------
; Probe Disk Drive Sectors per Track.
; -> Try 36, then 18 and so on to see what works as BIOS has no definite way
; -> of knowing using INT13H, SERVICE 08h... more arcane rubbish.
;-----------------------------------------------------------------------------------
mov ax,07c0h
mov es,ax
mov si,offset disksizes
probe_loop:
xor eax,eax
xor cx,cx
mov al,ds:[si]
inc si
cbw ; Extend AL to AX.
mov m_sectors,eax
cmp si,(offset disksizes)+4
jae short got_sect_size
mov cl,al
xor dx,dx
mov dl,m_driveNo
xor bx,bx ; Use future load address to overwrite (no danger).
mov ax,0201h
int 13h
jc short probe_loop ; If failed try next sector size down.
got_sect_size:
mov di,4 ; Retry load a few times.
readatt0:
xor ax,ax
mov dl,m_driveNo
int 13h ; Ensure FDC Boot Source is Reset Again.
mov ax,07c0h ; ES:[BX] = 07C0:0000
mov es,ax
xor bx,bx
mov ax,0208h ; Load 8 sectors.
mov dl,m_driveNo ; Drive to Load From (Boot Drive).
mov cx,02h ; Starting Sector
xor dh,dh
int 13h
jnc short doneloadingok
dec di
jnz short readatt0
mov si,offset errmsg1 ; Fail if we can't load stage2 loader.
call bootfail
doneloadingok:
mov dx,03f2h
xor al,al
out dx,al ; Ensure we turn off the floppy mode to enter 2nd stage loader in known state.
jmp doneloading
;====================================================================================
; HARD-DISK BOOT SOURCE.
;====================================================================================
skip_not_floppy:
mov ah,08h
mov dl,m_driveNo
int 13h
xor ax,ax
mov al,ch
mov ah,cl
and ah,11000000b
shr ah,6
mov m_cylinders,ax
xor eax,eax
mov al,cl
and al,00111111b
mov m_sectors,eax
mov ax,07c0h
mov es,ax
mov al,byte ptr es:[0]
call printbyte
mov di,4
attempthdload:
xor ax,ax
mov es,ax
mov dl,m_driveNo
int 13h
mov bx,07c00h
mov ax,0208h ; Load 8 sectors.
mov dl,m_driveNo ; Drive to Load From (Boot Drive).
mov cx,02h ; Starting Sector
xor dh,dh
int 13h
jnc short doneloading
dec di
jnz short attempthdload
mov si,offset errmsg1 ; Failed to load 2nd stage from HDD source.
call bootfail
;====================================================================================
; Switch to 2nd Stage Loader Now.
;====================================================================================
doneloading:
mov al,byte ptr es:[7c00h]
call printbyte
jmp short $
db 0eah
dw 0000h, 07c0h ; Hard coded Far Jump to 07c0:0000h.
;######################################################################################################
; !!!All first stage boot loader procedures and data go here!!!
;######################################################################################################
;Value Color Value Color
;00h Black 08h Dark gray
;01h Blue 09h Bright blue
;02h Green 0Ah Bright green
;03h Cyan 0Bh Bright cyan
;04h Red 0Ch Pink
;05h Magenta 0Dh Bright magenta
;06h Brown 0Eh Yellow
;07h Gray 0Fh White
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Print an ASCII string.
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
printstr:
mov ah,0Eh
mov bh,00h
mov bl,07h
lodsb
or al,al
jz short strDone
int 10h
jmp short printstr
strDone:
ret
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Print a byte value in hex.
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
printbyte:
pusha
xor ah,ah
mov cl,al
mov bh,00h
mov bl,07h
and al,11110000b
and cl,00001111b
shr al,4
mov si,offset hexLUT
add si,ax
mov al,ds:[si]
mov ah,0Eh
int 10h
xor ax,ax
mov al,cl
mov si,offset hexLUT
add si,ax
mov al,ds:[si]
mov ah,0Eh
int 10h
popa
ret
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Boot Failure and Reboot.
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
bootfail:
call printstr ; Display whichever error msg was passed in.
;mov si,offset errmsg0
;call printstr ; Display the "any key to reboot" message.
xor ax,ax
int 16h ; Wait for key press.
int 19h ; Force POST reboot by calling int 19h.
; ALTERNATIVE REBOOT.
; store magic value at 0040:0072h
; - 0000h - cold boot.
; - 1234h - warm boot.
;mov ax,40h
;mov es,ax
;mov word ptr es:[0072h],0000h
;db 0eah ; Jump to ffff:0000 (Alternative Reboot Scheme).
;dw 0000h
;dw 0ffffh
;=====================================================================================================
; BootLoader Data Area.
;=====================================================================================================
;errmsg0 db '<Press any key to reboot>',13,10,0
errmsg1 db 'error',13,10,0
msg0 db 'VXOS v1.0',13,10,0
msg1 db 'drive:',0
disksizes db 36, 18, 15, 9 ; SPT options for FDD. (Sectors per Track).
hexLUT db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
db 510-($-start) DUP (0) ; Add padding to ensure boot loader code is exactly 512bytes long.
db 055h,0aah ; Boot loader signature which must be present at end of 512byte 1st sector.
; BIOS will check this magic number to ensure that it is a bootable sector.
code ends ; End of Code Segment.
end start ; End of Block Marker.