Linux内核是一个复杂的开源项目,主要的编写语言是C语言和汇编语言,因此,深入理解Linux内核的必要条件是熟悉C语言。Linux内核是由全球顶尖的程序员编写的,其中采用了众多精妙的C语言编写技巧,是非常值得学习的典范。
另外,Linux内核采用GCC编译器来编译,了解和熟悉GCC编译器以及GDB调试器的使用也很有必要。
Linux内核代码已经达到2000万行,庞大的代码量会让读者在阅读和理解代码方面感觉到力不从心,那在Linux中有没有一款合适的阅读和编写代码的工具呢?
由Linux内核创始人Linus开发的git工具已经在全球范围内被广泛应用,因此读者也必须了解和熟悉git的使用。
Linux常用的编译工具GCC。
GCC工具
GCC(GNU Compiler Collection)编译器在1987年发布了第一个C语言版本,它是用GPL许可证发行的自由软件,也是GNU计划的关键部分。GCC现在是GNU Linux操作系统的默认编译器,同时也被很多自由软件采用。GCC在后续的发展过程中,扩展支持了很多的编程语言,如C++、Java、Go等语言。另外,GCC还支持多种不同的硬件平台,如x86、ARM等体系结构。
GCC的编译流程主要分成4个步骤。
- 预处理(Pre-Process)
- 编译(Compile)
- 汇编(Assemble)
- 链接(Link)
如图2.1所示,用C语言编写test程序的源代码test.c。首先进入GCC的预处理器(cpp)进行预处理,把头文件、宏等进行展开,生成test.i文件。接下来,进入GCC的编译器,由于GCC可以支持多种编程语言,这里调用C语言的编译器ccl。编译完成之后生成汇编程序,输出test.s文件。在汇编阶段,GCC调用汇编器(as)进行汇编,生成可重定位的目标程序。最后一步是链接,GCC调用链接器把所有目标文件和C语言的标准库链接成可执行的二进制文件。
![407031a603b31157087010f96f7085fa.png](https://img-blog.csdnimg.cn/img_convert/407031a603b31157087010f96f7085fa.png)
图1.1 GCC编译流程
由此可见,C语言代码需要经历两次编译和一次链接过程才能生成可执行的程序。
1.1.2 ARM GCC
GCC具有良好的可扩展性,除了可以编译x86体系结构的二进制程序外,还可以支持很多其他体系结构的处理器,如ARM、MIPS、RISC-V等。这里涉及两个概念,一个是本地编译,另一个是交叉编译。
- 本地编译:在当前目标平台编译出来的程序,并且可以运行在当前平台上。
- 交叉编译:在一种平台上编译,然后放到另一种平台上运行,这个过程称为交叉编译。之所以有交叉编译,主要是因为嵌入式系统的资源有限,不适合在嵌入式系统中进行编译,如早期ARM处理器性能低下,要编译一个完整的Linux系统是不现实的。因此,首先会在某个高性能的计算机上编译出能在ARM处理器运行的Linux二进制文件,然后烧录到ARM系统中运行。
- 交叉工具链:交叉工具链不只是GCC,还包含binutils、glibc等工具组成的综合开发环境,可以实现编译、链接等功能。在嵌入式环境中,通常使用uclibc等小型的C语言库。
交叉工具链的命名规则一般如下。
[arch] [-os] [-(gnu)eabi]
- arch:表示体系结构,如ARM、MIPS等。
- os:表示目标操作系统。
- eabi:嵌入式应用二进制接口。
许多Linux发行版提供了编译好的ARM GCC的工具链,如优麒麟Linux 18.04上提供如下和ARM相关的编译器。
- arm-linux-gnueabi:主要用于基于ARM32架构的Linux系统,可以用来编译ARM32架构的u-boot、Linux内核以及Linux应用程序等。优麒麟Linux 18.04系统中提供了GCC 5、GCC 6、GCC 7以及GCC 8等多个版本。
- aarch-linux-gnueabi:主要用于基于ARM64架构的Linux系统。
- arm-linux-gnueabihf:hf指的是支持硬件浮点(Hard Float)的ARM处理器。在之前的一些ARM处理器中不支持硬件浮点单元,所以由软件浮点来实现。但是最新的一些高端ARM处理器内置了硬件浮点单元,这样新旧两种架构的差异就产生了两个不同的EABI接口。
1.1.3 GCC编译
GCC编译的一般格式:
gcc [选项] 源文件 [选项] 目标文件
GCC的常用选项如表1.1所示。
表1.1 GCC的常用选项
![4582e3e13d0d68c6bd26a2ff0bb0ddb2.png](https://img-blog.csdnimg.cn/img_convert/4582e3e13d0d68c6bd26a2ff0bb0ddb2.png)
![af3b25a9e578180289b460ee142a9b79.png](https://img-blog.csdnimg.cn/img_convert/af3b25a9e578180289b460ee142a9b79.png)
本文摘自《奔跑吧 Linux内核 入门篇》
![c9fc16d508ea3fd8627a18313480feb1.png](https://img-blog.csdnimg.cn/img_convert/c9fc16d508ea3fd8627a18313480feb1.png)
end
喜欢的朋友欢迎转发到朋友圈