Контроль ЖД

Тема в разделе "WASM.ASSEMBLER", создана пользователем lukash, 26 сен 2006.

  1. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Может у кого есть ссылка на пример кода, отлавливающего обращение к портам под DOS, или что то почитать на эту тему?
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Это код одного очень продвинутого чела, от которого я в свое время получил немало priceless info.

     
  3. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Установка брекпойнтов на I/O действительно обламывается.
    Не совсем понятно зачем обнулять DRx.
    При установленном GD в DR7 такой код все равно сгенерит
    отладочное исключение. Имхо, в RM проще перехватить
    int 1 и в своем обработчике делать с DRx что в голову придет
     
  4. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Установка брекпойнтов на I/O действительно обламывается.
    Не совсем понятно зачем обнулять DRx.
    При установленном GD в DR7 такой код все равно сгенерит
    отладочное исключение. Имхо, в RM проще перехватить
    int 1 и в своем обработчике делать с DRx что в голову придет
     
  5. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Огромное спасибо, Chingachguk !
    Но, как всегда, есть еще один вопрос:
    У меня бряк на порт срабатывает после записи в порт (сделал TSR, и при нажатии на клавишу, сначала загорается лампочка в LPT, а потом срабатывает обработчик). Значит, запись в порт происходит до попадания в обработчик. А как же мне тогда запретить запись в порт? В обработчике находится hlt, так что после загорания диода все виснет (так я определяю до или после обработчика происходит запись в порт).
     
  6. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    В RM никак. Остается только сожалеть, что бряки на r/w работают
    после выполнения инструкции, вызвавшей исключение.

    З.Ы. Честно говоря, всегда вызывало недоумение такое решение
    интеловцев. Видимо реализация бряков до исполнения инструкции
    здорово повлияла бы на perfomance. ИМХО
     
  7. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Обидно :dntknw:

    Это означает что в PM можно? В чем тогда отличие?
    А в RM совсем-совсем никак (может другим способом)?
     
  8. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Действительно, здесь (http://www.intel.com/design/pentiumii/manuals/243192.htm Chapter 15.3.1.2) написано, что

    Там же и про SMM есть. Интересно, если использовать SMM, то SMI будет генерироватся до или после обращения к порту? Так в этой ветке
    http://www.wasm.ru/forum/viewtopic.php?id=8842&p=2 _BC_ написал, что

    Если сайс использует отладочныеt регистры, значит исключение (сайс) происходит сразу после обращения к порту. Получается, что обработчик SMI получит управление перед записью в порт?
     
  9. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Здесь что, совсем никого нет?

    Уже полностью разобрался как открыть, закрыть SMRAM и записать/прочитать что-нибудь туда (очень помогли архивы _BC_). Смещение для SMRAM Control Register у меня (430VX) равное 72h. Удачно сдампил SMRAM. В дизассемблерном дампе нашел процедуры открытия и закрытия памяти, но установить бряки на порт пока не получается. Как я понял, процедуры разрешения/запрета SMI и установки точки останова (IO_TRAP.ASM) взяты из дампа памяти. Но в моем дампе таких процедур нет, или я их еще не нашел:). Кнопка Power у меня не обрабатывается (AT). Помогите поставить бряки с моим дампом, или хотя бы подскажите где почитать (в интеловской документации на мой чипсет про это не сказано).

    Помогите хоть чем-нибудь!
     
  10. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    lukash

    Использование регистров отладки для этой цели не поможет, поскольку существует гарантированный перехват любого DRx приложением режима ядра.
    ДА ктати наиболее интересный момент, когда ставишь бряк поинт на чтение памяти в которой хранится адрес обработчика INT 1.. Но и этот случай обходится.
     
  11. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Если быть точным -- до завершения команды I/O. На старых процах это реализовывалось выдачей сигнала SMI# до RDY#. Ловушка же по I/O на проце срабатывает после полного завершения I/O-цикла.

    Нет.


    Chipset Intel Triton II 430VX
    North Bridge i82437VX
    South Bridge i82371SB PIIX3
    Это слишком старый чипсет, на нем не то что иотрапы, на нем даже ACPI не поддерживается.

    лучше развивай drX -- на их основе тоже можно решать задачи не хуже при должном подходе. Можно как на 'пре-', так и на 'пост-' успешно вклиниваться в нужных местах и подменять данные, хоть и не без геморроя. ;) Благо протокол посылки ATA-команд и данных довольно гибкий.
     
  12. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    _BC_

    А от чего зависит в какой момент будет сгенерировано исключение? Подскажите где о этом почитать.
     
  13. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    lukash

    мм, ты наверное не осознаешь полностью, что значит ловить I/O в "пре-", т.е. ПЕРЕД собственно выполнением I/O. Перехват I/O на "пре" -- это не перехват int 21h, "оригинальный обработчик" тут не вызовешь.
    "PRE"-перехват можно организовать и на drX -- но в общем случае это chipset-specific (хотя теоретически можно на IDE-контроллере вырубать IO Enable на те промежутки, когда irq не ожидается... но это всего лишь непроверенная мысль, хоть и универсальное решение).

    В твоем случае с IDE, "PRE" шибко и не нужно -- если тебе надо подменять считываемые/записываемые из/в устройства данные -- то можно вклиниваться в определенные моменты и подменять данные. Например, при ATA-командах, посылающих данные в устройство, после отлова записи в command port (сразу или по отлову готовности) можно самому послать нужные данные и закончить команду с последующим игнорированием устройством посылаемых данных. Грубо, но должно работать. При чтении вообще никаких проблем.
     
  14. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Каким образом?
     
  15. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Настроив систему на "невосприимчивость" на перехватываемых портах (в данном случае IDE) средствами чипсета, т.е. I/O-команды будут выполняться, но не доходить до устройств. Обработчик PRE восстанавливает "чувствительность" перехватываемых портов и вручную эмулирует I/O.
     
  16. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Вот, например, код процедуры для подачи ATA-команды:

    Код (Text):
    1. ; Стандартные базовые адреса каналов 1 и 2
    2. StandardATABases DW 1F0h, 170h
    3. ; Номер канала
    4. ChannelNumber DW ?
    5. ; Номер диска
    6. DiskNumber DB ?
    7. ; Базовый адрес группы портов контроллера ATA
    8. ATABasePortAddr DW ?
    9. ; Параметры ATA-команды
    10. ATAFeatures DB ? ;особенности
    11. ATASectorCount DB ? ;количество обрабатываемых секторов
    12. ATASectorNumber DB ? ;номер начального сектора
    13. ATACylinder DW ? ;номер начального цилиндра
    14. ATAHead DB ? ;номер начальной головки
    15. ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA)
    16. ATACommand DB ? ;код команды, подлежащей выполнению
    17. ; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
    18. ; интервал ожидания, 2 - неверный код режима адресации,
    19. ; 3 - неверный номер канала, 4 - неверный номер диска,
    20. ; 5 - неверный номер головки, 6 - ошибка при выполнении
    21. ; команды)
    22. DevErrorCode DB ?
    23. ; Время начала очередной операции с диском
    24. OpTime DD ?
    25.  
    26.  
    27. ;****************************************************
    28. ;*     ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
    29. ;* Входные параметры передаются через глобальные *
    30. ;* переменные: *
    31. ;* ChannelNumber - номер канала (1 или 2); *
    32. ;* DiskNumber - номер диска (0 или 1); *
    33. ;* ATAFeatures - "особенности"; *
    34. ;* ATASectorCount - количество секторов; *
    35. ;* ATASectorNumber - номер начального сектора; *
    36. ;* ATACylinder - номер начального цилиндра; *
    37. ;* ATAHead - номер начальной головки; *
    38. ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
    39. ;* ATACommand - код команды. *
    40. ;* После успешного выполнения функции: *
    41. ;* в ATABasePortAddr - базовый адрес HDD; *
    42. ;* в OpTime - момент начала выполнения команды; *
    43. ;* в DevErrorCode - ноль. *
    44. ;* При возникновении ошибки в DevErrorCode будет *
    45. ;* возвращен код ошибки. *
    46. ;****************************************************
    47. PROC SendCommandToHDD near
    48.      pushad
    49. ; Запомнить время начала операции с диском
    50.      ; Загрузить в ES сегмент данных BIOS
    51.      mov AX,0
    52.      mov ES,AX
    53.      ; Запомнить текущее время
    54.      mov EAX,[ES:046Ch]
    55.      mov [OpTime],EAX
    56. ; Проверить значение кода режима
    57.      cmp [ATAAddressMode],1
    58.      ja @@Err2
    59. ; Проверить корректность номера канала
    60.      mov BX,[ChannelNumber]
    61.      cmp BX,1
    62.      jb @@Err3
    63.      cmp BX,2
    64.      ja @@Err3
    65. ; Установить базовый адрес
    66.      dec BX
    67.      shl BX,1
    68.      mov AX,[BX+StandardATABases]
    69.      mov [ATABasePortAddr],AX
    70. ; Ожидание готовности HDD к приему команды
    71.      ; Выбрать нужный диск
    72.      mov DX,[ATABasePortAddr]
    73.      add DX,6 ;адрес регистра головок
    74.      mov AL,[DiskNumber]
    75.      cmp AL,1 ;проверить номера диска
    76.      ja @@Err4
    77.      shl AL,4
    78.      or AL,10100000b
    79.      out DX,AL
    80.      ; Ожидать, пока диск не будет готов
    81.      inc DX
    82. @@WaitHDReady:
    83.      ; Проверить время ожидания
    84.      mov EAX,[ES:046Ch]
    85.      sub EAX,[OpTime]
    86.      cmp EAX,BSYWaitTime
    87.      ja @@Err1 ;ошибка тайм-аута
    88.      ; Прочитать регистр состояния
    89.      in AL,DX
    90.      ; Проверить состояние сигнала BSY
    91.      test AL,80h
    92.      jnz @@WaitHDReady
    93.      ; Проверить состояние сигнала DRQ
    94.      test AL,08h
    95.      jnz @@WaitHDReady
    96. ; Загрузить команду в регистры контроллера
    97.      mov DX,[ATABasePortAddr]
    98.      inc DX ;регистр "особенностей"
    99.      mov AL,[ATAFeatures]
    100.      out DX,AL
    101.      inc DX ;счетчик секторов
    102.      mov AL,[ATASectorCount]
    103.      out DX,AL
    104.      inc DX ;регистр номера сектора
    105.      mov AL,[ATASectorNumber]
    106.      out DX,AL
    107.      inc DX ;номер цилиндра (младший байт)
    108.      mov AX,[ATACylinder]
    109.      out DX,AL
    110.      inc DX ;номер цилиндра (старший байт)
    111.      mov AL,AH
    112.      out DX,AL
    113.      inc DX ;номер головки/номер диска
    114.      mov AL,[DiskNumber]
    115.      shl AL,4
    116.      cmp [ATAHead],0Fh ;проверить номер головки
    117.      ja @@Err5
    118.      or AL,[ATAHead]
    119.      or AL,10100000b
    120.      mov AH,[ATAAddressMode]
    121.      shl AH,6
    122.      or AL,AH
    123.      out DX,AL
    124. ; Послать команду
    125.      mov AL,[ATACommand]
    126.      inc DX ;регистр команд
    127.      out DX,AL
    128. ; Сбросить признак ошибки
    129.      mov [DevErrorCode],0
    130.      jmp short @@End
    131. ; Записать код ошибки
    132. @@Err1: mov [DevErrorCode],1
    133.      jmp short @@End
    134. @@Err2: mov [DevErrorCode],2
    135.      jmp short @@End
    136. @@Err3: mov [DevErrorCode],3
    137.      jmp short @@End
    138. @@Err4: mov [DevErrorCode],4
    139.      jmp short @@End
    140. @@Err5: mov [DevErrorCode],5
    141. ; Завершение работы программы
    142. @@End: popad
    143.      ret
    144. ENDP SendCommandToHDD
    Как я понял, нужно вклинится в код до загрузки команды в регистры контроллера, проверить что это за команда, и затем, если нужно, послать команду с помощью приведенного выше кода, например.
    В каком месте лучше всего вклиниваться в код и как это правильно сделать. Если поставить бряк на “чтение регистра состояния”, то как я узнаю какая команда должна была передаться.
     
  17. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Тебе надо подменять ATA-команды без данных? Если нет -- то перехвата записи в command port достаточно и "post-".
     
  18. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    _BC_

    По моему, я немного неправильно написал: мне не нужно подменять посылаемые данные в порт, а подменять ATA команды. Мне нужно в определенный момент запретить запись в определенный сектор, или эмулировать запись. Так, например, при посылке команды 30h (Write Sector), мне нужно вклинится в код при проверке готовности устройства и запретить (эмулировать) запись. Я не очень понял где нужно вклинится и каким способом.

    Можно немного подробнее о "отлове записи в command port " (как перехватить запись).
     
  19. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Вот написал код, который, теоретически, должен вклиниваться после посылки команды.

    Код (Text):
    1. .386p
    2. cs16 segment use16 byte
    3. assume cs:cs16
    4. assume ds:cs16
    5.  
    6. org 100h
    7.  
    8. begin:
    9.  
    10. jmp main
    11.  
    12. main:
    13.  
    14. push 0    
    15. pop  es
    16. sub  word ptr es:[0413h],2
    17. mov  ax,es:[0413h]                    
    18. mov  cl,6                                                        
    19. shl  ax,cl          
    20. mov  es,ax ; копирование процедуры в память начиная с es:0000
    21. xor  si,si
    22. mov  cx,prg_lenght      
    23.  
    24. prg_copy:
    25.                 mov  bl,byte ptr cs:@@ResidentalCode[si]              
    26.                 mov  byte ptr es:[si],bl
    27.                 inc  si                
    28. loop cs:prg_copy      
    29.  
    30. cli
    31. push es
    32. pop ds    
    33. mov ax,0h
    34. mov es,ax
    35. mov dx,0000h+(offset int_01 - offset @@ResidentalCode)
    36. mov es:[1h*4],dx
    37. mov es:[1h*4+2],ds
    38. sti
    39.  
    40. cli
    41. mov eax,cr4
    42. or  eax,8           ;i/o breakpoints
    43. mov cr4,eax
    44. mov eax,1f6h    ;ide 0 master
    45. mov dr0,eax
    46. mov eax,020703h  ;enable port trace
    47. mov dr7,eax
    48. sti
    49.  
    50. int 20h
    51.  
    52. @@ResidentalCode:
    53.  
    54. int_01 proc far ; процедура обработки int 01h
    55.  
    56. pushf                      
    57. pusha
    58. push es
    59. push ds
    60.  
    61. push 0B800h
    62. pop  es
    63. mov ah,31
    64. mov al,1
    65. mov di,0
    66. mov es:[di],ax
    67.  
    68. cmp al,20h
    69. jnz  @@Err                      ;команда чтения сектора
    70.  
    71. mov dx,1f7h          ;установка ERR в 1
    72. mov al,1
    73. out dx,al
    74.  
    75. mov dx,3f6h        ;Разрешить прерывания от устройства
    76. mov al,0
    77. out dx,al
    78.  
    79. @@Err:
    80.  
    81. pop ds
    82. pop es
    83. popa
    84. popf
    85.  
    86. iret        
    87.  
    88. int_01 ENDP
    89.  
    90. RES_END:
    91. prg_lenght EQU RES_END - @@ResidentalCode
    92.  
    93. cs16 ends
    После посылки команды в 01F6h порт (в данном случае 20h), с 01F0h порта (ide 0 master ) можно считать данные (послу проверок на готовность). Если здесь установить ERR в 1 (01F7h), то в теории считывание данных происходить не должно. Но у меня сектора читаются, правда с большой задержкой. Подскажите где ошибка.
     
  20. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    lukash

    Качественно рубишься!

    Совершенно серьезно. Респект.