error on hardisk read and write functions

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
wonde
Posts: 6
Joined: Wed Mar 12, 2008 11:39 am

error on hardisk read and write functions

Post by wonde »

i have been trying to create a disk partition for my mini operating system I don't know what and where is the problem .I couldn’t get it writing and reading hardisk partition information ...i am using GRUB for loading my OS is there some thing which is connected with GRUB that protect me not to write partition information on the first sector of the hardisk ,and also do i need to initiate IRQ request for reading and writing a hardisk how can i do that...
Here is a function that read and writes to/from the hardisk
void hd_rw(unsigned int lba, unsigned int com, unsigned int sects_to_access, void *buf) {
unsigned int cyl = lba/(HD0.head * HD0.sect);
unsigned int head = (lba%(HD0.head*HD0.sect))/HD0.sect;
unsigned int sect = (lba%(HD0.head*HD0.sect))%HD0.sect+1;

while ((inb(HD_PORT_STATUS)&0xc0)!=0x40);
outb(0x00,HD_PORT_ERROR);
outb(sects_to_access, HD_PORT_SECT_COUNT);
outb(sect, HD_PORT_SECT_NUM);
outb(cyl>>8, HD_PORT_CYL_LOW);
outb(cyl>>16, HD_PORT_CYL_HIGH);
outb(0xE0 | (0xA0 << 4) | ((head >> 24) & 0x0F),HD_PORT_DRV_HEAD);

outb(com,HD_PORT_COMMAND);

while (!(inb(HD_PORT_STATUS) & 0x08)) {}
if (com == HD_READ){

insl(HD_PORT_DATA, buf, sects_to_access<<7);
puts("read\n");

}
else if (com == HD_WRITE)
{
outsl(buf, sects_to_access<<7,HD_PORT_DATA);
puts("written\n");

}


}
User avatar
Bughunter
Member
Member
Posts: 94
Joined: Mon Dec 18, 2006 5:49 am
Location: Netherlands
Contact:

Post by Bughunter »

User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

wonde, there are many errors in your "driver" code. The way you output the cylinder high and low bytes is very wrong. The byte you are sending to select the head is very wrong. You are not stopping to read the BSY and DRQ flags between each sector of data -- this is very wrong.

I think you should start by using the LBA function, rather than the CHS function, because your CHS calculations look bad. Please begin by reading the wiki article on using ATA:
http://www.osdev.org/wiki/ATA_PIO_Mode
Post Reply