Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68566
  • 博文数量: 10
  • 博客积分: 414
  • 博客等级: 一等列兵
  • 技术积分: 152
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-03 22:14
文章分类

全部博文(10)

文章存档

2012年(6)

2011年(4)

分类: LINUX

2012-06-13 19:58:01

最后的准备

关于$LFS

       贯穿这本书,环境变量LFS将被使用。从始至终定义这个变量是非常重要的。他需要被设置为选定的LFS分区的挂载点的值。检测LFS变量是不是被适当的设置了:

echo $LFS

       确保输出的信息显示LFS变量指向了LFS分区的挂载点,例如在随后的例子中提供的/mnt/lfs。如果输出是正确的,则变量将通过以下命令设置:

export LFS=/mnt/lfs

       设置这样的变量有利于命令的输入,例如我们可以输入mkdir $LFS/tools。当执行这条命令的时候shell将会把“$LFS”自动的替换成“/mnt/lfs”(或者无论这个变量设置成了什么)。

       不要忘了在你离开或者是重新进入工作环境(当使用su命令转到root用户或其他用户的时候)的时候检测$LFS变量是不是被设置了。

创建$LFS/tools目录

       所有在第五章中编译的包将被安装到/$LFS/tools目录中,以确保它们能独立于第六章中所编译的程序。在这里编译的程序只是临时工具,不会成为最终LFS系统的一部分。确保这些程序在一个独立的目录中,我们将更容易在使用后丢弃它们。这也可以避免这些软件出现在最终的产品目录中(This also prevents these programs from ending up in the host production directories)(在第五章中很容易做到)。

       使用root用户执行下边的命令来创建所需的目录:

mkdir -v $LFS/tools

       下一步是在宿主系统上创建一个/tools符号链接。这个链接会被指向新建立的LFS分区上的目录。使用root用户执行下边的命令:

ln -sv $LFS/tools /

注意

上边的命令是正确的。ln命令有几个语法差异,请在报告你认出错的地方时先查看coreutils ln的信息和l-n(1)

       我们所创建的符号链接使得工具链可以被编译,它总是指向/tools,这意味着编译器、汇编器和链接器将在第五章中协同工作(当我们让然使用来自宿主系统的工具时),下一部分也是这样(当我们“chroot”到LFS分区的时候)。

添加LFS用户

       当使用root用户登录系统后,一个很小的错误就可能损坏或破坏一个系统。因此,我们推荐在这一章中使用一个无特权的用户来编译这些包。你可以使用你自己的用户名,但要确保能够更容易的设置一个干净的系统,创建一个名为lfs的用户作为一新用户组的成员(通常也是lfs),并在执行安装操作的时候使用这个用户。使用root用户登录,通过执行下边的命令创建新用户:

groupadd lfs

useradd -s /bin/bash -g lfs -m -k /dev/null lfs

命令行选项的意思:

       -s /bin/bash

              设置bash作为新用户的默认shell

       -g lfs

              这个选项将lfs用户加入lfs用户组

       -m

              这个选项为新用户创建一个新的目录

       -k /dev/null

              这个选项通过把输入线路指向一个特殊的null设备来避免从预存文件夹复制文件的可能性。

       lfs

              这是新用户和用户组的真实名字。

       为了能够使用lfs用户登录(从root用户转换到lfs用户的时候lfs用户并不需要密码),要给lfs设置一个密码:

passwd lfs

       通过把$LFS/tools目录的拥有者修改成lfs来确保lfs用户对此目录的访问:

chown -v lfs $LFS/tools

       如果按照建议创建了独立的工作目录,将这个目录的拥有者设置成lfs

chown -v lfs $LFS/sources

       下一步,使用lfs用户登录。这可以通过一个虚拟控制台登录,通过显示管理器,或者使用下边的命令行:

su - lfs

       带有“-”的登录命令与不带这个选项的登录命令截然不同。它们之间的不同可以在bash(1)bash信息中找到。

配置环境

       通过为bash shell创建两个新的启动文件来设置一个好的工作环境。当使用lfs用户登录的时候,使用下边的命令创建一个.bash_profile

cat > ~/.bash_profile << "EOF"

exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash

EOF

       当使用lfs用户登录的时候,最初的shell通常是一个登录shell,它先读取了主机的/etc/profile(可能包含一些设置和环境变量)文件,然后读取.bash_profile文件。.bash_profile文件中的exec env -i.../bin/bash命令会将正在运行的登录shell更换成一个新的shell,这个shell除了HOMETERMPS1这几个环境变量之外不带有其它的变量。这将确保那些来自于宿主系统的不想要的或者是有潜在危险的变量不会被带进编译系统。我们在这儿所使用的技术已经能够确保构建一个安静的工作环境了。

       新的shell实例是non-login shell,它没有读取/etc/profile.bash_profile文件,但是已经读取了.bashrc文件了。现在创建.bashrc文件:

cat > ~/.bashrc << "EOF"

set +h

umask 022

LFS=/mnt/lfs

LC_ALL=POSIX

LFS_TGT=$(uname -m)-lfs-linux-gnu

PATH=/tools/bin:/bin:/usr/bin

export LFS LC_ALL LFS_TGT PATH

EOF

       set +h命令关闭了bashhash功能。Hashing通常是一个有用的功能——bash使用一个哈希表记住所有的可执行文件的目录,这样就避免了搜索PATH的时间并避免了重复查找相同的可执行文件。无论如何,新的工具在它们安装之后就将被使用。通过关闭hash功能,当运行程序的时候shell总会重新搜索PATHshell会找到在$LFS/tools中刚刚被编译的程序来运行,而不是运行那些存在不同地方的旧版程序。

       将用户的掩码(umask)设置成002以确保新创建的文件和目录只能够被它们的拥有者写入,但是可以被其他用户读取和运行(假设open(2)系统调用了默认的模式,新的文件权限将被设置成644,目录权限将被设置成755)。

       LFS变量需要被设置指向选定的挂载点。

       LC_ALL变量控制某些程序的位置,使得它们的信息能够符合制定国家的管理。如果宿主系统使用了一个低于2.2.4版的Glibc,把LC_ALL设置成“POSIX”或“C”之外的内容可能会在你离开chroot环境或回到这个环境的时候产生问题。把LC_ALL设置成“POSIX”或“C”(这两个是等价的)确保在chroot环境中所有的事情都能够按照预想的进行。

       LFS_TGT被设置成非缺省的,我们在编译我们的交叉编译器和链接器还有编译我们的临时工具链的时候会用到。更多的信息可以在5.2节中找到,“工具链技术说明”。

       通过把/tools/bin放在标准PATH的前边,shell程序会立即获得刚刚安装的程序。这个设置加上关闭了hashing功能,就避免了在第五章的环境中会使用到宿主系统中的老程序了。

       最后,为了准备好编译临时工具链的环境,加载刚刚配置的profile文件:

source ~/.bash_profile

关于SBUs

       许多人希望预先知道编译和安装一个包大约需要花多长时间。由于LFS可以在多种不同的系统上被构建,所以无法给出准确的估计时间。最大的包(Glibc)在最快的系统上大约需要花费20分钟,但是在一个速度很慢的系统上可能会花费3天的时间!我们将使用基础编译单位(Standard Build UnitSBU)代替估计时间。

       SBU测量的使用方式如下。我们要编译的第一个包是本书第五章里的Binutils。编译这个包所使用的时间将作为SBU的基础单位。所有的其它编译时间都相对于这个时间进行确定。

       例如,如果一个包的构建时间是4.5 SBUs,这就意味着如果系统花了10分钟来编译第一个包Binutils,则系统会花去大约45分钟来编译这个包。幸运的是,大多数的编译时间都小于Binutils的编译时间。

       一般,SBUs不会非常精确,因为它们将依赖很多的因素,包括系统中GCC的版本。他们在这里只给出了一个安装一个包的估计时间,但是时间的差值在某些情况下可能超过几十分钟。

       为了查看一些特定机器的确切时间,我们推荐你查看SBU主页

注意

对于许多的具有多处理器(或多核心)的现代系统来说,包的编译时间可以通过“并行编译”来减少,这可以通过设置一些环境变量或高速make程序有多少个处理器是可用的来完成。例如,Core2Duo处理器可以通过以下命令提供两个并发的编译过程:

export MAKEFLAGS='-j 2'

       或者只是在编译的时候加上下边的选项:

make -j2

       当通过这种方式使用并行处理的时候,在这本书中的SBU单元将比平时变化的更多。当然对编译过程输出文件的分析将变得更难,因为不同的编译行会被交错在一起。如果你在编译过程中遇到了问题,你就最好回到以前的用一个处理器变得过程中分析错误信息了。

关于测试套件

       许多的包提供了一个测试套件。为一个新编译的包运行这个测试套件是个很不错的想法,因为它可以提供一个“完整性检测”以确定每一个编译都被正确的编译了。一个测试套件通过它的对包的检测的设置通常能够证明编译后的程序能够按照开发者预计的运行。但是它不保证包没有漏洞。

       有一些测试套件比其他的更重要。例如, 用于核心工具链的测试套件——GCCBinutilsGlibc——因为它们在一个正常运转的系统中具有核心地位,所以它们非常重要。用于GCCGlibc的测试套件的测试过程要用很长时间才能完成,特别是在非常慢的硬件上,我们非常推荐你进行测试。

注意

经验表明在第五章中运行测试套件并没有什么效果。无法逃避的事实是,在这一章中宿主系统总是会给测试带来一些影响,经常会造成无法解释的失败。由于在第五章中编译的工具只是临时的,它们将在后边被丢弃,我们不推荐普通用户在第五章运行这些测试套件。这些测试套件是为测试人员和开发人员提供的,它们是完全可选的。

       一个常见的问题是,为GCCBinutils运行测试套件会耗尽终端(PTYs)。这将会造成大量的测试错误。这可能是由于多种原因造成的,但是最有可能造成这些错误的原因是宿主系统没有正确的配置devpts文件系统。有关这个问题的更多的细节在进行了讨论。

       有时候包的测试套件会测试失败,但是造成失败的原因开发人员都很清楚,或者这个原因根本不重要。查阅位于的日志文件,核实一下这些错误是不是我们预计到的会发生的错误。这个站点对于这本书中的测试都是有效地。

构建一个临时系统

介绍

       这一章展示了如何编译一个最基本的Linux系统。这个系统只是包含了那些足够用来在第六章中构建最终LFS系统的工具,这个系统所创建的工作环境比最小系统给更多的用户带来了便利。

       有两步完成这个基本系统的编译工作。第一步是构建一个新的独立于宿主系统的工具链(编译器、汇编器、链接器、库文件和一些有用的工具)。第二部是用这个工具链编译其它的基本工具。

       这一章中所编译的文件将被安装到$LFS/tools文件夹,这能够保证将这些文件独立于下一章中将要安装的文件以及宿主系统的工作目录。在这里将要编译的包都是临时的,我们不希望它污染接下来的LFS系统。

5.2 工具链技术说明

       这一个小节解释了在整体编译工程中有关编译方法相关的基本原理和技术细节。在这一个小节中你不必立刻弄明白所有细节。这些信息在正式的编译演示工程中将会更清晰。这一小节可能会在编译过程中被提及。

       第五章的目的就是创建一个空间,这个空间中将包含被正确配置的工具,而且这个空间使得之后的编译工作能够从宿主系统中分离出来。通过使用chroot,在接下来的章节中所使用的命令将会被包含到这个环境中,为了最终的LFS系统确保一个干净的、正确的编译环境。编译过程被设计的风险尽量小,这也是为方便新读者,另外这个编译过程同时有不少的教育价值。

重要

再继续之前,要知道工作平台的名字,这场被称为target triplet。一个确定target triplet的简单方法是运行随软件包源代码而附带的config.guess脚本。解压Binutils源代码,运行脚本./config.guess同时注意输出的内容。例如,对于一个现代的32Intel处理器,输出类似于i686-pc-linux-gnu

还要知道平台的动态链接起的名字,常被称为动态加载器(不要与Binutils中的标准的链接器ld混淆了)。动态链接器是由Glibc提供的,它将在一个程序加载共享库的时候被用到,为这个程序的运行做准备,然后再运行这个程序。一个32Intel机器的动态链接库将是ld-linux.so.2.有一个方法一定能够成功的获得动态链接器的名字,就是通过下边的命令检测一个宿主系统的二进制文件:readelf -l | grep interpreter,这个命令不会有输出。对应于所有平台的一个权威的参考信息被存储在Glibc代码树的root目录中的shlib-versions文件中。

阅读(2135) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~