Boot Sector Drive Parameter Block (Edit: Int13/08 not workin

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.
Post Reply
Kemp

Boot Sector Drive Parameter Block (Edit: Int13/08 not workin

Post by Kemp »

A question that I've wondered for a long time and nothing that I've read has addressed:

Does the BIOS fill in the real values in the drive info area (from what it auto-detects assuming a newish BIOS) once the boot sector is loaded into memory, or do you have to figure out the values yourself? It seems a bit pointless for the BIOS to do the auto-detection and then not bother telling you what it found, but I'm quite used to that sort of thing by now ;)

Just in case someone thinks I'm talking about the floppy drive parameter block (offset found at int 1e location), I'm talking about the one that starts at offset 3 in your boot sector.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Boot Sector Drive Parameter Block

Post by Brendan »

Hi,

The "BIOS Parameter Block" (BPB) that starts at offset 0x0B in the first sector is not used by the BIOS at all. Instead it contains values that DOS uses, and is entirely optional if you don't need compatibility with Microsoft OSs.

From my experience, without a correct BPB Windows 98 and earlier Microsoft OS's won't even format the disk, while Windows XP (and Linux, etc) will.

For floppies, the BIOS itself doesn't need to know how many sectors per track, total number of sectors, etc as it uses "number of sectors from starting CHS" only. If you ask the BIOS to read or write more sectors than exists, it'll try to transfer them until the floppy hardware returns a "sector not found" error (which the BIOS returns to it's caller).

The only values that the BIOS does need is timing data (head settle time, step rate time, etc) at the "int 0x1E" vector, which are set to default values at boot (and usually updated by the OS soon after).

For this reason the BIOS is more flexible than DOS or DOS's BPB as it will work with non-standard floppy formats, including non-sequential sector numbering and/or a non-constant sectors per track (these techniques were used once upon a time for copy protection). In general DOS supports a standardized subset of what the BIOS supports, and the BIOS supports a standardized subset of what the hardware itself supports. By writing software that uses the floppy disk controller directly incredibly strange arrangements are possible - the only problem is that you need to know what's going on before you can read it.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Kemp

Re:Boot Sector Drive Parameter Block

Post by Kemp »

Yeah, like I said, I know about the floppy block (though thanks still for confirming that stuff). So basically with the hard drives it's up to me to figure out how the drive is laid out? Also, is it safe to use Int 13 with AH = 42h (Extended Read), which allows me to just give the sector number, or did that never make it into the current standard (standard in the sense that most BIOSes implement it)?

Ref: http://lrs.fmi.uni-passau.de/support/doc/interrupt-57/RB-0670.HTM

The main reason I'm asking about this is that since I switched to loading my second stage by assuming head 0 / cylinder 0 / sector 8 for where sector 8 actually is my code has been failing (the hard drive controller returns an error), so I may have to go back to calculating it to be safe.
AR

Re:Boot Sector Drive Parameter Block

Post by AR »

The Linear Block Address Extended BIOS Disk Functions are supposedly mainstream since 1997, systems before or around then may not support them however.

There is a more important reason to use them on harddrives then simply having linear addressing though, that being that the old CHS functions can't read more than 8GB, if you have a drive larger than that then anything beyond 8GB is off limits, the LBA extensions shatter it with support for thousands of terabytes.

If you want to support older computers, or at least fail gracefully, you should make sure the extensions are supported first (There is a function to verify support) then optionally fall back to CHS if they aren't.

In regards to drive data, both the extended and CHS functions provide "Get Drive Parameters" functions which will tell you the geometry/block-count. As for determining the number of drives in the system, the CHS "Get Drive Parameters" function tells you but I'll have to get back to you when I've learned how the value it gives works :).
Kemp

Re:Boot Sector Drive Parameter Block

Post by Kemp »

Oh, ok, I missed the function to get those details, thanks for that one. I'll use the extended functions for now (while testing is confined to my own PC) and probably sort out a fall-back position later, though I doubt my OS will be run on a PC older than 1997 (mainly as ones a bit newer are dirt cheap ;) ).

Edit:
I appear to have found my problem... Virtual PC is apparently reporting a sectors per track number less than 8 (just about to run a quick boot sector I wrote that'll dump all the info out for me). I'm guessing my old CHS conversion using what I assumed would be good values was just coming up with a freak result that happened to be a valid place on the disk, hence loading the wrong data.

Progress report soon.
Kemp

Re:Boot Sector Drive Parameter Block

Post by Kemp »

Well great, function AH=08h reports that there are 0 sectors per track. *mumbles about dodgy BIOS calls* Gonna see what other ones say.

My code tells me that the function returns the following:
Number of drives : 16
Heads (selected drive) : 0
Sectors per track (selected drive) : 0

So my assumption now is that there is something wrong with my test code, but the only part I can see having a problem is my code to convert an 8-bit binary number to a two character text version of the hex equivalent (so that 00010111 would be printed as 17). I went through this code on paper and it all worked fine, and the fact that I'm getting real numbers out of it rather than random characters seems to indicate it's ok, though I did write it on the fly.

Code: Select all

bin2hex:
   MOV AH, AL
   AND AL, 00001111b   ; Lower digit
   AND AH, 11110000b   ; Higher digit
   SHR AH, 4           ; Make upper digit correct
   ADD AL, 48          ; Turn into ASCII character
   ADD AH, 48         ; And again
   RETN
It basically takes the number in AL and returns the text version of the hex in AX.

So that's where I am, either the BIOS is giving me stupid values back or my code is broke.


Edit: That procedure gives the two characters the wrong way round, so I've fixed that, obviously not getting the right values still though

Edit 2: Ok, I think that's enough for today. It has know started giving me an error when it calls the function. God knows what's going on. Error 1: Invalid function or parameter. AH is 08h and DL is the drive number (80h), what could possibly be wrong with that? >:(
Kemp

Re:Boot Sector Drive Parameter Block

Post by Kemp »

Ok, this is really annoying me now. I have this:

Code: Select all

   XOR AX, AX
   MOV AH, 08h
   MOV DL, 80h

   INT 13h
And I get back error 1 (invalid function or parameter). Those two parameters are the only ones required by function 08h (get disk params), so I can't see what could possibly be wrong. Any thoughts on this? :-\

As a sidenote, my bin2hex routine got severely shortened by not dealing with AH and AL as seperate things.


Edit:
When tried with the floppy drive (DL = 00 rather than 80h), it returns that there is 1 drive and that the selected drive (which is apparently the only one) has 0 heads and 0 sectors per track. I would assume it is virtual pc screwing with me, but if OSes can boot under it then it must work somehow.
AR

Re:Boot Sector Drive Parameter Block (Edit: Int13/08 not wor

Post by AR »

Have you actually attached a hard drive to the emulator? I think I recall having a similar problem where the values I was getting were 0 but it was caused by other operations manipulating the values accidentally setting them to 0.

You can also simply read 0040:0075 (byte) [0x475 Linear] to get the number of hard drives, I'm reasonably sure it is a standard for the layout of the BIOS Data Segment but for reliability Int 0x13 may be better.
Kemp

Re:Boot Sector Drive Parameter Block (Edit: Int13/08 not wor

Post by Kemp »

Yeah, a hard drive is attached, it's what it's booting from. I really should probably try it on real hardware, but my spare drive is at home right now, and I'm at uni, could always ask my gf to pick it up I suppose.
Post Reply