Пара вопросов по HDD

Тема в разделе "WASM.OS.DEVEL", создана пользователем drem1lin, 28 мар 2011.

  1. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Здравствуйте, ситуация такая - есть PATA-хард > 128 гиг, надо найти его порт и записать/считать несколько секторов. Соответственно 2 вопроса:
    1. Я использую код основанный на книге Кулакова - Программирование дисковых подсистем, и для обнаружения харда использую посылку ему команды IDETIFY DEVICE. А для работы с ним использую режим LBA 48. Поэтому приходиться иметь в коде 2 процедуры посылки команды, для LBA48 и для посылки IDENTIFY DEVICE. Можно ли их как то обьеденить? или заменить посылку IDENTIFY DEVICE на посылку READ SECTOR EXT?

    2. Не получается записать сектор на диск, машина зависает сразу, где внутри процедуры записи сектора. Процедура чтения сектора работает отлично, а в чем разница не пойму. Макрос debug выбрасывает на POST-плату переданное ей число, машина 2 раза зависала с кодом 15h. Может я что то упускаю из работы с хардом?
    Код (Text):
    1. ;***********************************************************
    2. ;Процедура посылки команды контроллеру жесткого диска.
    3. ;Вход:  DISK_NUMBER
    4. ;       ATA_SECTOR_COUNT
    5. ;       LBA_0_48
    6. ;       ATA_ADDRESS_MODE
    7. ;       ATA_COMMAND
    8. ;Выход: DEVICE_ERROR_CODE
    9. ;***********************************************************
    10. SendCommandToHDDLBA48 proc
    11.     pushad
    12.     debug 88h
    13.     mov eax, ds:[046ch]
    14.     mov ds:[OPERATION_TIMER], eax
    15. ; Проверить корректность номера канала
    16.     mov     BX,ds:[CHANNEL_NUMBER]
    17. ; Установить базовый адрес
    18.     cmp     BX, 1
    19.     db 66h
    20.     jne @@SecondChannel
    21.     mov     word ptr ds:[ATA_BASE_PORT_ADDR],01f0h
    22.     jmp @@PortSelected
    23. @@SecondChannel:
    24.     mov     word ptr ds:[ATA_BASE_PORT_ADDR],0170h
    25. @@PortSelected:
    26. ; Ожидание готовности HDD к приему команды
    27.     ; Выбрать нужный диск
    28.     mov     DX,ds:[ATA_BASE_PORT_ADDR]
    29.     add     DX,6    ;адрес регистра головок
    30.     mov     AL,ds:[DISK_NUMBER]
    31.     shl     AL,4
    32.     or      AL,10100000b
    33.     out     DX,AL
    34.     ; Ожидать, пока диск не будет готов
    35.     inc     DX
    36.     debug 15h
    37. @@WaitHDReady:
    38.     ; Проверить время ожидания
    39.     mov     EAX,ds:[046Ch]
    40.     sub     EAX,ds:[OPERATION_TIMER]
    41.     cmp     EAX,BSY_WAIT_TIME
    42.     ja large near ptr @@Err1 ;ошибка тайм-аута
    43.     ; Прочитать регистр состояния
    44.     in      AL,DX
    45.     ; Проверить состояние сигнала BSY
    46.     test    AL,80h
    47.     jnz     @@WaitHDReady
    48.     ; Проверить состояние сигнала DRQ
    49.     test    AL,08h
    50.     jnz     @@WaitHDReady
    51.    
    52.     debug 16h
    53.    
    54. ; Загрузить команду в регистры контроллера
    55.     mov     DX,ds:[ATA_BASE_PORT_ADDR]
    56.    
    57.     add     DX,2      ;счетчик секторов   +2
    58.     xor     al, al
    59.     out     DX,AL           ;SECTOR_COUNT 15...8 == 0
    60.     mov     AL,ds:[ATA_SECTOR_COUNT]
    61.     out     DX,AL           ;SECTOR_COUNT 7...0
    62.    
    63.     inc     DX      ;LBA low  +3
    64.     mov     AL,ds:[LBA_24_31]
    65.     out     DX,AL
    66.     mov     AL,ds:[LBA_0_7]
    67.     out     DX,AL
    68.    
    69.     inc     DX      ;LBA mid  +4
    70.     mov     Al,ds:[LBA_32_39]
    71.     out     DX,AL
    72.     mov     AL,ds:[LBA_8_15]
    73.     out     DX,AL
    74.    
    75.     inc     DX      ;LBA high +5
    76.     mov     Al,ds:[LBA_40_47]
    77.     out     DX,AL    
    78.     mov     AL,ds:[LBA_16_23]
    79.     out     DX,AL
    80.  
    81.     inc     DX      ;номер головки/номер диска    +6
    82.     mov     AL,ds:[DISK_NUMBER]
    83.     shl     AL,4
    84.     or      AL,10100000b
    85.     mov     AH,ds:[ATA_ADDRESS_MODE]
    86.     shl     AH,6
    87.     or      AL,AH
    88.     out     DX,AL
    89.    
    90.     debug 17h
    91. ; Послать команду
    92.     mov     AL,byte ptr ds:[ATA_COMMAND]
    93.     inc     DX      ;регистр команд
    94.     out     DX,AL
    95.     mov dword ptr ds:[DEVICE_ERROR_CODE], 0
    96.     jmp @@exit
    97. @@Err1:
    98.     mov dword ptr ds:[DEVICE_ERROR_CODE], 1
    99.  
    100. @@exit:
    101.     debug 89h
    102.     popad
    103.     Ret
    104. SendCommandToHDDLBA48 endp
    105.  
    106. ;***********************************************************
    107. ;Процедура чтения сектора hdd в режиме LBA48
    108. ;Вход:  eax - биты 0-31 адреса
    109. ;       dx  - биты 32-47
    110. ;       edi - адрес буфера приемника
    111. ;       DISK_NUMBER - диск primary/slave
    112. ;       CHANNEL_NUMBER - канал IDE
    113. ;Выход: DEVICE_ERROR_CODE - код ошибки
    114. ;***********************************************************
    115. ReadHDDSectorLBA48 proc
    116.         pushad
    117.         debug 86h
    118. ; Задать режим LBA
    119.         mov     byte ptr ds:[ATA_ADDRESS_MODE],1
    120. ; Послать команду чтения сектора (с повторами)
    121.         mov     byte ptr ds:[ATA_SECTOR_COUNT],1
    122.         mov     ds:[LBA_0_7],EAX
    123.         mov     ds:[LBA_32_39], dx
    124.         mov     byte ptr ds:[ATA_COMMAND],24h
    125.         call    large near ptr SendCommandToHDDLBA48
    126.         cmp     dword ptr ds:[DEVICE_ERROR_CODE],0
    127.         jne     @@End    ;закончить, сохранив код ошибки
    128. ; Ожидать готовность данных HDD
    129.         mov     DX,ds:[ATA_BASE_PORT_ADDR]
    130.         add     DX,7     ;адрес регистра состояния
    131. @@WaitCompleet:
    132.         ; Проверить время выполнения команды
    133.         mov     EAX,ds:[046Ch]
    134.         sub     EAX,ds:[OPERATION_TIMER]
    135.         cmp     EAX, MAX_HDD_WAIT_TIME
    136.         ja      @@Error1 ;ошибка тайм-аута
    137.         ; Проверить готовность
    138.         in      AL,DX
    139.     test    AL, 1
    140.     jnz     @@Error2
    141.         test    AL,80h   ;состояние сигнала BSY
    142.          jnz     @@WaitCompleet
    143.         test    AL,08h   ;состояние сигнала DRQ
    144.     jz      @@WaitCompleet
    145. ; Принять сектор
    146.        
    147.         mov     ECX, 256
    148.         mov     EDX,ds:[ATA_BASE_PORT_ADDR] ;регистр данных
    149.                
    150.         db 67h
    151.         rep     insw     ;принять блок данных
    152. ; Сбросить признак ошибки
    153.         mov     dword ptr ds:[DEVICE_ERROR_CODE],0
    154.     jmp @@End
    155. ; Записать номер ошибки
    156. @@Error1:
    157.         mov     dword ptr ds:[DEVICE_ERROR_CODE],1 ;ошибка тайм-аута
    158.     jmp  @@End
    159. @@Error2:
    160.     mov     dword ptr ds:[DEVICE_ERROR_CODE],2 ;ошибка
    161. @@End:  
    162.     debug 87h
    163.         popad
    164.        Ret
    165. ReadHDDSectorLBA48  endp
    166.  
    167. ;***********************************************************
    168. ;Процедура записи в сектор hdd в режиме LBA48
    169. ;Вход:  eax - биты 0-31 адреса
    170. ;       dx  - биты 32-47
    171. ;       edi - адрес буфера приемника
    172. ;       DISK_NUMBER - диск primary/slave
    173. ;       CHANNEL_NUMBER - канал IDE
    174. ;Выход: DEVICE_ERROR_CODE - код ошибки
    175. ;***********************************************************
    176. WriteHDDSectorLBA48 proc
    177.         pushad
    178.         debug 93h
    179. ; Задать режим LBA
    180.         mov     byte ptr ds:[ATA_ADDRESS_MODE],1
    181. ; Послать команду чтения сектора (с повторами)
    182.         mov     byte ptr ds:[ATA_SECTOR_COUNT],1
    183.         mov     ds:[LBA_0_7],EAX
    184.         mov     ds:[LBA_32_39], dx
    185.         mov     byte ptr ds:[ATA_COMMAND],34h
    186.         call    large near ptr SendCommandToHDDLBA48
    187.         cmp     dword ptr ds:[DEVICE_ERROR_CODE],0
    188.     jne     @@End    ;закончить, сохранив код ошибки
    189. ; Ожидать готовность данных HDD
    190.         mov     DX,ds:[ATA_BASE_PORT_ADDR]
    191.         add     DX,7     ;адрес регистра состояния
    192. @@WaitCompleet:
    193.         ; Проверить время выполнения команды
    194.         mov     EAX,ds:[046Ch]
    195.         sub     EAX,ds:[OPERATION_TIMER]
    196.         cmp     EAX, MAX_HDD_WAIT_TIME
    197.     ja      @@Error1 ;ошибка тайм-аута
    198.         ; Проверить готовность
    199.         in      AL,DX
    200.     test    AL, 1
    201.     jnz     @@Error2
    202.         test    AL,80h   ;состояние сигнала BSY
    203.     jnz     @@WaitCompleet
    204.         test    AL,08h   ;состояние сигнала DRQ
    205.         jz      @@WaitCompleet
    206. ; Принять сектор
    207.        
    208.         mov     ECX, 256
    209.     mov     EDX,ds:[ATA_BASE_PORT_ADDR] ;регистр данных
    210.     db 67h
    211.     rep     outsw     ;принять блок данных
    212. ; Сбросить признак ошибки
    213.         mov     dword ptr ds:[DEVICE_ERROR_CODE],0
    214.  
    215.         jmp @@End
    216. ; Записать номер ошибки
    217. @@Error1:
    218.         mov     dword ptr ds:[DEVICE_ERROR_CODE],1 ;ошибка тайм-аута
    219.     jmp  @@End
    220. @@Error2:
    221.         mov     dword ptr ds:[DEVICE_ERROR_CODE],2 ;ошибка
    222. @@End:  
    223.         debug 94h
    224.         popad
    225.         Ret
    226. WriteHDDSectorLBA48 endp
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    drem1lin
    1. IDETIFY DEVICE LBA48 не существует.
    2. Смотри доккументацию. А вообще в английской wiki.osdev.org все хорошо описано.
     
  3. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    так я знаю что его не существует, а заменить его на команду LBA48 любую нельзя?
     
  4. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    1) Ты это чисто для гимнастики ума делаешь, или как?

    Код там конечно интересный, но вот для обнаружения и вычисления портов в настоящее время не подходит.
    Если мы оба говорим о ISBN 5-318-00623-X.
    В частности 2.2 полностью не верен. А код в листинге 4.1 мягко скажем уже не не работоспособен.

    Ну как бы одного этого мало.

    Не на там ты экономию ищешь.

    Нет.

    Замечание к коду. Не только описывай, что предается в подпрограмму, а еще и как.

    Да опускаете. И судя по всему, не только "из работы с хардом".

    В предыдущей команде, вы не все данные вычитали, и DRQ у вас установлен.
    Все, получаете зацикливание, которое прервется только по "тайм-ауту".
    И судя по всему, вот этот код не корректен:
    И выхода по тайм ауту не происходит.

    И прочитайте, как правильно посылать адреса в LBA48, и как вообще правильно посылать команды устройству. У вас неправильная логика, как мне кажется, и все что ниже "debug 16h" содержит массу ошибок.