ITEEDU

Linux系统学习基础

第一章 开发工具学习

第二章 Linux内核制作

第三章 initramfs制作

第四章 Linux系统制作原理

第五章 文件系统启动方式配制

制作Linux的核心问题:根目录冲突(ld-linux.so位置)

由查找共享库的过程我们知道,链接器ld-linux.so的位置是写死在程序中的,那么写入的链接器的路径到底是怎么确定的呢?

在程序的编译过程中,gcc和binutils会查找C库中的头文件和共享库,链接器也是在编译过程中查找到的。至于是gcc还是binutils做的这工作我也不清楚,不过gcc和binutils一定是依赖于同一个C库的,搜索的也是同一个C库,所以不用考虑也可以。但一定要知道它们搜索的是哪个C库。

问题的产生

由于我们制作的linux是在源系统中的一个文件夹中的,而我们编译出来的程序的链接器还要指向目标系统的C库,这就导致了程序中写入的链接器的路径含有了目标系统所在文件夹这一部分,但这是不对的。

例如我们把/mylinux当做制作系统的根目录,先编译一个glibc在/mylinux文件夹中,再将工具链调整指向/mylinux中的glibc,之后编译的程序就都指向了/mylinux中的glibc

可是制作的系统中的程序的链接器就变成了/mylinux/lib/ld-linux.so.X了。这样我们把/mylinux中做好的系统放到一 个分区中启动时,由于没有/mylinux/lib/ld-linux.so.X这个链接器,所有程序都会因为找不到共享库而不能运行(静态编译的除外)。

如果你编译过lfs,那你制作的tools和上面的/mylinux是一样的,其中的程序的链接器为/tools/lib/ld-linux.so.2。你可以用ldd命令看一下。

这个问题可以总结为链接器写入程序的路径是相对于根目录的,而我们制作的系统不能占有根目录,而造成链接器的位置编译和运行时不一致。