Page 1 of 1

int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 8:46 am
by GB80CPU
Hello OSdevvers,

I've been stuck on this problem for some time now. I'm trying to get a primitive bootloader working using the extended 0x13 calls, 0x41 and 0x42. It works on qemu and bochs, but not on any real PC I have available here.

To isolate the problem the program simply loads (or at least should load) the first sector of the drive at 0x1000:0000 and display the first 80 bytes of this sector. Like I said, this is no problem on either qemu or bochs.
It might be something pretty stupid that I'm overlooking here. However, I can't see it.

Things I considered:
On real computers, this is booting from a usb-stick. I made sure the stick is recognized as a hard disk, legacy mode enabled (uefi). The emulators use a copy of the first 64MiB of this stick.
I've read somewhere the alignment of the DAP might be important. It should be in memory at location 0x7DE0, 16 byte alignment. Is this really important?
I might have taken a register value for granted or messed up a segment, but I can't find such an error myself.
I'm not too familiar with filesystems yet. The idea is to have the stick formatted as FAT32, loading further files via the filesystem instead of hardcoded hidden sectors.

So on the emulators, the expected happens: It prints the first 80 bytes, recognisable by the "FUBUKI" name among other things. On real systems though (3 tested, at least two are uefi, to be honest not sure about the third one) it displays garbage which certainly isn't from the usb-stick. Trying to read past the first sector doesn't even give garbage, just 80 spaces. (Sector 1 of the stick has the supposed second stage bootloader, so it should be recongisable)

The source:
http://pastebin.com/Z2jHj84d

I thought it would be better to do it this way to keep the post clean. Or should I just paste it in code tags here?

The stack location is perhaps not the best, but it should work. I have of course searched for solutions, not only on this site. Some good threads came up, but not specific enough to this problem.

Perhaps I've done something stupid. I don't know. I'd really appreciate some input though :P

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 9:35 am
by theesemtheesem
Hi,

As I understand You have already verified that all these machines boot from USB without problems, it's just Your code that does not seem to work. I'm not an expert in this, since my kernel is multiboot compliant and I use grub to boot it, but what comes to mind ist that possibly the drive number You are using is wrong? What is Your setup in bochs/qemu? Do You have any other hdd images set up? What is the setup in the "real" machines? Do these have any hard drives at all, or is it just the usb stick?

I cans see that Your drive number is hardcoded to 0x80. Maybe it would be better to grab the boot drive number from the BIOS? There is no guarantee that USB devices will be numbered starting from 0x80 even if no other hard drives are present.

Cheers,
Andrew

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 9:44 am
by GB80CPU
theesemtheesem wrote:Hi,

As I understand You have already verified that all these machines boot from USB without problems, it's just Your code that does not seem to work. I'm not an expert in this, since my kernel is multiboot compliant and I use grub to boot it, but what comes to mind ist that possibly the drive number You are using is wrong? What is Your setup in bochs/qemu? Do You have any other hdd images set up? What is the setup in the "real" machines? Do these have any hard drives at all, or is it just the usb stick?

I cans see that Your drive number is hardcoded to 0x80. Maybe it would be better to grab the boot drive number from the BIOS? There is no guarantee that USB devices will be numbered starting from 0x80 even if no other hard drives are present.

Cheers,
Andrew
The hardcoded 0x80 byte is overwritten by storing dl to that location after setting up the stack, so it should use the drive that the bios booted from. The 0x80 part was mainly for testing purposes and might be a bit misleading.
I call qemu like this: qemu.exe -L qemu -hda image -boot c
Bochs is just starting with the sample config file pointing to the image.
All computers are configured differently. One with 4 sata drives and two usb drives, one with only one sata drive, and one with no drives at all (except for the stick of course). They all respond the same way by printing something I can't find on the image, and only when loading from dq 0.

What they print though is consistent. The same on all computers.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 10:07 am
by theesemtheesem
Hi,

As I said I am no expert with bootsector code, but possibly You are making some assumptions about the "disk" geometry that are not necessarily true. Remember that booting from USB uses an emulation layer in the BIOS and You can't assume what the stick is emulated as. The way You invoke qemu makes Your image the first ATA hard drive, so obviously it should be handled as a hard drive. But that does not need to be true with real hardware bioses.

Have a look at this: http://board.flatassembler.net/topic.php?t=12389

The guy uses the int 13 / function 08h to get the emulated drives parameters and goes from there.

Can You print the stored value of dl to see what actually gets passed from the BIOS?

Cheers,
Andrew

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 10:59 am
by GB80CPU
theesemtheesem wrote:Hi,

As I said I am no expert with bootsector code, but possibly You are making some assumptions about the "disk" geometry that are not necessarily true. Remember that booting from USB uses an emulation layer in the BIOS and You can't assume what the stick is emulated as. The way You invoke qemu makes Your image the first ATA hard drive, so obviously it should be handled as a hard drive. But that does not need to be true with real hardware bioses.

Have a look at this: http://board.flatassembler.net/topic.php?t=12389

The guy uses the int 13 / function 08h to get the emulated drives parameters and goes from there.

Can You print the stored value of dl to see what actually gets passed from the BIOS?

Cheers,
Andrew
Good idea.
It appears that on every system, emulated or real, the drive gets assigned 0x80. I guess that's a good sign?
I'll have a look at the drive parameter interrupts as soon as I've got time.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 11:12 am
by theesemtheesem
Hi,

Yes, I had a look at the Bios Boot Services specification just now and it says that the boot device should always be assigned the number 0x80. Anyway, have a look at the drive parameters function. Anyway have a look at the 08h function of int 13h and have a look at the link I gave You in the previous post - as far as I understand the code from there works, and even thou it uses FAT12 maube it will help You to spot any problems with Your bootloader. Good luck!

Cheers,
Andrew

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 1:19 pm
by DavidCooper
Are you sure you've put your code at the right place on the flash drive? I'm wondering if you've copied it all to the start of a partition instead of to the beginning of the physical drive - that would explain why it works as a disk image when your code certainly is placed at the start of the file, but not on the flash drive where an MBR may be running first before handing control to your code at the start of a partition which will then load in the MBR again and display random garbage from that.

If this turns out to be what's going on, don't wipe out the MBR, but retain it and learn how to use it properly - it's much more reliable to boot a flash drive via an MBR rather than sticking your VBR there, so keep your code at the start of a partition. You'll need to work out which sector is the first of the partition and adjust your DAP to line up on that sector.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 1:44 pm
by GB80CPU
DavidCooper wrote:Are you sure you've put your code at the right place on the flash drive? I'm wondering if you've copied it all to the start of a partition instead of to the beginning of the physical drive - that would explain why it works as a disk image when your code certainly is placed at the start of the file, but not on the flash drive where an MBR may be running first before handing control to your code at the start of a partition which will then load in the MBR again and display random garbage from that.

If this turns out to be what's going on, don't wipe out the MBR, but retain it and learn how to use it properly - it's much more reliable to boot a flash drive via an MBR rather than sticking your VBR there, so keep your code at the start of a partition. You'll need to work out which sector is the first of the partition and adjust your DAP to line up on that sector.
Not sure, I thought so. Opening the flashdrive in HxD shows the code at sector 0. I use dd for Windows:

Code: Select all

dd bs=512 if=extendedDrive of=\\.\T:
dd bs=512 count=3 seek=3 if=loadKernel of=\\.\T:

dd bs=4096 count=16384 if=\\.\T: of=O:\OS_DISK_IMAGE\fubuki
I actually copy to the stick first, then create the image by reading from the stick. The bootloader not actually being at sector 0 would surely explain the consistent garbage read. Any method I can use to be sure whether the code is at physical sector 0 or not?
I guess I might have to stop being lazy and properly partition this drive?

Thanks for all the input.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 2:12 pm
by DavidCooper
I don't use dd and therefore can't work out what your commands with it do, but HxD can certainly show you where your code is located on the drive. If you open the drive as a logical drive, it will label the first sector of the partition as sector 0, but if you open it as a physical drive it will show the actual first sector on the drive as sector 0 instead. It seems unlikely that your code's in the wrong place, but it would be good to rule that out entirely.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 2:22 pm
by DavidCooper
GB80CPU wrote: I've read somewhere the alignment of the DAP might be important. It should be in memory at location 0x7DE0, 16 byte alignment. Is this really important?
I've never tried misaligning it, so I can't tell you if it's always vital. You have aligned it correctly though, so that can't be the issue here.

Something you could try is copying this bit of your code:-

Code: Select all

        mov si, 0
        mov di, 0
        mov ax, 0x1000
        mov ds, ax
        mov ax, 0xB800
        mov es, ax
        mov cx, 80
        mov bl, 0x02
.loop:
        movsb
        mov [es:di], bl
        inc di
        loop .loop
ahead of this bit:-

Code: Select all

loadSecondStage:
        xor ax, ax  ;; Should be redundant.
        mov ds, ax
 
        xor ah, ah
        mov dl, [driveNumber]
        int 0x13
        jc fail
 
        xor ax, ax
        mov ds, ax
 
        mov ah, 0x42
        mov dl, [driveNumber]
        mov si, DAP
        int 0x13
        jc fail
and then modifying the original part that prints the sector content to the screen to print again lower down the screen, replacing "mov di, 0" with "mov di, 160", the purpose being to see if anything is being loaded in at all. If the two lines don't match, something's been loaded in, and into the right location, and if something has been loaded in that isn't your boot sector, there might be a clue as to what it is in the garbage that's printed to screen, so you could write a new routine to display it as hex and see what it is. The last two bytes of the sector would likely be as interesting as the first 80.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 3:09 pm
by bwat
GB80CPU wrote:

Code: Select all

dd bs=512 if=extendedDrive of=\\.\T:
dd bs=512 count=3 seek=3 if=loadKernel of=\\.\T:

dd bs=4096 count=16384 if=\\.\T: of=O:\OS_DISK_IMAGE\fubuki
You probably want to give the "conv=sync" option to dd like I do in my installation:

Code: Select all

	dd if=mbr of=/dev/sdb seek=0 conv=sync
	dd if=system of=/dev/sdb seek=1 conv=sync

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 4:00 pm
by GB80CPU
I feel so stupid. Basically, DavidCooper was absolutely right. I didn't actually write to physical sector 0, but sector 32. HxD shows this correctly, but I accidentally selected logical instead of physical. So, yeah :oops:
So basically the BIOS got redirected by the partition table to sector 32 (right?), loaded it without a problem at 0000:7C00 and processed int 0x13 0x42 just fine. Indeed, the "garbage" that was displayed is identical to the contents of the real, physical sector 0.

Question remains how I can conveniently use dd or another program to access the actual drive.

Code: Select all

dd.exe bs=512 count=16384 if=\\.\PHYSICALDRIVEn of=output
*I do know that I'm not limited to bs=512 and that a larger block might be faster.
seems to be working just fine, though the PHYSICALDRIVEn part makes me a bit nervous. Checking a drive letter feels a lot safer to me.
I guess I have a lot more reading to do about partitions and filesystems.
bwat wrote:
GB80CPU wrote:

Code: Select all

dd bs=512 if=extendedDrive of=\\.\T:
dd bs=512 count=3 seek=3 if=loadKernel of=\\.\T:

dd bs=4096 count=16384 if=\\.\T: of=O:\OS_DISK_IMAGE\fubuki
You probably want to give the "conv=sync" option to dd like I do in my installation:

Code: Select all

	dd if=mbr of=/dev/sdb seek=0 conv=sync
	dd if=system of=/dev/sdb seek=1 conv=sync
Sounds like a good idea. Thanks. And thanks everyone for their input! Really grateful!

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 4:19 pm
by DavidCooper
No need to feel stupid - it's a common mistake, and one I've made myself. As for using dd, I've never dared to in case I trash the internal hard drive, so I just stick to using HxD to write to flash drives so that it can be done without any risk.

Re: int 0x13 0x42 usb drive problems

Posted: Wed Mar 26, 2014 4:24 pm
by GB80CPU
DavidCooper wrote:No need to feel stupid - it's a common mistake, and one I've made myself. As for using dd, I've never dared to in case I trash the internal hard drive, so I just stick to using HxD to write to flash drives so that it can be done without any risk.
Yes, been there, done that... accidentally replacing the code that boots Windows with something that draws a green line on the screen :P
Was easily fixed though.