0

I am referring BrokenThorn's OS development tutorial, and currently reading the part on developing a complete first stage bootloader that loads the second stage - Bootloaders 4.

In the part of converting Logical Block Address (LBA) to Cylinder-Head-Sector (CHS) format, this is the code that is used -

LBACHS:
      xor     dx, dx                              ; prepare dx:ax for operation
      div     WORD [bpbSectorsPerTrack]           ; divide by sectors per track
      inc     dl                                  ; add 1 (obsolute sector formula)
      mov     BYTE [absoluteSector], dl
      xor     dx, dx                              ; prepare dx:ax for operation
      div     WORD [bpbHeadsPerCylinder]          ; mod by number of heads (Absolue head formula)
      mov     BYTE [absoluteHead], dl             ; everything else was already done from the first formula

      mov     BYTE [absoluteTrack], al            ; not much else to do :)
      ret

I am not able to understand the logic behind this conversion. I tried using a few sample values to walk through it and see how it works, but that got me even more confused. Can someone explain how this conversion works and the logic used ?

Griwes
  • 8,805
  • 2
  • 43
  • 70
Cygnus
  • 3,222
  • 9
  • 35
  • 65
  • The formula for conversion **is provided in the article**. This question proves you didn't want to read, just copy code and hope to understand it by reading just it. You will fail miserably with this attitude. Also, regardless of what the tutorial does, ditch the floppy - you won't find any serious hardware still booting off it, and floppy BIOS interrupts have *many* problems, compared to just using "extended read" interrupt. – Griwes Dec 02 '13 at 12:15
  • I know that the formula is given in the article and I have read it. I have only not copied it here. As I already mentioned, I tried running this through with a few numeric samples, but could not understand. I do not ask questions just as I encounter them without first trying myself, and that is what I have written in my question. As I said, I know the formulas - I only could not understand the logic behind them. And they are not explained very well in the article either. – Cygnus Dec 02 '13 at 14:19
  • The previous article on Brokenthorn explains **exactly** how it works. Try reading more closely next time. – Griwes Dec 02 '13 at 14:28

1 Answers1

1

I am guessing that your LBA value is being stored in AX as you are performing division on some value.

As some pre-information for you, the absoluteSector is the CHS sector number, absoluteHead is the CHS head number, and absoluteTrack is the CHS cylinder number. Cylinders and tracks are the exact same thing, just a different name.

Also, the DIV operation for your code in 16-bit will take whatever is in the DX:AX register combination and divide it by some value. The remainder of the division will be in the DX register while the actual result will be in the AX register.

Next, the *X registers are 16-bit registers, where * is one of ABCD. They are made up of a low and high component, both referred to as *H and *L for high and low, respectively. For example, the DX register has DH for the upper 8 bits and DL for the lower 8 bits.

Finally, as the BYTE and WORD modifiers simply state the size of the data that will be used/transferred.

The first value you must extract is the sector number, which is obtained by diving the LBA value by the number of sectors per track. The DL register will then contain the sector number minus one. This is because counting sectors starts at 1, which is different than most values, which start at zero. To fix this, we add one to the DL register get the correct sector value. This value is stored in memory at absoluteSector.

The next value you must extract is the head number, which is obtained by dividing the result of the last DIV operation by the number of heads per cylinder. The DL register will then contain the head number, which we store at absoluteHead.

Finally, we get the track number. With the last division we already obtained the value, which is in the AL register. We then store this value at absoluteTrack.

Hope this cleared things up a little bit.

-Adrian

Adrian Collado
  • 699
  • 8
  • 20
  • Thanks for this very well detailed answer. Its cleared up things a lot. Just one question - what if I dont use logical block addressing and use the sector numbering from 1 ? How will that affect calculations ? – Cygnus Dec 05 '13 at 14:26
  • Each sector on the disk is on a specific head and track. The LBA value is simply the combination of these values so that you can access the sector linearly. As an example, in C you can have multidimensional arrays, such as `int i = data[c][h][s]`, where `data` is an array and c, h, and s are your CHS values. However, you can also access this linearly using `int i = *data[c * hpc * spt + h * spt + s]`, where hpc is heads per cylinder and spt is sectors per track. So, all in all, the process you are doing is basically just turning a linear index into a multidimensional array. – Adrian Collado Dec 05 '13 at 19:21