Skip to content

Latest commit

 

History

History
136 lines (113 loc) · 14.6 KB

File metadata and controls

136 lines (113 loc) · 14.6 KB

RAND Elecorner 36 — Обзор Архитектуры (Bare-Metal)

Данный документ описывает новую архитектуру системы, перешедшей от стадии Qt-симулятора к полноценной bare-metal OS для архитектуры x86 (32-bit).


Высокоуровневая архитектура

┌─────────────────────────────────────────────────────────────┐
│                    RAND Elecorner 36 OS                      │
│                                                              │
│  ┌────────────────────────────────────────────────────────┐  │
│  │                  User Space (Ring 3)                   │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │  │
│  │  │  Sh (CLI)│ │ Coreutils│ │ Пользова │ │ Сторонние│  │  │
│  │  │ terminal │ │ ls, cat  │ │  скрипты │ │  бинарни │  │  │
│  │  └──────────┘ └──────────┘ └──────────┘ └──────────┘  │  │
│  └──────────────────────┬─────────────────────────────────┘  │
│                         │ sysenter / int 0x80                │
│  ┌──────────────────────▼─────────────────────────────────┐  │
│  │              Уровень Системных Вызовов                  │  │
│  │      Syscall Handler (Переключение контекста)          │  │
│  └──────────────────────┬─────────────────────────────────┘  │
│                         │                                    │
│  ┌──────────────────────▼─────────────────────────────────┐  │
│  │                 ЯДРО (Ring 0 / C++)                     │  │
│  │  ┌────────────┐ ┌────────────┐ ┌────────────┐          │  │
│  │  │ Scheduler  │ │  VMM / PMM │ │ FileSystem │          │  │
│  │  │ (PIT/IRQ0) │ │ (Paging)   │ │  (FAT16)   │          │  │
│  │  └────────────┘ └────────────┘ └────────────┘          │  │
│  │  ┌────────────┐ ┌────────────┐                         │  │
│  │  │    IPC     │ │  libc Port │                         │  │
│  │  │ (Pipes/Msg)│ │ (Newlib)   │                         │  │
│  │  └────────────┘ └────────────┘                         │  │
│  │                                                         │  │
│  │  ┌──────────────────────────────────────────────────┐   │  │
│  │  │        Hardware Abstraction Layer (HAL)           │   │  │
│  │  │  ┌───────────┐ ┌────────────┐ ┌───────────────┐  │   │  │
│  │  │  │ VGA Text  │ │ Keyboard   │ │  Disk (ATA/IDE│  │   │  │
│  │  │  │ (0xB8000) │ │ (Port 0x60)│ │ (Port 0x1F0)  │  │   │  │
│  │  │  └───────────┘ └────────────┘ └───────────────┘  │   │  │
│  │  └──────────────────────────────────────────────────┘   │  │
│  └─────────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────▼─────────────────────────────────┐  │
│  │                       BIOS / Хардвар                    │  │
│  └─────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Future Vision: User-Space Drivers (Hybrid/Microkernel)

While the initial bootstrap phases place drivers (like keyboard and VGA) inside the Ring 0 kernel monolith, the long-term architecture envisions a transition to a microkernel-like isolation:

Isolation Strategy

  1. Virtual Memory Management (VMM): The PMM will be backed by a Paging system. Every user-space driver will run in its own isolated virtual address space, preventing stray pointers from crashing the core kernel.
  2. Ring 3 Execution: External drivers will be compiled as standalone .elf binaries and executed in unprivileged mode (Ring 3). The Global Descriptor Table (GDT) and a Task State Segment (TSS) will manage privilege levels.
  3. DriverAPI & Syscalls: Direct hardware access (e.g., inb, outb) will trigger General Protection Faults in Ring 3. Drivers will use a standardized C++ DriverAPI library that wraps software interrupts (int 0x80) to request the kernel to perform I/O operations, allocate memory, or register interrupt handlers safely. │ │ └────────────┘ └────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ │ │ Hardware Abstraction Layer (HAL) │ │ │ │ │ │ ┌───────────┐ ┌────────────┐ ┌───────────────┐ │ │ │ │ │ │ │ VGA Text │ │ Keyboard │ │ Disk (ATA/IDE│ │ │ │ │ │ │ │ (0xB8000) │ │ (Port 0x60)│ │ (Port 0x1F0) │ │ │ │ │ │ │ └───────────┘ └────────────┘ └───────────────┘ │ │ │ │ │ └──────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────▼─────────────────────────────────┐ │ │ │ BIOS / Хардвар │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

---

## 1. Загрузка Системы (Boot Process)

Процесс запуска кардинально отличается от запуска обычной .exe программы. Он делится на три ступени:

### Этап 1: Bootloader (16-bit)
1. BIOS компьютера читает нулевой сектор жесткого диска/дискеты в физическую память по адресу `0x7C00`.
2. Код загрузчика (`bootloader.asm`) инициализирует сегменты (DS, ES), парсит корневой каталог `FAT16`, находит `KERNEL.BIN`.
3. Загрузчик считывает кластеры ядра в память (например, на `0x10000`) через BIOS-прерывание `int 13h`.
4. Инструкция дальнего прыжка (`jmp far`) передает управление началу ядра.

### Этап 2: Kernel Entry (32-bit Assembly)
1. Стартовый код ядра (`kernel_entry.asm`) подготавливает *Защищенный Режим (Protected Mode)*.
2. Происходит настройка **GDT** (Global Descriptor Table).
3. Процессор переключается в 32-битный режим. Отключаются все BIOS-прерывания.
4. Вызываются конструкторы глобальных C++ объектов (содержимое секции `.init_array`).
5. Управление передается в функцию на C++ — `kernel_main()`.

### Этап 3: C++ Kernel Init
1. `kernel_main()` инициализирует собственный менеджер памяти (PMM), чтобы заработали функции `malloc` и `new`.
2. Настраивается **IDT** (Interrupt Descriptor Table) для приема аппаратных прерываний (нажатия клавиш, таймер).
3. Загружается `Scheduler` и драйвера оборудования (`VgaDriver`, `KeyboardDriver`).

---

## 2. Ключевые Подсистемы C++ Ядра

### 2.1 Поддержка С++ и Стандартной библиотеки
Мы пишем ОС на современном C++ (C++17). Однако на уровне "голого железа" нет стандартной библиотеки.
- **Newlib / libsupc++:** Исходный код C++ ядра компилируется с флагом `-ffreestanding`. Чтобы использовать классы `std::vector` или `std::string`, мы линкуем ядро со специально портированной версией библиотеки `libc/libm`, для которой реализованы так называемые *системные заглушки* (`_sbrk`, `_read`, `_write`).
- **Аллокатор кучи (Heap):** Перегружены глобальные операторы `::operator new` и `::operator delete`.

### 2.2 Physical Memory Manager (PMM)
Отвечает за учет физической оперативной памяти. Отслеживает свободные/занятые фреймы (блоки по 4Кб) с помощью Bitmap (битовой карты). Выдает свободные фреймы по запросу (например, для запуска нового процесса).

### 2.3 Virtual Memory Manager (VMM)
Обеспечивает Пейджинг (Paging). 
Создает таблицы страниц для каждого пользовательского процесса, изолируя их адресные пространства. Преподносит иллюзию, что программа владеет всеми 4ГБ памяти, прозрачно маппируя виртуальные адреса в физические.

### 2.4 Драйверы Консоли (VgaDriver & KeyboardDriver)
Поскольку Qt больше нет, ОС общается с пользователем через прямое управление аппаратурой компьютера:
- `VgaDriver`: Пишет ASCII символы с аттрибутами цвета напрямую в физический адрес памяти `0xB8000`. Поддерживает обработку escape-последовательностей (`\n`, `\b`) и аппаратную прокрутку (hardware scrolling).
- `KeyboardDriver`: Подписывается на прерывание `IRQ1` в PIC (Programmable Interrupt Controller). При нажатии клавиши функция-обработчик считывает её *Scan Code* из I/O порта `0x60`, конвертирует в нажатие (Key Event) и передает диспетчеру `InputManager`.

### 2.5 Scheduler и Тики (Таймер)
Система работает на прерываниях аппаратного таймера PIT (Programmable Interval Timer) — прерывание `IRQ0`.
Каждый вызов таймера вызывает системный **TICK**. Планировщик сохраняет контекст текущего процесса на стек (EIP, ESP, общие регистры EAX-EDX) и загружает контекст следующего процесса из таблицы (PCB — Process Control Block).

---

## 3. Принципы проектирования

| Принцип | Значение |
|---------|-----------|
| **Panic** | В случае неразрешимой ошибки (General Protection Fault) ядро моментально печатает дамп регистров и останавливает железо (hlt). |
| **Freestanding** | Ядро не зависит ни от какой хостовой ОС (ни Windows, ни Linux). |
| **Monolithic** | Драйверы (`Keyboard, VGA, Disk`) компилируются в один бинарный `KERNEL.BIN`. |
| **C++ ABI** | Ядро поддерживает классы, наследование, виртуальные функции. Однако *Exceptions (RTTI)* обычно отключены из-за накладных расходов памяти. |