Page 1 of 1

int 13h appears to succeed but doesn't actually work

Posted: Tue Sep 20, 2011 9:47 pm
by tragicomix
Hello folks!

I'm trying to write a simple bootloader that loads a small (50k) kernel. The currently currently does nothing more than just print a few messages.

The bootloader is (obviously) on sector #1 of the disk and the kernel is stored on sectors #2 and onwards.

My bootloader iteraters through each sector (starting with #2) until the last sector of the kernel, and loads these to memory. I read from disk using the int 13h, function 02h.

What I'm seeing is that the kernel is loaded correctly for the first 30 or so sectors. But the remaining sectors aren't being read into memory. I am checking for errors after the call to int 13h by looking at the CF as well as by examining AL (should be 1, and is in fact 1) for every call. Neither of these are showing anything wrong (i.e., CF is not set and AL=1).

I see this behavior in BOCHS, but the same code works correctly in QEMU. I am seeing some weird mixture of the two on real hardware - BOCHS fails to read anything after sector 30 or so, while real hardware seems to be able to read some of these correctly.

Do you guys have advice on what I could be doing wrong?

Any advice on how I should be debugging something like this?

Re: int 13h appears to succeed but doesn't actually work

Posted: Tue Sep 20, 2011 11:07 pm
by CelestialMechanic
Are you loading from a floppy or a hard drive, either real or emulated?

Since you are using function 02, what is your disk geometry, real or emulated? Function 02 uses CHS. If you are loading about 50Ki, or 100 sectors, you are almost certainly loading from multiple cylinders. Have you taken this into account?

Re: int 13h appears to succeed but doesn't actually work

Posted: Wed Sep 21, 2011 7:36 am
by madanra
With a real-mode segment being only 64K and your kernel being 50K, if you're not starting near the beginning of a segment your pointer is going to wrap round; have you taken that into account?

Re: int 13h appears to succeed but doesn't actually work

Posted: Wed Sep 21, 2011 10:15 am
by tragicomix
Thanks for the suggestions.

I think I've taken into accounts both the fact that I need to read multiple tracks. There isn't any offset wraparound happening because the initial offset is 0.

This might be a dump question, but is it correct to assume that all tracks have the same number of sectors?

What I'm doing is something like this:

Code: Select all

sector = 2
track = 0
head = 0

loop:
  read using int 13h
  sector ++
  if (sector > MAXSECTORSPERTRACK) /* obtained using int 13h function 08h)
  {
    sector = 1;
    track++;
  }
  if (track == MAXTRACKS)  {/* again from int 13h function 08h */
    head++;
  }

  jmp loop;
Is there something wrong with this approach?

Re: int 13h appears to succeed but doesn't actually work

Posted: Wed Sep 21, 2011 11:31 am
by Combuster
head 1 track 0 comes before head 0 track 1.

Re: int 13h appears to succeed but doesn't actually work

Posted: Wed Sep 21, 2011 3:54 pm
by tragicomix
Combuster wrote:head 1 track 0 comes before head 0 track 1.
You're right. Thanks a lot!

Re: int 13h appears to succeed but doesn't actually work

Posted: Thu Sep 22, 2011 1:23 pm
by intx13
tragicomix wrote: This might be a dump question, but is it correct to assume that all tracks have the same number of sectors?
Physically, no, not on modern disks. Logically, from the INT13H perspective, yes.