Monday, June 15, 2009

Trials, Tribulations, Successes, and STAGE1_BOOT_DRIVE_CHECK

I made a couple more images that go into my MBR to give me information. It took a while to learn the importance of not forgetting to place the '$' before a macro that evaluates a value. Without the '$' it dereferences memory and uses that dereferenced value instead of the value itself. And I solved other equally frustrating problems with the help of 'ndisasm' to see what I actually got compared to what I think I wrote. The results? Nothing I didn't expect. No reason emerged why my boots should fail.

So, I went back to stage1.S and decided to trace it through from beginning to end assuming my device can use LBA's.

A couple of mysteries. First,
lba_mode:
/* save the total number of sectors */
movl 0x10(%si), %ecx
%si is not set up, yet. This should be harmless (%si is at the end of the notification string), but it's seemingly useless.

The second mystery is why the code loads only one sector of the 15 following the MBR. I have to find out why.

A final thing I found--I was removing some code that deals with the upper bit of the current drive which it thinks ought to be set. The execution contains:
boot_drive_check:
jmp 1f
testb $0x80, %dl
jnz 1f
movb $0x80, %dl
1:
which appears to do nothing. But when you install from Grub, it uses:
/* The offset of BOOT_DRIVE_CHECK. */
#define STAGE1_BOOT_DRIVE_CHECK 0x4b
to wipe that first jmp 1f with nop; nop. This was wiping other stuff and that is surely one reason my boot loader wasn't working. It would have been nice to have a little comment there in stage1.S explaining that Grub might write two nops to the address STAGE1_BOOT_DRIVE_CHECK. Sigh.

Anyway, I worked on this for 8 hours straight. I'm learning Grub inside and out. But I can't wait to be done with Grub so I can move onto something more interesting and less frustrating than BIOS interrupt calls and boot loading. But, I have some nice leads to track down. I'll avoid the STAGE1_BOOT_DRIVE_CHECK problem. And I'll gdb grub and watch what happens when it runs 'install_func' which loads stage1 and 'embed_func' which loads stage 1.5.

No comments:

Post a Comment