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;
}
I'm calling it like this:
uint_8 *data = (uint_8 *)0x300000;
read_sector(0, 1, 1, data);
The only thing the debug printf will print is "ff | 255 | ". Any ideas?