Detecting hardware
- Revelation
- Member
- Posts: 47
- Joined: Sat Jun 21, 2008 8:15 am
Detecting hardware
Hi,
Now that my p-mode kernel is working properly, I want to communicate with my hardware. For example my hard drive. But I don't really know how to detect my hdd and other hardware. How can I do that?
Now that my p-mode kernel is working properly, I want to communicate with my hardware. For example my hard drive. But I don't really know how to detect my hdd and other hardware. How can I do that?
Now is the winter of my disk content.
Re: Detecting hardware
Use PIO, this a fairly good tutorial:
http://www.osdever.net/tutorials/lba.php
or DMA works too...
Jules
http://www.osdever.net/tutorials/lba.php
or DMA works too...
Jules
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: Detecting hardware
Scan the PCI Configuration Space. It should provide you with controllers to most buses. Then you should scan every bus separately. Everyone uses different method to say if there and how many devices are attached.
The other way is far more harder but probably more efficient. You could use the ACPI tables. But don't mess with that, it use machine code different from x86 assembly.
The other way is far more harder but probably more efficient. You could use the ACPI tables. But don't mess with that, it use machine code different from x86 assembly.
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
Current state: real-mode kernel-FS reader...
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Detecting hardware
The PCI space won't tell you all devices. ISA needs to be detected manually, standard peripherals must be detected manually. the floppy and ide controllers may not be listed in the PCI tables, nor in the ACPI tables, especially when dealing with computers predating those standards.
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: Detecting hardware
PCI will tell you if PCI-to-ISA bridge exist. If any then you should load ISA driver and test devices. PCI-to-ISA bridge may exist even if there isn't any ISA slots on your motherboard.Combuster wrote:The PCI space won't tell you all devices. ISA needs to be detected manually, standard peripherals must be detected manually. the floppy and ide controllers may not be listed in the PCI tables, nor in the ACPI tables, especially when dealing with computers predating those standards.
PCI will tell you most of the integrated devices and all the devices connected to PCI slot and it won't report about any other devices like peripherals, HDD, etc. Integrated devices into I/O chip also include bridges to buses (AGP, ISA, USB). You should "ask" every bus what devices are connected to it (if any).
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
Current state: real-mode kernel-FS reader...
- Revelation
- Member
- Posts: 47
- Joined: Sat Jun 21, 2008 8:15 am
Re: Detecting hardware
I currently have a hdd driver based on that tutorial, though I am not sure if it will work on my S-ATA drive. I also saw that this way of communicating to a drive only lets me access 4 drives, 2 on primary and 2 on secondary IDE.Use PIO, this a fairly good tutorial
This is the code I use to find if the drive on that IDE cable exists and if it is a hard drive:
Code: Select all
int DetectDrive(unsigned char ide, unsigned long drive)
{
unsigned short tmpword;
unsigned char check;
unsigned short base;
unsigned short buf[256];
unsigned short idx;
if (ide == 0)
base = 0x1F0;
else
if (ide == 1)
base = 0x170;
else
return 0; // only 2 IDE controllers
outb(base + 3, 0x88); // write
check = inb(base + 3); // read
if (check != 0x88) // check if the magic value is the same
{
puts("Error: the IDE controller does not exist.\n");
return 0;
}
outb(base + 6, 0xA0 | (drive << 4));
sleep(1); // wait a while, min wait time: 400ns
outb(base + 7, 0xEC); //send identify
if (!waituntilbusy(base))
return 0;
buf[0] = inw(base);
if (buf[0]) // if exists
{
puts("Drive exists\n");
for (idx = 1; idx < 256; idx++)
buf[idx] = inw(base); // read a word
if (buf[0] | 0x0040 == buf[0])
puts("Hard drive\n");
else
{
puts("No hard drive\n");
return 0;
}
return 1;
}
else
{
puts("Drive does not exist\n");
return 0;
}
}
Thanks, I'll try and look up some documents.Scan the PCI Configuration Space
Now is the winter of my disk content.
Re: Detecting hardware
It's my understanding that all motherboards have a PCI-to-ISA bridge, as most legacy devices (e.g. floppy) are connected to the (internal) ISA bus. But I may be wrong.Masterkiller wrote:PCI-to-ISA bridge may exist even if there isn't any ISA slots on your motherboard.
JAL
- Revelation
- Member
- Posts: 47
- Joined: Sat Jun 21, 2008 8:15 am
Re: Detecting hardware
When I use my detect code outside Bochs, it doesn't detect my SATA drive. Should I do something special for that?
Now is the winter of my disk content.
Re: Detecting hardware
Well, start with explaining how you detect it in Bochs.Revelation wrote:When I use my detect code outside Bochs, it doesn't detect my SATA drive. Should I do something special for that?
JAL
- Revelation
- Member
- Posts: 47
- Joined: Sat Jun 21, 2008 8:15 am
Re: Detecting hardware
I don't really. In Bochs I set my ata0-master to a hdd image, so not my real hdd. Also, that's ata0 and not sata.
Now is the winter of my disk content.
- Revelation
- Member
- Posts: 47
- Joined: Sat Jun 21, 2008 8:15 am
Re: Detecting hardware
I'm probably doing something very stupid, but why doesn't this work?
Code: Select all
static unsigned long pci_read(unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg)
{
outl(0xCF8, ((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | reg));
return inl(0xCFC);
}
void scanpci()
{
unsigned char bus, dev, func;
unsigned long a, value;
unsigned char classcode;
for (bus = 0; bus < 255; bus++)
for (dev = 0; dev < 32; dev++)
for (func = 0; func < 8; func++)
{
a = pci_read(bus, dev, func, 0x08); // class info
classcode = a >> 8;
if (classcode == 0x0C)
puts("USB detected\n");
}
}
Now is the winter of my disk content.
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: Detecting hardware
Suggestion: It depends on the compiler, but mostly "int" type uses current section BITS size. For 16-bit DOS application it should be 16-bit, in 32-bit protected mode 32-bit and in long-mode 64-bit. The "long" type is strict 32-bit in size. You should use it instead of int.Revelation wrote:I'm probably doing something very stupid, but why doesn't this work?
Code: Select all
static unsigned long pci_read(unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg) { outl(0xCF8, ((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | reg)); return inl(0xCFC); } void scanpci() { unsigned char bus, dev, func; unsigned long a, value; unsigned char classcode; for (bus = 0; bus < 255; bus++) for (dev = 0; dev < 32; dev++) for (func = 0; func < 8; func++) { a = pci_read(bus, dev, func, 0x08); // class info classcode = a >> 8; if (classcode == 0x0C) puts("USB detected\n"); } }
Contents of the 0x08 PCI regitser are 0xCCSSRRRR where, C is class code, S - Subclass, R - Revising. Shifting Right by 8 and in you get 0x00CCSSRR > 0x00010000 so it is impossible to be equal to 0x0C. Shift Right by 24 and you will get what you want.
http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html
According to this document might be better to do it: if(a>>16==0x0C03) to be sure you don't recognize Firewire as a USB
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
Current state: real-mode kernel-FS reader...
Re: Detecting hardware
You recognize SATA by the error "message" that you get back when you try to do an IDENTIFY command on that drive.
The details are in ATA_PIO_Mode.
The details are in ATA_PIO_Mode.
Re: Detecting hardware
'int' is guaranteed to be 32 bits on modern 32 and 64 bit platforms. However, instead of directly using long, it's better to define an int32_t type and use that for maximum portability.Masterkiller wrote:The "long" type is strict 32-bit in size. You should use it instead of int.
JAL
Re: Detecting hardware
It depends on the compiler, but mostly "int" type uses current section BITS size. For 16-bit DOS application it should be 16-bit, in 32-bit protected mode 32-bit and in long-mode 64-bit. The "long" type is strict 32-bit in size. You should use it instead of int.
Long>=Int
On my i586-32 GCC Cross Compiler, char=8, short = 16, int = 32, long = 32, long long = 64.
On my x86-64 GCC Cross Compiler, char=8, short = 16, int = 32, long = 64, long long = 64.
However, even these sizes are not guaranteed and you should always check before you use them.
Cheers,
Adam
Long>=Int
On my i586-32 GCC Cross Compiler, char=8, short = 16, int = 32, long = 32, long long = 64.
On my x86-64 GCC Cross Compiler, char=8, short = 16, int = 32, long = 64, long long = 64.
However, even these sizes are not guaranteed and you should always check before you use them.
Cheers,
Adam