Как работать с большими (>30gb) дисками через int 13 в досе
Как производится адресация у больших дисков (>30gb) при работе через int 13 в досе. С маленькими дисками вроде понятно, а большими застрял. Буду очень благодарен за совет или адрес к нормальной документации.
Если диск больше 8 Гб, то только через LBA, где используется не "цилиндр/головка/сектор", а абсолютный номер сектора (28-битный начиная с нуля). Этот формат подерживается через INT 13 Extended (функции с номерами от 40h и выше). Более подробно смотрите мой ответ в этом же разделе (от 31.01.2002).
gerard! Ты монстр, это до меня дошло, когда я просмотрел твои mess'ы. А можешь заодно рассказать, как работать через порты???
Вначале напомню, что первый канал IDE-контроллера использует порты с адресами 1F0-1F7, 3F6, 3F7, а
второй - соответственно 170-177, 376, 377. Я буду указывать адреса портов для регистров первого канала (для второго они будут на 80 меньше).
Итак, контроллер IDE использует следующие регистры:
1F0 - регистр данных. Через него идет обмен данными в режиме PIO (то есть при пересылке данных байт за байтом). В режиме прямого доступа (через DMA) он используется самим контроллером и к нему обращаться не следует. Этот регистр 16-битовый, то есть занимает и следующий за ним адрес 1F1, так что нужно использовать целые слова, даже если пересылаются байты (в этом случае старший байт слова равен 0).
1F1 - регистр ошибки. Его биты равны 1 в случае возникновения следующих ситуаций:
бит 0 - ошибка носителя (флэш-памяти);
бит 1 - отсутствует сменный носитель;
бит 2 - аварийное прекращение команды;
бит 3 - запрос на смену носителя;
бит 4 - сектор не найден;
бит 5 - преждевременная смена носителя;
бит 6 - неисправимая ошибка данных;
бит 7 - ошибка по контрольному коду;
Команда диагностики записывает в этот регистр свои коды ошибки:
00 - неисправно устройство 0 (master);
01 - оба устройства исправны;
80 - неисправно устройство 1 (slave);
81 - неисправны оба устройства;
Этот регистр используется также на запись некоторыми командами - для дополнительных параметров.
1F2 - счетчик секторов. Сюда заносится количество передаваемых секторов (от 1 до 255, 0 означает 256). При переходе к очередному сектору он уменьшается на 1, так что после аварийного завершения здесь можно прочитать количество необработанных секторов.
Следующие четыре регистра используются для указания адреса первого сектора при обмене данными. При переходе к очередному сектору сюда заносится его номер, так что при аварийном завершении можно узнать номер первого необработанного сектора. Формат адреса зависит от того, какой используется режим - CHS или LBA. Режим задается битом 6 регистра 1F6 (0 - CHS, 1 - LBA). Биты 5 и 7 этого регистра должны быть всегда равны 1, бит 4 - номер устройства (0 - master, 1 - slave). Остальные 28 бит содержат адрес сектора. В режиме LBA это линейный адрес (от 0 до 2^28-1), в режиме CHS регистр 1F3 содержит номер сектора, регистры 1F4, 1F5 - номер цилиндра, биты 0-3 регистра 1F6 - номер головки.
1F7 - регистр состояния. Его биты равны 1 в следующих случаях:
бит 0 - ошибка при выполнении команды;
биты 1 и 2 - не используются;
бит 3 - готовность к обмену данными;
бит 4 - готовность к выполнению следующей команды очереди;
бит 5 - устройство неисправно;
бит 6 - готовность к приему команды;
бит 7 - устройство занято.
3F6 - альтернативный регистр состояния. При его чтении запрос на прерываение не снимается (в отличие от регистра 1F7).
3F7 - не используется
Код очередной команды загружается в регистр команд, имеющий адрес 1F7 - ПОСЛЕ ЗАНЕСЕНИЯ ВСЕХ ДАННЫХ, так как запись кода автоматически вызывает выполнение соответствующей команды.
Кодов команд очень много (из 256 вожможных значений используется чуть меньше половины), поэтому я приведу только основные. Очень не советую экспериментировать с остальными - среди них есть недокументированные коды команд
низкоуровневого форматирования диска и даже полного стирания информации (включая служебную, которую сможет восстановить только фирма-изготовитель). Эти коды, как правило, свои для каждой модели.
Итак, основными (то есть обязательными для всех дисководов) являются следующие команды:
1) Команды настройки и диагностики:
E5 - проверить режим энергопотребления. Код режима возвращается в регистре 1F2 (00 - дежурный режим, 80 - режим ожидания, FF - активное состояние);
90 - диагностика ОБОИХ устройств;
DA - проверка готовности носителя;
EC - идентификация устройства. По этой команде через регистр данных передается 256 слов, содержащих полную информацию об устройстве. Упомяну только самые важные:
слова 1,3,6 - число логических дорожек, головок и секторов на дорожке;
слова с 10 по 19 - серийный номер в ASCII-коде;
слова с 27 по 46 - номер модели в ASCII-коде;
слово 47 - максимальное количество секторов при обмене данными;
слова 54,55,56 - текущее число логических дорожек, головок и секторов на дорожке;
слова 56,57 - текущее число секторов;
слова 60,61 - общее число секторов;
E0/E1/E6 - немедленно перейти в дежурный
режим/режим ожидания/спящий режим;
DE/DF/ED - запереть/отпереть/извлечь носитель (используется для CD-ROM и других сменных носителей, например, ZIP);
2) Команды задания параметров устройства:
E2/E3 - установка временного интервала, по
истечении которого устройство переходит в дежурный режим (standby)/в режим ожидания (idle). Код интервала заносится в регистр 1F2 и может быть следующим:
0 - не переходить;
от 1 до 240 - интервал от 5 секунд до 20 минут с шагом 5 секунд;
от 241 до 251 - интервал от 30 минут до 5.5 часов с шагом 30 минут;
252 - интервал 21 минута;
253 - интервал 8 часов;
254 - не используется;
255 - интервал 21 минута 15 секунд;
91 - установка числа логических секторов на дорожке (регистр 1F2) и максимального логического номера головки (регистр 1F6);
F8/F9 - чтение/установка максимального номера сектора (для режима LBA) или максимальных номеров сектора, цилиндра и головки (для режима CHS);
C6 - установка размера блока данных, передаваемого по одному запросу. Размер (в секторах) заносится в регистр 1F2 и должен быть степенью числа 2;
3) Команды обмена данными:
70 - найти сектор с указанным номером;
E4/E8 - чтение/запись буфера сектора через регистр данных;
C8/CA - чтение/запись секторов в режиме DMA;
C7/CC - чтение/запись секторов в режиме DMA с очередями. В отличие от предыдущей команды, эта допускает освобождение шины, если устройство не готово. Количество передаваемых секторов заносится в регистр 1F1 (а не 1F2), в регистр же 1F2 (старшие 5 бит) заносится тэг команды, позволяющий отличить ее от других аналогичных команд. Всего, таким образом, задается очередь до 32 команд, которые будут выполняться по мере готовности устройства.
Текущее состояние очереди отражается в регистре 1F2:
бит 0 - тип передаваемой информации (0 - данные, 1 - очередная команда);
бит 1 - направление передачи (0 - запись, 1 - чтение);
бит 2 - признак освобождения шины после получения команды;
биты с 3 по 7 - тэг команды, вызвавшей прерывание;
C4/C5 - чтение/запись группы секторов в режиме PIO (через регистр данных). Данные пересылаются блоками, размер которых устанавливается командой C6. Прерывание вырабатывается не после каждого сектора, а после каждого блока;
20/30 - чтение/запись секторов в режиме PIO (прерывание вырабатывается после каждого сектора);
40 - контрольное чтение и проверка секторов (без передачи данных).
Еще раз напомню, что сначала нужно занести в соответствующие регистры все параметры команды, и только потом послать в регистр команд ее код.
Кстати, тут недавно в ответе на вопрос про режим DMA для флоппи порекомендовали книгу Кулакова "Программирование дисковых подсистем". Я к этой рекомендации присоединяюсь - многое я узнал именно оттуда. Вышла она в начале года в "Питер-Пресс". По интерфейсу ATA/ATAPI там отдельная глава (и самая большая из всех), из которой можно узнать гораздо больше.
неподскажешь с чего начать?
а ещё всё это в протектэд мод(((...как там с прерываниями работать?