rust的os的基础设施
branch ch1
使用 {no_std}
移除 {main}
_start作为入口
fn _start {
进行对各个段的打印 TODO
rust extern "C"语法
rust write_volatile
rust unsafe
.bss段需要清零
并sbi shutdown退出
}
定义panic handler
fn panic_handler {
通过location打印file,line TODO
rust location, file, line
sbi shutdown
}
定义sbi调用
asm sbi_call执行机器态sbi指令 TODO
riscv asm相关
li
ecall
x10-x17
sbi指令相关
SBI_CONSOLE_PUTCHAR=1
rust 内嵌汇编相关
inlateout
in
putchar用给println调用
shutdown用来关机
println
实现macro 调用宏format_args
实现Write trait
链接脚本ld
ld脚本,指导ld如何将.o和.a/.so组合成最终elf或bin
MEMORY定义物理内存属性(rw, BASEADDRESS,大小)
SECTIONS指定输入section(来自.o)
将多个.o的(比如1.0的.o和2.0的.o)根据ld脚本指示将sections合并
如何映射到输出
objdump -h filename.o
可以查看各个section的信息
符号
比如stext = . 可以在代码中通过extern引用这些地址 见main
从 BASE_ADDRESS 开始,
代码段 .text, text的开始结束address是
stext,etext
只读数据段 .rodata,
数据段 .data,
bss 段 .bss
设置了stack
本身bss 用于存放 未初始化的全局/静态变量
不占用可执行文件空间:
.bss 段在编译后的二进制文件中仅记录大小,不存储实际数据(因为未初始化变量默认值为零)。
运行时动态分配:
程序加载时,由启动代码(如 crt0)或内核为其分配内存并清零。
适合stack的需求
适合stack的本质需求
需要连续的内存区域:
栈通常是一块连续的内存,用于存储函数调用的返回地址、局部变量等
运行时动态增长
栈的大小在链接时确定,但实际使用是动态的(通过栈指针 sp 操作)。
无需初始化
栈空间在程序启动时才会被使用,
栈内存的初始值是无意义的(每次函数调用会覆盖原有内容)。
bss存储数据,如果在data里使用栈,栈会初始化0,导致二进制文件里大量0
由低到高依次放置
entry.asm
.bss.stack预留64k
作为os的stack空间
.section .bss.stack
.globl boot_stack
boot_stack:
.space 4096 * 16
.globl boot_stack_top 声明全局
boot_stack_top: 符号地址具体位置
stack top命名 boot_stack_top
stack bottom命名 boot_stack
_start作为入口地址
4_start:
5 la sp, boot_stack_top
6 call rust_main
第一条指令 la sp, boot_stack_top
第二 call rust_main
TODO
riscv sp
riscv la
riscv call
sp设置为boot_stack_top栈顶
调用rust_main
logging.rs
兼容log crate 方便打印
TODO boards/qemu.rs

Generated 2025-05-05 04:17:35 +0000
25bcfca-dirty 2025-05-04 14:47:56 +0000