Emulation of CHS hard drives [Solved]
Emulation of CHS hard drives [Solved]
Does anyone know if it is possible to get either Qemu or Bochs to emulate a hard drive that only supports CHS? I was testing my OS on an old (ancient) computer and realized that its hard drive didn't support LBA (or at least that is what it told me from the identify command). My kernel only supports LBA right now so I though this would be a good opportunity to add support for legacy CHS addressing. Now what I need is a proper way (hopefully in an emulator) to test the CHS -> LBA and LBA -> CHS conversion code.
Last edited by Stevo14 on Thu Jun 12, 2008 12:42 pm, edited 1 time in total.
Re: Emulation of CHS hard drives
Hi,
Cheers,
Brendan
Could you simply modify your code that detects if the hard drive supports LBA, so that the rest of the OS thinks the hard drive doesn't support LBA when it actually does?Stevo14 wrote:Does anyone know if it is possible to get either Qemu or Bochs to emulate a hard drive that only supports CHS? I was testing my OS on an old (ancient) computer and realized that its hard drive didn't support LBA (or at least that is what it told me from the identify command). My kernel only supports LBA right now so I though this would be a good opportunity to add support for legacy CHS addressing. Now what I need is a proper way (hopefully in an emulator) to test the CHS -> LBA and LBA -> CHS conversion code.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Emulation of CHS hard drives
I've done something similar to that already. All reads and writes are addressed in LBA but if the drive doesn't support LBA, the address is converted to CHS on the fly before being sent to the drive. The code is already written, but now I need a way to test it and debug it without constantly transferring the kernel and rebooting.Brendan wrote:Hi,
Could you simply modify your code that detects if the hard drive supports LBA, so that the rest of the OS thinks the hard drive doesn't support LBA when it actually does?Stevo14 wrote:Does anyone know if it is possible to get either Qemu or Bochs to emulate a hard drive that only supports CHS? I was testing my OS on an old (ancient) computer and realized that its hard drive didn't support LBA (or at least that is what it told me from the identify command). My kernel only supports LBA right now so I though this would be a good opportunity to add support for legacy CHS addressing. Now what I need is a proper way (hopefully in an emulator) to test the CHS -> LBA and LBA -> CHS conversion code.
Re: Emulation of CHS hard drives
Hi,
"All reads and writes are addressed in LBA but if the drive doesn't support LBA (or if you modify the code to pretend that LBA isn't supported), the address is converted to CHS on the fly before being sent to the drive."
I checked the source code for Bochs, and it's hard drive interface does support both LBA and CHS. Your code detects that LBA is supported and then chooses to use LBA for the hard drive interface, but it could choose to use CHS for the hard drive interface instead.
Cheers,
Brendan
Let me rephrase:Stevo14 wrote:I've done something similar to that already. All reads and writes are addressed in LBA but if the drive doesn't support LBA, the address is converted to CHS on the fly before being sent to the drive. The code is already written, but now I need a way to test it and debug it without constantly transferring the kernel and rebooting.Brendan wrote:Could you simply modify your code that detects if the hard drive supports LBA, so that the rest of the OS thinks the hard drive doesn't support LBA when it actually does?
"All reads and writes are addressed in LBA but if the drive doesn't support LBA (or if you modify the code to pretend that LBA isn't supported), the address is converted to CHS on the fly before being sent to the drive."
I checked the source code for Bochs, and it's hard drive interface does support both LBA and CHS. Your code detects that LBA is supported and then chooses to use LBA for the hard drive interface, but it could choose to use CHS for the hard drive interface instead.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Emulation of CHS hard drives
Ah, ok. Sorry I mis-understood you before. I just did this. It seems to work in Qemu and Bochs (EDIT: I was wrong, it doesn't work after all) but errors on the real hardware. I will look into this more. Here is how I translate and send the CHS values to the drive:Brendan wrote: (or if you modify the code to pretend that LBA isn't supported)
Code: Select all
int ata_seek(ata_drive_t *d, unsigned int block)
{
//null pointer
if(d == 0)
return -1;
d->current_block = block;
if(d->mode == ATA_LBA )
{//lba addressing
outportb(d->ports.LBA_low, d->current_block);
outportb(d->ports.LBA_mid, d->current_block >> 8);
outportb(d->ports.LBA_high, d->current_block >> 16);
outportb(d->ports.drive_head, d->id | ((d->current_block >> 24) & 0x0F));
}
else
{//CHS addressing
unsigned int cyl = d->current_block / (d->heads * d->sectors);
unsigned int tmp = d->current_block % (d->heads * d->sectors);
unsigned int head = tmp / d->sectors;
unsigned int sect = tmp % d->sectors + 1;
outportb(d->ports.LBA_low, sect);
outportb(d->ports.LBA_mid, cyl);
outportb(d->ports.LBA_high, cyl >> 8);
outportb(d->ports.drive_head, d->id | head);
}
return 0;
}
Is this correct?
Thanks for looking over the code. I made some changes elsewhere in the ATA detection code and it now seems to work in emulators but not on real hardware (again...). Probably due to timing issues like you said (as the command doesn't error but bogus data is read/returned).bewing wrote:but make sure that you note that timing issues are MUCH more vital on real hardware when you are dealing with a CHS-only drive.
Ok, so I solved the problem. A good look through the ATA spec showed me that I was not waiting for the proper flags in the status register at the correct times. It worked on the emulated drives (and on real hard drives if they were new) because they just happened to have the data ready before I started reading it. But regardless, I now have a (more) standards-compliant ATA hard disk driver!
Thanks everyone for your help.
Thanks everyone for your help.