Page 1 of 1

ide_initialize is not finding any drives

Posted: Mon Dec 28, 2015 12:12 pm
by osdever
I've tried to implement HDD support. I'm readed the tutorial from Quafios creator, but ide_initialize is not finding any drives. My code is:

Code: Select all

void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2, unsigned int BAR3, unsigned int BAR4)
{
   debug_print(NOTICE,"ide_initialize: started");
   int j, k, count = 0;

BAR0 &= 0xFFFFFFFC;
BAR1 &= 0xFFFFFFFC;
BAR2 &= 0xFFFFFFFC;
BAR3 &= 0xFFFFFFFC;
BAR4 &= 0xFFFFFFFC;
   debug_print(NOTICE,"ide_initialize: detecting I/O ports");
   // 1- Detect I/O Ports which interface IDE Controller:
   channels[ATA_PRIMARY  ].base  = (BAR0) + 0x1F0*(!BAR0);
   channels[ATA_PRIMARY  ].ctrl  = (BAR1) + 0x3F4*(!BAR1);
   channels[ATA_SECONDARY].base  = (BAR2) + 0x170*(!BAR2);
   channels[ATA_SECONDARY].ctrl  = (BAR3) + 0x374*(!BAR3);
   channels[ATA_PRIMARY  ].bmide = (BAR4) + 0; // Bus Master IDE
   channels[ATA_SECONDARY].bmide = (BAR4) + 8; // Bus Master IDE
      debug_print(NOTICE,"ide_initialize: ide_write()");
   ide_write(ATA_PRIMARY  , ATA_REG_CONTROL, 2);
   ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
      debug_print(NOTICE,"ide_initialize: detecting devices");
   // 3- Detect ATA-ATAPI Devices:
      int i;
   for (i = 0; i < 2; i++)
   {
         debug_print(NOTICE,"ide_initialize: cycle 1");
      for (j = 0; j < 2; j++) {
   debug_print(NOTICE,"ide_initialize: cycle 2");
         unsigned char err = 0, type = IDE_ATA, status;
         ide_devices[count].reserved   = 0; // Assuming that no drive here.
   debug_print(NOTICE,"ide_initialize: vars set");
         // (I) Select Drive:
         ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j<<4)); // Select Drive.
            debug_print(NOTICE,"ide_initialize: drive selected");
         sleep(1); // Wait 1ms for drive select to work.
   debug_print(NOTICE,"ide_initialize: ATA_IDENT");
         // (II) Send ATA Identify Command:
         ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
         sleep(1); // This function should be implemented in your OS. which waits for 1 ms. it is based on System Timer Device Driver.
   debug_print(NOTICE,"ide_initialize: Polling");
         // (III) Polling:
         if (!(ide_read(i, ATA_REG_STATUS))){ debug_print(NOTICE,"ide_initialize: No device is attached."); continue; }// If Status = 0, No Device.
   debug_print(NOTICE,"ide_initialize: is ATA?");
         while(1) {
            status = ide_read(i, ATA_REG_STATUS);
            if ( (status & ATA_SR_ERR)) {err = 1;   debug_print(ERROR,"ide_initialize: No ATA"); break;} // If Err, Device is not ATA.
            if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)){ debug_print(SUCCESS,"ide_initialize: All is right.");break;} // Everything is right.
            else{debug_print(ERROR,"IDE Unknown Error");break;}
         }

         // (IV) Probe for ATAPI Devices:

         if (err) {
            unsigned char cl = ide_read(i,ATA_REG_LBA1);
            unsigned char ch = ide_read(i,ATA_REG_LBA2);

            if   (cl == 0x14 && ch ==0xEB) type = IDE_ATAPI;
            else if   (cl == 0x69 && ch ==0x96) type = IDE_ATAPI;
            else continue; // Unknown Type (And always not be a device).

            ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
            sleep(1);
         }

         // (V) Read Identification Space of the Device:
         ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);

         // (VI) Read Device Parameters:
         ide_devices[count].reserved   = 1;
         ide_devices[count].type      = type;
         ide_devices[count].channel   = i;
         ide_devices[count].drive   = j;
         ide_devices[count].sign      = ((unsigned short *) (ide_buf + ATA_IDENT_DEVICETYPE   ))[0];
         ide_devices[count].capabilities = ((unsigned short *) (ide_buf + ATA_IDENT_CAPABILITIES   ))[0];
         ide_devices[count].commandsets  = ((unsigned int   *) (ide_buf + ATA_IDENT_COMMANDSETS   ))[0];

         // (VII) Get Size:
         if (ide_devices[count].commandsets & (1<<26)){
            // Device uses 48-Bit Addressing:
            ide_devices[count].size   = ((unsigned int   *) (ide_buf + ATA_IDENT_MAX_LBA_EXT   ))[0];
            // Note that Quafios is 32-Bit Operating System, So last 2 Words are ignored.
         } else {
            // Device uses CHS or 28-bit Addressing:
            ide_devices[count].size   = ((unsigned int   *) (ide_buf + ATA_IDENT_MAX_LBA   ))[0];
         }

         // (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
         for(k = ATA_IDENT_MODEL; k < (ATA_IDENT_MODEL+40); k+=2) {
            ide_devices[count].model[k - ATA_IDENT_MODEL] = ide_buf[k+1];
            ide_devices[count].model[(k+1) - ATA_IDENT_MODEL] = ide_buf[k];}
         ide_devices[count].model[40] = 0; // Terminate String.
         count++;
      }
}
   // 4- Print Summary:
   for (int i = 0; i < 4; i++)
      if (ide_devices[i].reserved == 1) {
         printf(" Found %s Drive %dGB - %s\n",
            (const char *[]){"ATA", "ATAPI"}[ide_devices[i].type],         /* Type */
            ide_devices[i].size/1024/1024/2,               /* Size */
            ide_devices[i].model);
      }
}
It's not finding any drives, but displays me just Found ATA Drive 0 GB - <either nothing or some stupid unprintable text> 4 times.
This is my init function:

Code: Select all

void os_lowlevel_init()
{
    debug_print(NOTICE,"init: Initializing architecture-specific features...\n");
    arch_init(); //Initialize architecture-specific features.
    tty_putchar('\n');
    debug_print(NOTICE,"init: Initializing memory management...");
    init_memory();
    debug_print(NOTICE,"init: Initializing PIT...");
    setupPIT();

    debug_print(NOTICE,"init: Initializing mouse (debug mode)...");
    mouse_install();

    
    debug_print(NOTICE,"init: Initializing STDIO...");
    init_stdio();
    debug_print(NOTICE,"init: Initializing VFS...");
    init_rootfs();
    debug_print(NOTICE,"init: Initializing ATA...");
    ide_initialize(0x1F0, 0x3F4, 0x170, 0x374, 0x000);
    debug_print(SUCCESS,"init: All work is done, exiting.");
}

Re: ide_initialize is not finding any drives

Posted: Mon Dec 28, 2015 1:01 pm
by iansjack
Does your computer have any IDE drives?

Re: ide_initialize is not finding any drives

Posted: Mon Dec 28, 2015 1:31 pm
by osdever
iansjack wrote:Does your computer have any IDE drives?
I'm testing it in QEMU. On real computer it also doesn't works.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 5:46 am
by osdever
Is anybody here? I want help.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 6:01 am
by iansjack
We can't see how you're calling the function, so it's difficult to offer constructive comments. But please don't take that as an invitation to post a load of code for someone else to debug.

Apply some simple debugging techniques. What are the values you are using for the I/O ports? Do they look reasonable? Single step through the code to see exactly what is happening.

I'll put it down to the fact that English is not your native language, but your latest post sounds a little demanding. You can ask for help but demanding it is normally counterproductive.

Edit: There is a thread here that discusses problems with the same code you have copy-pasted, so you may want to look at it.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 7:54 am
by osdever
iansjack wrote:We can't see how you're calling the function, so it's difficult to offer constructive comments. But please don't take that as an invitation to post a load of code for someone else to debug.

Apply some simple debugging techniques. What are the values you are using for the I/O ports? Do they look reasonable? Single step through the code to see exactly what is happening.

I'll put it down to the fact that English is not your native language, but your latest post sounds a little demanding. You can ask for help but demanding it is normally counterproductive.

Edit: There is a thread here that discusses problems with the same code you have copy-pasted, so you may want to look at it.
Give me a link to that thread, please.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 7:56 am
by osdever
iansjack wrote:We can't see how you're calling the function, so it's difficult to offer constructive comments. But please don't take that as an invitation to post a load of code for someone else to debug.

Apply some simple debugging techniques. What are the values you are using for the I/O ports? Do they look reasonable? Single step through the code to see exactly what is happening.

I'll put it down to the fact that English is not your native language, but your latest post sounds a little demanding. You can ask for help but demanding it is normally counterproductive.

Edit: There is a thread here that discusses problems with the same code you have copy-pasted, so you may want to look at it.

Code: Select all

    debug_print(NOTICE,"init: Initializing ATA...");
    ide_initialize(0x1F0, 0x3F4, 0x170, 0x374, 0x000);
It's in OS_lowlevel_init() function. This is my kernel_main():

Code: Select all

void kernel_main(struct mboot_info *mboot)
{
    initVBE(mboot);
    initTTY();
    // printf() uses memory allocating, which will be initialized later
    tty_wrstr("U365 kernel is loaded. TTY and VBE are initialized. Running os_lowlevel_init()...\n\n");
    //Run pre-run tasks and start the shell.
    os_lowlevel_init();
    debug_print(SUCCESS,"OS is initialized. Loading the shell...");
    ishMain();
    while(1);
}



Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 8:03 am
by osdever
This is my TTY output.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 8:32 am
by iansjack
It looks as if you are detecting the drives but not printing the information correctly, so your subject heading is midleading. To find out why that is single-step from (V) to the end of ide_initialize to see exactly what is happening. It should be obvious exactly where things are not working.

I presume that you have tested your sleep() function.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 8:52 am
by osdever
iansjack wrote:It looks as if you are detecting the drives but not printing the information correctly, so your subject heading is midleading. To find out why that is single-step from (V) to the end of ide_initialize to see exactly what is happening. It should be obvious exactly where things are not working.

I presume that you have tested your sleep() function.
I'm tested it, it works.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 10:07 am
by iansjack
Then start single-stepping with a debugger. Inspect the variables at every stage until they don't read what you think they should. Then you have found the location of your error.

Re: ide_initialize is not finding any drives

Posted: Wed Dec 30, 2015 12:00 pm
by osdever
iansjack wrote:Then start single-stepping with a debugger. Inspect the variables at every stage until they don't read what you think they should. Then you have found the location of your error.
Ok.

Re: ide_initialize is not finding any drives

Posted: Sat Jan 02, 2016 8:29 am
by iocoder
catnikita255 wrote:I've tried to implement HDD support. I'm readed the tutorial from Quafios creator, but ide_initialize is not finding any drives. My code is:

Code: Select all

void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2, unsigned int BAR3, unsigned int BAR4)
{
   debug_print(NOTICE,"ide_initialize: started");
   int j, k, count = 0;

BAR0 &= 0xFFFFFFFC;
BAR1 &= 0xFFFFFFFC;
BAR2 &= 0xFFFFFFFC;
BAR3 &= 0xFFFFFFFC;
BAR4 &= 0xFFFFFFFC;
   debug_print(NOTICE,"ide_initialize: detecting I/O ports");
   // 1- Detect I/O Ports which interface IDE Controller:
   channels[ATA_PRIMARY  ].base  = (BAR0) + 0x1F0*(!BAR0);
   channels[ATA_PRIMARY  ].ctrl  = (BAR1) + 0x3F4*(!BAR1);
   channels[ATA_SECONDARY].base  = (BAR2) + 0x170*(!BAR2);
   channels[ATA_SECONDARY].ctrl  = (BAR3) + 0x374*(!BAR3);
   channels[ATA_PRIMARY  ].bmide = (BAR4) + 0; // Bus Master IDE
   channels[ATA_SECONDARY].bmide = (BAR4) + 8; // Bus Master IDE
      debug_print(NOTICE,"ide_initialize: ide_write()");
   ide_write(ATA_PRIMARY  , ATA_REG_CONTROL, 2);
   ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
      debug_print(NOTICE,"ide_initialize: detecting devices");
   // 3- Detect ATA-ATAPI Devices:
      int i;
   for (i = 0; i < 2; i++)
   {
         debug_print(NOTICE,"ide_initialize: cycle 1");
      for (j = 0; j < 2; j++) {
   debug_print(NOTICE,"ide_initialize: cycle 2");
         unsigned char err = 0, type = IDE_ATA, status;
         ide_devices[count].reserved   = 0; // Assuming that no drive here.
   debug_print(NOTICE,"ide_initialize: vars set");
         // (I) Select Drive:
         ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j<<4)); // Select Drive.
            debug_print(NOTICE,"ide_initialize: drive selected");
         sleep(1); // Wait 1ms for drive select to work.
   debug_print(NOTICE,"ide_initialize: ATA_IDENT");
         // (II) Send ATA Identify Command:
         ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
         sleep(1); // This function should be implemented in your OS. which waits for 1 ms. it is based on System Timer Device Driver.
   debug_print(NOTICE,"ide_initialize: Polling");
         // (III) Polling:
         if (!(ide_read(i, ATA_REG_STATUS))){ debug_print(NOTICE,"ide_initialize: No device is attached."); continue; }// If Status = 0, No Device.
   debug_print(NOTICE,"ide_initialize: is ATA?");
         while(1) {
            status = ide_read(i, ATA_REG_STATUS);
            if ( (status & ATA_SR_ERR)) {err = 1;   debug_print(ERROR,"ide_initialize: No ATA"); break;} // If Err, Device is not ATA.
            if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)){ debug_print(SUCCESS,"ide_initialize: All is right.");break;} // Everything is right.
            else{debug_print(ERROR,"IDE Unknown Error");break;}
         }

         // (IV) Probe for ATAPI Devices:

         if (err) {
            unsigned char cl = ide_read(i,ATA_REG_LBA1);
            unsigned char ch = ide_read(i,ATA_REG_LBA2);

            if   (cl == 0x14 && ch ==0xEB) type = IDE_ATAPI;
            else if   (cl == 0x69 && ch ==0x96) type = IDE_ATAPI;
            else continue; // Unknown Type (And always not be a device).

            ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
            sleep(1);
         }

         // (V) Read Identification Space of the Device:
         ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);

         // (VI) Read Device Parameters:
         ide_devices[count].reserved   = 1;
         ide_devices[count].type      = type;
         ide_devices[count].channel   = i;
         ide_devices[count].drive   = j;
         ide_devices[count].sign      = ((unsigned short *) (ide_buf + ATA_IDENT_DEVICETYPE   ))[0];
         ide_devices[count].capabilities = ((unsigned short *) (ide_buf + ATA_IDENT_CAPABILITIES   ))[0];
         ide_devices[count].commandsets  = ((unsigned int   *) (ide_buf + ATA_IDENT_COMMANDSETS   ))[0];

         // (VII) Get Size:
         if (ide_devices[count].commandsets & (1<<26)){
            // Device uses 48-Bit Addressing:
            ide_devices[count].size   = ((unsigned int   *) (ide_buf + ATA_IDENT_MAX_LBA_EXT   ))[0];
            // Note that Quafios is 32-Bit Operating System, So last 2 Words are ignored.
         } else {
            // Device uses CHS or 28-bit Addressing:
            ide_devices[count].size   = ((unsigned int   *) (ide_buf + ATA_IDENT_MAX_LBA   ))[0];
         }

         // (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
         for(k = ATA_IDENT_MODEL; k < (ATA_IDENT_MODEL+40); k+=2) {
            ide_devices[count].model[k - ATA_IDENT_MODEL] = ide_buf[k+1];
            ide_devices[count].model[(k+1) - ATA_IDENT_MODEL] = ide_buf[k];}
         ide_devices[count].model[40] = 0; // Terminate String.
         count++;
      }
}
   // 4- Print Summary:
   for (int i = 0; i < 4; i++)
      if (ide_devices[i].reserved == 1) {
         printf(" Found %s Drive %dGB - %s\n",
            (const char *[]){"ATA", "ATAPI"}[ide_devices[i].type],         /* Type */
            ide_devices[i].size/1024/1024/2,               /* Size */
            ide_devices[i].model);
      }
}
It's not finding any drives, but displays me just Found ATA Drive 0 GB - <either nothing or some stupid unprintable text> 4 times.
This is my init function:

Code: Select all

void os_lowlevel_init()
{
    debug_print(NOTICE,"init: Initializing architecture-specific features...\n");
    arch_init(); //Initialize architecture-specific features.
    tty_putchar('\n');
    debug_print(NOTICE,"init: Initializing memory management...");
    init_memory();
    debug_print(NOTICE,"init: Initializing PIT...");
    setupPIT();

    debug_print(NOTICE,"init: Initializing mouse (debug mode)...");
    mouse_install();

    
    debug_print(NOTICE,"init: Initializing STDIO...");
    init_stdio();
    debug_print(NOTICE,"init: Initializing VFS...");
    init_rootfs();
    debug_print(NOTICE,"init: Initializing ATA...");
    ide_initialize(0x1F0, 0x3F4, 0x170, 0x374, 0x000);
    debug_print(SUCCESS,"init: All work is done, exiting.");
}
Hi! This code is way too old, and I am not sure if this code is bug free. The accuracy of the article from which you have got this code is disputed. I suggest you have a look at other online implementations and compare them to this code. You could also check the latest version of quafios ATA driver (https://github.com/quafios/quafios/blob ... ide.c#L713).