How to use multiple disks?

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.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

How to use multiple disks?

Post by Bonfra »

When the bootloader is loaded, the bios sets DL as the drive number. For example, if booting happens from an HDD the value of DL will be 0x80 which is universal for all HDD as far as I've understood. In the kernel, I'm implementing an interface to access files on the disk and I thought about reading other disks other than the boot one. I found this source in the wiki (I use the LBA one) which allows me to read sectors from the bootdrive as HDD. It works and I'm developing the filesystem driver and the VFS. But how can I access other disks? In my case, I burn the image in a USB and boot it from a real PC with its own hard drive. How can I access it?
Regards, Bonfra.
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: How to use multiple disks?

Post by pvc »

Value 0x80 represents first drive, value 0x81 represents second, 0x82 third, etc.
These values are, of course, only valid for int 0x13 BIOS calls.
And it's the BIOS that decides which physical drive has which id. I am not sure if drive ids can be non-consecutive numbers or not.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

pvc wrote:it's the BIOS that decides which physical drive has which id
Is there a way to detect all connected drives?
Regards, Bonfra.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How to use multiple disks?

Post by iansjack »

As explained here: https://wiki.osdev.org/ATA_PIO_Mode#Det ... ialization , you can use the ATA IDENTIFY command on each port to determine whether a drive is attached.
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: How to use multiple disks?

Post by pvc »

I am not exactly sure, but I think, your best bet would be probing consecutive ids with IDENTIFY command and see if it succeeds or fails.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

pvc wrote:I am not exactly sure, but I think, your best bet would be probing consecutive ids with IDENTIFY command and see if it succeeds or fails.
This is more of a bootloader solution. I'd like to achieve this in the kernel, I'm reading @iansjack solution of the ATA identify command. It looks a bit scary but seems right. I'll let you know if I understand something
Regards, Bonfra.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: How to use multiple disks?

Post by nexos »

To access a USB stick, you must write a USB host controller driver. Then you must write a driver for mass storage devices. USB is very difficult, however...
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

Following the IDENTIFY command explained here I wrote this code:

Code: Select all

int ata_identify(uint16_t drive)
{
    // Select master drive
    outportb(ATA_DRIVE_SELECT, ATA_MASTER);

    // Clear parameters
    outportb(ATA_SECTORS_COUNT, 0);
    outportb(ATA_LBA_LO, 0);
    outportb(ATA_LBA_MID, 0);
    outportb(ATA_LBA_HI, 0);

    // Identify command
    outportb(ATA_COMMAND_IO, ATA_IDENTIFY_COMMAND);
    uint8_t status = inportb(ATA_STATUS_PORT);

    if(status == ATA_NO_DEVICE)
        return ATA_NO_DEVICE;
}
The explanation continued but I stopped writing when I noticed that I didn't use the drive parameter. Is the wiki not describeing how to detect a specific drive or is me not reading correctly?
Regards, Bonfra.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

nexos wrote:To access a USB stick, you must write a USB host controller driver. Then you must write a driver for mass storage devices. USB is very difficult, however...
The USB is booted with some sort of HDD emulation or something, anyway using the example from the wiki I managed to read the sectors from the USB stick.
Regards, Bonfra.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

I readed some bits from Ben Lunt book and then write(copyed) this loop to detect all the connected devices:

Code: Select all

    size_t current_device = 0;
    for(int bus = 0; bus < PCI_MAX_BUS; bus++)
        for(int dev = 0; dev < PCI_MAX_DEVICE; dev++)
            for(int func = 0; func < PCI_MAX_FUNCTION; func++)
                if(pci_read_word(bus, dev, func, 0) != UINT16_MAX)
                {
                    pci_device_t data;
                    uint32_t* dataptr = (uint32_t*)&data;

                    // read in the 256 bytes (64 dwords)
                    for(int i = 0; i < 64; i++)
                        dataptr[i] = pci_read_dword(bus, dev, func, i << 2);

                    devices[current_device++] = data;
                }

Then I filter the devices taking only the ones with class = 1, so the ATA devices.
It's strange how when I boot the os on real hardware there seems to be any ATA device connected. I tried on multiple machines but all returns me zero ATA devices. Instead in QEMU, I get back at least one device. How is that possible? There must be an ATA controller.
Regards, Bonfra.
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: How to use multiple disks?

Post by pvc »

Do your test machines have real parallel IDE interface? Or are they SATA only? For SATA, they may use either IDE controller or AHCI controller. For IDE controllers you should look for PCI devices with class == 1 and subclass == 1. For AHCI controllers, it's class == 1 and subclass == 6.
Assuming your PCI config space read routine is ok.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

pvc wrote:Do your test machines have real parallel IDE interface? Or are they SATA only? For SATA, they may use either IDE controller or AHCI controller. For IDE controllers you should look for PCI devices with class == 1 and subclass == 1. For AHCI controllers, it's class == 1 and subclass == 6.
I test for any device with class == 1, I've not tested any subclass for now.

Edit:
I noticed that I accidentally deleted a digit from the device count, I wrote 3 instead of 32, so it couldn't work. Now it works and found the devices. Let's see how It goes from now on.

Now I should use the detected device in some way that I yet don't know but I'm sure it's explained in this awesome book. I'll link it here for future readers:
http://www.fysnet.net/media_storage_devices.htm
Regards, Bonfra.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: How to use multiple disks?

Post by Bonfra »

Can someone link me some actual working code that manages the pci and the ata so that I can better learn? I can find some articles here and there but they are all very confusing. I searched on the wiki and on GitHub I can find only some bits not related to each other. Nothing complete or well explained.
If someone can link some code it could be awesome.
Regards, Bonfra.
jaihsonk
Posts: 24
Joined: Thu Jul 14, 2022 10:46 am
Libera.chat IRC: json
Location: Canada
Contact:

Re: How to use multiple disks?

Post by jaihsonk »

After reading this, am I right to conclude that one must go from port to port indiscriminately sending IDENTIFY commands? And will whatever device connected (if there is one) will send a 16 bit number to identify what kind of device is attached?
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to use multiple disks?

Post by Octocontrabass »

jaihsonk wrote:After reading this, am I right to conclude that one must go from port to port indiscriminately sending IDENTIFY commands?
You can discriminate a little bit. There are certain combinations of status and error register values that will tell you for certain that no drive is connected.
jaihsonk wrote:And will whatever device connected (if there is one) will send a 16 bit number to identify what kind of device is attached?
If a hard drive is connected, it will reply with 512 bytes of data the same way it would if you used the READ command to read one sector. Those 512 bytes of data will tell you just about everything you need to know about the drive.

If something else is connected, it will abort the command and fill the command block registers with a signature to tell you that you should use IDENTIFY PACKET DEVICE instead.

If nothing is connected, nothing will happen. (On really old PCs, you might see bus capacitance when reading the nonexistent drive's registers.)
Post Reply