Это была отличная кривая обучения, которая, по -видимому, помогла мне создать более теоретические и концептуальные идеи, связанные с теориями/законами о основных загадках операционных систем и ядра. Я предположил, что у меня была хорошая идея о том, как работал Осс. Тем не менее, создание моей собственной ОС было абсолютно более определенным по сравнению с просто чтением. На мой взгляд, честное мнение. Это было для меня способом лучше понять программное обеспечение, с которым я хотел бы встретиться с режимом ядра и пользовательским режимом.
Прежде чем мы начнем, хотя ядро и операционная система составляют 32 бит. Я тоже объясню концепции в 64 битах, очевидно, одним из них является длинным режимом.
Режимы
Прерывания
Дескрипторы
Пейджинг
Подробнее о защищенном режиме в Intel® 64 и IA-32 Architectures Architectures Руководство разработчика Developer Том 3A: Руководство по программированию системного программирования, часть 1; Глава 3 *
Что такое прерывания
Вы можете думать о прерываниях как о сигнале или данных, которые отправляются таким устройством, как клавиатура, твердотельный диск, жесткий драйвер или мышь и программное обеспечение, которое сообщает процессору, что событие произошло, и необходимо немедленно прекратить то, что он делает в настоящее время, чтобы перейти к тому, что отправило его в прерывание.
Например, когда вы перемещаете/нажимаете мышь, контроллер мыши отправит прерывание контроллеру прерывания для процессора, внимание ЦП немедленно перейдет в прерывание мыши и продолжит выполнять рутину (движение мыши или щелчок). После прерывания мыши процессор будет продолжать делать то, что было, до прерывания или отправиться в управление другим прерыванием, если оно было сигналом.
+------------------------+ +------------+
| TYPES OF INTERRUPTS |------------| Exceptions |
+------------------------+ +------------+
/
/
/
+------------+ +------------+
| HARDWARE | | SOFTWARE |
| INTERRUPTS | | INTERRUPTS |
+------------+ +------------+
Линии IRQ, или IRQ на основе PIN: они, как правило, статически маршрутизируются на чипсете. Провода или линии, проходящие от устройств на чипсете, до контроллера IRQ, который сериализует запросы на прерывание, отправляемые устройствами, отправляя их на ЦП ОДИН, чтобы предотвратить гонки. Во многих случаях контроллер IRQ будет отправлять несколько IRQ в процессор сразу, основываясь на приоритете устройства. Примером очень известного контроллера IRQ является цепочка контроллера Intel 8259, которая присутствует на всех совместимых с IBM-PC Chipsets, складывая два контроллера, каждый из которых обеспечивает 8 входных контактов в общей сложности 16 полезных сигналов IRQ на Legacy IBM-PC.
Прерывания на основе сообщений: они сигнализируют, написав значение в местоположение памяти, зарезервированное для информации о прерывании устройства, самого прерывания и информации о векторе. Устройству назначено местоположение, в которое оно записывается либо прошивкой, либо программным обеспечением ядра. Затем устройство генерируется IRQ с использованием арбитражного протокола, специфичного для шины устройства. Примером шины, которая предоставляет функциональность прерывания на основе сообщений, является шина PCI. От wiki.osdev - https://wiki.osdev.org/Erenterrupts
Вход - запись определяет область в памяти, с чего начать, наряду с пределом региона и привилегиями доступа, связанными с записью. Привилегия доступа, как при сообщении процессора, если ОС работает в системе (кольцо 0) или приложения (кольцо 3). Это предотвращает приложения или Usermode иметь доступ к определенным регистрам/операндам и мнемонике. Такие как регистры CR и CLI/STI соответственно.
Предел - размер дескриптора сегмента
Сегментный селектор - это регистры, которые держат индекс дескрипторов
Чтобы быть более явным, индекс не является селектором
Вещи, которые хранят сегментные регистра:
Доступ к таблице дескрипторов также имеет привилегии, это называется RPL (уровень привилегий запроса) для каждого регистра, но для cs называется CPL (текущий уровень привилегий). Они оба служат разным целям, которые вы можете узнать в руководствах Intel или AMD.
Таблица для использования для изучения. Одна таблица - это GDT, другой - LDT.
Неформальное правило для концептуального представления использования селектора: поэтому неформальное правило:
selecter = index + table_to_use + privilege table_to_use + index = descriptor = вся информация о сегменте памяти, которая будет использоваться
где знак плюса не является арифметической операцией
Битовое поле сегмента Сегмента Регистр:
15 3 2 0
+--------------------------------------------------+----+--------+
| Index | TI | RPL |
+--------------------------------------------------+----+--------+
TI = Table Indicator: 0 = GDT, 1 = LDT
The TI specify if the Descriptor were dealing with is a GDT or LDT
IF(TI == 0) THEN
... THE DESCRIPTOR IS A GDT
ELSEIF(TI == 1) THEN
... THE DESCRIPTOR IS A LDT
GDT 1: 1 с логическим адресом, пример GDT, работающего с селектором:
<---- Selector ----> +----- Segment Selector Register
+-------+----+-----+ v
| Index | TI | RPL | = DS
+-------+----+-----+ GDT LDT
| | +---------------------+ +---------------------+
| +------------>| Null Descriptor | | Null Descriptor |
| +---------------------+ +---------------------+
| | Descriptor 1 | | Descriptor 1 |
| +---------------------+ +---------------------+
| | | | |
| ... ... ... ... ... ... ... ...
| | |
| +---------------------+
+------------------->| Descriptor K |
+---------------------+
| |
... ... ... ...
RPL (Request Privilege Level) describes the privilege for accessing the descriptor
Мы храним все базу GDT (адрес) и предел (размер нашего GDT) в GDTR. GDTR указывает на все наши записи GDT в памяти, начиная с базы. После этого он загружен с помощью Mnemonic lgdt :
typedef union _gdt_descriptor
{
struct
{
uint64_t limit_low : 16 ;
uint64_t base_low : 16 ;
uint64_t base_middle : 8 ;
uint64_t access : 8 ;
uint64_t granularity : 8 ;
uint64_t base_high : 8 ;
};
} __attribute__((packed)) gdt_entry_t ;
gdt_entry_t gdt_entrys[ 256 ];
/* The GDTR (GDT Register) */
struct gdtr
{
uint16_t limit;
uint32_t base;
} __attribute__((packed)) gdtr;
...
gdtr.base = &gdt_entrys;
gdtr.limit = ( sizeof (gdt_descr) * 256 ) - 1 )
Прочитайте больше на нем в руководстве по программисту AMD64, том 2, раздел 4.7 (стр. 84 - 90 {+})
Ссылка на это и далее. https://notes.shichao.io/utlk/ch2/#paging-in-hardware Это было, безусловно, самым веселым, что я был очень взволнован, когда я понял это.
x86 ОС, пропитанная виртуальным адресом, с 4 КБ страницами:
x86 OS CR4.PAE Прогулка виртуальный адрес с 4 КБ.
x86_64 (IA-32E) OS CR4.LME/CR4.PAE Прогулка Виртуальный адрес с 4 КБ.
• Флаги WP и PG в контрольном регистре CR0 (бит 16 и бит 31 соответственно).
• Флаги PSE, PAE, PGE, PCIDE, SMEP, SMAP и PKE в контрольном регистре CR4 (бит 4, бит 5, бит 7, бит 17, бит 20, бит 21 и бит 22 соответственно).
• Флаги LME и NXE в MSR IA32_EFER (бит 8 и бит 11 соответственно). • Флаг переменного тока в регистре EFLAGS (бит 18). По главе 4 Intel® 64 и IA-32 Architectures Architectures Developer Руководство разработчика 3A: Руководство по программированию системного программирования, часть 1; Глава 4
• Флаги LME и NXE в MSR IA32_EFER (бит 8 и бит 11 соответственно). • Флаг переменного тока в регистре EFLAGS (бит 18). Глава 4 Intel® 64 и IA-32 Архитектурного программного обеспечения Руководство разработчика программного обеспечения Том 3A: Руководство по программированию системы, часть 1; Глава 4
Если CR4.PAE и/или CR4.LME установлены на 1, то PSE полностью игнорируется.
Не добавлен терминал
cd smkrnl; make run
За иской вдохновения/поддержки в моих постоянных усилиях по этому проекту и для того, чтобы помочь мне понять определенные концепции в развитии ядра/ОС. =)