Прерывания от винчестера.

Тема в разделе "WASM.ASSEMBLER", создана пользователем Mika0x65, 18 дек 2007.

  1. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Мое почтение всем.

    Пытаюсь заткнуть прерывания от винчестера, но они почему-то все равно приходят. При чем, как всегда, под виртуальными машинами все Ок (Bochs, VMWare), на реальном железе процедура обработки прерывания выполняется. Пробовал разные варианты: и подождать DRDY и очистить "ожидающие" прерывания (хотя, по идее, это не нужно), но прерывания приходят и приходят.

    У кого-нибудь есть варианты, почему такое может быть? Тестовый код выглядит так:

    Код (Text):
    1. org 0x7C00
    2.  
    3.  xor ax, ax
    4.  mov ds, ax
    5.  mov es, ax
    6.  mov ss, ax
    7.  mov sp, 0x7C00
    8.  
    9.  cli
    10.  
    11.  mov ax, 0xB800
    12.  mov es, ax
    13.  
    14.  mov dword [0x76 * 4], .hndlr
    15.  
    16. ;Select device
    17.  mov al, 0x0
    18.  mov dx, 0x1F6
    19.  out dx, al
    20.  
    21. ;Wait DRDY
    22.  mov dx, 0x1F7
    23. .wait_DRDY:
    24.  in al, dx
    25.  test al, 0x40
    26.  mov word [es:0x2], 0x731
    27.  jz .wait_DRDY
    28.  mov word [es:0x2], 0x720
    29.  
    30. ;Read status
    31.  mov dx, 0x1F7
    32.  in al, dx
    33.  nop
    34.  nop
    35.  nop
    36.  nop
    37.  
    38. ;Read alternate status
    39.  mov dx, 0x3F6
    40.  in al, dx
    41.  nop
    42.  nop
    43.  nop
    44.  nop
    45.  
    46. ;Set nIEN
    47.  mov al, 0x2
    48.  out dx, al
    49.  
    50. ;Send IDENTIFY_DEVICE for test
    51.  mov dx, 0x1F7
    52.  mov al, 0xEC
    53.  out dx, al
    54.  
    55.  sti
    56.  
    57.  jmp $
    58.  
    59. .hndlr:
    60.  mov ax, 0xB800
    61.  mov es, ax
    62.  mov word [es:0x0], 0x730
    63.  iret
    64.  
    65. times 510 - ($ - $$) db 0xFF
    66. dw 0xAA55
    Вроде бы, никаких ошибок нет. У кого-нибудь есть идеи?

    Заранее благодарен.
     
  2. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Заткнуть прерывания от винта можно следующим образом:
    Код (Text):
    1. StandardIDEBases        dd      1F0h,3F6h,170h,376h
    2.  
    3.                         mov     esi,offset StandardIDEBases
    4.                         mov     edx,[esi+4]
    5.                         mov     al,2
    6.                         out     dx,al       ; 1 - st chanel disable
    7.                         mov     edx,[esi+12]
    8.                         out     dx,al       ; 2 - nd chanel disable
    Но, это работает только для IDE винтов для которых диапазон ввода/вывода фиксирован.
    Если у Вас винт воткнут в RAID контроллер или SATA винт - то надо искать соответствующий девайс на шине PCI узнать диапазон адресов ввода/вывода и далее работать с ним как с обычным IDE, ну или почти как с обычным.
     
  3. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Вообще то IDE тоже надо на PCI искать, потому что во-первых может быть подключён дополнительный IDE контроллер и IO адреса у него будут другие, а во-вторых интегрированный контроллер тоже может работать не в Legacy, а в Native режиме и адреса у него могут быть любые - хотя такое практически и не встречается...
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Exception13
    А в чем отличие от моего кода?

    Как я понял из экспериментов, прерывание всегда приходит всего один раз, когда выставляешь nIEN. Тестил на двух разных устройствах. Пришлось смириться с этим фактом.