Files
Elyz/kernel/docs/cpu/introduction.md
2026-07-07 16:40:41 +03:00

5.5 KiB
Raw Permalink Blame History

CPU подсистема: концептуальная модель

Состав и ответственность

CPU подсистема отвечает за:

  1. Обработку прерываний и исключений — IDT, обработчики.
  2. Исключения ранней загрузки — пока ядро ещё не полностью инициализировано.
  3. TLB Shootdown — межпроцессорное прерывание для синхронизации TLB.
  4. 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, которые:

  1. Пушат вектор и (возможно) dummy error code.
  2. Переходят в early_common.
  3. Сохраняют все регистры.
  4. Вызывают rust_early_exception_handler(vector, error_code).
  5. Паникуют (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                         │