Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

uCore 实现

从 _entry 到 main,内核只需要一块可用的栈;完成输出与关机则依靠 SBI。以下代码来自 uCore 2026A 第一章。

入口与启动栈

entry.S 的 _entry 先把 sp 设为 boot_stack_top,再调用 main。boot_stack 与栈顶之间预留 64 KiB。

kernel.ld 将内核起始地址设为 0x80200000,各段按页对齐。启动栈位于普通 BSS 之前,因而清零 BSS 不会抹掉正在使用的栈。

清零与主函数

main.c 的 clean_bss 清零 [s_bss, e_bss)。随后 main 调用 console_init 并输出各段边界。本章的 console_init 为空,字符输出由 SBI 完成。

最后,main 执行 panic("ALL DONE"),由 panic 调用关机函数。本章的 threadid() 固定返回 0;进程与线程管理要到后续章节才引入。

输出与终止

printf.c 逐个处理格式字符,通过 consputc 输出。指针格式 %p 打印十六进制地址。

sbi.c 将服务号放入 a7、参数放入 a0 等寄存器,再执行 ecall。关机服务号为 8。沿着 printf → consputc → SBI 和 panic → shutdown → SBI 两条路径,可以看到同一套固件接口如何承担输出与关机。

运行观察

运行报告中的 ELF 各段边界如下:

区域地址区间
代码[0x80200000, 0x80201000)
只读数据[0x80201000, 0x80202000)
可写数据边界s_data = e_data = 0x80202000
启动栈[0x80202000, 0x80212000)
清零区间s_bss = e_bss = 0x80212000

s_bss 与 e_bss 相等,因此 clean_bss 的循环执行零次。进入 main 时 sp = 0x80212000,正好指向栈顶;调用 clean_bss 后,栈指针向低地址移动,为函数调用留出空间。

查看启动过程 · 录制信息