OSDev

для всех
Текущее время: 04 май 2024, 02:32

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: 09 янв 2009, 13:04 

Зарегистрирован: 09 янв 2009, 12:19
Сообщения: 4
Приветствую всех участников этого форума, этот вопрос будет моим первым.
Собственно, изучение принципов разработки ОС встало на этом вопросе.
Люблю когда все однозначно и идеально, но, как ни крути, однозначности у меня не получается.
Написал вот такой код:

Код:
STATUS_PORT equ 0x64
KBD_CMD_BUF equ 0x64
KBD_DATA_BUF equ 0x60
KBD_OUT_BUF equ 0x60

OUT_BUF_FULL equ 0x01
INPT_BUF_FULL equ 0x02

CMD_RD_OUT equ 0xD0
CMD_WR_OUT equ 0xD1

A20_GATE equ 0x02

enable_a20:

; Отключить прерывания. Прошу объяснить зачем.
; Без отключения прерываний выполнение программы
; зацикливается в wait_output_buffer.
cli

; Подождать, пока контроллер обработает уже поступившие команды
; Следует ли ожидать, что выходной буфер будет также пуст, как
; это требуется перед посылкой запроса на выдачу содержимого
; выходного порта?
call empty_input_buffer
;call empty_output_buffer

; Нужно ли отключать клавиатуру (0xAD)
; как это делается в примере http://wiki.osdev.org/A20_Line ?
;call disable_keyboard

; Послать запрос на выдачу содержимого выходного порта
mov al, CMD_RD_OUT
out KBD_CMD_BUF, al

; Подождать пока контроллер обработает команду и
; выдаст содержимое выходного порта
call wait_output_buffer
in al, KBD_OUT_BUF

push ax

; Следующий байт, отправленный на порт 60h, будет
; выставлен на выходной порт
mov al, CMD_WR_OUT
out KBD_CMD_BUF, al

; Перед посылкой данных на порт 60h требуется очистить входной буфер.
; Следует ли ожидать, что он уже будет пуст, т.к. его очистили заранее,
; а команды, отправленные после этого все были обработаны?
;call empty_input_buffer

pop ax
or al, A20_GATE

; Включить линию A20
out KBD_DATA_BUF, al

; Если клавиатура была отключена, здесь следует ее включение.
;call enable_keyboard

; Для чего можно и нужно ли сбрасывать (0xFF на 0x64) контроллер
; как это делается в bootmgr от Microsoft?
;call reset_keyboard

sti

ret

empty_input_buffer:
in al, STATUS_PORT
test al, INPT_BUF_FULL
jnz empty_input_buffer
ret

empty_output_buffer:
in al, STATUS_PORT
test al, OUT_BUF_FULL
jz @F
in al, KBD_OUT_BUF
jmp empty_output_buffer
@@: ret

wait_output_buffer:
in al, STATUS_PORT
test al, OUT_BUF_FULL
jz wait_output_buffer
ret


Все вопросы в коде по пунктам


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 13:40 
A20 трогать вообше не надо))) Это пережиток 286 архитектуры


Вернуться к началу
  
 
СообщениеДобавлено: 09 янв 2009, 14:08 

Зарегистрирован: 09 янв 2009, 12:19
Сообщения: 4
Либо вы ошибаетесь, либо мой Core2 Duo на самом деле 286-ой, т.к. под VMWare 6.5 32-битная адресация работает только после включения A20. Проверку делал так:
check_a20:
push ds es
xor ax, ax
mov ds, ax
dec ax
mov es, ax
mov ax, [ds:0x0000]
not word [es:0x0010]
xor ax, [ds:0x0000]
not word [es:0x0010]
pop es ds
ret


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 15:15 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Что это пережиток, это точно. Связан он с ошибкой в процессоре 80286, который в реальном режиме не отсекал адрес, в реузльтате чего на линии A20 могла появиться единица, что позволяло адресовать память свыше 1 Мбайта прямо из реального режима. Чтобы обеспечить полную совместимость в этом вопросе с более ранними процессорами, воспользовались внешней схемой, которую назвали Gate A20 ("шлюз" или "вентиль" линии A20), который мог принудительно обнулять эту линию. Естественно, при переключении в защищённый режим необходимо было разрешать нормальную передачу адреса по этой линии, а вот в реальном в зависимости от потребностей она могла быть как запрещена (для полной совместимости с 8086), так и разрешена.

В современных компутерах эта схема поддерживается ради совместимости с уже с 80286. Лично я не встречал случаев, чтобы вентиль А20 был по умолчанию закрыт, однако для гарантии перед переходом в защищённый режим всё ж стоит выдать команду на его разрешение. Но вот как она выдаётся, я сходу не скажу.

Что же касается ВМВаре, то, может, там как раз эта линия по умолчанию запрещена: под виртуальными машинами я почти никогда работать не пробовал (только чуть-чуть под Параллелс).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 16:46 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Это такой вопрос, где всегда однозначного, идеального, решения добиться трудно, потому что аппаратура в некоторых редких случаях ведет себя достаточно странно (см. статью "A20 - a pain from the past"). Про необходимость "вычищать" порт 60h из-за возможных посылок хосту от контроллера/клавиатуры много читал, видел это в различных исходниках и даже когда-то использовал сам, но со временем пришел к выводу, что в этом нет необходимости. Необходимость запрета прерываний связана с тем, что приходится посылать двухбайтовую команду, между посылками которой возможна активация клавиатурного обработчика, который, возможно, станет посылать другие команды, т.е. есть вероятность "разорвать" одну команду другими. Открывать шлюз нужно обязательно, потому что как раз-таки в подавляющем большинстве случаев по умолчанию он закрыт, причем и на самых современных компьютерах, только не следует забывать при тестировании, что шлюз перекрывает не вообще доступ к памяти за первым мегом, а лишь к четным мегам, т.е. 2-му, 4-му и т.д. Короче, я когда-то тоже долго "страдал" неидеальностью моего кода, но потом все-таки пришел к коду, который к сегодняшнему дню протестирован на огромном количестве самых разнообразных компьютеров и проблем не вызывал, причем не только при явном тестировании (здесь могут быть неявные проблемы из-за кэширования памяти), но и после тестирования при последующей интенсивной работе со всем объемом памяти. Кстати, если кто-то обнаружит неработоспособность представленного ниже кода на каком-либо компьютере при каких-либо неестественных обстоятельствах (ну к примеру вы лежали на клаве во время отработки данного кода), буду весьма благодарен, если вы мне об этом сообщите. Вот код:

открываем шлюз адресной линии A20:
1) устанавливаем флаг GateA20 (бит 1) порта вывода контроллера клавиатуры
2) устанавливаем флаг GateA20 (бит 1) порта A управления системой

cli
call Startup.WaitForEmpty
jnz @f
mov al, 0D1h ; команда контроллера для записи в порт вывода
out 64h, al
call Startup.WaitForEmpty
jnz @f
mov al, 0DFh ; Reset=1, GateA20=1
out 60h, al
call Startup.WaitForEmpty
@@: sti

call Startup.TestGateA20
jnz @f

in al, 92h
test al, 02h ; если флаг уже установлен, но шлюз не сработал,
jnz Startup.Error_4 ; будем считать это ошибкой
and al, 0FEh ; на всякий случай очищаем флаг Reset
or al, 02h
out 92h, al

call Startup.TestGateA20
jnz @f

.Error_4: call Startup.SystemError
db "4"

@@:

Используемые подпрограммы
-------------------------

.WaitForEmpty: xor cx, cx
@@: in al, 64h
and al, 02h
loopnz @b
ret

.TestGateA20: mov ax, [1000h]
dec ax
mov [es:1010h], ax ; es=0FFFFh... вроде бы :)
sub ax, [1000h]
ret


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 18:22 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Команда 0FFh, как я понимаю, нужна для отмены пульсации младших четырех бит порта вывода. Т.е., если эта команда находится перед установкой шлюза A20, как мне кажется, она паредназначена для того, чтобы остановить возможное произвольное изменение состояния шлюза, которое могло быть активизировано "недавно" отработавшим посторонним кодом. Но это лишь мои предположения. Лично я использую команду 0FXh только для работы с битом Reset (т.е. в виде 0FEh).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 18:49 

Зарегистрирован: 05 дек 2008, 03:58
Сообщения: 57
CLI нужно для блокировки не столько контроллера 8042. Она сам блокируется во время посылки сколько сторонниx прерываний.
Можно и безнее и проще.

Еще можно открыть линию так
WaitInputBufferEmpty
mov al,EFh
out 64,al
Одна команда =) Почти прямой доступ.

FF это мелкий хак. Временная задержка плюс блокировка клавиотуры на время пока контроллер не откроет линию A20. Это для очень старых компов может быть актуальным.
<code>
Из исходников MS.
We must wait for the a20 line to settle down, which (on an AT)
may not happen until up to 20 usec after the 8042 has accepted
the command. We make use of the fact that the 8042 will not
accept another command until it is finished with the last one.
The 0FFh command does a NULL 'Pulse Output Port'. Total execution
time is on the order of 30 usec, easily satisfying the IBM 8042
settling requirement. (Thanks, CW!)

mov al,0FFh ;* Pulse Output Port (pulse no lines)
out STATUS_PORT,al ;* send cmd to 8042
call empty_8042 ;* wait for 8042 to accept cmd

</code>
На современном пульс длиться 6 мс.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 19:07 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Я сейчас тоже прочел, что эта команда действительно используется не в начале (мое недавнее предположение), а "в конце" для задержки перед вызовом TestGateA20, однако не всегда ее использование приводит к подобным результатам. См. в той же статье "A20 - a pain from the past", где в частности есть ссылка на код minix, в котором в одном случае используется эта команда, а в другом нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 19:08 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1418
Наверное, не 6 мс, а 6 мкс. Но в любом случае надо ждать: ЦП работает по-любому многократно быстрее.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 09 янв 2009, 19:15 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Думаю задержку можно реализовать и по-другому, а также в другом месте, например, непосредственно в функции TestGateA20, выполняя многократное тестирование в цикле (я подобное где-то видел).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 41


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB