os内核入门-linux0.11编译介绍

原创 thatway 那路谈OS与SoC嵌入式软件 2022-02-28 07:00

1. linux0.11编译过程与目标文件

系统的学习一个软件,做到可以移植参考,在某个电路板上运行起来,我觉得首要解决的问题就是编译的过程。弄清楚要在电路板上运行的二进制文件是由哪些源代码生成的,又是用什么编译工具生成的,了解了这些我们就可以造一个在电路板上运行的有OS的软件系统了,所有软件代码技术all in control
自主可控

很荣幸我们学习的这套linux0.11的源码就是全公开的,所以赶快开始研究一下吧。回顾一下我们编译运行的过程:

cd 0-prepEnv/hit-oslab-qiuyu/oslab/linux-0.11
make
../run

make后出现Image
表示编译成功,如下:

tools/build boot/bootsect boot/setuptools/kernel  > Image

Image目标文件

我们执行run命令的时候,虚拟机就运行起来了OS,先看下这个run,其实是一个shell脚本,vim run可以看到

$OSLAB_PATH/bochs/bochs-gdb-q -f $OSLAB_PATH/bochs/bochsrc.bxrc

bochs-gdb是一个x86硬件平台的开源模拟器,跟我们常用的Vmware和VirtualBox虚拟机一样,bochs运行对应的配置文件为bochsrc.bxrc

vim bochsrc.bxrc

floppya:1_44="$OSLAB_PATH/linux-0.11/Image", status=inserted

可以看到这里加载的二进制镜像文件就是Image

综上,编译产生的Image文件就是我们的目标文件,这个文件可以在虚拟机上运行,也就是说可以在实际的电路板上运行。下面我们先看一张图了解下这个Image是怎么产生的:

在编译的时候,最后可以看到:

cp -f tools/system system.tmp
strip system.tmp
objcopy -O binary -R .note -R .commentsystem.tmp tools/kernel
tools/build boot/bootsect boot/setuptools/kernel  > Image

首先把system文件复制了一份到system.tmp

strip
删除目标文件中的全部或者特定符号,这样可以减小可执行文件的大小。

objcopy -O binary
把目标文件system.tmp
的内容从
elf
文件格式变成kernel的二进制格式

build程序把boot/bootsectboot/setup tools/kernel这三个文件的执行头删除,然后把他们顺序组合在一起产生一个名为Image的二进制内核映像文件。

上面的打印,是通过什么源码产生的?

答案在编译工具make所使用的MakeFile文件

vim Makefile

Image: boot/bootsect boot/setuptools/system tools/build                                                                          
   cp -f tools/system system.tmp
   strip system.tmp
   objcopy -O binary -R .note -R .comment system.tmp tools/kernel
tools/buildboot/bootsect boot/setup tools/kernel $(ROOT_DEV) > Image

这个tools/build是什么?

vim Makefile

tools/build: tools/build.c                                                                                                        
gcc $(CFLAGS) \                                                                                 
-o tools/build tools/build.c
可以看到build程序是由tools/build.c编译来,也就是作者自己写的一个c程序,后面章节详细介绍。  

2. 编译过程和make工具


上面的分析可以看到目标文件**Image**是由Makefile里面的代码规定怎么生成的,下面先介绍下makefile,对编译链接有一个基础的认识。  

什么是make工具和makefile?

这里用到的make工具也叫GUN make,是一个开源命令工具,他解释了makefile中的指令。在makefile文件中描述了整个工程所有文件的编译顺序、编译规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。  

Make工具是告诉了怎么干活,具体干活还是要靠编译器。上面说到build程序把boot/bootsect boot/setuptools/kernel这个三个程序文件变成了一个,其中boot/bootsect boot/setup本身就是汇编语言,就使用**8086的汇编器**进行汇编和链接,tools/kernel是c源码使用GUN出品的开源编译器**gcc**进行编译。你一定对这个过程比较好奇吧,请往下看:  

程序编译目标程序的过程是什么?

预处理 ----> 编译 ----> 汇编 ----> 链接

1)
预处理

在该阶段,编译器将C源代码中的包含的头文件如stdio.h添加进来

如果单独执行此步骤,我们使用参数:”-E”

用法:gcc -E hello.c -o hello.i

作用:将hello.c预处理输出hello.i文件。

2)
编译

在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把c的高级语言代码翻译成低级的汇编语言。

如果单独执行此步骤,我们使用参数:”-S”

用法:gcc –S hello.i –o hello.s

作用:将预处理输出文件hello.i汇编成hello.s文件。

3)
汇编

把汇编语言书写的代码转换为机器可识别的机器指令(二进制)。编译后产生的机器指令文件(在linux中默认后缀为“.o”)虽然可被机器识别,但是还不能被执行。

如果单独执行此步骤,参数:“-c”

用法:gcc –c hello.s –o hello.o

作用:将汇编输出文件hello.s编译输出hello.o文件。

4)
链接

将多个目标文件,或者目标文件和库文件链接称为可被操作系统执行的可执行程序。链接器不检查函数所在的源文件,只检查所有目标文件的定义的符号。将目标文件使用的函数和其他目标或者库文件中的相关符号进行合并,并对所有文件中的符号进行重新安排,并连接系统相关文件最终生成可执行程序。

如果单独执行此步骤,参数:“-o”

用法:gcc hello.o –o hello

作用:将编译输出文件hello.o链接成最终可执行文件hello。

研究程序研究到二进制也算到头了。二进制怎么给cpu运行,可以学习下微机原理知识,这里不展开说明了。

静态库

在链接阶段,会将汇编生成的目标文件.o与引用到的库(linux下.a文件,windows下.lib文件)一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

动态库

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。

什么是elf可执行文件?

编译完成后的目标文件一般是一个elf (Executable and Linkable Format)文件,比如**tools/****system**  

就是一个elf可执行文件。再比如gcc hello.c –o hello的目标文件hello或者a.out都是elf文件,elf文件是可以运行的。我们打开一个elf文件可以看到ELF字样:

但是其他部门我们直接是看不到内容的,这里有一个工具:

readelf -a a.out

读出目标文件max.o的ELF Header和Section Header Table

另外Linux下的反汇编命令:

objdump -d a.out >hello.txt

它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。

更多ELF知识参考:https://blog.csdn.net/daide2012/article/details/73065204

objcopy -o binary什么是binary文件?

这里所谓的“二进制”,英文称为raw binary。这种程序只包含**机器码**。而ELF程序还包含有其它额外的信息,如段的加载地址,运行地址,重定位表,符号表,执行ELF程序则需要一个ELF Loader。Linux内核启动的时候往往是没有ELFLoader的,所以,只能采用raw binary格式。所以**Image**就是一个binary文件。  

后记:

linux  

知识是有点多,随便写点都又超篇幅了,但是能学到的东西也多。
Makefile
文件的具体分析放在下次文章里面,然后尽快进入内核源码分析。

linux0.11学习系列,纯干货分享,无广告,不打赏。欢迎转载,欢迎评论交流!

往期链接:

os内核入门-linux0.11运行环境搭建

os内核入门-linux0.11诞生的故事和源码初探

results matching ""

    No results matching ""