Page 1 of 1
My kernel can't read hard disk on the real machine.
Posted: Fri Dec 25, 2015 8:02 am
by 626788149
My kernel can read hard disk on qemu or bochs, but can't read hard disk on real machine.
I always get 0xFF when I execute inb(0x1F7) under the real machine.
Code: Select all
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
ide_wait_ready(bool check_error)
{
int num = 0x10000;
int r;
while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY) {
if (--num == 0) {
return -1;
}
if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
return -1;
return 0;
}
Code: Select all
int
ide_read(uint32_t secno, void *dst, uint32_t driver ,size_t nsecs)
{
int r;
assert(nsecs <= 256);
ide_wait_ready(0);
outb(0x1F6, 0xE0 | (driver << 4) | ((secno >> 24) & 0x0F));
outb(0x1F1, 0x00);
outb(0x1F2, nsecs);
outb(0x1F3, secno & 0xFF);
outb(0x1F4, (secno >> 8) & 0xFF);
outb(0x1F5, (secno >> 16) & 0xFF);
outb(0x1F6, 0xE0 | ((driver&1)<<4) | ((secno>>24)&0x0F));
outb(0x1F7, 0x20); // CMD 0x20 means read sector
for (; nsecs > 0; nsecs--, dst += SECTSIZE) {
if ((r = ide_wait_ready(1)) < 0)
return r;
insl(0x1F0, dst, SECTSIZE/4);
}
return 0;
}
Re: My kernel can't read hard disk on the real machine.
Posted: Fri Dec 25, 2015 12:06 pm
by osdever
Maybe your HDD is not IDE?
Re: My kernel can't read hard disk on the real machine.
Posted: Fri Dec 25, 2015 7:53 pm
by 626788149
catnikita255 wrote:Maybe your HDD is not IDE?
Do I need initialize IDE before use it ?
Re: My kernel can't read hard disk on the real machine.
Posted: Fri Dec 25, 2015 9:09 pm
by Brendan
Hi,
626788149 wrote:catnikita255 wrote:Maybe your HDD is not IDE?
Do I need initialize IDE before use it ?
You need to find out if IDE/ATA exists before you use it. Most real computers use
SATA/AHCI instead (and some use SCSI, and some might be using
NVMe already).
Cheers,
Brendan
Re: My kernel can't read hard disk on the real machine.
Posted: Fri Dec 25, 2015 9:27 pm
by ~
Maybe you are using SATA disks/controllers, and if that's the case, you will most likely need to use a different set of registers than the typical 0x1F0-0x1F7 or 0x170-0x177 port ranges.
You would need to detect the port ranges for the disk controllers (using tye PCI bus functionality, I/O ports and/or memory mapped registers).
See this to see if it can help you. You can also use programs like PCI32 for Windows to manually scan for port addresses and use that like an initial hint for the addresses of all your PCI devices:
Craig Hart's PCI Programs:
http://devel.archefire.org/mirrors/memb ... nloads.htm
http://wiki.osdev.org/PCI_IDE_Controller
Re: My kernel can't read hard disk on the real machine.
Posted: Sat Dec 26, 2015 9:47 pm
by 626788149
Brendan wrote:Hi,
626788149 wrote:catnikita255 wrote:Maybe your HDD is not IDE?
Do I need initialize IDE before use it ?
You need to find out if IDE/ATA exists before you use it. Most real computers use
SATA/AHCI instead (and some use SCSI, and some might be using
NVMe already).
Cheers,
Brendan
yes, your are right, My hard disk is SATA/AHCI and I changed my hard disk to compatible mode and I get an ECC error.
Re: My kernel can't read hard disk on the real machine.
Posted: Sat Dec 26, 2015 9:48 pm
by 626788149
~ wrote:Maybe you are using SATA disks/controllers, and if that's the case, you will most likely need to use a different set of registers than the typical 0x1F0-0x1F7 or 0x170-0x177 port ranges.
You would need to detect the port ranges for the disk controllers (using tye PCI bus functionality, I/O ports and/or memory mapped registers).
See this to see if it can help you. You can also use programs like PCI32 for Windows to manually scan for port addresses and use that like an initial hint for the addresses of all your PCI devices:
Craig Hart's PCI Programs:
http://www.archive.org/download/devel.a ... nloads.htm
http://wiki.osdev.org/PCI_IDE_Controller
I changed my hard dsk to compatible mode and I get an ECC error ,Maybe I have to find out other way.
Re: My kernel can't read hard disk on the real machine.
Posted: Sun Dec 27, 2015 12:38 am
by ~
First you still need to make sure that you're actually using the actual BAR (base address registers) from the PCI device, as most likely they aren't the typical 0x1F0 or 0x170.
Then you must make sure that you aren't sending CD/DVD commands to a hard disk or hard disk commands to a CD/DVD, since they send ABORT signals when doing things like trying to identify them and sending the command for their counterpart (as in IDENTIFY PACKET DEVICE on a hard disk instead of IDENTIFY DEVICE).
Re: My kernel can't read hard disk on the real machine.
Posted: Sun Dec 27, 2015 3:03 am
by Brendan
Hi,
~ wrote:First you still need to make sure that you're actually using the actual BAR (base address registers) from the PCI device, as most likely they aren't the typical 0x1F0 or 0x170.
Then you must make sure that you aren't sending CD/DVD commands to a hard disk or hard disk commands to a CD/DVD, since they send ABORT signals when doing things like trying to identify them and sending the command for their counterpart (as in IDENTIFY PACKET DEVICE on a hard disk instead of IDENTIFY DEVICE).
More specifically; you'd want to start with PCI bus enumeration; and when you find a "mass storage controller" device (base class = 0x01) determine if it's IDE (sub-class = 0x01) or something else (SATA, RAID, SCSI, etc), and if it is IDE examine the "interface" part of the class code to determine what sort of programming interface it's using. The "interface" part of the class code will tell you if the controller is in "legacy ISA emulation mode" or in "native PCI mode". It will also tell you if the controller allows you to change it from one mode to the other.
If it's using "legacy ISA emulation mode" then it will use the ancient ISA resources (base IO port 0x01F0 or 0x0170, ISA IRQ 14 or 15) regardless of what anything else says (and the BARs shouldn't be used); and if it's using "native PCI mode" then you must use BARs (and PCI IRQs and not ISA IRQs 14 or 15).
Note that wherever possible I'd recommend trying to switch the controller into "native PCI mode" if necessary/possible; partly because it's more flexible and better for performance (especially when you start thinking about IO APICs and/or MSI); and partly because it allows you to support systems with 2 or more IDE controller devices without resource conflicts (e.g. 2 or more PCI devices that both think they "own" IO port 0x01F0, etc).
Cheers,
Brendan