OSDev Wiki
Регистрация
Advertisement

История[]

При проектировании микропроцессора 80286 инженеры Intel допустили ошибку, позволившую из реального режима обращаться к части памяти за пределами младшего мегабайта — так называемой области верхней памяти (HMA). Чтобы компенсировать эту ошибку и гарантировать совместимость со старыми программами, в состав компьютера пришлось включить специальную схему, блокирующую 20-й разряд шины адреса (или все старшие разряды, начиная с 20-го — это зависит от особенностей чипсета) — Gate A20 (вентиль или шлюз линии A20). При использовании старых программ реального режима этот вентиль может быть закрыт, что обеспечит присутствие на линии A20 логического нуля, а при работе новых программ, поддерживающих защищённый режим, этот вентиль должен быть обязательно открыт.

Работа GateA20-0

Способы управления вентилем линии A20[]

Имеется два способа для разрешения или запрета вентиля линии A20. Один из них основан на использовании контроллера интерфейса PS/2 (часто неправильно называемого контроллером клавиатуры), другой — порта 92h.

Использование контроллера интерфейса PS/2[]

Контроллер интерфейса PS/2, помимо прочих своих функций, управляет также состоянием вентиля линии A20. Эта возможность обеспечивается тем, что контроллер, помимо линий ввода-вывода, связанных с интерфейсами PS/2 клавиатуры и мыши, имеет ещё несколько свободных «ног», одна из которых, а именно разряд 1 порта 2, и используется для управления вентилем линии A20: когда на ней находится 1, вентиль открыт, когда 0 — закрыт.

Для разрешения вентиля, т.е. для обеспечения нормального функционирования адресной линии A20, можно воспользоваться такой последовательностью команд:

    call   WaitForEmpty  ; Ожидание готовности контроллера
    jnz    @F            ; Переход, если ошибка
    mov    al, 0D1h      ; Команда выдачи данных в порт 2 контроллера
    out    64h, al
    call   WaitForEmpty  ; Ожидание готовности контроллера
    jnz    @F            ; Переход, если ошибка
    mov    al, 0DFh      ; Данные для порта 2
    out    60h, al
    call   WaitForEmpty  ; Ожидание готовности контроллера
@@:

...

; Подпрограмма ожидания готовности контроллера PS/2 к приёму очередного байта
; Если за разумное время контроллер не перешёл в состояние готовности,
; возвращается признак ошибки: сброшенный флаг ZF
WaitForEmpty:
    push   cx
    mov    cx, 0FFFFh    ; Счётчик ожидания готовности
@@: in     al, 64h       ; Чтение состояния контроллера
    test   al, 02h       ; Входной буфер пуст?
    loopnz @B            ; Если не пуст, продолжаем ждать
    pop    cx
    ret

Запрет вентиля A20 выполняется аналогичным образом, только вместо константы 0DFh в порт 2 необходимо вывести константу 0DDh.

Использование порта 92h[]

Порт 92h на ранних компьютерах, оснащённых вентилем A20, отсутствовал, поэтому достаточно долгое время главным способом разрешения или запрещения вентиля оставались описанные выше манипуляции с контроллером интерфейса PS/2. Однако необходимая последовательность команд для этого достаточно длинна, а её выполнение занимает приличное время, поскольку контроллер намного медленнее центрального процессора ПК. Кроме того, некоторые современные системные платы уже не имеют контроллера PS/2, поскольку этот интерфейс считается устаревшим. Поэтому в настоящее время рациональнее переключать состояние линии A20 вторым способом, часто называемым быстрым и основанным на использовании порта 92h, присутствующего во всех современных чипсетах. За вентиль линии A20 отвечает 1-й разряд порта; остальные разряды изменять нельзя.

Разрешение вентиля A20 через порт 92h выполняется следующим образом:

    in     al, 92h
    or     al, 02h
    out    92h, al

Запрещение вентиля выполняется аналогичным образом, только команду or al, 02h надо заменить на and al, 0FDh.

Заметим, что между командами in и out теоретически может потребоваться введение задержки.

Advertisement