引导与内核地基
12 项
引导链
已实测
UEFI 固件 → Limine 引导管理器 → initsoke.efi 引导加载器 → sptkrnl.elf 内核 → BSD 组件。initsoke.efi 自行读取 ESP 上的内核与 initrd、解析 ELF64、整块连续装载、建立恒等映射与 HHDM 与内核映像页表、采集内存图与 RSDP 与帧缓冲、退出引导服务,再按自研交接 ABI 跳进内核。
串口证据
- limine: Loading executable `boot():/boot/sptkrnl.elf`
- Physical base: 0x1bfb9000 Virtual base: 0xffffffff80000000
- Base revision: 6
内核入口与版本
已实测
冷入口设置 CR4 的 OSFXSR/OSXMMEXCPT 并执行 fninit,随后进入 kmain。版本号不在代码里写死,构建期由 version.toml 生成版本模块。
串口证据
- [snmk] long mode entry
- [snmk] SNMK KNRL_VER=0.3.1000.0 (edition preview)
引导事实收编
已实测
引导器响应块被收编成内核内部引导事实,HHDM 基址、内存图、可用页数、内核映像大小全部取自运行期而非编译期常量。
串口证据
- [snmk] loader: Limine 12.9.0
- [snmk] hhdm=0xffff800000000000 memmap=35 usable=115548 pages kernel_img=172 modules=1
- [snmk] kernel phys=0x000000001bfb9000 virt=0xffffffff80000000 rsdp=0xffff80001fb7e014
帧缓冲(如实记录)
已实测
记录引导器给出的 GOP 帧缓冲几何与通道掩码。当前 QEMU/OVMF 给的是 32bpp、每通道 8bit,日志照实写 8bit/channel —— 不把 32bpp 说成 10bit,全链路 10bit 尚未实现。
串口证据
- [snmk] fb: 1280x800 pitch=5120 bpp=32 8bit/channel masks r=8/16 g=8/8 b=8/0
物理页管理
已实测
从引导器内存图建立空闲页栈,内核拿到全部可用物理页。
串口证据
- [snmk] pmm: 115547 pages free
引导堆
已实测
内核早期阶段先上线 bump 分配器,供地基各子系统在真实分配器就位前使用。
串口证据
- [snmk] heap: bootstrap bump online (256 KiB)
虚拟内存
已实测
收编引导器页表建立内核地址空间,恒等映射、HHDM 与内核映像三段各就各位。
串口证据
- [snmk] vmm: kernel aspace online, cr3=0x000000001bf7c000 hhdm=0xffff800000000000
CPU 底盘
已实测
每 CPU 的 GDT/TSS/GS 就位,256 项向量 IDT 装载完毕,异常路径带自检(故意触发
串口证据
- [snmk] cpu: gdt/idt/tss ready
- [snmk] exc: #UD selftest ok
LAPIC 与抢占式调度
已实测
LAPIC 经显式 MMIO 映射上线,用 PIT 校准出真实频率后启动周期定时器,抢占式调度随之生效。
串口证据
- [snmk] lapic: online @ phys=0x00000000fee00000 virt=0xffffff0000000000 id=0
- [snmk] lapic: timer calibrated 627045 ticks/10ms (62704kHz)
- [sched] preemptive online
多核上线
已实测
AP 经 Limine 的 MP 服务启动并全部上线。注意这里只是上线,AP 上线后停在 hlt,不参与调度 —— 真 SMP 调度见「已知缺口」。
串口证据
- [snmk] smp: 4 cpu online (bsp_lapic_id=0)
HAL 分层
已实测
机器相关层独立成 hal/(内存、CPU、中断、时间、SMP、控制台),内核只保留策略。拆层前后串口证据逐条一致,属纯重构。
串口证据
- [snmk] vmm: kernel aspace online, cr3=0x000000001bf7c000 hhdm=0xffff800000000000
BSD 组件层
已实测
FreeBSD 15.1-RELEASE 源码子集作为 SNMK 内核内的组件层接入,libkern 编入 libbsd.a 并被内核链接,符号为上游原版。
串口证据
- [snmk] bsd: sysinit=0 modules=0
用户态
6 项
syscall 门
已实测
SYSCALL/SYSRET 已 armed。调用编号是六域单一来源 syscall.h,内核侧分发表由脚本在构建期生成,不手写第二份。
串口证据
- [snmk] syscall: gate armed, lstAr=0xffffffff80001138
- [snmk] syscall: dispatch self-test ok
ring 3 与 initrd
已实测
ELF64 装载器按 W^X 与 PTE_USER 装载用户程序,ustar initrd 提供首批服务 initd 与 logd,THREAD_SPAWN 让服务拉起服务。ring 3 的越权访问被内核拒绝而非静默放过。
串口证据
- [initd] ring-3 alive, tid=1
- [initd] 非法 fd 已被拒绝,返回=-22
- [initd] logd pid=2 spawned
用户态抢占
已实测
时钟节拍能从 ring 3 夺走 CPU,含 GS 交换、地址空间切换与异常帧回填。用户程序不主动让出也抢得走。
串口证据
- [initd] round 10
- [snmk] sched: preempt user pid=1 ticks=8
- [logd] 轮次跑完,转入静默常驻
Soke64 C ABI
已实测
纯 C ABI 头配 C++ 实现。syscall 指令在用户态只有一处,Zig 侧只做适配;调用编号与错误码同一份单一来源,内核侧表构建期生成。
串口证据
- [cxxprobe] C ABI 可用,tid=3
- [cxxprobe] Result 持有错误码=-22
C++ 用户态运行时
已实测
cxxrt 提供堆分配器、__cxa_atexit 与 __cxa_finalize 与纯虚兜底;链接脚本 KEEP 住 .init_array 并由 crt 显式遍历,全局构造器与析构器都能真正执行。
串口证据
- [cxxprobe] 全局构造器已执行(.init_array)
- [cxxprobe] 构造器写入的魔数=23063
- [cxxprobe] 全局析构器已执行(__cxa_finalize)
动态链接
已实测
ET_DYN 共享对象装载含按基址重定位与 W^X,DT_NEEDED 递归装载并去重,符号按名跨对象解析。四类重定位(RELATIVE / 64 / GLOB_DAT / JUMP_SLOT)已实现,其余类型显式报错 —— 不静默跳过。内核即装载器,不引入外部 ld.so。
串口证据
- [snmk] dynlink: lib libdlprobe.so base=0x0000200000000000 entry=0x0000200000000000
- [snmk] dynlink: objs=3 libs=2 relocs=12
- [dynprobe] dynamic link verified
发行与验证
3 项
.spk 包格式
已实测
容器为 ustar,含控制文件与载荷清单。键约束单一来源 schema/control.keys,内核常量由构建期生成;宿主 spkbuild.py 打包与校验做到字节可复现。内核解得开宿主打的包。
串口证据
- [snmk] spk: welcome-notes 1.0.0 x64 payload=data.tar.zst files=2
安装介质(ISO)
已实测
BIOS/UEFI 混合 ISO,介质名由版本单源给出,命名严格遵循规则 24。从 ISO 引导得到的证据与从 ESP 引导逐条一致。
串口证据
- Soke0_pre_0.3.1000.0_zh-CN_x64_v1.iso
验证门禁
已实测
串口证据断言(verify-serial.py 配 tools/expect/ 清单)与宿主机单元测试(zig build test)构成双门禁,任一条不中即非零退出 —— 门禁失败不会被当成通过。
这些证据是怎么来的
tools/start-soke.sh 跑一遍完整的构建 → FAT32 ESP 镜像 →
OVMF 无头启动 → 串口日志,然后由 tools/verify-serial.py
拿 tools/expect/ 下的清单逐条断言:某条证据必须出现,
且顺序不能倒退。任一条不中就非零退出,失败不会被当成通过。
清单里刻意不写死数值(页数、频率、CPU 数),只断言形态固定的串 ——
否则清单会变成拿环境差异当回归。