编译过程及编译工具
目前正在学习gem5模拟器的一些内容,过程中遇到了很多问题,特别是有关编译器的问题和程序执行过程的问题,想要将部分内容记录下来,全是个人理解,有错误还请批评指正。
链接器的目的是将多个.o文件链接为一个文件的过程,而.ld文件或者称为链接脚本就是描述如何将这些输入(.o)文件映射为一个输出文件,一般是可执行文件。程序的执行过程大概如下图所示:
使用基于arm架构的交叉编译器 arm-none-eabi-
#交叉编译器的命名规则: arch [-vendor] [-os] [-(gnu)eabi] ,其中
arch 表示指令集体系结构,如ARM、MIPS、RISCV等
vecdor 表示工具链的供应商
os 表示目标操作系统
eabi 表示Embedded Application Binary Interface,即嵌入式应用二进制接口
比如:arm-none-eabi:这个是没有操作系统的,所以就不可能支持那些跟操作系统密切关联的函数,比如fork(2)。他使用的是newlib这个专用于嵌入式系统的C库
arm-none-linux-eabi: 用于linux的,使用Glibc库
之后在使用交叉编译器的时候,还有很多该交叉编译器下的各种编译工具和编译选项,对不同的交叉编译器而言,编译工具和编译选项基本上都是相同的,下面介绍一些比较重要的编译工具和编译选项
首先是编译工具,其中
-as 通常用于将汇编代码转换为目标文件
-ld 用于将多个目标文件链接成可执行文件或库文件
-gcc 用于编译C语言源代码文件
-g++ 用于编译C++源代码文件
-cpp 用于对源文件进行预处理
-ar 用于创建静态库文件
-nm 用于查看目标文件的符号表信息
-strip 用于去除目标文件中的符号表等信息
-objcopy 用于复制目标文件
-objdump 用于将目标文件反汇编为汇编代码。
然后是一些编译选项,这里将一些不同的编译选项进行了组合并赋予了新的自定义命名,读者可以格局需求自行组合与命名
-CFLAGS:指定C语言编译选项,包括调试信息开启、优化级别为3、链接unistd库、
包含当前目录等。
-CXXFLAGS:指定C++编译选项,与CFLAGS类似,但还包括禁用异常处理。
-ASFLAGS:指定汇编器选项,这里是指定为Little-endian模式。
-LNK_OPT:指定链接器选项,这里是禁用启动文件。
-LNK_SCRIPT:指定链接脚本文件为boot.ld。(这个boot.ld在后面会进一步讲)
-LNK_FILE_OPT:指定链接器选项,包括禁用启动文件和使用指定的链接脚本文件
其中-Xlinker 选项可以在编译过程中将参数传递给链接器,用于控制链接器的行为和
处理特定情况,从而影响最终生成的可执行文件或库文件的特性和行为。
.ld文件格式
先来看一个基本的.ld文件长什么样
ENTRY(_Reset)
SECTIONS
{
.text : {
. = 0x00000000;
boot.o (INTERRUPT_VECTOR)
*(.text)
}
. = 0x80000000;
.data : { *(.data) }
.bss : { *(.bss COMMON) }
. = ALIGN(8);
stack_base = .;
. = . + 0x1000; /* 4kB of stack memory*/
. = . + 0x1000; /* 4kB of stack memory for IRQ*/
PROVIDE (end = .) ;
}
可以看到,一个基本的.ld文件主要包括三个部分text段、data段和bss段,其中text段是用于存放程序的代码段,data段用于存放程序的初始化数据,而bss段存放的是未初始化的全局变量。下面解读一下.ld文件中的各行代码:
ENTRY(_Reset):
这里指定了程序的入口点为_Reset,即程序启动时首先执行的函数。
ECTIONS:
这个部分定义了不同的段(sections),如.text段、.data段、
.bss段等,用于存放程序的代码、数据和未初始化的数据。
.text : { ... }:
这里定义了.text段,其中包括程序的代码部分。
. = 0x00000000;将当前位置设置为0x00000000,然后
boot.o (INTERRUPT_VECTOR)将boot.o文件中的
INTERRUPT_VECTOR部分放在这个位置,*(.text)将所有的.text段内容放在这里。
. = 0x80000000;:
将当前位置设置为0x80000000,用于存放数据段。
.data : { *(.data) }:
定义了.data段,用于存放程序的初始化数据。
.bss : { *(.bss COMMON) }:
定义了.bss段,用于存放未初始化的全局变量。
. = ALIGN(8);: