LFS(二)
LFS(二)
0.前言
前文接下来基础的环境基础准备,我们接下来就需要进行进一步的搭建,比如对前篇文章工具的利用
1.测试工具链
在Linux中,工具链是一种用于编译、链接和构建软件的工具集合,结合了编译器、汇编器、链接器和调试器等工具,将源代码转化为可执行的库文件,前面的四个库的安装和部署仅仅是为了给后续形成工具链而做足准备条件
1 |
|
1 |
|
正常来说,如果输出大致如下 [Requesting program interpreter: /tools/lib/ld-linux.so.2]则表示调整成功,我这里输出结果发现是空的,很离谱,首先思考是不是我的路径存在问题,首先查看linux.so.2是否存在
1 |
|
发现名字不一样,太可恶了,修改一下对应名称
1 |
|
为了防止再次出错,我们现在开始回头重新工具链接调整并且逐步验证,首先将/tools/bin目录下的ld文件重命名为ld-old
1 |
|
将/tools/$(gcc -dumpmachine)/bin目录下的ld文件重命名为ld-old,其中$(gcc -dumpmachine)是GCC交叉编译器的目标体系结构, 一般返回值为x86_64-pc-linux-gnu
1 |
|
将/tools/bin目录下的ld-new文件重命名为ld
1 |
|
在/tools/$(gcc -dumpmachine)/bin目录下创建一个指向/tools/bin/ld的符号链接
1 |
|
该命令将显示/tools/$(gcc -dumpmachine)/bin目录下的ld文件的详细信息,包括其权限、所有者和大小等。如果输出中包含指向/tools/bin/ld的符号链接,则说明ln命令已成功创建
从GCC交叉编译器中获取规范文件,并将其中的/lib/ld-linux.so.2路径替换为/tools/lib/ld-linux.so.2。前面也有so文件重新命名了
1 |
|
要检验命令是否成功,可以使用以下命令:
1 |
|
该命令将显示$(gcc -print-libgcc-file-name)/specs文件中包含/tools/lib/ld-linux.so.2路径的行。如果输出中包含该路径,则说明sed命令已成功替换规范文件中的路径。发现没哟反馈,查了一下,发现是没有specs文件,直接歇逼,这里touch一下再重新执行gcc命令
1 |
|
命令提示gcc:unrecognized option ‘-mtune=k8’,则可能是因为-mtune=k8选项不再被支持。-mtune=k8选项用于指定GCC编译器生成的代码针对AMD K8系列处理器进行优化。然而,该处理器已经过时,现代处理器通常使用更先进的架构和指令集。可以尝试将-mtune=k8选项替换为更适合当前处理器的选项,例如-march=native或者-march=x86-64。这些选项将根据当前系统的处理器类型自动选择最佳的优化设置
1 |
|
我觉得可能是我之前的版本安装不兼容的问题,gcc的这个报错有些解决不了,后面发现这里使用的是_64的lfslivecd,猜测这里是对应的包在编译安装时出现了指引问题,我接下里的想法是先将lfslivecd的版本退回,基本是能搞定的。
工具链的调整方法有好几种,而且不同版本GCC的specs可能会有不同,但实际上都是把specs文件中的/lib/ld-linux.so.2替换成了/tools/lib/ld-linux.so.2即可,所以这里出现问题倒也正常。
2.测试工具链调整(重整版)
对于前面的报错进行了检测和尝试,猜测API Header的编译安装版本问题,推荐使用Linux-2.6.22.5,但是64位的虚拟lfsfilecd只有Linux-2.6.22.1的版本,反倒不适用了,后续就出现了一系列的报错问题,接下来我将64位的虚拟机改为32位进行实验操作,前面的操作基本一样,除了磁盘命名的差异,在32位中磁盘命名为hdd,64位中的磁盘命名为had,修改对应名称的指令即可,以及在gcc的编译安装中不需要添加–disable-multilib的指令,我延续前篇日报的测试工具链调整
如前篇文章中提到,要检验命令是否成功,可以使用以下命令
该命令将显示$(gcc -print-libgcc-file-name)/specs文件中包含/tools/lib/ld-linux.so.2路径的行。如果输出中包含该路径,则说明sed命令已成功替换规范文件中的路径。这里终于也是输出了包含的该路径,说明命令操作成功
1 |
|
可以通过执行echo $GCC_INCLUDEDIR命令来检查GCC_INCLUDEDIR环境变量是否已经被成功取消设置。如果该命令返回空值,那么说明unset GCC_INCLUDEDIR命令已经成功运行并删除了GCC_INCLUDEDIR环境变
好咧,再次进行工具链的调整和尝试:
1 |
|
如果输出大致如下 [Requesting program interpreter: /tools/lib/ld-linux.so.2],则表示调整成功,因为所有的库已经连接到了/tools/lib下
测试成功后,由于内容空间有限,这里需要进行删除测试文件
1 |
|
构建交叉编译工具链的作用是为目标系统(即LFS系统)提供一个能够在主机系统上运行的编译器和相关工具,以便在主机系统上编译和构建LFS系统所需的软件包。由于主机系统和目标系统的硬件架构和操作系统不同,因此需要使用交叉编译工具链来进行编译和构建。交叉编译工具链通常包括binutils、GCC和Glibc等工具,它们可以将源代码编译成适用于目标系统的可执行文件和库文件,为后续的LFS系统构建奠定基础。
3.测试工具的安装
前面的测试仅仅是为了验证所有的库已经连接到了/tools/lib下,接下来就对于Binutils 和 GCC 等软件包套件的运行测试,为了支持本次测试,需要先安装Tcl、Expect 与 DejaGNU。只有运行了测试,才能确保重要工具的正常工作,因此这部分的测试尤为重要
Tcl是一种脚本语言,用于编写各种应用程序和工具,在linux系统中通常是被用作解释器语言,一达到编写shell脚本,自动化测试脚本,GUI界面等
1 |
|
这里的指令基本是认识的,除了make install-private-headers,该命令是Linux内核源码中的一个Makefile目标,它的作用是将内核的私有头文件安装到指定的目录中,这里是安装 Tcl 的头文件。下一个软件包 Expect 需要它们才能构建
上文提到Tcl 软件包包含工具命令语言,是一个可靠的通用脚本语言。Except 软件包是用 Tcl 语言编写的,因此需要先安装Tcl,接下来我们了解一下Expect,它是一种自动化工具,用于编写脚本来模拟用户与系统之间的交互,在Linux系统中,其通常是被用于自动化测试、远程登录、批量操作等场景
1 |
|
这里主要解析三个指令:
首先是patch –Np1 –i /lfs-sources/expect-5.43.0-spawn-1.patch,这个指令是应用了一个补丁文件到expect软件包的源代码中,也就是patch的作用,-N表示忽略已经存在的补丁,-p1选项表示去掉路径浅醉,-i则是指定要应用的不对文件,后续的/lfs-sources/expect-5.43.0-spawn-1.patch则是一个补丁文件的路径,包含了对expext软件包的修改内容
cp configure{,.bak}是将当前目录下的configure文件复制一份并将其备份为configure.bak文件,{,.bak}表示使用花括号扩展语法,将第一个参数(configure)扩展为两个参数(configure和.bak),从而实现同时复制和重命名的功能
sed ‘s@/usr/local/bin@/bin@’ configure.bak > configure则是表示将configure.bak中的/usr/local/bin替换为了/bin覆盖掉现有的configure文件,开头的s便是替换的操作符
DejaGNU也是一个自动化测试的框架,用于测试GNU工具集中的软件包,它可以在不同的操作系统和硬件平台上运行测试。其主要作用简化GNU软件包的测试过程,提高测试效率和准确性。其广泛应用于GNU工具集中的各种软件包的测试中,如GCC、GDB、Binutils等,这也就是我们为什么使用它的原因
1 |
|
安装成功后删除对应包的内容
1 |
|
首先前面提到了GCC-4.1.2-Pass 1的编译安装,这里是Pass2的编译安装。 在lfs的搭建过程中,Pass1和Pass2是两个不同的阶段,GCC-4.1.2 - Pass 1是第一个编译阶段,它的目的是为了生成一个能够运行在当前主机上的最小化版本的GCC编译器。这个编译器只能用于后续的构建过程,而不能用于实际的应用程序开发。在这个阶段中,GCC会被编译成一个静态链接库,以便后续的构建过程可以使用它来编译其他软件包
GCC-4.1.2 - Pass 2是第二个编译阶段,它的目的是为了生成一个完整的、可用于实际应用程序开发的GCC编译器。在这个阶段中,GCC会被编译成一个动态链接库,并且会包含所有必要的库文件和头文件。这个编译器可以用于编译和链接实际的应用程序
1 |
|
这里需要讲解一下的就是sed ‘s/^XCFLAGS =$/& -fomit-frame-pointer/‘ gcc/Makefile.in.tmp > gcc/Makefile.in,sed的使用,前文有了替换相关字符的案例讲解,这里是主要介绍’s/^XCFLAGS =$/& -fomit-frame-pointer/‘,s表示替换操作,^XCFLAGS =$:表示查找以”XCFLAGS =”开头,以”$”结尾的行,&表示匹配到的整个模式,-fomit-frame-pointer/则是要添加的选项
1 |
|
如果输出如下 [Requesting program interpreter: /tools/lib/ld-linux.so.2]
则表示调整成功,因为所有的库已经连接到了/tools/lib下。
1 |
|
4.其他基本软件包的编译和安装
继续编译和安装其他基本软件包,这些软件包提供了操作系统的其他重要功能,如文件压缩、文本处理、文件查找等。这些软件包将使我们的LFS系统更加完善和实用
Binutils的功能和使用的效果前文也进行了说明,pass1和pass2的区别和作用也可以类比于前者gcc的相关安装,这里就不就行细节的阐述了
1 |
|
Ncurses是一个用于开发文本界面的库,它提供了一组API,可以在终端中创建复杂的用户界面。使用Ncurses库,开发者可以创建菜单、对话框、文本框等控件,并实现键盘和鼠标事件的处理。Ncurses库还支持多种颜色和字符属性,可以让界面更加美观和易于阅读。Ncurses库被广泛应用于Linux和Unix系统中的命令行工具和图形化界面程序的开发
1 |
|
Bash是一种Unix/Linux操作系统下的命令行解释器,也是一种脚本语言。它可以执行用户输入的命令,并支持变量、条件语句、循环语句等基本编程结构,可以用于编写各种自动化脚本和任务。Bash还提供了丰富的内置命令和函数,可以方便地进行文件操作、进程管理、网络通信等操作。在Linux系统中,Bash通常作为默认的Shell
1 |
|
Bzip相比并不陌生,是一个用于压缩和解压缩文件的工具,它使用Burrows-Wheeler变换和霍夫曼编码算法来实现高效的数据压缩。是作为默认的压缩工具之一
1 |
|
Coreutils-6.9是一个包含了一系列基本命令行工具的软件包,它们是Linux和Unix系统中最常用的工具之一。这些工具包括cp、mv、rm、ls、mkdir、rmdir等,可以用于文件和目录的操作、文本处理、进程管理等任务
1 |
|
Diffutils是一个用于比较文件和目录之间差异的工具集合,它包括了diff、cmp、sdiff等命令。使用Diffutils-2.8.1,用户可以比较两个文本文件或目录之间的差异,并输出差异的详细信息。这些差异信息可以用于版本控制、代码审查、文件同步等任务。
1 |
|
Findutils是一个用于在文件系统中查找文件和目录的工具集合,它包括了find、locate、xargs等命令。通过Findutils,用户可以根据文件名、类型、大小、修改时间等条件来查找文件和目录,并输出它们的详细信息。这些信息可以用于文件管理、备份、恢复等任务。
1 |
|
Gawk是一种文本处理工具,它是GNU Awk的缩写。Gawk可以读取文本文件,并对其中的数据进行处理和分析。它支持多种操作,如字符串匹配、正则表达式、数学计算、数组操作等
1 |
|
Gettext是一个用于国际化和本地化支持的工具集合,它包括了gettext、msgfmt、xgettext等命令。使用Gettext,开发者可以将程序中的文本字符串提取出来,并进行翻译和本地化处理,以适应不同的语言环境
1 |
|
grep的作用就比较熟悉了,也是打交道较多的工具,用于文本搜索和过滤的命令行工具,它可以在文件中查找指定的字符串,并将包含该字符串的行输出到屏幕上。Grep支持多种搜索模式和选项,可以进行大小写敏感或不敏感的搜索,支持正则表达式等高级搜索功能。还嫩沟通过管道符号进行输入和输出的进一步传递
1 |
|
gzip是一个用于文件压缩和解压缩的命令行工具,它可以将文件压缩成gzip格式,并将压缩后的文件保存在磁盘上。gzip支持多种压缩级别和选项,可以根据需要进行不同程度的压缩和优化
1 |
|
make是一个用于编译源代码的命令行工具,它可以根据Makefile文件中的规则和依赖关系,自动化地进行编译、链接和生成目标文件等操作。Makefile文件通常包含了源代码的文件名、编译选项、依赖关系和目标文件等信息,用户可以通过修改Makefile文件来定制编译过程和生成不同的目标文件
1 |
|
Patch是一个用于文件补丁和更新的命令行工具,它可以将差异文件(patch文件)应用到原始文件中,以实现文件的更新、修复或修改等操作。Patch支持多种补丁格式和选项,可以根据需要进行不同类型的补丁操作。同时,Patch还可以与其他命令组合使用,例如通过管道符号将Patch的输出传递给另一个命令进行进一步处理
1 |
|
Perl是一种通用的脚本语言,它具有强大的文本处理和正则表达式功能,可以用于各种任务,例如系统管理、网络编程、Web开发等。Perl-5.8.8版本在其发布时是一个非常流行的版本,许多软件和工具都使用了它作为基础环境
1 |
|
Sed是一个文本处理工具,它可以在命令行中对文本进行编辑和转换。它支持多种编辑模式和选项,可以根据需要进行不同类型的文本处理操作,例如替换、删除、插入、移动等
1 |
|
tar是一个用于文件打包和解包的命令行工具,它可以将多个文件或目录打包成一个单独的文件,并将其保存在磁盘上。tar支持多种打包格式和选项,可以根据需要进行不同类型的打包和解包操作
1 |
|
Texinfo是一个用于文档编写和格式化的工具,它可以将纯文本文件转换成各种格式的文档,例如HTML、PDF、Info等。Texinfo支持多种标记语言和选项,可以根据需要进行不同类型的文档编写和格式化操作
1 |
|
util-linux 是一个开放源码的软件包,是一个对任何Linux系统的基本工具套件。 含有一些标准UNIX 工具,如login。 Util-linux 软件包包含许多工具。 其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器,打开tty 端口和得到内核消息
1 |
|
Stripping是指从可执行文件中删除不必要的符号信息和调试信息,以减小文件大小并保护代码的安全性。在编译生成可执行文件时,编译器会将一些符号信息和调试信息嵌入到文件中,这些信息对于调试和开发过程非常有用,但是在发布产品时却不需要这些信息。因此,通过使用strip命令可以去除这些信息,从而减小文件大小
1 |
|
接下来退出lfs用户
1 |
|
5.创建系统配置文件
通过前面的步骤,我们就把基本的软件包都编译安装完毕了,接下来就是配置系统的配置文件了,首先是重新设置目录权限
1 |
|
创建三个重要的目录,dev、proc和sys是Linux系统中的三个特殊目录,它们分别用于存储设备文件、进程信息和系统状态信息。
1 |
|
再创建两个目标系统所必须的设备文件
1 |
|
mknod -m 600 $LFS/dev/console c 5 1创建了一个名为console的字符设备文件,它的主设备号为5,次设备号为1。该设备文件通常用于控制台输出,即显示系统启动信息和用户登录提示等,第二个命令mknod -m 666 $LFS/dev/null c 1 3创建了一个名为null的字符设备文件,它的主设备号为1,次设备号为3。该设备文件通常用于丢弃不需要的输出,即将输出重定向到null设备文件中,从而实现“黑洞”效果
这里需要学习一下,之前没有接触过黑洞效果的概念,黑洞效果是指将输出重定向到一个特殊的设备文件中,从而实现“丢弃”输出的效果,在Linux系统中,null设备文件就是用于首先黑洞效果的一种常见方式,当程序输出内容时,如果将其重定向到null设备文件中,那么这些输出就会被直接丢弃,不会显示在屏幕上,也不会写入到文件中
利用主系统加载几个重要的文件系统
1 |
|
这里需要注意的是,当我们使用mount命令挂载分区时,操作系统会将该分区的文件系统信息保存在内存中。但是,当重新启动系统时,这些信息就会丢失,因为它们只存在于内存中,而没有被写入到磁盘上。因此,在重新启动系统后,之前挂载的分区就会失效,需要重新使用mount命令加载。
再接下来就是将lfs-sources里面的源码包复制到$LFS/sources目录中
1 |
|
Chroot到目标系统的目录
1 |
|
该命令将$LFS变量指定的目录作为新的根目录,并使用/tools/bin/env命令创建一个新的环境变量。然后,它设置了一些常见的环境变量,如HOME、TERM和PATH,并指定了一个新的提示符PS1。
最后,该命令使用/tools/bin/bash命令启动一个新的bash shell,并通过–login选项加载用户的配置文件。+h选项表示启用历史记录功能,即保存之前输入的命令,以便下次使用时可以调用
这时候,我们会在提示符的位置,发现“I have no name!”,这是正常的,当系统无法读取/etc/passwd文件中的用户信息时,就会出现提示符为“I have no name!”的情况,我们并没有设置,所以就是这种情况
这篇的内容大致上就在这里结束了,接下来就是建立目标系统的目录结构等相关内容了。