Writing bootloader to FAT32 USB problem
Writing bootloader to FAT32 USB problem
Hello, everyone.
I've written (found & made a few minor adjustments) a simple "Hello world" bootloader, which works if compiled as a img file and used on a virtual machine, but I want to write it to a FAT32 USB flash drive without corrupting it's file system. For this task I tried using HxD hex editor, under menu "Extras" -> "Open disk..." and selecting my USB pen drive by letter. I after that replaced values after SysID (everything after FAT32 index table...or whatever) up to the final boot signature and modified the first 3 bytes accordingly. After saving the changes I removed my USB, inserted it again and everything worked (no FS corrupted). However, by booting "real hardware" from USB (my PC does support that, since I've installed my operating system - Win7,8 - that way several times) it just simply jumps over it and starts booting from my second drive (HDD with wins) bootstart list.
What am I missing? If you want to see the assembly code to check if anything there is corrupted say so.
(Is it possible for this to be caused because I changed in my BIOS setting the way it "reads" disks from default - IDE - to ASCI? I did not want to try to change it because my WIN won't boot up afterwards.)
Sincerely.
I've written (found & made a few minor adjustments) a simple "Hello world" bootloader, which works if compiled as a img file and used on a virtual machine, but I want to write it to a FAT32 USB flash drive without corrupting it's file system. For this task I tried using HxD hex editor, under menu "Extras" -> "Open disk..." and selecting my USB pen drive by letter. I after that replaced values after SysID (everything after FAT32 index table...or whatever) up to the final boot signature and modified the first 3 bytes accordingly. After saving the changes I removed my USB, inserted it again and everything worked (no FS corrupted). However, by booting "real hardware" from USB (my PC does support that, since I've installed my operating system - Win7,8 - that way several times) it just simply jumps over it and starts booting from my second drive (HDD with wins) bootstart list.
What am I missing? If you want to see the assembly code to check if anything there is corrupted say so.
(Is it possible for this to be caused because I changed in my BIOS setting the way it "reads" disks from default - IDE - to ASCI? I did not want to try to change it because my WIN won't boot up afterwards.)
Sincerely.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Writing bootloader to FAT32 USB problem
An USB stick is likely to have a partition table, where you'd need to set the bootable bit and maybe add/replace a MBR instead of dealing with just the filesystem. One other thing to check is if the boot signature is present at the correct location.
Re: Writing bootloader to FAT32 USB problem
This option is called AHCI. It has effect only if you are trying to work with SATA device directly (not through BIOS). I think Combuster is right. Check active flag in partition table. If you don't know how to do it then open your USB flash drive as a physical disk in HxD and show hex dump of its first sector (MBR).makuc9 wrote:What am I missing? If you want to see the assembly code to check if anything there is corrupted say so.
(Is it possible for this to be caused because I changed in my BIOS setting the way it "reads" disks from default - IDE - to ASCI? I did not want to try to change it because my WIN won't boot up afterwards.)
If you have seen bad English in my words, tell me what's wrong, please.
Re: Writing bootloader to FAT32 USB problem
Well, I sure hope we are talking about the same stuff. Anyway. I have edited the first sector (sector 0) on USB. There are a few specifications about FS (like OEM name, sectors per cluster...). Boot record, actually. The first 3 bytes here are JUMP code + nop, then is FAT32 stuff and after that is the place where your bootloader can actually be written (am I correct?). and than at 511 & 512 (last 2 bytes in 512 bytes large boot record) is boot signature.
I compile it using NASM and use HxD editor (steps explained in my first post) to write it to Sector 0 of USB.
Code: Select all
BITS 16
ORG 0x7C00
Start:
jmp Skip
nop
; OEM Parameter block, FAT 12/16/32
bOemName db "MSDOS4.0"
wBlockSize dw 0
bSecPerClus db 0
wReservedSecs dw 0
bNumFats db 0
wRootEntries dw 0
wSectors16 dw 0
bMediaType db 0
wFATSz16 dw 0
wSecPerTrack dw 0
wNumHeads dw 0
lSecCache dd 0
lSectors32 dd 0
lFATSz32 dd 0
wExtFlags dw 0
wFSVer dw 0
lRootCluster dd 0
wFSInfo dw 0
wBkBootSec dw 0
BytesPerCluster dd 0
CurrentCluster dd 0
lDataSector dd 0
bDriveNum db 0
bReserved db 0
bBootSig db 0
lVolSerial dd 0xDEADF007
szVolLabel db "-----------"
bSysID db "COPYHERE"
Skip:
cli
xor ax, ax
mov ds, ax
mov es, ax
; Other stuff for bootloader to do
hlt
TIMES 510-($-$$) db 0
DW 0xAA55
Last edited by makuc9 on Mon Mar 04, 2013 6:27 am, edited 1 time in total.
Re: Writing bootloader to FAT32 USB problem
And what about MBR?
If you have seen bad English in my words, tell me what's wrong, please.
Re: Writing bootloader to FAT32 USB problem
A disk does not require an MBR, does it? Although, conventionally, hard disks are partitioned the MBR is - in essence - just a first stage boot loader. What is to stop you having an unpartitioned disk and replacing the MBR by a custom bootloader (i.e. treating the disk, or USB stick, as a large floppy disk)?
Re: Writing bootloader to FAT32 USB problem
I'm not sure that TS doesn't have MBR on the flash drive.
If you have seen bad English in my words, tell me what's wrong, please.
Re: Writing bootloader to FAT32 USB problem
Hmm, what am I doing wrong? Why doesn't that work on my USB drive?
Link to the assembled binary file:
https://mega.co.nz/#!KFdGCAQI!CMB95XMmU ... IH-xo-kUyg
Link to the MBR record of rewritten USB FAT32:
https://mega.co.nz/#!zJkAhK5C!fL6UtnLRq ... gsFX8txW50
Any help appreciated. As I said before, all I can achieve is been successfully skipped by bootloader on another disk.
Edit:
If I disconnect all other disks, my PC only stays there and nothing happens (it remains on "Verifynd DMI Pool Data ......" and there is char indicator (you know, that flashing thingy indicating where you are to write next letter) in a new line.
Code: Select all
BITS 16
ORG 0x7C00
Start:
jmp Skip
nop
;****************************************;
; ----- OEM Parameter block, FAT32 ----- ;
;****************************************;
bOemName db "MSDOS4.0" ; 8 bytes
; ----- FAT32 Bios Parameter Block ----- ;
wBlockSize dw 0
bSecPerClus db 0
wReservedSecs dw 0
bNumFats db 0
wRootEntries dw 0
wSectors16 dw 0
bMediaType db 0
wFATSz16 dw 0
wSecPerTrack dw 0
wNumHeads dw 0
lSecCache dd 0 ; lHiddenSecs
lSectors32 dd 0
;*******************************************;
; ----- Extended BIOS Parameter Block ----- ;
;*******************************************;
lFATSz32 dd 0
wExtFlags dw 0 ; Bits 0-3 = Active FAT, 7 = !FAT
wFSVer dw 0
lRootCluster dd 0
wFSInfo dw 0
wBkBootSec dw 0
BytesPerCluster dd 0 ;Reserved 1
CurrentCluster dd 0 ;Reserved 2
lDataSector dd 0 ;Reserved 3
bDriveNum db 0
bReserved db 0
bBootSig db 0
lVolSerial dd 0xDEADF007
szVolLabel db "-----------"
bSysID db "COPYHERE"
; ----- Booting process pro ----- ;
Skip:
; ----- Adjust registers ----- ;
cli
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; ----- Display load message ----- ;
mov si, msgLoading
call print_s
jmp $
hlt
; ----- Predefined functions ----- ;
print_s:
lodsb ; get next character
or al, al ; check, if null-terminator
jz end ; yes? -> printing done
mov ah, 0eh ; no? -> print the character
int 10h ; call BIOS
jmp print_s ; repeat until null-terminator found
end: ; Return upon function exe completion
ret
; ----- Data ----- ;
msgLoading db "Will be loading operating system...", 0
TIMES 510-($-$$) db 0
DW 0xAA55
https://mega.co.nz/#!KFdGCAQI!CMB95XMmU ... IH-xo-kUyg
Link to the MBR record of rewritten USB FAT32:
https://mega.co.nz/#!zJkAhK5C!fL6UtnLRq ... gsFX8txW50
Any help appreciated. As I said before, all I can achieve is been successfully skipped by bootloader on another disk.
Edit:
If I disconnect all other disks, my PC only stays there and nothing happens (it remains on "Verifynd DMI Pool Data ......" and there is char indicator (you know, that flashing thingy indicating where you are to write next letter) in a new line.
Re: Writing bootloader to FAT32 USB problem
Flash drives are just emulated usb emulated floppy and hdd drives. Consequently, the same rules apply. A well made floppy or HD bootloader written to the MBR will load your code. I'm not sure how to work with partitions, however, but if you look a few posts down at my older post (i have 2 posts on the front page, one dealing with my bootloader issues, the other with v86), you'll see an example of a bootloader that isn't using a file system. I don't know anything about fat (i opted out of it when i realized i didn't need it for my current project), but i think you could learn from my sample code (but read and see how it was made to work).makuc9 wrote:Hmm, what am I doing wrong? Why doesn't that work on my USB drive?Link to the assembled binary file:Code: Select all
BITS 16 ORG 0x7C00 Start: jmp Skip nop ;****************************************; ; ----- OEM Parameter block, FAT32 ----- ; ;****************************************; bOemName db "MSDOS4.0" ; 8 bytes ; ----- FAT32 Bios Parameter Block ----- ; wBlockSize dw 0 bSecPerClus db 0 wReservedSecs dw 0 bNumFats db 0 wRootEntries dw 0 wSectors16 dw 0 bMediaType db 0 wFATSz16 dw 0 wSecPerTrack dw 0 wNumHeads dw 0 lSecCache dd 0 ; lHiddenSecs lSectors32 dd 0 ;*******************************************; ; ----- Extended BIOS Parameter Block ----- ; ;*******************************************; lFATSz32 dd 0 wExtFlags dw 0 ; Bits 0-3 = Active FAT, 7 = !FAT wFSVer dw 0 lRootCluster dd 0 wFSInfo dw 0 wBkBootSec dw 0 BytesPerCluster dd 0 ;Reserved 1 CurrentCluster dd 0 ;Reserved 2 lDataSector dd 0 ;Reserved 3 bDriveNum db 0 bReserved db 0 bBootSig db 0 lVolSerial dd 0xDEADF007 szVolLabel db "-----------" bSysID db "COPYHERE" ; ----- Booting process pro ----- ; Skip: ; ----- Adjust registers ----- ; cli xor ax, ax mov ds, ax mov es, ax mov fs, ax mov gs, ax ; ----- Display load message ----- ; mov si, msgLoading call print_s jmp $ hlt ; ----- Predefined functions ----- ; print_s: lodsb ; get next character or al, al ; check, if null-terminator jz end ; yes? -> printing done mov ah, 0eh ; no? -> print the character int 10h ; call BIOS jmp print_s ; repeat until null-terminator found end: ; Return upon function exe completion ret ; ----- Data ----- ; msgLoading db "Will be loading operating system...", 0 TIMES 510-($-$$) db 0 DW 0xAA55
https://mega.co.nz/#!KFdGCAQI!CMB95XMmU ... IH-xo-kUyg
Link to the MBR record of rewritten USB FAT32:
https://mega.co.nz/#!zJkAhK5C!fL6UtnLRq ... gsFX8txW50
Any help appreciated. As I said before, all I can achieve is been successfully skipped by bootloader on another disk.
Edit:
If I disconnect all other disks, my PC only stays there and nothing happens (it remains on "Verifynd DMI Pool Data ......" and there is char indicator (you know, that flashing thingy indicating where you are to write next letter) in a new line.
EDIT: just from glancing at your code, it does work, you're just putting it in the wrong place. Your BIOS isn't finding it.
Re: Writing bootloader to FAT32 USB problem
You were right, in a way... I finally managed to solve my problem. Here is cause of the problem, for anyone who is facing the same thing:kohlrak wrote:Flash drives are just emulated usb emulated floppy and hdd drives. Consequently, the same rules apply. A well made floppy or HD bootloader written to the MBR will load your code. I'm not sure how to work with partitions, however, but if you look a few posts down at my older post (i have 2 posts on the front page, one dealing with my bootloader issues, the other with v86), you'll see an example of a bootloader that isn't using a file system. I don't know anything about fat (i opted out of it when i realized i didn't need it for my current project), but i think you could learn from my sample code (but read and see how it was made to work).
EDIT: just from glancing at your code, it does work, you're just putting it in the wrong place. Your BIOS isn't finding it.
http://support.microsoft.com/kb/954457
And I've been trying so hard to discover what I was doing wrong, until you got me thinking to the right way (and into more googling ).
Thanks. (And I only discover this now, after modifying the code numerous times already, modifying for doing the same thing different way. Argh. Stupid me ...
Thank you all for your time and cooperation. Sincerely.