Page 2 of 2

Re: How to use multiple disks?

Posted: Mon Jan 30, 2023 11:21 am
by jaihsonk
OK so i did some reading and there is a register at port 0x1f6 is a disk ID. BIOS sets that to the ID of the disks booted to. How can I find more IDs? Sorry if this is a dumb question lol

Re: How to use multiple disks?

Posted: Mon Jan 30, 2023 11:59 am
by Octocontrabass
Er, I don't know what you've been reading, but port 0x1F6 isn't an ID. If your IDE controller is mapped at the legacy addresses, that port contains the drive select bit, but that only tells you which drive is selected on that IDE channel.

What kind of ID are you looking for? Why do you need an ID? There are different IDs available, and the one that works best for you will depend on what you want to do with it.

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 1:39 pm
by jaihsonk
I must have read something wrong. I think I'm not clicking somewhere.
Attatched is a snippet of som code I wrote. Let me know if I have the correct understanding of what to do

Code: Select all

bool ata_identify(uint16_t base_port)
{
    outb(base_port + 6, 0xA0); //master
    outb(base_port + 2, 0);
    outb(base_port + 3, 0);
    outb(base_port + 4, 0);
    outb(base_port + 5, 0);
    outb(base_port + 7, 0xEC);

    uint8_t buf[512];
    unsigned short* ptr = (unsigned short*) buf;

    // Wait for the buffer to be ready
    uint8_t c = insb(base_port + 7);
    if(!c)
        return false;

    while(c & 0x80)
        c = insb(base_port + 7);
    
    uint8_t lba_mid = insb(base_port + 4), lba_hi = insb(base_port + 5);
    if(lba_hi || lba_mid)
        return false;

    do
        c = insb(base_port + 7);
    while(!(c & 0x08) || !(c & 0x01));

    for (int i = 0; i < 256; i++)
    {
        *ptr = insw(base_port);
        ptr++;
    }
    return true;
}

int ata_count_connected_disks()
{
    int res = 0;
    for(uint16_t i = 0x400; i < 0xFFFF; i += 8)
        if(ata_identify(i))
            res++;
    return res;
}

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 2:04 pm
by Octocontrabass

Code: Select all

    outb(base_port + 6, 0xA0); //master
There may be two devices attached to an IDE channel; you're only checking one of them.

Code: Select all

    uint8_t c = insb(base_port + 7);
Are you using "inb" or "insb" here? They are not the same thing.

Code: Select all

    while(!(c & 0x08) || !(c & 0x01));
I'm pretty sure you wanted to use "&&" instead of "||" here. Also, if the error bit is set, you can't read the identify data from the disk.

Code: Select all

        *ptr = insw(base_port);
Are you using "inw" or "insw" here? They are not the same thing.

Code: Select all

    for(uint16_t i = 0x400; i < 0xFFFF; i += 8)
        if(ata_identify(i))
Use PCI to find the addresses of IDE controllers, don't probe for them like this. (Unless you want to use IDE on an ancient PC that doesn't support PCI - then you can assume the IDE controller uses 0x1F0.)

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 2:48 pm
by jaihsonk
OK so PCI will tell me the port num of IDE controller. Does one IDE controller control every disks connected? or will each disk have its own controller? If each disk has its own controller, then will PCI tell me address of each controller?

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 2:59 pm
by Octocontrabass
jaihsonk wrote:Does one IDE controller control every disks connected? or will each disk have its own controller?
There may be any number of IDE controllers. Each IDE controller may have up to two channels. Each channel may have up to two disks.
jaihsonk wrote:will PCI tell me address of each controller?
Yes.

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 3:04 pm
by jaihsonk
OK thank you so much. This s a lot clearer now. Humans are a lot better the articles lol

Re: How to use multiple disks?

Posted: Tue Jan 31, 2023 3:21 pm
by jaihsonk
For anyone else, I also found this video to explain a fw things: https://www.youtube.com/watch?v=CF_copQaORQ