FAT32 Bootloader Problem
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
FAT32 Bootloader Problem
Hello everybody,
i'm new to the great world of OS-Developement and i have a few questions. I tried to write my own FAT32 bootloader which should be able to load and execute a Kernel. To check if it works on real hardware, i want to do this on an usb stick. Now my problem: If i write a stage1 boot loader with a fat32 bios parameter block like this:
OEM_ID db "QUASI-OS"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x08
ReservedSectors dw 0x0020
TotalFATs db 0x02
MaxRootEntries dw 0x0000
NumberOfSectors dw 0x0000
MediaDescriptor db 0xF8
SectorsPerFAT dw 0x0000
SectorsPerTrack dw 0x003D
SectorsPerHead dw 0x0002
HiddenSectors dd 0x00000000
TotalSectors dd 0x00FE3B1F
BigSectorsPerFAT dd 0x00000778
Flags dw 0x0000
FSVersion dw 0x0000
RootDirectoryStart dd 0x00000002
FSInfoSector dw 0x0001
BackupBootSector dw 0x0006
TIMES 13 DB 0 ;jumping to next offset
DriveNumber db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "QUASI BOOT"
SystemID db "FAT32 "
(yes, i have it from the internet due to learning purposes), compile it with nasm to a file like "boot.bin" and then copying it to the usb stick with "dd if=boot.bin of=/dev/sdb1 bs=512" it doesnt work. Linux doesnt recognize the usb stick any more. What am i doing wrong? Is the Fat32 Bios Parameter Block wrong?
Thanks,
Tony
P.S.: Sorry for my bad english, im from germany
i'm new to the great world of OS-Developement and i have a few questions. I tried to write my own FAT32 bootloader which should be able to load and execute a Kernel. To check if it works on real hardware, i want to do this on an usb stick. Now my problem: If i write a stage1 boot loader with a fat32 bios parameter block like this:
OEM_ID db "QUASI-OS"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x08
ReservedSectors dw 0x0020
TotalFATs db 0x02
MaxRootEntries dw 0x0000
NumberOfSectors dw 0x0000
MediaDescriptor db 0xF8
SectorsPerFAT dw 0x0000
SectorsPerTrack dw 0x003D
SectorsPerHead dw 0x0002
HiddenSectors dd 0x00000000
TotalSectors dd 0x00FE3B1F
BigSectorsPerFAT dd 0x00000778
Flags dw 0x0000
FSVersion dw 0x0000
RootDirectoryStart dd 0x00000002
FSInfoSector dw 0x0001
BackupBootSector dw 0x0006
TIMES 13 DB 0 ;jumping to next offset
DriveNumber db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "QUASI BOOT"
SystemID db "FAT32 "
(yes, i have it from the internet due to learning purposes), compile it with nasm to a file like "boot.bin" and then copying it to the usb stick with "dd if=boot.bin of=/dev/sdb1 bs=512" it doesnt work. Linux doesnt recognize the usb stick any more. What am i doing wrong? Is the Fat32 Bios Parameter Block wrong?
Thanks,
Tony
P.S.: Sorry for my bad english, im from germany
Re: FAT32 Bootloader Problem
I just want to throw in a suggestion, because I think it's a lot more simple approach. I never touch the the BIOS Parameter block, I just use the formatting tool already included (in my case windows, right click -> format in FAT32) and then open my boot.bin in HxD (hex-editor) and copy all the code from offset after SystemID member in the EBPB into sector 0 of my USB stick at the same offset. That way i preserve the EBPB. Just make sure that your jump is aligned from the first 3 bytes.
But perhaps it'd be easier to see the fault if you posted some more code. My start of my bootloader looks like this:
But perhaps it'd be easier to see the fault if you posted some more code. My start of my bootloader looks like this:
Code: Select all
BITS 16
ORG 0x7C00
Start:
jmp Skip
nop
;*********************************************
; OEM Parameter block, FAT 12/16/32
; I dont use the values from this particular example
; They are here for reference!
;*********************************************
bOemName db "MollenOS" ;8 Bytes
; /* FAT 12/16 BIOS Parameter Block starts here */
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 mirroring
wFSVer dw 0
lRootCluster dd 0
wFSInfo dw 0
wBkBootSec dw 0
BytesPerCluster dd 0 ;Reserved1
CurrentCluster dd 0 ;Reserved2
lDataSector dd 0 ;Reserved3
bDriveNum db 0
bReserved db 0
bBootSig db 0
lVolSerial dd 0xDEADF007
szVolLabel db "MollenOS V1"
bSysID db "COPYHERE"
Skip:
cli
xor eax, eax ;Clear Eax
xor ecx, ecx ;Clear Ecx
jmp 0:FixCS
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
Ok thank you, this is very helpful, but then i have another question:
How do you copy it just after the ebpb? Are you using dd? Can you tell me the parameters that i have to use?
How do you copy it just after the ebpb? Are you using dd? Can you tell me the parameters that i have to use?
Re: FAT32 Bootloader Problem
I find the correct offset by locating the System ID label, where i named it "COPYHERE", so I can easily locate the correct offset in my boot.bin.
To copy it over i use a hex editor. I don't use DD since I'm on windows.
Just open the USB stick in the hex editor and edit sector 0.
To copy it over i use a hex editor. I don't use DD since I'm on windows.
Just open the USB stick in the hex editor and edit sector 0.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
It works, thank you! But when i use the entries in the ebpb in order to load a stage2 Bootloader (like a "KRNLDR.SYS" or anything else) does it work then? Because when nasm compiles, the entries are all 0...
Re: FAT32 Bootloader Problem
No problem! And yes it will work because after you've copied the modified code to sector 0 it will use the entries in the EBPB on the USB stick and not the ones in the boot.bin (as long as you don't copy the EBPB aswell!). This is because the variables are at the same place in memory.
Re: FAT32 Bootloader Problem
Original code could have jump instruction with other destination label than "after_EBPB". So, following way would be better:
Code: Select all
dd bs=1 count=3 if=boot.bin of=%1
dd bs=1 count=422 if=boot.bin of=%1 skip=90 seek=90
If you have seen bad English in my words, tell me what's wrong, please.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
Ok, i have just another question. I have the following Code:
It should only print the String "Loading Boot Image" on the Screen. In VirtualBox it does well, but if i put the usb into real hardware and boot from it, the screen flickers and then only a "Smiley" is drawn on screen and nothing more. If i only put a "mov al, 'h' mov ah, 0eh int 10h" it works on the real hardware. So i think there must be something strange with the lodsb maybe?!?
Code: Select all
BITS 16
ORG 0x7C00
Start:
jmp Skip
nop
;*********************************************
; OEM Parameter block, FAT 12/16/32
; I dont use the values from this particular example
; They are here for reference!
;*********************************************
bOemName db "Test OS" ;8 Bytes
; /* FAT 12/16 BIOS Parameter Block starts here */
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 mirroring
wFSVer dw 0
lRootCluster dd 0
wFSInfo dw 0
wBkBootSec dw 0
BytesPerCluster dd 0 ;Reserved1
CurrentCluster dd 0 ;Reserved2
lDataSector dd 0 ;Reserved3
bDriveNum db 0
bReserved db 0
bBootSig db 0
lVolSerial dd 0xDEADF007
szVolLabel db "Test Os V1"
bSysID db "COPYHERE"
Skip:
cli
mov si, msgLoading
call Print
hlt
Print:
lodsb
or al, al
jz PrintDone
mov ah, 0eh
int 10h
jmp Print
PrintDone:
ret
msgLoading db "Loading Boot Image...", 0x00
TIMES 510-($-$$) DB 0
DW 0xAA55
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
I just figured out, that the problem must be at the Adress of the msgLoading variable. If i only mov al, [msgLoading], virtual box prints me an "L" as expected, but the real hardware only puts an " ". What am i doing wrong here?
Re: FAT32 Bootloader Problem
Try to setup segments, you don't do this
Add this in to setup DS and ES segments correctly:
*Because the SI register uses the ES segment to access data correctly, and it may contain garbage.
and you are using the SI register to hold the address of your string. So ES needs to be set correctly
Add this in to setup DS and ES segments correctly:
Code: Select all
;Setup Segments
xor ax, ax
mov ds, ax
mov es, ax
and you are using the SI register to hold the address of your string. So ES needs to be set correctly
Re: FAT32 Bootloader Problem
Which processor you talking about? My intel xeon behave differently and use DS for SI unless you explicity override it.MollenOS wrote:*Because the SI register uses the ES segment to access data correctly
Re: FAT32 Bootloader Problem
I'm sorry. I swapped them.
SI normally uses DS and DI normally uses ES.
Either way it's a good idea to setup both ES and DS correctly at the start of stage1
SI normally uses DS and DI normally uses ES.
Either way it's a good idea to setup both ES and DS correctly at the start of stage1
Re: FAT32 Bootloader Problem
No, all access except the string instructions (stos* / movs*) default to use DS.MollenOS wrote:I'm sorry. I swapped them.
SI normally uses DS and DI normally uses ES.
Either way it's a good idea to setup both ES and DS correctly at the start of stage1
for example,
MOV EAX, [EDI] => EAX := [DS:EDI]
As a side note, in long mode all segments are ignored except privilege level in CS and SS.Intel Manual wrote: In Volume 2, Instruction format:
The default segment register is SS for the effective addresses containing a BP index, DS for other effective addresses.
Yes, I totally agree.MellonOS wrote:Either way it's a good idea to setup both ES and DS correctly at the start of stage1
Re: FAT32 Bootloader Problem
And don't forget about direction flag.
If you have seen bad English in my words, tell me what's wrong, please.
-
- Posts: 19
- Joined: Mon Dec 03, 2012 8:57 am
Re: FAT32 Bootloader Problem
ok thank you, it worked. Now im trying to write a bootloader in the first sector of my usb stick, which can load a stage2 bootloader file namend "KRNLDR.SYS". I've only done this using fat12 yet but i want to do it with fat32 now. I'm not sure about what to do at all, but i think the following is correct:
1. load FAT into memory
2. load root dir into memory (using fat)
3. search root dir for KRNLDR.SYS
4. -> not found? -> error message -> hlt
5. found? -> search for starting cluster
6. load starting cluster into memory (without FAT)
7. look at FAT what value there is for this cluster
8. cluster entry <= 0xFFFFFFF8 -> load this cluster into memory under last cluster -> goto step 7
9. next cluster entry >= 0xFFFFFFF8 -> this is the last cluster, load into memory and return
can i do it like this or is this approach wrong?
1. load FAT into memory
2. load root dir into memory (using fat)
3. search root dir for KRNLDR.SYS
4. -> not found? -> error message -> hlt
5. found? -> search for starting cluster
6. load starting cluster into memory (without FAT)
7. look at FAT what value there is for this cluster
8. cluster entry <= 0xFFFFFFF8 -> load this cluster into memory under last cluster -> goto step 7
9. next cluster entry >= 0xFFFFFFF8 -> this is the last cluster, load into memory and return
can i do it like this or is this approach wrong?