Page 1 of 1
HDD writing problem
Posted: Wed Jul 29, 2009 12:31 am
by accelleon
Ok, I'm fairly new to HDD access for my OS so please bare with me.
When ever I try to write to the HDD Virtual PC and Bochs freeze. My reading code works fine so its not my inb, inw, outb, or outw. When testing with bochs the last thing bochs outputs on the command prompt is:
Don't get error no more.
Please tell me what this means, I was using the tutorial
here.
The code is:
Code: Select all
int hdd_write_sect(unsigned long sectorLBA, unsigned short *buffer)
{
unsigned char pollbyte;
short idx = 0;
//Set required LBA info
outb(0x1F6, 0xE0 | (0 << 4) | ((sectorLBA >> 24) & 0x0F));
outb(0x1F1, 0x00);
outb(0x1F2, 0x01);
outb(0x1F3, (unsigned char)sectorLBA);
outb(0x1F4, (unsigned char)(sectorLBA >> 8));
outb(0x1F5, (unsigned char)(sectorLBA >> 16));
outb(0x1F7, 0x30);
//Poll five times like the wiki's ATA tut says
pollbyte = inb(0x1F7);
pollbyte = inb(0x1F7);
pollbyte = inb(0x1F7);
pollbyte = inb(0x1F7);
pollbyte = inb(0x1F7);
//Test the bits
while (!pollbyte) {
//Check for Err bit (Error)
if(pollbyte & 1)
return 0;
//Check for Df bit (Drive Fault)
if(pollbyte & 0x20)
return -1;
//Repoll
pollbyte = inb(0x1F7); }
//Send data
for(idx = 0; idx < 256; idx++)
{
outw(0x1F0, buffer[idx]);
//Delay
inb(0x1F7);
}
return 1;
}
PS: Using Visual C++
Re: HDD writing problem
Posted: Wed Jul 29, 2009 6:52 am
by Thor
accelleon wrote:Code: Select all
for (idx = 0; idx < 256; idx++)
{
tmpword = buffer[8 + idx * 2] | (buffer[8 + idx * 2 + 1] << 8); <--- A char << 8 will be 0
outw(0x1F0, tmpword);
}
}
I can see a few problems here. For one, tmpword and buffer are unsigned chars, whilst they should be unsigned shorts. Also, your for loop that reads the data is a failure. A simple loop like this:
Code: Select all
for(idx = 0; idx < 256; idx++)
outw(0x1F0, buffer[idx]);
should suffice (Though remember when writing to the HDD you need a 400 nanosecond delay between each word transfer).
Hope this helps
Also, a piece of advice: don't copy code directly from tutorials... especially code that you don't understand. You'll learn a lot more writing it yourself, and it's a lot more satisfying
EDIT: Yet another thing: sectorLBA should be an unsigned long, not a short. Do you know your basic datatypes?
Re: HDD writing problem
Posted: Thu Jul 30, 2009 3:08 am
by accelleon
EDIT: Yet another thing: sectorLBA should be an unsigned long, not a short. Do you know your basic datatypes?
Well, actually I purposely put an unsigned short for testing the function, I did understand that an unsigned long would have fitted better as it can contain larger numbers. As for the code I understood it fine except for the reading data from port 0xF10. I will test your correction in a little bit.
Edit: Well your correction was unsuccessful, thanks for the help though I'm starting to wonder if some ports are messed up. If any one can verify I'm using the right ports for primary controller please do so. Oh and I also tried to change sectorLBA to unsigned long and to no avail it froze up. Btw I did mount a HDD image in bochs but all of a sudden I don't get the bochs error no more, it just freezes.
Edit2: Through extensive debugging I have found that the freezing occurs when trying to send the 255th word to port 0x1F0. Any suggestions, I have now updated the code in the first post to my current code.
Re: HDD writing problem
Posted: Thu Jul 30, 2009 11:12 am
by Thor
Code: Select all
//Test the bits
while (!pollbyte) {
//Check for Err bit (Error)
if(pollbyte & 1)
return 0;
//Check for Df bit (Drive Fault)
if(pollbyte & 0x20)
return -1;
//Repoll
pollbyte = inb(0x1F7); }
It's this polling loop right here. It will loop while pollbyte == 0, so it won't even go through once (unless there's no HDD, in which case it will hang). You also don't wait for the drive to be ready before sending it data. Try replacing while(!pollbyte){
with
Code: Select all
do{
// Your code
}while((pollbyte & 0x88) != 0x08){
(A do loop so it will at least go through once to check for errors)
Hope this helps
Re: HDD writing problem
Posted: Thu Jul 30, 2009 5:10 pm
by accelleon
Code: Select all
do{
// Your code
}while((pollbyte & 0x88) != 0x08){
Shouldn't that be
Code: Select all
do{
// code
} while(pollbyte & 0x88) != 0x08);
The code still doesn't work. I'm starting to think its the floppy disk read function thats messing up. If it helps the code to my make_bootable_hdd function:
Code: Select all
int make_bootable_hdd()
{
int i = 0;
int sec = 0;
int ret = 0;
for(i=0; i<16/*2881*/; i++)
{
DebugPrintf("Writing sector %i...",sec);
ret = HDD_Write_Test(sec, (unsigned short*)flpydsk_read_sector(sec));
if(ret == 0)
{
DebugPrintf("\nErr bit was set: An error has occurred.");
return 0;
}
else if(ret == -1)
{
DebugPrintf("\nDf bit was set: A drive fault error has occurred.");
return 0;
}
DebugPrintf(" Done.\n");
sec++;
}
}
The entire point of this function is to copy all the virtual floppy disks data to the virtual hdd. flpydsk_read_sect returns an array of unsigned chars so I just cast it as an array of unsigned shorts so there shouldn't be a problem. The only thing that might cause this is that the returned array from flpydsk_read_sect doesn't return an array of 255 unsigned chars...
Edit: I got it to work by changing a few values around so its fine thanks for all the help.
Re: HDD writing problem
Posted: Thu Jul 30, 2009 11:02 pm
by Thor
No problem ^-^
Re: HDD writing problem
Posted: Fri Jul 31, 2009 2:45 am
by accelleon
Oh and also since I'm thinking about it: Which would be easier to use and program, a Master Boot Record or a Volume Boot Record. And to go with that if I use a Volume Boot Record how would I be able to make use of a file system without writing my own format utility as the Volume Boot Record is used for unpartitioned storage systems? But with the Master Boot Record how much modification would I need to use my OS (I'm currently using a floppy disk image)?
Re: HDD writing problem
Posted: Fri Jul 31, 2009 4:29 pm
by Thor
A volume boot record would be easier, but it would have the obvious disadvantage of only having one partition.
As for the filesystem, there are a couple options. The most obvious (not to mention practical) is to have your OS do it. I find this is a good resource for FAT filesystems:
Microsoft FAT Specifications
I actually printed it out for quick reference
Re: HDD writing problem
Posted: Fri Jul 31, 2009 8:08 pm
by accelleon
Once again thanks your a big help.