|
使用 {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相关
|
sbi指令相关
|
rust 内嵌汇编相关
|
|
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是
|
只读数据段 .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
|
|
|
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
|
|
|
|
|
|
|
Generated
2025-05-05 04:17:35 +0000
25bcfca-dirty
2025-05-04 14:47:56 +0000