要对内核进行页映射,首先要知道内核在内存中的位置和内核的大小。内核在内存中的位置很好知道,因为是启动代码拷贝进去的,而内核的大小就不好知道了,只有最后将各个obj文件组合成内核文件的ld命令才知道。而ld命令的命令行参数很难定义参数告诉代码,此时就需要链接器脚本linker script了。ld使用命令-T指定链接器
linker script功能很强大,可以告诉链接器应该怎么干活儿,除了告诉链接器起始代码地址在哪里,是什么样的cpu机器类型外,最重要的是告诉链接器各个文件的各个section应该怎么组合:应该从哪个地址开始放,各个section以什么顺序放,分别怎么对齐等等,最终组成输出文件的各个section
除此之外,linker script还可以定义各种符号,放到最终生成的符号表中。符号表是一堆符号的列表,每个符号包含了符号名字,符号所引用的内存地址,以及其他一些属性信息。符号本身不占用程序的任何内存空间,实际上就是一个地址的符号表示。
在C语言中,当定义一个变量时,实际上是做了两件事:1. 定义一个符号,最终放到符号表中,为其关联一个地址;2. 为这个变量分配一块儿内存空间,可以对其进行访问。举例来说:
int a;
a = 10;
printf("%d\n", a);
int *pa = &a;
int a;定义了一个变量,首先在符号表中创建符号a,保存a对应的地址,然后在内存空间中给a预留了一个int大小的空间,空间的地址由符号表中a对应的地址指定。
第二行a=10;是为符号a所代表的地址指向的int大小的内存空间赋值为10,第三行是引用符号a所代表地址指向的int大小内存空间中的数据。
第四行&a是直接从符号表中取符号a所对应的地址的值,该值与内存中的实际数据无关,在编译链接期间就可确定(当然,本例中a是局部变量,其地址还是运行期确定的,静态变量和全局变量的地址编译器确定)。
linker script中定义的符号,只是符号表中的一个符号,其没有对应的内存空间,只是表示了一个地址值。因此,如果在linker script中如此定义了两个符号:
.text :
{
_text_begin = .;
*(.text)
_text_end = .;
}
在代码中如下访问是错误的:
extern int _begin_text, _end_text;
int a = _end_text - _begin_text;
上面引用_begin_text和_end_text的方式是采用变量的访问方式,直接访问变量所对应的内存中的值,实际上这些符号在内存中没有对应的值。如下访问是正确的:
extern int _begin_text, _end_text;
int a = &_end_text - &_begin_text;
另外,数组名字实际上就是一个符号值,可以直接拿来使用,如下访问也是正确的:
extern char _begin_text[], _end_text[];
int a = _end_text - _begin_text;
分享到:
相关推荐
在链接器脚本(linker script)中,可以指定输入文件的 sections 到输出文件的映射,以及输出文件的 memory layout。这个脚本可以使用‘-T’命令行选项来指定。 arm-linux-ld 命令还可以生成 elf 文件,可以借助...
Set the name of the dynamic linker. This is only meaningful when generating dynamically linked ELF executables. The default dynamic linker is normally correct; don't use this unless you know wh
**Visual-Linker: Gnu Linker** 在深入探讨Gnu Linker之前,我们首先要理解链接器的作用。链接器是编程过程中的一个关键组件,它将编译器生成的多个目标文件(.o或.obj)合并成一个可执行文件或者库。在C++编程环境...
### 项目中的常见问题及其解决方案 #### 一、代码规范问题 在软件开发过程中,遵循良好的代码规范至关重要。这不仅能提高代码的可读性和可维护性,还能减少潜在的错误和冲突。 **解决建议:** ...
2. **编写User Command**:在Keil的“Target Options”-> “Post-Linker”选项卡中添加自定义命令行: ``` fromelf --bin --output ..\Obj\SmartSwitch.bin ..\OBJ\SmartSwitch.axf ``` 其中: - `--bin`表示...
5. **实测可用**: 提供者提到该编译链已经在德克萨斯仪器的OK系列(例如OMAP、AM系列等)上验证过,这意味着它可以成功编译并运行在这些硬件上的软件。 6. **应用范围**: 使用`arm-linux-gnueabihf`编译链的场景...
MinGW编译时报错: fatal error: -fuse-linker-plugin, but liblto_plugin-0.dll not found 时缺少的一个文件,将文件下载后放在C:\MinGW\libexec\gcc\mingw32\xxx目录下(xxx是你的g++版本号)下,问题即可解决
linux链接脚本lds解析
#### Linker 链接器选项用于控制最终可执行文件或库的生成过程,包括指定库文件的位置、符号表的处理方式等: - `-c`: 指定输出文件名。 - `-m`: 指定映射文件的路径。 - `-o`: 指定输出文件名。 - `-w`: 忽略警告...
- **源文件添加**:在MPLAB IDE中添加必要的Source Files和Header Files以及Linker Script。 ##### 5. 修改程序 - 对于源程序的修改主要是针对硬件差异的部分,因为所使用的CPU类型相同,因此只需对少数部分进行...
- Linker Version:编译器和链接器的版本信息。 - Image Base:程序在内存中的默认基地址。 - Section Alignment:节的内存对齐要求,影响文件和内存布局。 - File Alignment:文件在磁盘上的对齐方式。 - ...
The compiler system, featuring compiler, linker, assembler, resource Editor and a lot of useful tools
在win10下使用MinGW编译一个c++文件的时候莫名出现“g++: fatal error: -fuse-linker-plugin, but liblto_plugin-0.dll not found”,将这个dll放置在安装目录下,安装目录根据实际的来C:\MinGW\libexec\gcc\mingw32...
3. **预处理器选项**(Preprocessor Options)、**汇编器选项**(Assembler Options)、**连接器选项**(Linker Options)等未在给定内容中详细说明,但也是GCC的重要组成部分。 #### 五、结论 GCC作为一款开源的...
5. **expression** - 算式(运算式): 由一个或多个操作符和操作数组成的代码片段,产生一个值。 6. **function** - 函式: 执行特定任务的可重复使用的代码块。 7. **pattern** - 范式、模式、样式: 一种设计模式,...
- linker script:链接脚本,定义了内存分配和段设置。 - Makefile或Project Options:编译和构建配置。 5. 使用步骤: - 安装KEIL5并导入工程模板。 - 根据需求修改main.c和其他源文件。 - 设置目标板类型和...
sanity install @nacelle/sanity-plugin-pim-linker 证书 您需要提供与机舱空间关联的ID和令牌。 这些凭据可以在“找到。 您可以通过以下两种方式之一添加这些凭据: 在./config/@nacelle/sanity-plugin-pim-...
5. **Expression** - 算式(运算式):在编程中,表达式是能够产生值的语法结构,通常涉及运算符和操作数。 6. **Function** - 函式:执行特定任务的代码块,可以接受参数并返回结果。 7. **Pattern** - 范式、...