免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6782 | 回复: 4
打印 上一主题 下一主题

[内核入门] 理解LFS工具链的建立和些许疑问,望牛人解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-19 09:58 |只看该作者 |倒序浏览
本帖最后由 hugh556606 于 2013-07-19 10:01 编辑

Description:
起因: 最近在按照LFS-6.3的版本构建自己的Linux OS
        参照的教程是:http://www.adintr.com/myarticle/aslinux_p003.html,官方的文档也可以.都差不多,不过前者更贴近实际的操作.
在构造Linux 操作系统的过程中,要构造交叉编译工具链,GCC,bintuils,Glibc被重复编译了多次,不明缘由,在chinaunix上找到了相关的解释,但有些问题还是不明白.
找到的相关解释:
LFS的目标是完全从源代码构造一个“独立的”和“纯净的”的Linux系统。
如果只是编译内核和需要的工具,也是能启动的,但是却引入了太多的host上的“元素”。
包括链接库的代码,编译过程中使用的工具,环境变量等等

首先构造一个干净的、不依赖于host系统的、能够自己自足的工具链,然后使用我们自己构造的工具链取代host系统中的工具来编译剩余的系统。
LFS-BOOK的作者这样说:“我们相信,对阅读LFS BOOK的人来说,如何创建一个正确的工具链是最应该知道的。其他的都是第二位的。”

在Linux系统中,一个工具链主要包括binutils, gcc, glibc。首先编译了binutils(Pass1)和gcc(Pass1)。尽管在Pass1中,这两个工具包是链接到host系统的共享链接库上去的,但已经是由我们自己的源码包编译来的。另外值得注意的是,在Pass1的gcc编译中使用了make bootstrap,这意味着gcc源码将被重复编译三遍,其中第二遍和第三遍使用第一遍编译得到的二进制gcc,并比较第二遍和第三遍编译的结果,一次来保证编译器自身编译的正确性。
接下来就是编译一个临时的glibc。这是一个Linux系统的核心,它将被后面的几乎每一个软件包所使用。为了在接下来的编译过程中使用这个glibc取代host系统的glibc,这里需要对工具链做出正确的调整,使ldscript和gcc specs文件中的链接路径指向我们新编译的glibc所在的位置。
这样,接下来编译的binutils(Pass2)和gcc(Pass2)将被连接到刚才编译得到的glibc上面。至此,已经得到了一个独立于host系统的工具链。在第五章剩余的部分,我们将使用这个工具链编译出一个可以用于chroot进去的独立的工作环境。


为了创建一个干净的工作环境,在宿主系统中新创建一个lfs用户组,并添加了lfs用户,在安装过程中将一直使用该用户。
首先编译Binutils ,这时是使用宿主系统的环境。毫无疑问现在利用Binutils生成的程序会受到宿主系统的影响。例如:使用生成的ld(标准连接器)程序将会连接到默认的/lib目录(宿主系统)下的二进制文件。
然后编译Gcc,仍然需要宿主系统的环境。显然Gcc也受宿主系统的影响,这可以从它的编译来看,它依赖的是宿主的Glibc,而Binutils可以使用刚生成的。Glibc提供了动态连接器,用来找到并加载一个程序运行时所需的共享库,在做好程序运行的准备之后,运行这个程序。此时生成的Gcc会使用/lib(宿主系统)下的动态连接器,而不是$LFS/tools/lib下的。
通过上面两步,我们就可以使用刚生成的bintuils和Gcc来编译Glibc了。现在我们将bintuils、Gcc和Glibc都重新编译了一次。接下来就要通过调整工具链来解决刚提到的两个问题。一是重新编译ld,将ld连接到$LFS/tools/lib下的函数库。二是调整动态连接器,修改Gcc的SPEC文件,将动态连接器连接到/tools/lib/ld-Linux.so.2(ld-Linux.so.2是动态连接器的名字)。
到这里看似可以编译其它的工具了,但是接下来的工作并不是如此,而是再次编译了bintuils和Gcc,然后用第一次生成的Glibc和现在生成的bintuils、Gcc来编译其它的工具,整个临时环境才搭建成功。
这里有个问题是为什么要将Bintuils和Gcc编译两次,可以直接用宿主系统?第一次编译bintuils和Gcc的目的一方面是为了编译Glibc;另一方面是为了能自己编译出第二遍的Gcc,即使得Gcc是自我编译的。如果直接使用宿主系统可以满足编译Glibc的要求,但是Gcc就不是自我编译了。这里为了保证制造的正确性以及使Gcc是自我编译,所以Binutils和Gcc比其它的工具都多编译一次。
接下面其它工具的编译都是使用第二次编译的Binutils和Gcc以及第一次编译的Glibc。至此,工具链就准备好了,我们可以利用这些工具生成最终的系统。同样最先生成的软件还是Binutils和Gcc,不过在编译它们之前,我们先编译出Glibc,它也是我们最终需要的C库。再次调整工具链,让随后编译的工具都连接到这个库上。不难理解,在前面的调整中我们将工具链使用的库从宿主系统转向新安装的库目录。同样,现在将工具链所使用的库从临时的库转向LFS系统最终的库目录。

问题:
(1) 在红色标记的内容
在Pass1的gcc编译中使用了make bootstrap,这意味着gcc源码将被重复编译三遍,其中第二遍和第三遍使用第一遍编译得到的二进制gcc,并比较第二遍和第三遍编译的结果,一次来保证编译器自身编译的正确性。
-->为何使用了make bootstrap,就意味着gcc要被重复编译三遍?
(2) 海绿色标记的内容
它的意思可以用下图来描述

意思就是说第二次编译的Binutils和GCC以及第一次编译的Glibc构成了我们所需要的工具链,可以利用这些工具生成最终的系统.
接下来,用这个工具最先编译的是Glibc,然后是Binutils和GCC,于是,第三次编译的工具链理所当然的就成为了最新的工具链,用这些工具链去编译其它的软件.为什么用第三次编译的工具链?我以为第三次编译的工具链是作为目标系统的工具,是在目标机上使用的编译工具,在构建目标系统的时候应该用第二遍的.
(3) 大家有没有发现,第(1)和第(2)描述的流程是不一样的
第(1)点是第三遍和第二遍都是由第一遍编译出来的,而第(2)点,是第三遍由第二遍得来,第二遍由第一遍得来,不知道哪个是正确的

论坛徽章:
0
2 [报告]
发表于 2013-07-23 09:37 |只看该作者
1)为何使用了make bootstrap,就意味着gcc要被重复编译三遍?
这个没什么说的,make bootstrap就是这样做的

2)为什么用第三次编译的工具链?
考虑到从x86到arm系统的交叉编译工具链,需要三步才能完成

3)显然是1->2->3

论坛徽章:
0
3 [报告]
发表于 2013-08-06 16:27 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2018-07-26 14:53 |只看该作者
加油
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP