Здравствуйте, ситуация такая - есть PATA-хард > 128 гиг, надо найти его порт и записать/считать несколько секторов. Соответственно 2 вопроса: 1. Я использую код основанный на книге Кулакова - Программирование дисковых подсистем, и для обнаружения харда использую посылку ему команды IDETIFY DEVICE. А для работы с ним использую режим LBA 48. Поэтому приходиться иметь в коде 2 процедуры посылки команды, для LBA48 и для посылки IDENTIFY DEVICE. Можно ли их как то обьеденить? или заменить посылку IDENTIFY DEVICE на посылку READ SECTOR EXT? 2. Не получается записать сектор на диск, машина зависает сразу, где внутри процедуры записи сектора. Процедура чтения сектора работает отлично, а в чем разница не пойму. Макрос debug выбрасывает на POST-плату переданное ей число, машина 2 раза зависала с кодом 15h. Может я что то упускаю из работы с хардом? Код (Text): ;*********************************************************** ;Процедура посылки команды контроллеру жесткого диска. ;Вход: DISK_NUMBER ; ATA_SECTOR_COUNT ; LBA_0_48 ; ATA_ADDRESS_MODE ; ATA_COMMAND ;Выход: DEVICE_ERROR_CODE ;*********************************************************** SendCommandToHDDLBA48 proc pushad debug 88h mov eax, ds:[046ch] mov ds:[OPERATION_TIMER], eax ; Проверить корректность номера канала mov BX,ds:[CHANNEL_NUMBER] ; Установить базовый адрес cmp BX, 1 db 66h jne @@SecondChannel mov word ptr ds:[ATA_BASE_PORT_ADDR],01f0h jmp @@PortSelected @@SecondChannel: mov word ptr ds:[ATA_BASE_PORT_ADDR],0170h @@PortSelected: ; Ожидание готовности HDD к приему команды ; Выбрать нужный диск mov DX,ds:[ATA_BASE_PORT_ADDR] add DX,6 ;адрес регистра головок mov AL,ds:[DISK_NUMBER] shl AL,4 or AL,10100000b out DX,AL ; Ожидать, пока диск не будет готов inc DX debug 15h @@WaitHDReady: ; Проверить время ожидания mov EAX,ds:[046Ch] sub EAX,ds:[OPERATION_TIMER] cmp EAX,BSY_WAIT_TIME ja large near ptr @@Err1 ;ошибка тайм-аута ; Прочитать регистр состояния in AL,DX ; Проверить состояние сигнала BSY test AL,80h jnz @@WaitHDReady ; Проверить состояние сигнала DRQ test AL,08h jnz @@WaitHDReady debug 16h ; Загрузить команду в регистры контроллера mov DX,ds:[ATA_BASE_PORT_ADDR] add DX,2 ;счетчик секторов +2 xor al, al out DX,AL ;SECTOR_COUNT 15...8 == 0 mov AL,ds:[ATA_SECTOR_COUNT] out DX,AL ;SECTOR_COUNT 7...0 inc DX ;LBA low +3 mov AL,ds:[LBA_24_31] out DX,AL mov AL,ds:[LBA_0_7] out DX,AL inc DX ;LBA mid +4 mov Al,ds:[LBA_32_39] out DX,AL mov AL,ds:[LBA_8_15] out DX,AL inc DX ;LBA high +5 mov Al,ds:[LBA_40_47] out DX,AL mov AL,ds:[LBA_16_23] out DX,AL inc DX ;номер головки/номер диска +6 mov AL,ds:[DISK_NUMBER] shl AL,4 or AL,10100000b mov AH,ds:[ATA_ADDRESS_MODE] shl AH,6 or AL,AH out DX,AL debug 17h ; Послать команду mov AL,byte ptr ds:[ATA_COMMAND] inc DX ;регистр команд out DX,AL mov dword ptr ds:[DEVICE_ERROR_CODE], 0 jmp @@exit @@Err1: mov dword ptr ds:[DEVICE_ERROR_CODE], 1 @@exit: debug 89h popad Ret SendCommandToHDDLBA48 endp ;*********************************************************** ;Процедура чтения сектора hdd в режиме LBA48 ;Вход: eax - биты 0-31 адреса ; dx - биты 32-47 ; edi - адрес буфера приемника ; DISK_NUMBER - диск primary/slave ; CHANNEL_NUMBER - канал IDE ;Выход: DEVICE_ERROR_CODE - код ошибки ;*********************************************************** ReadHDDSectorLBA48 proc pushad debug 86h ; Задать режим LBA mov byte ptr ds:[ATA_ADDRESS_MODE],1 ; Послать команду чтения сектора (с повторами) mov byte ptr ds:[ATA_SECTOR_COUNT],1 mov ds:[LBA_0_7],EAX mov ds:[LBA_32_39], dx mov byte ptr ds:[ATA_COMMAND],24h call large near ptr SendCommandToHDDLBA48 cmp dword ptr ds:[DEVICE_ERROR_CODE],0 jne @@End ;закончить, сохранив код ошибки ; Ожидать готовность данных HDD mov DX,ds:[ATA_BASE_PORT_ADDR] add DX,7 ;адрес регистра состояния @@WaitCompleet: ; Проверить время выполнения команды mov EAX,ds:[046Ch] sub EAX,ds:[OPERATION_TIMER] cmp EAX, MAX_HDD_WAIT_TIME ja @@Error1 ;ошибка тайм-аута ; Проверить готовность in AL,DX test AL, 1 jnz @@Error2 test AL,80h ;состояние сигнала BSY jnz @@WaitCompleet test AL,08h ;состояние сигнала DRQ jz @@WaitCompleet ; Принять сектор mov ECX, 256 mov EDX,ds:[ATA_BASE_PORT_ADDR] ;регистр данных db 67h rep insw ;принять блок данных ; Сбросить признак ошибки mov dword ptr ds:[DEVICE_ERROR_CODE],0 jmp @@End ; Записать номер ошибки @@Error1: mov dword ptr ds:[DEVICE_ERROR_CODE],1 ;ошибка тайм-аута jmp @@End @@Error2: mov dword ptr ds:[DEVICE_ERROR_CODE],2 ;ошибка @@End: debug 87h popad Ret ReadHDDSectorLBA48 endp ;*********************************************************** ;Процедура записи в сектор hdd в режиме LBA48 ;Вход: eax - биты 0-31 адреса ; dx - биты 32-47 ; edi - адрес буфера приемника ; DISK_NUMBER - диск primary/slave ; CHANNEL_NUMBER - канал IDE ;Выход: DEVICE_ERROR_CODE - код ошибки ;*********************************************************** WriteHDDSectorLBA48 proc pushad debug 93h ; Задать режим LBA mov byte ptr ds:[ATA_ADDRESS_MODE],1 ; Послать команду чтения сектора (с повторами) mov byte ptr ds:[ATA_SECTOR_COUNT],1 mov ds:[LBA_0_7],EAX mov ds:[LBA_32_39], dx mov byte ptr ds:[ATA_COMMAND],34h call large near ptr SendCommandToHDDLBA48 cmp dword ptr ds:[DEVICE_ERROR_CODE],0 jne @@End ;закончить, сохранив код ошибки ; Ожидать готовность данных HDD mov DX,ds:[ATA_BASE_PORT_ADDR] add DX,7 ;адрес регистра состояния @@WaitCompleet: ; Проверить время выполнения команды mov EAX,ds:[046Ch] sub EAX,ds:[OPERATION_TIMER] cmp EAX, MAX_HDD_WAIT_TIME ja @@Error1 ;ошибка тайм-аута ; Проверить готовность in AL,DX test AL, 1 jnz @@Error2 test AL,80h ;состояние сигнала BSY jnz @@WaitCompleet test AL,08h ;состояние сигнала DRQ jz @@WaitCompleet ; Принять сектор mov ECX, 256 mov EDX,ds:[ATA_BASE_PORT_ADDR] ;регистр данных db 67h rep outsw ;принять блок данных ; Сбросить признак ошибки mov dword ptr ds:[DEVICE_ERROR_CODE],0 jmp @@End ; Записать номер ошибки @@Error1: mov dword ptr ds:[DEVICE_ERROR_CODE],1 ;ошибка тайм-аута jmp @@End @@Error2: mov dword ptr ds:[DEVICE_ERROR_CODE],2 ;ошибка @@End: debug 94h popad Ret WriteHDDSectorLBA48 endp
drem1lin 1. IDETIFY DEVICE LBA48 не существует. 2. Смотри доккументацию. А вообще в английской wiki.osdev.org все хорошо описано.
1) Ты это чисто для гимнастики ума делаешь, или как? Код там конечно интересный, но вот для обнаружения и вычисления портов в настоящее время не подходит. Если мы оба говорим о ISBN 5-318-00623-X. В частности 2.2 полностью не верен. А код в листинге 4.1 мягко скажем уже не не работоспособен. Ну как бы одного этого мало. Не на там ты экономию ищешь. Нет. Замечание к коду. Не только описывай, что предается в подпрограмму, а еще и как. Да опускаете. И судя по всему, не только "из работы с хардом". В предыдущей команде, вы не все данные вычитали, и DRQ у вас установлен. Все, получаете зацикливание, которое прервется только по "тайм-ауту". И судя по всему, вот этот код не корректен: И выхода по тайм ауту не происходит. И прочитайте, как правильно посылать адреса в LBA48, и как вообще правильно посылать команды устройству. У вас неправильная логика, как мне кажется, и все что ниже "debug 16h" содержит массу ошибок.