|
|
| 使用 {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