本章目的:
对内存进一步的管理,实现动态的分配和释放。
实现page级别的内存分配和释放。
内存管理分类
-自动管理内存-栈(stack)
-静态内存-全局变量/静态变量。放在数据段里面。
-动态管理内存-堆(heap)
内存映射表
堆的大小和起始地址,这些都是编译器的工作。
链接器脚本:决定了有哪些节,这些节放在什么位置上。
链接器脚本(Linker Script)
ENTRY
语法 | ENTRY(symbol) |
例子 | ENTRY(_start) |
-ENTRY命令用于设置“入口点”,即程序中执行的第一条指令。
-ENTRY命令的参数是一个符号(symbol)的名称。
OUTPUT_ARCH
语法 | OUTPUT_ARCH(bfdarch) |
例子 | OUTPUT_ARCH("riscv") |
-OUTPUT_ARCH指定输出文件所适用的计算机体系架构。
-是64位的riscv还是32位的不在这里体现,在"-march=rv32ima -mabi=ilp32"中指定。
-riscv64-unkonwn-elf- 中的64标识的是host是64位的。
MEMORY
语法 | MEMORY{ name[(attr)] : ORIGIN = origin, LENGTH = len } |
例子 | MEMORY{ rom(rx): ORIGIN = 0, LENGTH = 256K ram(!rx): org = 0x40000000, L = 4M } |
-MEMORY用于描述目标机器上内存区域的位置、大小和相关。
SECTIONS
语法 | SECTIONS{ sections-command sections-command ... } |
例子 | SECTIONS{ . = 0x10000; .text : { *{.text} } . = 0x8000000; .data : { *{.data} } .bss : { *{.bss} } } > ram |
-SECTIONS告诉链接器如何将input sections映射到output sections,以及如何将output sections放置在内存中。
-section-command除了可以是堆out section的描述外还可以是符号赋值命令等其他形式。
-“. =”中的"."表示的是当前位置,从这个位置开始就要访text节了。“ { *{.text} }”中的"*"是通配符,表示所有的输入的text节都放置于输出的text节内。之后指针往上移动到0x8000000的位置,开始放data节和bss节。
PROVIDE
语法 | PROVIDE( symbol = expression ) |
例子 | PROVIDE( _text_start = . ) |
-可以在Linker Script中定义符号(Symbols)
-每个符号包括一个名字(name)和一个对应的地址值(address)
-在这些代码中可以访问这些符号,等同于访问一个地址。
通过链接器脚本的符号获取各个output sections在内存中的地址范围,链接器脚本描述的信息: