First let me point out that this is not homework, it's just something I'm doing because I'm bored ;-)
I'm trying to get my little hobby operating system to read from the hard disk. So far all I can get is the byte FF (255). I've tested this in both Bochs and QEMU and the same thing happens. Here's the hard disk reading part of my code:
#include <harddisk.h>
#include <types.h>
#define CMD_READ 0x20
#define CMD_WRITE 0x30
// NR = no retry
#define CMD_READ_NR 0x21
#define CMD_WRITE_NR 0x31
byte *read_sector(uint_8 drivenum, uint_8 sector, uint_16 cylinder, uint_8 *buffer)
{
uint_8 drive;
uint_16 port_base;
// Yes, I know I could use some binary operations.
// This is a lot easier to read though.
switch (drivenum)
{
case 0:
drive = 0xA0;
port_base = (uint_8)0x1f0;
break;
case 1:
drive = 0xB0;
port_base = (uint_8)0x1f0;
break;
case 2:
drive = 0xA0;
port_base = (uint_8)0x170;
break;
case 3:
drive = 0xB0;
port_base = (uint_8)0x170;
// If I ever get bored enough to add them, 0x1e8 for
// ide2 and 0x168 for ide3.
}
// send some info to the IDE controller
// drive to read from
outportb(port_base + 6, drive);
// just one sector
outportb(port_base + 2, 1);
// sector
outportb(port_base + 3, sector);
// extract low and high bytes from cylinder number
uint_8 cyl_low = cylinder & 0xFF;
uint_8 cyl_high = (cylinder & 0xFF00) >> 8;
// ...then send them to the IDE controller
outportb(port_base + 4, cyl_low);
outportb(port_base + 5, cyl_high);
// and now send the command
outportb(port_base + 7, CMD_READ);
// now read the data in from the buffer
int i;
for (i = 0; i < 256; i++)
{
buffer[i] = inportw(port_base);
// debugging
printf("%x\t| %d\t| %c\n", buffer[i], buffer[i], buffer[i]);
}
return buffer;
}
OK, just got that working. Turns out I was reading into the buffer wrong. Now I have another problem. This *should* be 512 bytes, I added it up myself. But sizeof() gives me 516, and I get some random, obviously incorrect values when I print out the partition info. (A byte with only the top bit set is never 192.) Any ideas?