OSDev

для всех
Текущее время: 28 мар 2024, 11:48

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
СообщениеДобавлено: 16 дек 2015, 13:13 

Зарегистрирован: 16 дек 2015, 13:01
Сообщения: 3
Доброе время суток! я пишу драйвер для некоторой кастомной оси (intel , х86, многозадачная) для контроллера IDE на PCI . Я уже написал поиск контроллера на шине и портировал код с osdev : http://wiki.osdev.org/PCI_IDE_Controller
Но есть следующий вопрос: команды out и in направляются на фиксированные адреса портов или они как-то берутся из Pci bar - ов устройства ?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 дек 2015, 16:25 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Ну, во-первых, необходимо обеспечить, чтоб сам контроллер был настроен должным образом. Если к нему подключен загрузочный диск, то BIOS гарантированно контроллер настроит (правда, не факт, что настройка будет удобной для конкретной ОС, но пользоваться им будет можно), а вот если контроллер -- не тот, через который идёт загрузка, он может быть вообще не настроен (а тогда этим надо заниматься самостоятельно -- найти его на PCI и сконфигурировать должным образом).

Во-вторых, поддерживающие PnP устройства, в т.ч. любые контроллеры на PCI, гарантированно могут быть настроены для обращений к ним как к ячейкам памяти, а вот поддержку портов ввода-вывода могут и не иметь. Кроме того, для устройств, которые могут быть настроены и так, и эдак, система, выполняющая настройку, выбирает вариант настройки по своему усмотрению, причём рекомендуется настраивать доступ к регистрам устройств не как к портам, а как к ячейкам памяти. Соответственно, не факт, что к уже настроенному контроллеру удастся обратиться командами in и out -- вполне может быть, что придётся использовать mov. Речь, естественно, о настройке современных устройств; контроллеры жёстких дисков, как правило, умеют "притворяться" старьём, не допускающим настройки и работающим через строго определённые порты ввода-вывода. Естественно, в последнем варианте нельзя будет использовать "продвинутые" возможности контроллеров, а только те, что существовали в старых контроллерах IDE.

В общем, если система разрабатывается под конкретный ПК с конкретным железом и конкретной версией BIOS, можно "закладываться" на то, как именно данный BIOS выполняет настройку железа. Однако если ОС должна быть достаточно универсальной, нужно предусматривать все возможные варианты.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 дек 2015, 19:55 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
1)Согласен с тем что надо убедиться в том что контролёр PCI-IDE настроен и запущен.
Цитата:
Если к нему подключен загрузочный диск, то BIOS гарантированно контроллер настроит (

Где-то видел требования что BIOS должен настроить и запустить все контролёры жёстких дисков на материнской плате.
Но он не обязан настраивать и запускать контролёры на платах расширения.

2) Что касается PnP. Если он включён в настройках биоса.
И если на плате расширения стоит ПЗУ-память, то биос обязан вызвать её код.

3) PCI-CFG биос должен настроить и без включения PnP. Хотя бывает и такое.

4)
Цитата:
Соответственно, не факт, что к уже настроенному контроллеру удастся обратиться командами in и out -- вполне может быть,

Это конечно верно. И описано в стандарте PCI. Но есть стандарты на жёсткие диски. Есть у нас контролёр PCI-IDE то он обязан сделать порты для совместимости. А если прочий контроллер дисков, то нет.

5)
Цитата:
В общем, если система разрабатывается под конкретный ПК с конкретным железом и конкретной версией BIOS, можно "закладываться" на то, как именно данный BIOS выполняет настройку железа. Однако если ОС должна быть достаточно универсальной, нужно предусматривать все возможные варианты.

Не пишите универсальных драйверов. Пишите для каждого контроллера свой драйвер. Иногда их можно объединить в семейства.

Цитата:
Но есть следующий вопрос: команды out и in направляются на фиксированные адреса портов или они как-то берутся из Pci bar - ов устройства ?

Читаем BAR регистр отвечающей за BM_BASE. Если он настроен, тогда контроллер настроен. Проверяем дальше читаем другие BAR регистры если там не 0, то регистры настроены и используем их значения. Если 0 то используются стандартные фиксированные значения.

Подробнее можно прочитать в:
http://ru.osdev.wikia.com/wiki/Работа_с_жесткими_дисками_и_их_контроллерами
PS. Протокол чтения там реализован неверно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 дек 2015, 13:05 

Зарегистрирован: 16 дек 2015, 13:01
Сообщения: 3
Мне уже удалось прочитать PCI BAR0-BAR4, во всех ,кроме последнего нули. Судя по этому http://wiki.osdev.org/PCI_IDE_Controller#Detecting_a_PCI_IDE_Controller описанию мой контроллер должен управляться через фиксированные адреса портов. Но вот в чем проблема - после вызова функции
Код:
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000)
система не находит ни одного диска. Я использую kvm с параметрами:
Код:
-drive file=${OPTARG},if=ide,bus=0,unit=0
или просто:
Код:
-hda ${IMAGEFILE}


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 18 дек 2015, 00:25 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Извините, но штатный телепат этого форума взял отпуск на ∞ число дней. Вернётся не скоро. Так что не плохо бы если вы сами проверили разные варианты и привели результаты работы.

Как у вас сделана проверка? Какую команду выполняете? При посылке команды как меняется состояние сигналов BSY DRDY
Что в конечном счёте в регистре статуса и регистре ошибок?
Перед выполнением команды не забыли обнулить регистры?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 21 дек 2015, 16:15 

Зарегистрирован: 16 дек 2015, 13:01
Сообщения: 3
pavia писал(а):
Извините, но штатный телепат этого форума взял отпуск на ∞ число дней. Вернётся не скоро. Так что не плохо бы если вы сами проверили разные варианты и привели результаты работы.

Как у вас сделана проверка? Какую команду выполняете? При посылке команды как меняется состояние сигналов BSY DRDY
Что в конечном счёте в регистре статуса и регистре ошибок?
Перед выполнением команды не забыли обнулить регистры?

Вот какой код выполняется:
Код:
 // код, выполняемый после обнаружения ide  контроллера на шине PCI   
   bus = dev.bus;
   device = dev.dev;
   func = dev.func;

   cmdbase_pri = get_bar( &dev, 0 );
   ctrlbase_pri = get_bar( &dev, 1 );
   cmdbase_sec = get_bar( &dev, 2 );
   ctrlbase_sec = get_bar( &dev, 3 );
   bmidebase = get_bar( &dev, 4 );
   bmidebase &= 0xfffe;
   if ( cmdbase_pri == 0xffff || ctrlbase_pri == 0xffff || bmidebase == 0xffff )
   {
      sys_printf( "Error in PCI config for primary channel\n" );
   }
   else
   {
      cmdbase_pri &= 0xfffe;
      ctrlbase_pri &= 0xfffe;
      if ( cmdbase_pri == 0 )
      {
         sys_printf( "Device doesn't provide specific reg for primary ...defaulting\n" );
         cmdbase_pri = ATA_BASE_PRI;
         ctrlbase_pri = cmdbase_pri + DEV_CTRL_REG;
      }
      else
         ctrlbase_pri -= 4;
      bmidebase_pri = bmidebase;
      channels[0].base = cmdbase_pri;
      channels[0].ctrl = ctrlbase_pri;
      channels[0].bmide = bmidebase_pri;
      channels[0].nIEN = 0;
   }
   if ( cmdbase_sec == 0xffff || ctrlbase_sec == 0xffff || bmidebase == 0xffff )
   {
      sys_printf( "Error in PCI config for secondary channel\n");
   }
   else
   {
      cmdbase_sec &= 0xfffe;
      ctrlbase_sec &= 0xfffe;
      if ( cmdbase_sec == 0 )
      {
         sys_printf( "Device doesn't provide specific reg for secondary... defaulting\n" );
         cmdbase_sec = ATA_BASE_SEC;
         ctrlbase_sec = cmdbase_sec + DEV_CTRL_REG;
      }
      else
         ctrlbase_sec -= 4;
      bmidebase_sec = bmidebase + 8;
      channels[1].base = cmdbase_sec;
      channels[1].ctrl = ctrlbase_sec;
      channels[1].bmide = bmidebase_sec;
      channels[1].nIEN = 0;
   }

   sys_printf( " channels[0].base  %4x\n", channels[0].base );
   sys_printf( " channels[0].ctrl  %4x\n", channels[0].ctrl );
   sys_printf( " channels[0].bmide  %4x\n", channels[0].bmide );

   sys_printf( " channels[1].base  %4x\n", channels[1].base );
   sys_printf( " channels[1].ctrl  %4x\n", channels[1].ctrl );
   sys_printf( " channels[1].bmide  %4x\n", channels[1].bmide );

   sys_printf( "Reseting controllers\n" );
   if ( !reset_controller( channels[0].base ) )
      sys_printf( "can't reset channel 0\n" );
   if ( !reset_controller( channels[1].base ) )
      sys_printf( "can't reset channel 1\n" );
 

   for ( int c = 0, s = 0; c < 2; c++ )
   {
      if ( detect_master( channels[c].base ) )
      {
         //my_drives[s] = 1;
         sys_printf( "detect master %i\n", c );
      }

      s++;
      if ( detect_slave( channels[c].base ) )
      {
        // my_drives[s] = 1;
         sys_printf( "detect slave %i\n", c );
      }
      s++;
   }


//////////функции детектирования мастера и слейва ////////////////////////////////////////////////
uint8_t detect_master( uint16_t port )
{
   int32_t tmp;
   outportb( port + DRV_HD_REG, 0xA0 );  // Set drive
   pio_wait_busy( port );
   tmp = inportb( port + STATUS_REG );  // Read status
   if ( tmp & STA_DRDY )
      return 1;
   else
      return 0;
}

uint8_t detect_slave( unsigned short port )
{
   int32_t tmp;
   outportb( port + DRV_HD_REG, 0xB0 );  // Set drive
   pio_wait_busy( port );
   tmp = inportb( port + STATUS_REG );  // Read status
   if ( tmp & STA_DRDY )
      return 1;
   else
      return 0;
}

uint8_t pio_wait_busy( uint16_t port )
{
   for ( int i = 0; i < 4; i++ )
      sysutil_msleep( 10 );

   uint8_t st= pio_get_status( port );
   sys_printf("status b: %2x\n",st);
   return ( pio_get_status( port ) & STA_BSY );  // true if busy else false
}


uint8_t pio_get_status( uint16_t port )
{
   return pio_inbyte( port + STATUS_REG );
}



вот вывод, который я получаю:
Код:
Device doesn't provide specific reg for primary ...defaulting
Device doesn't provide specific reg for secondary... defaulting
 channels[0].base   1f0
 channels[0].ctrl   3f6
 channels[0].bmide  c040
 channels[1].base   170
 channels[1].ctrl   376
 channels[1].bmide  c048

Reseting controllers
status b:  0
status b:  0
status b:  0
status b:  0
status b:  0
status b:  0


Как видите , статус все время =0 и не меняется


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 21 дек 2015, 19:56 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Код:
   if ( !reset_controller( channels[0].base ) )

Протокол программного сброса начинается с установки бита SRST. А он расположен в channels[0].ctrl

После сброса диск может выставить DRDY в 1 спустя более чем 31 секунду. БИОС ждет до 60 секунд.

А вообще для эмуляторов рекомендую пропустить стадию сброса и сразу перейти к стадии IndefineDevice и там уже по наличию ошибок, ответов определять наличие дисков.

Так как сброс долгая операция, то виндоус её не делает. А эмуляторы подстраиваются под виндоус. И эмулирует только те команды, что нужны для работы виндоуса.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB