В оглавлении перечислены более-менее в логическом порядке статьи об экспериментах с разработкой ОС.
- Эксперименты с загрузкой Операционной Системы
- Operation System boot experiments
- Загрузка операционной системы Hello world
- Ассемблер и ядро Операционной Системы
- Вторичный загрузчик Операционной Системы
- Experimenting with OS Kernel Loading using Menuet OS boot loader
- Protected Mode Kernel Hello World
- Схема адресации в защищенном режиме
- Переключение в защищенный режим в загрузчике
- Разработка собственного загрузчика для FAT32
- FAT32 загрузчик, загрузка с флешки (начало разработки)
- Чтение секторов физического диска под Windows
- Вывод значений регистров на ассемблере в загрузчике
- MBR загрузчик в режиме LBA
- Преобразование из LBA в CHS и обратно. MBR загрузчик в режиме CHS
- Предварительные эксперименты с чтением FAT32 на C под Windows
- FAT32 загрузчик, загрузка с флешки (результат)
- Эксперименты с ядром
- GCC Calling conventions investigation
- Изменение соглашений передачи параметров функций в gcc (Function attributes)
- GCC Inline Assembly Experiments
- Экранные функции в ядре ОС
- Обработка прерываний исключений и прерываний в защищённом режиме
- Обработка исключений и прерываний — обзор
- Вектора прерываний и исключений
- Источники прерываний
- Таблица прерываний защищённого режима
- Маскируемые прерывания
- Источники исключений
- Классификация исключений процессора
- Рестарт программы или задачи при обработке исключения
- Не маскируемые прерывания
- Запрет и разрешение прерываний
- Приоритезация одновременных прерываний в процессоре
- Таблица дескрипторов прерываний IDT
- Дескрипторы прерываний IDT gate дескрипторы
- Обработка исключений
- Передача кода ошибки в обработчик исключения
- Справочник по исключениям
- Interrupt 0—Divide Error Exception (#DE)
- Interrupt 1—Debug Exception (#DB)
- Interrupt 2—NMI Interrupt
- Interrupt 3—Breakpoint Exception (#BP)
- Interrupt 4—Overflow Exception (#OF)
- Interrupt 5—BOUND Range Exceeded Exception (#BR)
- Interrupt 6—Invalid Opcode Exception (#UD)
- Interrupt 7—Device Not Available Exception (#NM)
- Interrupt 8—Double Fault Exception (#DF)
- Interrupt 9—Coprocessor Segment Overrun
- Interrupt 10—Invalid TSS Exception (#TS)
- Interrupt 11—Segment Not Present (#NP)
- Interrupt 12—Stack Fault Exception (#SS)
- Interrupt 13—General Protection Exception (#GP)
- Interrupt 14—Page-Fault Exception (#PF)
- Interrupt 16—x87 FPU Floating-Point Error (#MF)
- Interrupt 17—Alignment Check Exception (#AC)
- Interrupt 18—Machine-Check Exception (#MC)
- Interrupt 19—SIMD Floating-Point Exception (#XM)
- Interrupts 32 to 255—User Defined Interrupts
- Архитектура обработки исключений в IBM PC Compatible системах
- Другие статьи по OSDev…
Пришла пора продолжить серию постов об экспериментах с разработкой Операционной Системы. У меня есть загрузчики, есть билд-система для сборки ядра. Есть заготовка экранных функций. Загрузчик загружает ядро в память по адресу 0x10000, переводит процессор в защищенный режим и передает управление на ядро. Ядро в данный момент просто выводит на экран несколько отладочных сообщений в цикле. Эдакий сферический конь в вакууме. Работает этот «конь» недолго. Дело в том, что у компьютера по-умолчанию настроены ряд прерываний. В частности таймер. Это прерывание вызывается весьма часто. В момент старта компьютер работает в реальном режиме. И прерывания обрабатываются обработчиками прерываний реального режима. Таблица прерываний реального режима находится в адресах 0 — 0x400.
В защищённом режиме, прерывания обрабатываются по-другому. У меня кода обработки прерываний пока нет, поэтому первое же прерывание приводит мою тестовую систему к перезагрузке.
Об обработке прерываний есть статья James Molloy: http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html. Есть ещё другие материалы, но я планирую для начала обратиться к первоисточникам. К документации Intel.
Прерывания и исключения — обзор
Прерывания и исключения — события, означающие что где-то в системе
(оборудовании) или внутри текущей выполняющейся программы или
задачи возникло состояние, требующее немедленного внимания
процессора. Обычно прерывания и исключения приводят к принудительной
передачи управления от текущей выполняемой программы или задачи к
специальной программной процедуре или задаче, называемой
обработчиком прерывания или обработчиком исключения. Действие,
выполняемое процессором в ответ на прерывание или исключение
называют обработка прерывания или исключения (servicing or handling the
interrupt or exception).
Прерывания возникают в случайные моменты времени в момент
выполнения программы в ответ на сигналы от аппаратуры. Системные
платы используют прерывания для сигнализации о возникновении событий
внешних по отношению к процессору, таких как запросы на обработку от
переферийных устройств. Программы тоже могут генерировать прерывания
путем выполнения инструкции процессора INT n.
Исключения возникают когда процессор определяет возникновение ошибки
(detects error condition) в процессе выполнения инструкции. Например —
деление на ноль. Процессор определяет разнообразные error conditions
включая нарушения защиты (protection violations), ошибки страниц (page
faults), internal machine faults. Архитектура процессоров Pentium 4, Intel Xeon,
P6 family и Pentium позволяет генерацию machine-check excheption при
возникновении внутренних аппаратных ошибок (hardware errors) или
ошибок шины (bus errors).
Когда прерывание принимается или детектируется исключение, текущая
процедура или задача приостанавливается пока процессор выполняет
код обработчика прерывания или исключения. Когда выполнение
обработчика прекращается, процессор возобновляет выполнение
прерванной процедуры или задачи. Возобновление выполнения прерванной
процедуры или задачи возникает без нарушения состояния программы,
если восстановление после исключения возможно и прырывание не
вызвало принудительного завершения текущей выполняемой программы.
Вектора прерываний и исключений
Для упорядочивания обработки исключений и прерываний, каждому
отдельному исключению и каждому прерыванию (interrupt condition),
требующему специальной обработки процессором, назначается уникальный
идентификатор, называемый номером вектора (vector number). Процессор
использует vector number (номер), назначенный исключению или
прерыванию как индекс в таблице дескрипторов прерываний (interrupt
descriptor table IDT). Таблица содержит адреса (entry point) обработчиков
исключений или прерываний.
Разрешенный диапозон для vector numbers от 0 до 255. Номера от 0 до 31
зарезервированы в Intel 64 и IA-32 архитектурах для architecturedefined
прерываний и исколючений. Не все из vector numbers в этом диапозоне
имеют назначенную функцию. Неназначенные vector numbers в этом
диапозоне зарезервированы. Не используйте эти зарезервированные
номера.
Vector numbers в диапозоне от 32 до 255 отведены под user-defined
прерывания и не зарезервированы Intel 64 и IA-32 архитектурами. Эти
прерывания в основном предназначены для внешних устройств ввода-
вывода.
Процессор получает прерывания из 2-х источников:
— Внешние (аппаратно генерируемые) прерывания.
— Программно-генерируемые прерывания.
Внешние (аппаратные) прерывания
Внешние прерывания получаются через контакты процессора или через
локальный контроллер прерываний APIC. Главные контакты, означающие
состояние прерывания на процессорах Pentium 4, Intel Xeon, P6 family и
Pentium — LINT[1:0] pins, соединенные с локальным APIC. Когда локальный
APIC включен, LINT[1:0] pins, могут быть запрограммированы с помощью
APIC local vector table (LVT), на ассоциацию с любым процессорным
исключением или вектором прерывания.
Когда локальный APIC является глобальным/аппаратные прерывания
запрещены, тогда эти контакты конфигурируются как INTR и NMI контакты,
соответственно. Сигнал на контакте INTR сигнализирует процессору, что
внешнее прерывание возникло. Процессор читает из системной шины
inerrupt vector, предоставляемый внешним контроллером прерываний,
таким как 8259A. Сигнал на контакте NMI говорит процессору, что
немаскируемое прерывание (NMI), назначенное на вектор прерывания 2.
Прерывания и исключения защищенного режима
Vector No. | Mnemonic | Description | Type | Error Code | Source |
0 | #DE | Divide Error | Fault | No | DIV и IDIV инструкции |
1 | #DB | RESERVED | Fault/Trap | No | For Intel use only |
2 | — | NMI Interrupt | Interrupt | No | Nonmaskable externel interrupt |
3 | #BP | Breakpoint | Trap | No | INT 3 instruction |
4 | #OF | Overflow | Trap | No | INT0 instruction |
5 | #BR | BOUND Range Exceeded | Fault | No | BOUND instruction |
6 | #UD | Invalid Opcode (Undefined Opcode) |
Fault | No | UD2 instruction or reserved opcode |
7 | #NM | Device Not Available (No Math Coprocessor) |
Fault | No | Floating-point or WIT/FWAIT instruction |
8 | #DF | Double Fault | Abort | Yes (zero) | Any instruction that can generate an exception, an NMI, or an INTR. |
9 | Coprocessor Segment Overrun (reserved) |
Fault | No | Floating-point instruction | |
10 | #TS | Invalid TSS | Fault | Yes | Task switch or TSS access. |
11 | #NP | Segment Not Present | Fault | Yes | Loading segment registers or accessing system segments. |
12 | #SS | Stack-Segment Fault | Fault | Yes | Stack operations and SS register loads |
13 | #GP | General Protection | Fault | Yes | Any memory reference and other protection checks |
14 | #PF | Page Fault | Fault | Yes | Any memory reference |
15 | — | (Intel reserved. Do not use) | Fault | No | |
16 | #MF | x87 FPU Floating-Point Error (Math Fault) |
Fault | No | x87 FPU floating-point or WAIT/FWAIT instruction |
17 | #AC | Alignment Check | Fault | Yes(Zero) | Any data reference in memory |
18 | #MC | Machine Check | Abort | No | Error codes (if any) and source are model dependant |
19 | #XM | SIMD Floating-Point Exception | Fault | No | SSE/SSE2/SSE3 floating point instructions |
20-31 | — | Intel reserved. Do not use. | |||
32-255 | — | User Defined ( Non reserved) Interrupts |
Interrupt | External interrupt or INT n instruction |
Внутренний контроллер прерываний процессора localAPIC обычно соединен с
системным контроллером прерываний I/O APIC. Внешние прерывания
полученные через контакты системного контроллера прерываний I/O APIC
могут быть направлены на внутренний контроллер прерываний local APIC
через системную шину (Pentium 4, Intel Core Duo, Intel Core 2, Intel® Atom™,
and Intel Xeon processors) или через APIC serial bus (P6 family and Pentium
processors). Внешний контроллер прерываний I/O APIC определяет vector
number прерывания и шлёт этот номер внутреннему контроллеру
процессора (local APIC). Когда система включает множество процессоров,
процессоры могут также слать прерывания один другому посредством
системной шины (Pentium 4, Intel Core Duo, Intel Core 2, Intel Atom, and
Intel Xeon processors) или посредством APIC serial bus (P6 family and
Pentium processors).
Контакты LINT[1:0] не доступны в процессорах Intel486 и ранних
процессорах Pentium не имеющих встроенного внутреннего local APIC. Эти
процессоры имеют специальные жестко назначенные контакты NMI и INTR.
В системах с такими процессорами прерывания обычно генерируются
системным контроллером прерываний (8259A), с посылкой прерываний
через контакт INTR.
Заметьте, что несколько других контактов на процессоре могут приводить
к возникновению процессорного прерывания. Однако эти прерывания не
обрабатываются механизмом обработки прерываний и исключений
описанным здесь. Эти контакты включают: RESET#, FLUSH#, STPCLK#,
SMI#, R/S#, and INIT#. Есть ли они у конкретного процессора, зависит от
реализации конкретной модели. Функции контактов описаны в технических
описаниях прилагаемых к конкретным процессорам. Контакт SMI#
описывается в главе 26 «System Management».
Маскируемые аппаратные прерывания
Любое внешнее прерывание доставленное процессору посредством
контакта INTR или через внутренний local APIC называется маскируемым
аппаратным прерыванием. Через Маскируемые аппаратные прерывания
доставленные через контакт INTR могут быть любыми в диапозоне 0 — 255.
Прерывания доставленные через внутренний local API могут быть векторами
в диапозоне 16 — 255.
Флаг IF регистра EFLAGS позволяет маскировать всю группу маскируемых
аппаратных прерываний. При получении прерываний с векторами от 0 до
15 через внутренний local APIC, APIC сообщает (indicates) получение
неверного вектора прерывания.
Процессор получает исключения из трех источников:
— Обнаруживаемые процессором Program-Error exceptions
— Программно генерируемые исключения
— Machine-check exceptions.
Program-Error Exceptions
Процессор генерирует одно или более исключений при обнаружении
программных ошибок в процессе выполнении приложения, кода
операционной системы или executive. Архитектуры Intel64 и IA-32
определяют vector number для каждого processor-detectable exception.
Исключения подразделяются на faults, traps и aborts.
Программно-генерируемые исключения
Инструкции INTO, INT3 и BOUND позволяют программную генерацию
исключений. Эти инструкции позволяют выполнение проверки условий в
местах выполнения потока инструкций. Например INT 3 вызывает
генерацию breakpoint exception. Инструкция INT n может быть использована
для эмуляции исключений в программах, но есть ограничение. Если INT n
вызывает вектор для одного из architecturally-defined исключений,
процессор генерирует прерывание на корректный вектор (для доступа
к обработчику исключения) но не кладет код ошибки на стек. В отличии
от аппаратно-генерируемое исключения нормально сохраняющего на стеке
код ошибки. Обработчик исключения будет пытаться взять
код ошибки со стека при обработке исключения. Но, так как код ошибки
не был сохранён в стеке, вместо кода ошибки из стека будет извлечён
EIP (на месте пропущенного кода ошибки). Это приведёт к возврату из
обработчика по неверному адресу. (Т.о. нельзя с помощью INT n
обращаться к обработчикам аппаратно-генерируемых исключений).
Machine-Check Exceptions
Процессоры семейств P6 family и Pentium предоставляют внутренние и
внешние machine-check механизмы для проверки операций внутреннего
аппаратного чипа и транзакций шины. Эти механизмы — implementation
dependent (непереносимы). Когда процессор обнаруживает machinecheck
ошибку, процессор сигнализирует об ошибке с помощью machine-check
exception (vector 18) и возвращает код ошибки.
Классификация исключений
Исключения подразделяются на faults, traps и aborts в зависимости от
пути их поступления или в зависимости от возможности рестара
инструкции вызвавшей исключение без потери работоспособности
(continuity) программы или задачи.