46 lines
1.9 KiB
C
46 lines
1.9 KiB
C
#include "gdt.h"
|
|
|
|
// Наша таблица GDT и указатель на неё
|
|
struct gdt_entry gdt[5];
|
|
struct gdt_ptr gdtp;
|
|
|
|
// Ассемблерная функция для загрузки регистра GDTR и обновления сегментов
|
|
extern void gdt_flush(uint32_t);
|
|
|
|
// Внутренняя функция для сборки дескриптора из человеческих параметров
|
|
static void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) {
|
|
gdt[num].base_low = (base & 0xFFFF);
|
|
gdt[num].base_middle = (base >> 16) & 0xFF;
|
|
gdt[num].base_high = (base >> 24) & 0xFF;
|
|
|
|
gdt[num].limit_low = (limit & 0xFFFF);
|
|
gdt[num].granularity = (limit >> 16) & 0x0F;
|
|
|
|
gdt[num].granularity |= gran & 0xF0;
|
|
gdt[num].access = access;
|
|
}
|
|
|
|
void gdt_init(void) {
|
|
// Настраиваем указатель GDT
|
|
gdtp.limit = (sizeof(struct gdt_entry) * 5) - 1;
|
|
gdtp.base = (uint32_t)&gdt;
|
|
|
|
// 1. Нулевой дескриптор (обязателен, всегда нули)
|
|
gdt_set_gate(0, 0, 0, 0, 0);
|
|
|
|
// 2. Сегмент кода ядра (Kernel Code)
|
|
// База = 0, Лимит = 0xFFFFF, Доступ = 0x9A, Гранулярность = 0xCF (страничная разметка, 4ГБ)
|
|
gdt_set_gate(1, 0, 0xFFFFF, 0x9A, 0xCF);
|
|
|
|
// 3. Сегмент данных ядра (Kernel Data)
|
|
// Всё то же самое, но Доступ = 0x92 (разрешена запись, это сегмент данных)
|
|
gdt_set_gate(2, 0, 0xFFFFF, 0x92, 0xCF);
|
|
|
|
// 4. Юзерский код (Ring 3) — пока заглушка, заюзаем в Части 2
|
|
gdt_set_gate(3, 0, 0, 0, 0);
|
|
// 5. Юзерские данные (Ring 3) — пока заглушка, заюзаем в Части 2
|
|
gdt_set_gate(4, 0, 0, 0, 0);
|
|
|
|
// Загружаем GDT в процессор
|
|
gdt_flush((uint32_t)&gdtp);
|
|
}
|