5.5 KiB
5.5 KiB
CPU подсистема: концептуальная модель
Состав и ответственность
CPU подсистема отвечает за:
- Обработку прерываний и исключений — IDT, обработчики.
- Исключения ранней загрузки — пока ядро ещё не полностью инициализировано.
- TLB Shootdown — межпроцессорное прерывание для синхронизации TLB.
- Local APIC — программируемый контроллер прерываний.
CPU Subsystem
┌─────────────────────────────────────────────────────────┐
│ CPU Core #0 │
│ │
│ ┌──────────────┐ ┌─────────────────────────┐ │
│ │ LAPIC │ │ IDT │ │
│ │ │ │ │ │
│ │ ICR ────────┼────────► 0: #DE (Divide Error) │ │
│ │ EOI │ │ 1: #DB (Debug) │ │
│ │ (timer) │ │ ... │ │
│ │ │ │ 8: #DF (Double Fault) │ │
│ │ │ │ 13: #GP (GPF) │ │
│ │ │ │ 14: #PF (Page Fault) │ │
│ │ │ │ ... │ │
│ │ │ │ 0xFD: TLB Shootdown │ │
│ └──────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Модули
| Файл | Компонент | Функция |
|---|---|---|
idt.rs |
IDT структуры | Определение IdtEntry, IdtPtr, InterruptDescriptorTable |
interrupts.rs |
Обработчики | Early handlers, Page Fault, Double Fault, GPF, TLB shootdown |
lapic.rs |
Local APIC | Инициализация LAPIC, EOI, broadcast IPI |
Порядок инициализации
kmain()
│
├── cpu::interrupts::init_early_exceptions()
│ └── IDT для векторов 0-31 + TLB shootdown (0xFD)
│
├── ... (PMM, LAPIC, Page tables) ...
│
├── cpu::interrupts::init_idt()
│ └── Перезагрузка IDT с полными обработчиками
│
├── STI (разрешение прерываний)
│
└── ... (работа с прерываниями)
Обработка исключений: два этапа
Этап 1: Early (до VMM)
На раннем этапе загрузки (до настройки page tables и heap) ядро
не может обрабатывать сложные исключения. Для векторов 0-31
устанавливаются early_handler_N, которые:
- Пушат вектор и (возможно) dummy error code.
- Переходят в
early_common. - Сохраняют все регистры.
- Вызывают
rust_early_exception_handler(vector, error_code). - Паникуют (HALT).
Этап 2: Полный (после VMM)
После инициализации VMM три критических исключения получают полноценные обработчики:
- Page Fault (#PF, вектор 14): попытка обработать (COW, lazy).
- Double Fault (#DF, вектор 8): HALT с сообщением.
- General Protection Fault (#GPF, вектор 13): HALT с сообщением.
- TLB Shootdown (вектор 0xFD): межпроцессорный TLB сброс.
TLB Shootdown: модель
При изменении page tables на одном ядре, TLB других ядер устаревает. Протокол:
CPU 0 (инициатор) CPU 1 (мишень)
│ │
├── local_tlb_flush_asid() │
├── SHOOTDOWN_LOCK.lock() │
├── SHOOTDOWN_ASID = asid │
├── SHOOTDOWN_ACK = 0 │
├── LAPIC: broadcast IPI │
│ (вектор TLB_SHOOTDOWN_VECTOR) ───► прерывание!
│ ├── handle_tlb_shootdown_ipi()
│ ├── local_tlb_flush_asid()
│ ├── SHOOTDOWN_ACK |= 1 << core
│ ├── LAPIC::send_eoi()
│ └── iretq
│ │
├── spin_loop() ◄────────────────────┤
│ (ждёт ACK от всех ядер) │
├── SHOOTDOWN_LOCK.unlock() │
└── continue │