论文部分内容阅读
摘要:LFS是近几年逐渐流行起来的一种制作Linux系统的方法,它以完全DIY的方式让使用者打造属于自己的Linux系统。虽然LFS手册已经提供了非常详尽的制作流程,但LFS的初学者如果仅仅依靠这种手把手式的操作很难了解到LFS的核心思想,这和LFS的设计目的是背道而驰的。文章简单介绍了LFS的框架以及在使用过程中需要注意的问题,使初学者能理清LFS制作过程的大致思路,顺利完成LFS的第一次安装。
关键词:LFS;Linux;工具链:glibc
引言
从Linux诞生以来,它的发展非常迅速,迄今已经有300多个Linux发行版。国外的Fedora(原RedHat)、Debian、SUSE、Gentoo,国内的红旗、Magiclinux已经成为Linux的中坚力量,IBM、SUN、Intel等厂商也表示出对Linux的浓厚兴趣,加大了资金投入。目前Linux在服务器市场和Unix、Windows Server三分天下,市场占有率年年攀升;在嵌入式系统中Linux逐渐显示出它稳定、高效、易定制、易裁减、硬件支持广泛等优势,成为嵌入式操作系统中的一支主流;而在桌面应用方面,Linux也慢慢缩短了与Windows之间的差距,在易用性、娱乐等方面都有很大改进,随着XGL的推出,Linux已经能实现效果非常出色的3D桌面。正因为Linux的应用范围不断扩大,影响不断加深,有越来越多的计算机爱好者开始表现出对Linux的兴趣。在这些Linux爱好者之中,已经有不少人不满足于使用Linux完成日常工作,而更关心是否能建立一—个为自己量身定制、所有部件都在自己掌控之中的Linux,这就是LFS。
1 LFS的意义
目前Linux的发行版大致可以分为两类:以Fedora、SUSE等为代表的二进制发行版,这些版本是目前Linux的主流,特点是不需要编译就可以运行,安装时间短、操作简便;另一种是以源码方式发行的Linux,据笔者所知目前只有Gentoo,特点是在安装过程中需要全部或部分编泽软件包,但由于编译过程中编译器会针对本机的硬件进行优化,所以运行速度要稍微快一点。
LFS的全称是Linux From Scratch,LFS也不属于任何一类。可以理解为从无到有的Linux,它不是一种Linux发行版,而是一份手册(确切的说是一种思想),它是指不用任何预先编译好的软件包,也不用安装基本系统的CD-ROM或启动盘,而利用现有的Linux系统开发自己定制的系统。这个系统的所有设置都可以根据自己的需求和偏好来设定,同时在满足自己需求的基础上也是相当精简的。
可能对于大部分电脑用户来说,使用LFS是一种浪费时间的行为,但有两类人比较适合使用它:
(1)对Linux的编译、组成有强烈兴趣的人。这些Linux爱好者对操作系统的内部结构非常着迷,不满足于使用市面上任何一种Linux发行版,而打算构建自己的Linux。LFS能让用户对系统有更多的控制,不依赖于他人的Linux来实现,并可以掌控系统的每一个细节,比如目录布局和启动脚本配置等。最重要的是,这个通过LFS建立起来的Linux无论用来做什么,和其他Linux发行版相比肯定是最精简的,因为这个Linux中的所有部件都是由自己编译,每安装一个软件都需要自己审核。这和目前大部分Linux发行版“打包”式的安装方式完全不同,更加适合Linux发烧友的胃口。
(2)打算比较完整地了解Linux构成的初学者。它可以帮助人们学习Linux系统内部是如何工作的。构建一个LFS系统会帮助初学者了解Linux是如何运转,各部件是如何有机的结合在一起工作的。本文的主要对象就是这些LFS初学者。
2 使用LFS所需具备的基本条件
在使用LFS之前,对于初学者来说Linux相关的一些基础知识是必须具备的:
(1)能较为熟练地使用一种shell(推荐用bash)。这是最起码的要求,否则在Linux中就寸步难行。至少会使用ls、mkdir、cp等基本命令,对输入输出重定向也应该非常清楚。
(2)掌握tar及压缩工具(bzip2、gzip)的用法。因为几乎所有的源码都是经过压缩的tar格式的文件。
(3)需要知道Linux分区的结构,根目录的各个子目录的用途。
工欲善其事,必先利其器。如果已经具备了Linux基本知识,请到LFS官方网站(WWW.1inuxfromscratch.org)下载LFS手册和LiveCD,目前已经有不少国内的LFS爱好者对LFS手册做了汉化,也可以到国内的Linux社区(如WWW.1inuxsir.org)中下载LFS手册中文版。需要说明的是,LFS的目的是通过已存在的Linux的系统(宿主系统)建立一个自己的系统,而LFS的LiveCD就是一个可以通过光盘启动的宿主系统。理论上任何宿主系统都可以使用LFS,但由于各方面的原因(如发行版现成的编译器、连接器等工具的版本不匹配,某些发行版在Linux系统中加入了些不兼容的功能)导致某些宿主系统使用LFS的失败率很高,因此还是推荐LFS的初学者使用LiveCD。
3 LFS构建Linux的思路
虽然相关手册已经对LFS操作步骤描述的很详细了,但如果仅仅是简单地根据手册上的说明操作,那只会停留在知其然而不知其所以然的地步,达不到剖析Linux结构的目的。因此在使用LFS之前,大致了解一下LFS的原理是十分必要的。
首先介绍一下在Linux中关于依赖的概念。大家都知道在Windows中有许多后缀名为dll的动态链接文件,这些文件向运行于Windows操作系统下的程序提供代码、数据或函数。在Linux中也有许多这种文件,它们之间有错综复杂的依赖关系,大多数Linux发行版都提供了包管理器(如Fedora的RPM、Debian的APT),用来管理程序和程序之间的依赖关系。在使用LFS的过程中,本质上要解决的就是依赖问题。我们使用LFS就是要建立一个“纯净”的,不依赖于宿主系统的操作系统,我们称之为目标系统。这里所说的不依赖于宿主系统可以简单地理解为目标系统中所有的程序都不“受制于”宿主系统中的程序,否则宿主系统中的某个软件一有变动都可能导致目标系统无法使用。正因为有这个限制,我们不能直接用宿主系统来编译目标系统,因为编译的过程中将用到许多宿主系统的库,直接编译的目标系统会依赖于这些库。
在Linux中非常重要的glibc库,是提供系统调用和基本函数的c库,所有动态连接的程序都要用到它,它是LFS制作过程中的关键环节。在Linux平台下大部分程序是动态连接的,比如要使用vi,它依赖于glibc和ncurses,而ncurses又 依赖于glibc。因为几乎所有的程序都依赖于glibc,所以,在目标系统中必须先把glibc编译出来,才能保证目标系统的“自给自足”。
但是目标系统的glibc可以由目标系统的编译器来编译吗?不行。因为我们必须保证编译Gilbc的编译工具和和目标系统中依赖于glibc的编译工具版本是一致的。但一般情况下,目标系统中各种工具的版本总是高于宿主系统中的版本。因此得先建立一个临时编译环境,这个环境包含了gcc、binutils、make等各种必需的和编译有关的工具,它们的版本必须和目标系统中工具的版本完全一致,我们把这个临时环境称为工具链(toolchains)。通过工具链先制作目标系统中的glibc以及各种必需的编译工具,接着就可以把编译其他软件的工作从工具链逐步转移给目标系统,整个目标系统编译完成后就可以直接删除工具链。
问题是这个工具链由谁编译出来?这个任务只能由宿主系统来完成,通过宿主系统提供的编译工具可以制造出一个工具链。但因为要保证工具链依赖的glibc和工具链所生成的glibc是一致的,制作工具链的过程中不能直接使用宿主系统中的glibc,需要先制作一个临时的、和目标系统匹配的glibc供工具链使用。
表面上看起来问题已经解决了,但宿主系统可以直接编译一个供工具链使用的glibc吗?个别情况下是可以的,但在LFS中不提倡这么做。因为这里存在一个问题,不同版本的gcc编译出来的程序可能会不一样,而宿主系统和工具链中gcc的版本未必是相同的,这样会导致宿主系统直接编译出来的glibc对于工具链来说有可能不能用。所以应该先由宿主系统编译一遍gcc和binutils,使它们的版本和工具链中的版本一致,再由新的gcc和binutils参与glibc的编译。
图1是LFS的流程简图,其中虚线箭头是指工具对glibc的依赖。从图中可以看出,要制造一个不依赖于宿主系统的目标系统,首先要做一个工具链,通过工具链来编译目标系统中的程序。我们得先制作一个临时的glibc,通过这个glibc编译出来的工具链可以脱离对宿主系统中glibc的依赖。把宿主系统完全编译出来后,删除工具链即可。
4 使用LFS过程中需要注意的情况
LFS手册已经提供了非常详尽的操作流程,因此本文对具体的操作过程不再赘述,但对于接触Linux时间不是很长的人来说在还存在某些“陷阱”,有些甚至可能会造成致命的错误。这里简单总结一下安装过程中可能会遇到的问题并对需要注意的地方加以分析,使大家在学习LFS的过程中避免花费不必要的时间和精力。
(1)由于编译Linux需要很长时间,第一次安装请用LiveCD作为宿主系统,并请完全按照手册上的步骤来操作,在编译过程中不要对任何参数进行修改,也不要从网上下载最新的源码来代替LiveCD中的源码,否则稍有不慎就会前功尽弃。因为安装LFS的过程中需要编译大量软件包,这些软件包之间有着错综复杂的依赖关系,使用最新版本的gcc未必能保证一些软件顺利通过编译。在对LFS的安装步骤比较熟悉并清楚各个软件包的依赖关系之后,再用其他Linux发行版作为宿主系统,到那时可以根据自己需要选择各种软件最新的源码并进行优化。
(2)在使用LFS的过程中,了解每一步骤的具体含义是十分必要的,因为安装LFS除了能了解Linux的基本结构外,另一个收获就是能掌握大量Linux的常用命令并能灵活运用。但是在安装过程中,将会出现不少对于初学者来说难以理解的语句,特别是调整工具链等过程会出现Perl语言。如果对这些语句不是很熟悉的话,很有可能少输或错输一个字符而误删除了已经辛辛苦苦编译了几小时甚至十几小时的目标系统。另外,由于错输字符而导致的问题的“潜伏期”可能会很长,特别是调整工具链过程中的隐患往往到LFS整个编译工作的结尾阶段才会体现出来。因此如果对Perl不是很熟悉的话,建议大家可以暂时不理会这些语句的具体含义,直接将它们复制下来并运行,只要知道这些语句所起到的作用就可以了。当然,Perl是很重要的脚本语言,在Linux中几乎无处不在,回过头来还是应该掌握它的基本内容的。
(3)大部分LFS的初学者是采用LiveCD作为启动光盘并在该系统下进行LFS的安装的。LiveCD中的桌面环境十分有限,而整个编译过程又相当耗费CPU资源,在这十几个小时(甚至几十个小时)中几乎无法做其他工作,如果能了解编译每个软件所需要的时间,就可以更合理地进行安排。由于硬件配置存在差别,每台电脑编译软件所需要的时间不可能完全相同,因此LFS中提出了一个SBU(标准编译时间单位)的概念。编译Binutils软件包所花费的时间就是1单位的SBU,对于一个编译时间为4.5 SBU的软件包,这意味着如果一个系统静态编译安装Binutils需要花费10分钟,那么编译这个软件包将大约需要45分钟。大部分软件包编译所需要的时间都小于1SBU,但在编译gcc或者glibc这些软件包之前最好能把握一下时间,避免编译过程中不得不关机的情况。
(4)保证工具链的完整是顺利编译目标系统的前提条件。工具链相当于宿主系统和目标系统之间的中介,虽然工具链到最后是被完全删除的,但它是整个编译过程的核心环节。因此不要因为节省时间而跳过编译工具链的某些步骤,否则会得不偿失。
5 结束语
到目前为止,大家对LFS应该有了一个基本的了解。但是,成功地安装LFS仅仅是一个开始,它只是一个最基本的Linux系统,在此基础之上可以根据自己的喜好选择衍生的LFS:如果想打造一个实用的、高效的桌面系统或服务器系统,可以参考BLFS(Beyond LFS),在那里可以了解到怎么样在LFS的基础上建立数据库、网络等服务以及对图形界面的支持;如果对交叉编译感兴趣,可以采用CLFS(cross LFS);另外,如果对LFS的全手工操作感到厌烦了,可以选择ALFS(AutomatedLFS)自动完成这些工作。但无论选择哪种LFS,在学习LFS的过程中都会加深对Linux系统结构、包依赖关系等内容的了解。编译过程可能会消耗比较多的时间,但最终面对着一个完全由自己打造的Linux,会觉得物有所值。
关键词:LFS;Linux;工具链:glibc
引言
从Linux诞生以来,它的发展非常迅速,迄今已经有300多个Linux发行版。国外的Fedora(原RedHat)、Debian、SUSE、Gentoo,国内的红旗、Magiclinux已经成为Linux的中坚力量,IBM、SUN、Intel等厂商也表示出对Linux的浓厚兴趣,加大了资金投入。目前Linux在服务器市场和Unix、Windows Server三分天下,市场占有率年年攀升;在嵌入式系统中Linux逐渐显示出它稳定、高效、易定制、易裁减、硬件支持广泛等优势,成为嵌入式操作系统中的一支主流;而在桌面应用方面,Linux也慢慢缩短了与Windows之间的差距,在易用性、娱乐等方面都有很大改进,随着XGL的推出,Linux已经能实现效果非常出色的3D桌面。正因为Linux的应用范围不断扩大,影响不断加深,有越来越多的计算机爱好者开始表现出对Linux的兴趣。在这些Linux爱好者之中,已经有不少人不满足于使用Linux完成日常工作,而更关心是否能建立一—个为自己量身定制、所有部件都在自己掌控之中的Linux,这就是LFS。
1 LFS的意义
目前Linux的发行版大致可以分为两类:以Fedora、SUSE等为代表的二进制发行版,这些版本是目前Linux的主流,特点是不需要编译就可以运行,安装时间短、操作简便;另一种是以源码方式发行的Linux,据笔者所知目前只有Gentoo,特点是在安装过程中需要全部或部分编泽软件包,但由于编译过程中编译器会针对本机的硬件进行优化,所以运行速度要稍微快一点。
LFS的全称是Linux From Scratch,LFS也不属于任何一类。可以理解为从无到有的Linux,它不是一种Linux发行版,而是一份手册(确切的说是一种思想),它是指不用任何预先编译好的软件包,也不用安装基本系统的CD-ROM或启动盘,而利用现有的Linux系统开发自己定制的系统。这个系统的所有设置都可以根据自己的需求和偏好来设定,同时在满足自己需求的基础上也是相当精简的。
可能对于大部分电脑用户来说,使用LFS是一种浪费时间的行为,但有两类人比较适合使用它:
(1)对Linux的编译、组成有强烈兴趣的人。这些Linux爱好者对操作系统的内部结构非常着迷,不满足于使用市面上任何一种Linux发行版,而打算构建自己的Linux。LFS能让用户对系统有更多的控制,不依赖于他人的Linux来实现,并可以掌控系统的每一个细节,比如目录布局和启动脚本配置等。最重要的是,这个通过LFS建立起来的Linux无论用来做什么,和其他Linux发行版相比肯定是最精简的,因为这个Linux中的所有部件都是由自己编译,每安装一个软件都需要自己审核。这和目前大部分Linux发行版“打包”式的安装方式完全不同,更加适合Linux发烧友的胃口。
(2)打算比较完整地了解Linux构成的初学者。它可以帮助人们学习Linux系统内部是如何工作的。构建一个LFS系统会帮助初学者了解Linux是如何运转,各部件是如何有机的结合在一起工作的。本文的主要对象就是这些LFS初学者。
2 使用LFS所需具备的基本条件
在使用LFS之前,对于初学者来说Linux相关的一些基础知识是必须具备的:
(1)能较为熟练地使用一种shell(推荐用bash)。这是最起码的要求,否则在Linux中就寸步难行。至少会使用ls、mkdir、cp等基本命令,对输入输出重定向也应该非常清楚。
(2)掌握tar及压缩工具(bzip2、gzip)的用法。因为几乎所有的源码都是经过压缩的tar格式的文件。
(3)需要知道Linux分区的结构,根目录的各个子目录的用途。
工欲善其事,必先利其器。如果已经具备了Linux基本知识,请到LFS官方网站(WWW.1inuxfromscratch.org)下载LFS手册和LiveCD,目前已经有不少国内的LFS爱好者对LFS手册做了汉化,也可以到国内的Linux社区(如WWW.1inuxsir.org)中下载LFS手册中文版。需要说明的是,LFS的目的是通过已存在的Linux的系统(宿主系统)建立一个自己的系统,而LFS的LiveCD就是一个可以通过光盘启动的宿主系统。理论上任何宿主系统都可以使用LFS,但由于各方面的原因(如发行版现成的编译器、连接器等工具的版本不匹配,某些发行版在Linux系统中加入了些不兼容的功能)导致某些宿主系统使用LFS的失败率很高,因此还是推荐LFS的初学者使用LiveCD。
3 LFS构建Linux的思路
虽然相关手册已经对LFS操作步骤描述的很详细了,但如果仅仅是简单地根据手册上的说明操作,那只会停留在知其然而不知其所以然的地步,达不到剖析Linux结构的目的。因此在使用LFS之前,大致了解一下LFS的原理是十分必要的。
首先介绍一下在Linux中关于依赖的概念。大家都知道在Windows中有许多后缀名为dll的动态链接文件,这些文件向运行于Windows操作系统下的程序提供代码、数据或函数。在Linux中也有许多这种文件,它们之间有错综复杂的依赖关系,大多数Linux发行版都提供了包管理器(如Fedora的RPM、Debian的APT),用来管理程序和程序之间的依赖关系。在使用LFS的过程中,本质上要解决的就是依赖问题。我们使用LFS就是要建立一个“纯净”的,不依赖于宿主系统的操作系统,我们称之为目标系统。这里所说的不依赖于宿主系统可以简单地理解为目标系统中所有的程序都不“受制于”宿主系统中的程序,否则宿主系统中的某个软件一有变动都可能导致目标系统无法使用。正因为有这个限制,我们不能直接用宿主系统来编译目标系统,因为编译的过程中将用到许多宿主系统的库,直接编译的目标系统会依赖于这些库。
在Linux中非常重要的glibc库,是提供系统调用和基本函数的c库,所有动态连接的程序都要用到它,它是LFS制作过程中的关键环节。在Linux平台下大部分程序是动态连接的,比如要使用vi,它依赖于glibc和ncurses,而ncurses又 依赖于glibc。因为几乎所有的程序都依赖于glibc,所以,在目标系统中必须先把glibc编译出来,才能保证目标系统的“自给自足”。
但是目标系统的glibc可以由目标系统的编译器来编译吗?不行。因为我们必须保证编译Gilbc的编译工具和和目标系统中依赖于glibc的编译工具版本是一致的。但一般情况下,目标系统中各种工具的版本总是高于宿主系统中的版本。因此得先建立一个临时编译环境,这个环境包含了gcc、binutils、make等各种必需的和编译有关的工具,它们的版本必须和目标系统中工具的版本完全一致,我们把这个临时环境称为工具链(toolchains)。通过工具链先制作目标系统中的glibc以及各种必需的编译工具,接着就可以把编译其他软件的工作从工具链逐步转移给目标系统,整个目标系统编译完成后就可以直接删除工具链。
问题是这个工具链由谁编译出来?这个任务只能由宿主系统来完成,通过宿主系统提供的编译工具可以制造出一个工具链。但因为要保证工具链依赖的glibc和工具链所生成的glibc是一致的,制作工具链的过程中不能直接使用宿主系统中的glibc,需要先制作一个临时的、和目标系统匹配的glibc供工具链使用。
表面上看起来问题已经解决了,但宿主系统可以直接编译一个供工具链使用的glibc吗?个别情况下是可以的,但在LFS中不提倡这么做。因为这里存在一个问题,不同版本的gcc编译出来的程序可能会不一样,而宿主系统和工具链中gcc的版本未必是相同的,这样会导致宿主系统直接编译出来的glibc对于工具链来说有可能不能用。所以应该先由宿主系统编译一遍gcc和binutils,使它们的版本和工具链中的版本一致,再由新的gcc和binutils参与glibc的编译。
图1是LFS的流程简图,其中虚线箭头是指工具对glibc的依赖。从图中可以看出,要制造一个不依赖于宿主系统的目标系统,首先要做一个工具链,通过工具链来编译目标系统中的程序。我们得先制作一个临时的glibc,通过这个glibc编译出来的工具链可以脱离对宿主系统中glibc的依赖。把宿主系统完全编译出来后,删除工具链即可。
4 使用LFS过程中需要注意的情况
LFS手册已经提供了非常详尽的操作流程,因此本文对具体的操作过程不再赘述,但对于接触Linux时间不是很长的人来说在还存在某些“陷阱”,有些甚至可能会造成致命的错误。这里简单总结一下安装过程中可能会遇到的问题并对需要注意的地方加以分析,使大家在学习LFS的过程中避免花费不必要的时间和精力。
(1)由于编译Linux需要很长时间,第一次安装请用LiveCD作为宿主系统,并请完全按照手册上的步骤来操作,在编译过程中不要对任何参数进行修改,也不要从网上下载最新的源码来代替LiveCD中的源码,否则稍有不慎就会前功尽弃。因为安装LFS的过程中需要编译大量软件包,这些软件包之间有着错综复杂的依赖关系,使用最新版本的gcc未必能保证一些软件顺利通过编译。在对LFS的安装步骤比较熟悉并清楚各个软件包的依赖关系之后,再用其他Linux发行版作为宿主系统,到那时可以根据自己需要选择各种软件最新的源码并进行优化。
(2)在使用LFS的过程中,了解每一步骤的具体含义是十分必要的,因为安装LFS除了能了解Linux的基本结构外,另一个收获就是能掌握大量Linux的常用命令并能灵活运用。但是在安装过程中,将会出现不少对于初学者来说难以理解的语句,特别是调整工具链等过程会出现Perl语言。如果对这些语句不是很熟悉的话,很有可能少输或错输一个字符而误删除了已经辛辛苦苦编译了几小时甚至十几小时的目标系统。另外,由于错输字符而导致的问题的“潜伏期”可能会很长,特别是调整工具链过程中的隐患往往到LFS整个编译工作的结尾阶段才会体现出来。因此如果对Perl不是很熟悉的话,建议大家可以暂时不理会这些语句的具体含义,直接将它们复制下来并运行,只要知道这些语句所起到的作用就可以了。当然,Perl是很重要的脚本语言,在Linux中几乎无处不在,回过头来还是应该掌握它的基本内容的。
(3)大部分LFS的初学者是采用LiveCD作为启动光盘并在该系统下进行LFS的安装的。LiveCD中的桌面环境十分有限,而整个编译过程又相当耗费CPU资源,在这十几个小时(甚至几十个小时)中几乎无法做其他工作,如果能了解编译每个软件所需要的时间,就可以更合理地进行安排。由于硬件配置存在差别,每台电脑编译软件所需要的时间不可能完全相同,因此LFS中提出了一个SBU(标准编译时间单位)的概念。编译Binutils软件包所花费的时间就是1单位的SBU,对于一个编译时间为4.5 SBU的软件包,这意味着如果一个系统静态编译安装Binutils需要花费10分钟,那么编译这个软件包将大约需要45分钟。大部分软件包编译所需要的时间都小于1SBU,但在编译gcc或者glibc这些软件包之前最好能把握一下时间,避免编译过程中不得不关机的情况。
(4)保证工具链的完整是顺利编译目标系统的前提条件。工具链相当于宿主系统和目标系统之间的中介,虽然工具链到最后是被完全删除的,但它是整个编译过程的核心环节。因此不要因为节省时间而跳过编译工具链的某些步骤,否则会得不偿失。
5 结束语
到目前为止,大家对LFS应该有了一个基本的了解。但是,成功地安装LFS仅仅是一个开始,它只是一个最基本的Linux系统,在此基础之上可以根据自己的喜好选择衍生的LFS:如果想打造一个实用的、高效的桌面系统或服务器系统,可以参考BLFS(Beyond LFS),在那里可以了解到怎么样在LFS的基础上建立数据库、网络等服务以及对图形界面的支持;如果对交叉编译感兴趣,可以采用CLFS(cross LFS);另外,如果对LFS的全手工操作感到厌烦了,可以选择ALFS(AutomatedLFS)自动完成这些工作。但无论选择哪种LFS,在学习LFS的过程中都会加深对Linux系统结构、包依赖关系等内容的了解。编译过程可能会消耗比较多的时间,但最终面对着一个完全由自己打造的Linux,会觉得物有所值。