summaryrefslogtreecommitdiff
path: root/docs/specs/global_init.md
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
commit8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch)
treeaa739deaac0266f17c4e91b333957501cb1ea2e9 /docs/specs/global_init.md
parent3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff)
downloadlume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.gz
lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.xz
Remove old code
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'docs/specs/global_init.md')
-rw-r--r--docs/specs/global_init.md208
1 files changed, 0 insertions, 208 deletions
diff --git a/docs/specs/global_init.md b/docs/specs/global_init.md
deleted file mode 100644
index cd14dae..0000000
--- a/docs/specs/global_init.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# 全局初始化序列 (Global Initialization)
-
-## 1. 目标 (Objective)
-
-统筹 LumeOS 从汇编跃迁至 C++ 后的全局初始化流程。定义子系统间的严格启动顺序、全局对象的生命周期管理范式、以及 BSP/AP 的两阶段同步协议。
-
-## 2. 前置依赖 (Dependencies)
-
-- **汇编环境契约:** 依赖 `linker_and_entry.md` 保证的执行环境:BSS 段已被清零、高半区虚拟内存(`early_pgdir`)已映射、`tp` 寄存器已保存当前 CPU ID、`gp` 寄存器已就绪。注意:`early_cpp_init()` 已在 `entry.S` 中由 BSP 调用完毕(在 `kernel_main` 之前),不在本模块的管辖范围内。
-
-- **全局基础契约:** 依赖 `00_conventions.md` 中禁用了 C++ 异常与 RTTI 的环境。
-
-- **并发同步契约:** 依赖 `spinlock.md` 提供的 `Spinlock`(但在 BSP 独占期不使用)。
-
-
-## 3. 核心数据结构与生命周期范式 (Data Structures & Lifecycle)
-
-在内核早期,物理内存管理 (PMM) 和字节级分配器 (Slab) 尚未就绪,传统的 `new` 和隐式的全局构造函数极易引发缺页崩溃或顺序未定义行为。
-
-### 3.1 显式生命周期模型 (Placement New 范式)
-
-对于所有复杂的内核全局单例(如 `PhysicalMemoryManager`, `Scheduler`),**严禁**直接定义为全局变量依赖 `.init_array` 隐式构造。必须采用以下静态缓冲区分配 + 显式 Placement New 的范式:
-
-```cpp
-// 示例:kernel/mm/pmm_global.cc
-
-// Placement new 声明(freestanding 环境无 <new> 头文件,自行提供)
-// 定义于 include/lume/new.h
-inline void* operator new(size_t, void* ptr) noexcept { return ptr; }
-inline void operator delete(void*, void*) noexcept {}
-
-// 1. 在 .bss 段静态分配对齐的内存区块,不触发任何构造函数
-alignas(PhysicalMemoryManager) uint8 g_pmm_buf[sizeof(PhysicalMemoryManager)];
-
-// 2. 暴露全局指针供外部访问
-PhysicalMemoryManager* g_pmm = nullptr;
-
-// 3. 在 kernel_main 的严格时序中被显式调用
-void pmm_init(uint64 fdt_paddr) {
- // 使用 Placement New 在预分配的内存上执行构造函数
- g_pmm = new (g_pmm_buf) PhysicalMemoryManager(fdt_paddr);
-}
-```
-
-**关于 `<new>` 头文件:** 在 `-ffreestanding -nostdlib` 编译环境下,`<new>` 可能不可用或行为不一致。LumeOS 在 `include/lume/new.h` 中自行提供 placement new 声明,不依赖任何标准库头文件。
-
-### 3.2 简单数据结构的按需初始化
-
-对于没有复杂依赖的 Plain Old Data (POD) 或简单锁对象:
-
-- `Spinlock` 等对象直接作为 BSS 段全局变量,由 `entry.S` 清零。随后在所属子系统的 `init()` 方法中调用 `lock.init("name")` 赋予身份。
-
-### 3.3 `.init_array` 的使用边界
-
-`early_cpp_init()` 在 `entry.S` 中遍历 `.init_array`。只有满足以下**全部**条件的全局构造函数才允许出现在此表中:
-
-- 构造函数不依赖任何子系统(PMM、Slab、VMM、Scheduler 均未初始化)。
-- 构造函数不分配动态内存。
-- 构造函数不获取任何锁。
-
-实际上,应该尽量让 `.init_array` 为空。绝大多数全局对象应走 §3.1 的 Placement New 路径。
-
-
-## 4. 公共 API (Public APIs)
-
-### 4.1 内核 C++ 唯一入口
-
-```cpp
-// 定义于 kernel/main.cc
-// 被 entry.S 中的 real_start 在开启 MMU、调用 early_cpp_init 后跳转
-// 所有 CPU 从此入口进入 C++ 世界
-// a0 = cpu_id, a1 = fdt_paddr
-extern "C" void kernel_main(uint64 cpu_id, uint64 fdt_paddr) __attribute__((noreturn));
-```
-
-### 4.2 子系统初始化签名规范
-
-所有子系统的初始化入口必须遵循统一签名,并在 `kernel/main.cc` 内部按图谱依次调用。每个 `xxx_init()` 函数成功时无返回值,失败时直接 `kernel_panic()`:
-
-```cpp
-void console_init(); // 1. UART 就绪,此后 kprintf/kernel_panic 可输出
-void fdt_init(uint64 fdt_paddr); // 2. 解析 FDT,构建设备节点表
-void pmm_init(); // 3. 从 FDT 获取内存布局,建立 Buddy 分配器
-void slab_init(); // 4. 建立 kmem_cache,此后 operator new 可用
-void vmm_init(); // 5. 建立精细化内核页表,废弃 early_pgdir
-void trap_init(); // 6. 设置 stvec,注册 IRQ 分发器
-void plic_init(); // 7. 配置 PLIC 中断控制器(阈值、优先级、使能位)
-void timer_init(); // 8. 配置定时器中断(调度器时钟源)
-void sched_init(); // 9. 构造 BSP 的 Idle Task 和初始就绪队列
-```
-
-### 4.3 AP 初始化签名
-
-AP 在 BSP 完成全局初始化后执行,仅限 Per-CPU 私有数据:
-
-```cpp
-void vmm_init_ap(); // 切换 satp 至 BSP 建好的内核页表
-void trap_init_ap(); // 设置本 CPU 的 stvec
-void plic_init_ap(); // 配置本 CPU 在 PLIC 上的 Context 使能
-void timer_init_ap(); // 启动本 CPU 的定时器中断
-void sched_init_ap(); // 初始化本 CPU 的 O(1) 就绪队列、创建 Idle Task
-```
-
-## 5. 并发与锁契约 (Concurrency & Locks)
-
-这是整个内核生命周期中**唯一一段不受自旋锁约束的特殊时期**,必须严格遵循以下阶段隔离:
-
-### 5.1 两阶段同步协议
-
-LumeOS 启动过程中存在**两个独立的同步屏障**,不要混淆:
-
-| 同步点 | 位置 | 变量 | 含义 |
-|--------|------|------|------|
-| 第一道 | `entry.S` (汇编层) | `boot_sync_flag` | AP 等待 BSP 建立 `early_pgdir`,完成后所有 CPU 齐步进入虚拟地址空间 |
-| 第二道 | `kernel_main` (C++ 层) | `ap_boot_sync` | AP 等待 BSP 完成全部子系统初始化,完成后 AP 开始 Per-CPU 初始化 |
-
-### 5.2 绝对单核期 (BSP 独占)
-
-- 在 `kernel_main` 启动初期,AP 卡在第二道屏障 `ap_boot_sync` 处自旋。
-
-- BSP 拥有对全局数据结构的**绝对独占权**。在此期间调用 `pmm_init`、`vmm_init` 等函数时,**无需获取该子系统的 `Spinlock`**(也不应获取,因为锁可能尚未初始化)。
-
-### 5.3 多核唤醒与并发期 (AP 启动)
-
-- BSP 完成所有全局初始化后,通过 `__atomic_store_n(&ap_boot_sync, 1, __ATOMIC_RELEASE)` 唤醒 AP。`RELEASE` 语义保证 AP 读到 `ap_boot_sync == 1` 时,所有全局单例对象必然已构造完毕。
-
-- AP 进入后,**只能执行 Per-CPU 的局部初始化**(如设置自身的 `stvec`、初始化 PLIC Context、创建 Per-CPU Idle Task)。
-
-- 一旦 AP 的 Per-CPU 初始化完成并开启中断,所有子系统对全局数据的访问必须严格遵守 `spinlock.md` 契约。
-
-
-## 6. 错误路径 (Error Paths)
-
-初始化阶段的错误处理极度苛刻:
-
-- **console_init 之前的 Panic:** 此时 UART 尚未就绪,`kernel_panic()` 无法输出任何信息。唯一行为是关中断 + `wfi` 死循环(静默死亡)。可通过 JTAG/GDB 附加调试。
-
-- **console_init 之后的 Panic:** 可输出 Panic 消息和调用栈信息后死循环。
-
-- 任何子系统的 `init` 方法如果检测到硬件缺失(如 FDT 解析不到内存节点)或关键资源耗尽(Slab 无法建立早期缓存),必须**立即调用 `kernel_panic()`**。
-
-- 此阶段系统尚未具备任务调度与资源回收能力,无后路可退。
-
-
-## 7. 状态机 / 时序图 (State Machine / Sequence)
-
-### 7.1 全局初始化依赖 DAG 图
-
-`kernel_main` 必须严格按照自顶向下的单向依赖顺序执行,任何逆序调用将导致 `kernel_panic` 或缺页崩溃。
-
-```
- entry.S (汇编世界)
- │
- early_cpp_init() ← 遍历 .init_array (应尽量为空)
- │
- ════════════════
- kernel_main()
- ════════════════
- │
- ┌─────────────┴──────────────┐
- │ │
- [BSP (cpu_id == 0)] [AP (cpu_id != 0)]
- │ │
- 1. console_init() 自旋等待
- └─ UART 就绪 ap_boot_sync == 1
- └─ 此后 Panic 可输出 │
- │ │
- 2. fdt_init(fdt_paddr) │
- └─ 解析 FDT 设备树 │
- │ │
- 3. pmm_init() │
- └─ Buddy 分配器就绪 │
- │ │
- 4. slab_init() │
- └─ operator new 可用 │
- │ │
- 5. vmm_init() │
- └─ 完整内核页表就绪 │
- └─ 废弃 early_pgdir 恒等映射 │
- │ │
- 6. trap_init() │
- └─ stvec 挂载 trap_vector │
- │ │
- 7. plic_init() │
- └─ PLIC 中断控制器就绪 │
- │ │
- 8. timer_init() │
- └─ 定时器中断就绪 │
- │ │
- 9. sched_init() │
- └─ Idle Task (Task 0) 创建 │
- └─ Per-CPU 就绪队列初始化 │
- │ │
- ──[RELEASE 屏障]──────────────────> 读到 1
- ap_boot_sync = 1 │
- │ 1. vmm_init_ap()
- │ 2. trap_init_ap()
- │ 3. plic_init_ap()
- │ 4. timer_init_ap()
- │ 5. sched_init_ap()
- │ │
- ▼ ▼
- arch::cpu::intr_on() arch::cpu::intr_on()
- BSP 变为 Idle Task AP 变为 Idle Task
- 进入调度循环 进入调度循环
-```
-
-**BSP 进入调度的方式:** BSP 在 `sched_init()` 中将自身的执行上下文注册为 CPU 0 的 Idle Task (Task 0)。开启中断后,第一个定时器中断触发调度器接管执行流。不是通过 `sched_yield()` 主动让出,而是被定时器中断被动抢占进入调度循环。 \ No newline at end of file