Real-Mode x86 ASM: как сделать основы?

Я сейчас читаю boot.s файл в исходном коде для первого когда-либо ядра Linux (при условии, что 0.01 действительно является первым публичным выпуском).

Я знаю C и ASM, последний значительно меньше первого. Несмотря на это, я, кажется, в состоянии понять и по существу понять код в исходных файлах.

Этот файл меня смущает, хотя. Теперь я понимаю, что это происходит в реальном режиме, а не в защищенном режиме. Излишне говорить, что я никогда не видел код ASM, написанный в реальном режиме. Защищенным режимом был режим де-факто, x86-операционные системы работали еще до моего рождения, так что этого следовало ожидать.

Вот рутина, которую я хочу лучше понять:

/*
 * This procedure turns off the floppy drive motor, so
 * that we enter the kernel in a known state, and
 * don't have to worry about it later.
 */
kill_motor:
    push dx
    mov dx,#0x3f2
    mov al,#0
    outb
    pop dx
    ret

Глядя вверх outbЯ считаю, что он используется для передачи байтов в порты на компьютере. Я рискну предположить, основываясь на документации на C, что этот сценарий передает байт 'stop motor' в качестве первого аргумента, а в качестве номера порта флоппи-дисковода - в качестве второго.

Этот интерфейс предоставляется BIOS? Или непосредственно с помощью дисковода гибких дисков? Я предполагаю, что BIOS имеет скромные "драйверы" для очень простой работы всех основных устройств.

Вот где я в тупике: кажется, что цифры как #0x3f2 вытаскиваются из воздуха. Это явно аппаратные номера портов или что-то в этом роде. Этот файл усыпан такими числами, без объяснения того, на что они ссылаются. Где я могу найти исчерпывающую справку, которая показывает все аппаратные порты и контрольные номера, которые они могут получить в реальном режиме? Кроме того, кажется, что файл перемещает ядро ​​в памяти во время процессов загрузки с жестко закодированными адресами памяти. Где я могу найти руководство по тому, какие диапазоны адресов памяти доступны для записи в реальном режиме?

Я также прочитал комментарий Линуса о перепрограммировании прерываний, чтобы избежать конфликта между BIOS и внутренними аппаратными прерываниями. Я не собираюсь лгать, это пошло прямо над моей головой.

Помощь была бы отличной; Гугл, кажется, немного по теме, на случай, если вам интересно.

2 ответа

Решение

Во-первых, добро пожаловать в мир настоящего модного ассемблера! Вы, вероятно, уже поняли, что фактический ассемблер во многом одинаков между реальным режимом и защищенным режимом - основными различиями являются размеры операндов и расположение / управление памятью.

В Интернете есть некоторые ресурсы для реальной моды - вы просто должны выследить их! Одним из очень важных ресурсов является список прерываний Ральфа Брауна (известный как RBIL) - он предоставляет много информации о различных прерываниях, используемых в программировании в реальном режиме. Другой является карта памяти CMOS BiosCentral, которая описывает, какую информацию BIOS хранит (или должен хранить) в различных местах памяти.

Чтобы ответить на некоторые ваши вопросы относительно кода Linux, который вы разместили:outb инструкция для записи байта в al в порт dx - 0x3f2 - порт контроллера флоппи-дисковода. Википедия может помочь вам с основным списком номеров портов x86, но вам придется поискать подробную информацию о фактическом формате al биты.

какие диапазоны адресов памяти доступны для записи в режиме реального времени?

Вы должны провести некоторое исследование INT 15h, AX=E820h - он возвращает карту памяти, описывающую, какие области памяти можно использовать, а какие зарезервировать. Обратите внимание: при рассмотрении прерываний важно видеть, насколько они "новы", потому что старые BIOS могут их не поддерживать.

... перепрограммирование прерываний, чтобы избежать конфликта между BIOS и внутренними аппаратными прерываниями

Многие устройства имеют программируемые прерывания (которые используются для обслуживания оборудования, когда оно требует внимания). Обычно BIOS сортирует начальное назначение во время своих процедур запуска, но для ОС весьма характерно перенастраивать аппаратные прерывания для своих собственных целей или для предотвращения известных несовместимостей.

Последнее замечание: it seems that numbers like #0x3f2 are being pulled out of thin air, Ответ - да. Большая часть загрузочного источника для Linux ужасна (да, это только мое мнение) и, похоже, выдает случайные адреса, номера портов и другие биты без какого-либо значимого объяснения. Придерживайтесь этого, ищите другие реальные ресурсы, и в конце концов это будет иметь смысл. Да, и если вы встретите исчерпывающую ссылку - скажите ВСЕМ (потому что она в настоящее время не существует).

Эти адреса были брошены в камень 30 лет назад, когда IBM выпустила первый IBM PC. 0x3f0 - это первый адрес для первичных регистров контроллера гибких дисков. Список адресов доступен здесь.

Одним из нетипичных шагов команды разработчиков IBM было то, что они собрали машину из стандартных готовых деталей. Большинство чипов были от Intel, контроллер гибких дисков был NEC. Непреднамеренное обеспечение того, что каждый может построить клон. Эти клоны использовали одинаковые адреса для обеспечения совместимости программного обеспечения, превращая выбор IBM в отраслевой стандарт, который можно было бы жестко закодировать.

Другие вопросы по тегам