FAT32 Bootloader Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

FAT32 Bootloader Problem

Post by tonydemann »

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
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: FAT32 Bootloader Problem

Post by MollenOS »

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:

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
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

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?
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: FAT32 Bootloader Problem

Post by MollenOS »

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.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

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...
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: FAT32 Bootloader Problem

Post by MollenOS »

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.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post by egos »

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.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

Ok, i have just another question. I have the following Code:

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
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?!?
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

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?
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: FAT32 Bootloader Problem

Post by MollenOS »

Try to setup segments, you don't do this ;)

Add this in to setup DS and ES segments correctly:

Code: Select all

	;Setup Segments
        xor    ax, ax
	mov 	ds, ax
	mov 	es, ax
*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 :D
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: FAT32 Bootloader Problem

Post by bluemoon »

MollenOS wrote:*Because the SI register uses the ES segment to access data correctly
Which processor you talking about? My intel xeon behave differently and use DS for SI unless you explicity override it.
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: FAT32 Bootloader Problem

Post by MollenOS »

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
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: FAT32 Bootloader Problem

Post by bluemoon »

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
No, all access except the string instructions (stos* / movs*) default to use DS.
for example,
MOV EAX, [EDI] => EAX := [DS:EDI]
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.
As a side note, in long mode all segments are ignored except privilege level in CS and SS.

MellonOS wrote:Either way it's a good idea to setup both ES and DS correctly at the start of stage1
Yes, I totally agree.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: FAT32 Bootloader Problem

Post by egos »

And don't forget about direction flag.
If you have seen bad English in my words, tell me what's wrong, please.
tonydemann
Posts: 19
Joined: Mon Dec 03, 2012 8:57 am

Re: FAT32 Bootloader Problem

Post by tonydemann »

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?
Post Reply