LFS安装手记

说明 :
这里只对LFS的官方文档中没有详细阐述或有错误的操作步骤
,  命令等进行补充说明 ,  所以 ,  这不是一本LFS安装指南 ,  
只是自己在安装LFS过程中对LFS文档的一些补充
.
所以
,  请按照LFS的文档来安装LFS系统 ,  如果发现某个安装步骤在本文档中有描述 ,  请参照并以本文档为正确答案

=============================================================================================

1 .  LFS分区建立之前系统的分区情况 :

Disk 
/ dev / hda :   30.0  GB ,   30005821440  bytes
255  heads ,   63  sectors / track ,   3648  cylinders
Units 
=  cylinders of  16065   *   512   =   8225280  bytes

   Device Boot    Start       End    Blocks   Id  
System
/ dev / hda1    *           1         765     6144831      7   HPFS / NTFS
/ dev / hda2            766        3204    19591267 +    f  Win95 Ext ' d (LBA)
/dev/hda3          3205      3334   1044225   82  Linux swap
/dev/hda5           766      2373  12916228+   7  HPFS/NTFS
/dev/hda6          2374      3204   6674976   83  Linux

=============================================================================================

2. 创建分区
    fdisk /dev/hda
    键入m可以查看帮助, 键入p可以打印当前的分区表, 键入n可以新建一个分区, 键入w可以保存设置并退出, 键入q不保存设置退出
    第一部分就是键入p之后打印出来的结果
    键入n, 按照提示, 将未分配的2.4G的一个分区建立起来, 这里是/dev/hda4, 然后键入w
    重启系统, 键入mke2fs /dev/hda4, 格式化分区
    然后mount -t ext2 /dev/hda4 /mnt/lfs, 分区挂载完成
    此时的分区表如下:
    
Disk /dev/hda: 30.0 GB, 30005821440 bytes
255 heads, 63 sectors/track, 3648 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1   *         1       765   6144831    7  HPFS/NTFS
/dev/hda2           766      3204  19591267+   f  Win95 Ext
' d (LBA)
/ dev / hda3           3205        3334     1044225     82   Linux swap
/ dev / hda4           3335        3648     2522205     83   Linux
/ dev / hda5            766        2373    12916228 +     7   HPFS / NTFS
/ dev / hda6           2374        3204     6674976     83   Linux

=============================================================================================

3 .  动态加载器和标准连接器ld

动态加载器是用来寻找和加载共享库的
,  是Glibc的一部分; 标准连接器是binutils的一部分 ,  用来将目标代码obj和共享库 ,  静态库链接成可执行文件
所以
,  我的理解是 ,  标准连接器是用来生成可执行文件的 ,  而动态加载器是用来在执行可执行文件时 ,  将该可执行文件用到的共享库加载到内存的
在LFS的中文官方文档中
,  把动态加载器也称为动态连接器 ,  我个人十分不赞成这种说法 ,  因为这使我把这个 " 动态连接器 " " 标准连接器 " 混淆
称它为
" 动态加载器 " 更为确切 !

此外
,  在我的环境(RedHat9)下 ,  通过命令 readelf  - / bin / rmdir   |   grep  interpreter 看到 ,  我的动态加载器是  / lib / ld - linux . so . 2  

=============================================================================================

4 .  关于gcc的编译细节问题 ,  文档提到可以使用gcc  - v来查看 ,  这里写了一个helloworld ,  然后gcc  - v的结果如下 :

Reading specs from 
/ usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / specs
Configured with
:   ../ configure  -- prefix =/ usr  -- mandir =/ usr / share / man  -- infodir =/ usr / share / info  -- enable - shared  -- enable - threads = posix  -- disable - checking  -- with - system - zlib  -- enable - __cxa_atexit  -- host = i386 - redhat - linux
Thread model
:  posix
gcc version 
3.2 . 2   20030222  (Red Hat Linux  3.2 . 2 - 5 )
/ usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / cc1  - lang - - - D__GNUC__ = 3   - D__GNUC_MINOR__ = 2   - D__GNUC_PATCHLEVEL__ = 2   - D__GXX_ABI_VERSION = 102   - D__ELF__  - Dunix  - D__gnu_linux__  - Dlinux  - D__ELF__  - D__unix__  - D__gnu_linux__  - D__linux__  - D__unix  - D__linux  - Asystem = posix  - D__NO_INLINE__  - D__STDC_HOSTED__ = 1   - Acpu = i386  - Amachine = i386  - Di386  - D__i386  - D__i386__  - D__tune_i386__ hello . - quiet  - dumpbase hello . - version  - / tmp / ccm7oBng . s
GNU CPP version 
3.2 . 2   20030222  (Red Hat Linux  3.2 . 2 - 5 ) (cpplib) (i386 Linux / ELF)
GNU C version 
3.2 . 2   20030222  (Red Hat Linux  3.2 . 2 - 5 ) (i386 - redhat - linux)
        compiled by GNU C version 
3.2 . 2   20030222  (Red Hat Linux  3.2 . 2 - 5 ) .
ignoring nonexistent directory 
" /usr/i386-redhat-linux/include "
# include "..." search starts here:
#include <...> search starts here:

/ usr / local / include
/ usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / include
/ usr / include
End of search list
.
as 
- - Qy  - / tmp / ccGGN20C . / tmp / ccm7oBng . s
GNU assembler version 
2.13 . 90.0 . 18  (i386 - redhat - linux) using BFD version  2.13 . 90.0 . 18   20030206
/ usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / collect2  -- eh - frame - hdr  - m elf_i386  - dynamic - linker  / lib / ld - linux . so . 2   / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 /http://www.cnblogs.com/../ crt1 . / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 /http://www.cnblogs.com/../ crti . / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / crtbegin . - L / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2   - L / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 /http://www.cnblogs.com/..   / tmp / ccGGN20C . - lgcc  - lgcc_eh  - lc   - lgcc  - lgcc_eh  / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 / crtend . / usr / lib / gcc - lib / i386 - redhat - linux / 3.2 . 2 /http://www.cnblogs.com/../ crtn . o

注意上面倒数第三行有一段
:   - dynamic - linker  / lib / ld - linux . so . 2 ,  这就是将来可执行文件中动态加载器的定义所在 ,  这里也同时验证了LFS文档中的
一句话
:   " 对动态连接器的引用是作为硬路径嵌入每一个ELF共享程序中的,你可以用:'readelf -l <name of binary> | grep interpreter'来验证 "

=============================================================================================

5 .   " 在第二遍安装 Binutils时,我们可以利用--with-lib-path来控制ld的库搜索路径。从这里开始,核心工具链已经自给自足了。第五章的随后部份
    都会连接到/tools下的新Glibc上,这样就对了
"
    
说这句话的原因是
,  在第一遍安装binutils和gcc的时候 ,  所用的库都是原来系统的 ,  而当LFS自身的GLIBC安装完成后 ,  必须把binutils和gcc所使用到的库
都链接到这个新安装的GLIBC上
,  所以才需要安装第二遍binutils和gcc

另外
,  由于第一次 ,  gcc binutils glibc都会安装在 $LFS / tools目录下 ,  不符合UNIX系统的习惯 ,  所以当chroot之后 ,  就会重新安装glibc ,  将其放置到 / usr
目录下(
/ usr / include   / usr / lib) ,  此时 ,  gcc和binutils就可以按照缺省设置来再重新安装了 ,  不需要手动去改他们的安装配置了 ! 也给今后安装其他
所有软件都扫平了道路

=============================================================================================

6 .   " 将库文件中的函数连接到使用它们的程序中,有两种方法:静态连接或动态连接。当一个程序是静态连接时,它使用的函数会包含在可执行文件中,结果就是比较大的执行文件。当一个程序是动态连接时,可执行文件中包含的是针对连接器的引用,说明了要使用的库文件名称,以及使用的函数名称,结果就是执行文件要小多了。这个可执行文件在某种程度上比静态连接的要慢,因为在运行时连接要花一些时间。(还有第三种方法,是使用动态连接器的可编程接口,参见dlopen的man文档,以获得更多信息。) "

通过动态加载器的可编程接口
,  自己来装载动态库 !

=============================================================================================

7 .   "  su - lfs  "     " - "  让 su 命令启动一个新的,干净的shell .     第一次听说  " - "  还有这个作用

=============================================================================================

8 .  摘录了LFS文档中比较精采的一段 ,  特别是使用set  + h这个开关关掉bash的hash功能 ,  这一点很重要 ,  有时候改动了环境变量make仍然失败 ,  可能
    原因就在这了
:

当你是lfs用户的身份时,用以下命令来设置一个好的工作环境:

cat 
>   ~/. bash_profile  <<   " EOF "
set 
+ h
umask   022
LFS
=/ mnt / lfs
LC_ALL
= POSIX
PATH
=/ tools / bin : $PATH
export LFS LC_ALL PATH
unset CC CXX CPP LD_LIBRARY_PATH LD_PRELOAD
EOF

source 
~/. bash_profile

set 
+ h 关掉bash的  " hash " 功能。hash 通常是一个有用的特性,这时 bash 使用 hash 表(哈希表)来记住可执行文件的完整路径,以避免为了找到同一个文件而进行多次 `PATH '  搜索。然而,我们希望立刻就能使用新安装的工具。关掉hash功能,那些交互的命令(make,patch, sed,cp 等等)将总是使用新的程序。

把用户文件创建掩码(umask)设置为 022,保证新创建的文件和目录只能被文件的所有者执行写操作,而能被所有人读和执行。

LFS 变量自然要设置成你加载 LFS 分区的位置。

LC_ALL 变量控制某些软件包的本地化,使它们输出的信息遵守指定国家的规范。当你的主系统glibc版本低于2.2.4时,如果在第五章中把$LC_ALL设置成 "POSIX" 或 "C" 以外的值,当你退出第六章的chroot环境后,要再次进入就会有麻烦。设置成 "POSIX" (或"C",它们俩是相同的)我们保证在chroot环境中不会出现任何问题。

我们把 /tools/bin 附加到标准路径前面,是为了在安装过程中,总是能用到已经安装了的临时工具。

CC, CXX, CPP, LD_LIBRARY_PATH 和 LD_PRELOAD 环境变量都有可能破坏我们的第五章工具链,因此这里取消它们的设置,以预防可能的问题。

在用 source 命令读了刚才创建的设置文件后,我们已经准备好了,下面就开始编译下一章中要用到的临时工具。

=============================================================================================

9. 编译binutils-2.14的时间称为SBU时间, 在我的P10笔记本上耗时5分钟! 也就是说, 我的配置下, SBU时间是5分钟!

=============================================================================================

10. 在编译安装GLIBC的时候, 由于GCC3.3.1和GLIBC不兼容的缘故, 需要给GLIBC打个补丁才能正确编译, 这个补丁命令是:

    patch -Np1 -i ../glibc-2.3.2-sscanf-1.patch
    
    这里的patch命令, -N相当于--forward, 表示就算该补丁已经打过也照样再打, -p1参数的意思就是忽略掉后面补丁文件名路径中的第一个/
    如果是p3, 那就忽略掉三个/ ; 最后参数-i表示指定补丁文件名(含路径), 这里也可以不用-i参数, 使用<这个重定向符号, 也可以表示把补丁文件
    作为输入给patch, 如: patch -Np1 < ../glibc-2.3.2-sscanf-1.patch    

=============================================================================================

11. 在做GLIBC的测试套件时, 发生一个超时错误, 如下(当时网线没插):

GCONV_PATH=/mnt/lfs/sources/glibc-build/iconvdata LC_ALL=C MALLOC_TRACE=/mnt/lfs/sources/glibc-build/resolv/tst-leaks.mtrace  /mnt/lfs/sources/glibc-build/elf/ld-linux.so.2 --library-path /mnt/lfs/sources/glibc-build:/mnt/lfs/sources/glibc-build/math:/mnt/lfs/sources/glibc-build/elf:/mnt/lfs/sources/glibc-build/dlfcn:/mnt/lfs/sources/glibc-build/nss:/mnt/lfs/sources/glibc-build/nis:/mnt/lfs/sources/glibc-build/rt:/mnt/lfs/sources/glibc-build/resolv:/mnt/lfs/sources/glibc-build/crypt:/mnt/lfs/sources/glibc-build/linuxthreads /mnt/lfs/sources/glibc-build/resolv/tst-leaks  > /mnt/lfs/sources/glibc-build/resolv/tst-leaks.out
Timed out: killed the child process but it exited 0
make[2]: *** [/mnt/lfs/sources/glibc-build/resolv/tst-leaks.out] Error 1
make[2]: Leaving directory `/mnt/lfs/sources/glibc-2.3.2/resolv
'
make[
1 ] :   ***  [resolv / tests] Error  2
make[
1 ] :  Leaving directory ` / mnt / lfs / sources / glibc - 2.3 . 2 '
make: *** [check] Error 2

=============================================================================================

12. 在安装GLIBC的最后步骤, 如果运行了 make localedata/install-locales , 那么就不要运行下面的一堆命令了, 因为这个命令会install所有的locale信息.

=============================================================================================

13. LFS的文档上说, TCL的测试总是无法通过, 现实情况测试是, TCL的测试基本通过, 只有网络socket部分的测试没有通过, socket后续的测试没有完成, 
就被我ctrl-c了  :)

=============================================================================================

14. LFS文档中在安装TCL完成后, 提醒TCL的源码目录不要删除, 这是因为后面的expert软件需要用到TCL源码目录下的一些头文件, 这里给出验证:
在安装expert的第一步configure的时候, 输出中有这样一句:

checking for Tcl private headers... found in /mnt/lfs/sources/tcl8.4.4/generic

这就证明LFS的文档所言非虚了, 但是这个configure是如何知道到/mnt/lfs/sources/tcl8.4.4/generic目录下去找的, 这就不知道了

=============================================================================================

15. 在第二遍安装binutils时, 最后的时候有这样的一句:

make -C ld LIB_PATH=/usr/lib:/lib

这里的LIB_PATH的设定是为将来的LFS系统服务的, 因为将来的LFS系统的库都在/usr/lib和/lib下, 所以这里要设定好, 然后在将来安装LFS系统的时候
重新安装binutils, 从而使动态加载器能到/usr/lib和/lib下去找库, 从而和/tools/lib等tools下的目录脱离关系

=============================================================================================

16. 给目录权限设置sticky位, 是为了保证属于该用户的文件只能被该用户删除.
     通常用在一些对所有用户都开放权限的目录, 如/tmp, 由于这个目录所有的用户都有r w x的权限, 所以, 使用一个sticky, 可以保证一个文件不能被除
     所有者之外的其他用户删除!
     给目录或文件加sticky位, 在chmod时, 第一位设置成1即可, 如chmod 1777 /tmp
     
     给一个文件设置sticky位, 已经不常用了, 原本的意思是告诉内核, 对于这种文件, 运行时尽量让其保留在内存中. 现在已经基本不用了
     
=============================================================================================

17. 在chroot之后, 安装GLIBC时, 做make check测试套件时, 没有出现错误!   :)

=============================================================================================

18. 在LFS系统中安装coreutils时, 这句链接不知道是什么意思:  ln -s test /bin/[  
    [ 这个恐怕是在shell中用来代替test的??
    在RH9中查证, 发现还真有 [ 这个东东, 在/usr/bin目录下, 也是一个链接, 指向本目录下的test程序  :)
    
=============================================================================================

19. 在安装findutils时, 有这样一段描述, 却没有命令行, 不知应该怎么做才算正确:

"缺省情况下,updatedb 数据库的位置是 /usr/var.为了符合 FHS 规范,把它放在 /var/lib/misc/locatedb里,要把localstatedir=/var/lib/misc 参数传递给configure脚本. "

????     

我看了configure脚本, 看到 "localstatedir=
' ${prefix} / var ' ", 说明的确是这样, 所以, 我在configure命令行里这样加上了参数:

./configure --prefix=/usr --libexecdir=/usr/bin --localstatedir=/var/lib/misc
     
=============================================================================================

20. 每次重新chroot, 进入LFS环境时, 需要注意以下两点,非常重要!!

1. 每次chroot之后, 需要重新mount两个文件系统-proc和devpts。有的时候会发现这两个文件系统已经挂上了,没有关系,因为一个文件本身就可以被多次挂载,更何况这两个是虚拟文件系统,如果不放心,可以将他们都一直umount直到出错,然后再mount上去即可,mount完了记得用df -ah查看一下
2. 做完chroot和mount proc,devpts时, 我觉得应该做一下set +h, 来去掉bash的hash功能,这可以通过这个命令做到:exec /tools/bin/bash --login + h ,也就是说,做完chroot和mount之后,请运行这个命令。如果已经在第六章中将新的bash安装好了,那么,请运行 exec /bin/bash --login +h =============================================================================================    

21. 第六章里编译gcc时,有一处命令错误:

ln -s ../usr/bin/cpp /lib
其实就是在/lib下面创建一个cpp的链接,因为有些程序是硬到/lib下面去找cpp的。
这里../usr/bin/cpp不对,应该是/usr/bin/cpp,这个错误比较明显,危害不大,嘿嘿

 

你可能感兴趣的:(安装)