LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3330|回复: 22

裸机源码LINUX,做你从未做过的事(LFS+BLFS for LINUX菜鸟)

[复制链接]
发表于 2008-9-27 11:52:04 | 显示全部楼层 |阅读模式
用UBUNTU已经两年了。从DAPPER-6.06到现在的HARDY-8.04(只用了一个月就不用了)。自我感觉开始的时候LINUX技术突飞猛进,一段时间后进展非常缓慢。觉得自己还是一个菜鸟级的初学者,也觉得UBUNTU掩盖了LINUX的很多东西,我用的只是它的外壳,然后动动鼠标打打命令而已。而且用UBUNTU你甚至都不用打命令,用新立得什么都装好了。后来我不满足于现状,慢慢学会了用dpkg来编译和打包内核。后来想想,能不能直接在一台全新的机器上(也就是裸机),从源码开始一步步编译出内核,进而编译出整个系统呢?
上网找了资料,很快就找到了,这就是LFS(linux from scratch,从零开始LINUX)。
相关的资料,网上都非常齐全。LFS的官方网站是

http://www.linuxfromscratch.org

上面有6.3版本的英文手册。
在国内有6.2版本的中文翻译手册,网址是

http://lamp.linux.gov.cn/Linux/LFS-6.2/index.html

国内还有一个比较不错的网站:

http://www.magiclinux.org


---------------------

我这里以一个初学者的身份再进一步的补充说明几个简单问题(作为初学者扫盲),以及6.3英文官方手册的几个BUG(一定要看),余下的部份大家去看看上面的网站就可以了。

1、我在一个操作系统(如UBUNTU)下载了LINUX内核源码,现在可以删除这个操作系统,开始用这个源码启动机器了吗?
回答:当然不行。源码只是文本文件,而机器是只认二进制文件的(也就是XP下的.exe可执行文件),如果二进制文件用于启动机器的话,将有着更严格的要求。你需要用一个工具来编译这些源码,使之成为内核二进制文件,同时还要进行一些相关操作才可以用它来启动机器。

2、LFS的原理是什么?是怎么操作的?
回答:LFS的基本原理是,在现有的具有编译能力(或者叫开发能力)的操作系统上,或者用可启动的具有编译能力的光盘,编译出全新的开发环境,然后在这个全新的开发环境,编译出相关的程序和内核,最后用这个内核启动机器。
具体的操作,可以看看官方的手册就明白了。

3、我已经会在UBUNTU下编译和安装内核,这和用LFS方式安装的内核有什么不同?
回答:你在UBUNTU下编译和安装的内核,利用了UBUNTU的编译工具和库文件,在用这个内核启动时,又用了UBUNTU下的应用程序和工具,因此和 LFS相比有一些“不正宗”,或者叫“出老千”。而且在UBUNTU下编译内核的步骤是如此简单,用make-kpkg能够轻松创建内核。除了能够熟悉内核的配置选项以外,你几乎学不到其他的东西了。当然并不是说在UBUNTU下编译内核不重要,恰恰相反,这是你走向LFS的关键一步。因为LINUX内核的菜单,要熟悉它本身就是一项浩大的工作。
如果你学过编译内核,那么LFS对你是驾轻就熟。如果没有学过也没有关系,一步步来,照样能够完成工作。
如何在UBUNTU下编译内核,可以看这:http://forum.ubuntu.org.cn/viewtopic.php?f=50&t=34172

4、LFS不是也用到了现有的开发环境吗?和上面提到的有什么不同?
不同点是,LFS是先利用现有的开发环境,构建出新的开发环境,然后才用这个新的开发环境编译内核,并且编译相关的程序。在你最终完成并用新内核启动机器时,里面的东西全部都是你一步步从源码编译来的东西,没有一样是直接从UBUNTU上拿来用的。

5、这里是对LFS的比较详细的解释:
LINUX下所有的应用程序,不外乎是由配置文件(etc)、库文件(lib)、程序文件(bin)组成。而要生成这个应用程序,你需要源代码,同时需要一个开发环境,由连接器、编译器、库文件组成。
编译器将源代码编译为二进制代码,它本身也是程序,所以需要库文件;连接器告诉编译器连接到哪个库文件,同时将编译器产生的结果输出给机器执行。连接器本身也是程序,也需要库文件。因此可以知道,库文件是很重要的。在LFS里,库文件是GLIBC,编译器是GCC,连接器是Binutils(它是一个程序包,其中真正用于连接的程序是ld)。

LFS的运作过程:
假设你现有的环境为A,制作的开发环境为B,最终的环境为C。
那么,一开始,先用库文件A/编译器A/连接器A,制作出了连接器B。
我在这表示成:LIB-A+GCC-A+LD-A==>LD-B

然后用库文件A/编译器A/连接器B,制作出编译器B。
就是:LIB-A+GCC-A+LD-B==>GCC-B。

然后是用库文件A/编译器B/连接器B,制作出库文件B。
LIB-A+GCC-B+LD-B==>LIB-B

由于编译器GCC-B和连接器LD-B都用了原系统的LIB-A,所以不是“纯种”的。而新生成的库LIB-B在编译完LD-B和GCC-B后,将会进行一个重定向,使得它并不依赖于原来系统的库,所以是相对“纯正”的。一定要注意这点!这里是关键的转折点。
新的库文件仅仅是依赖于你要编译的新的内核头文件。同时要认识到你编译出的库文件,除非你没有给它指定内核的头文件,不然它都不会依赖和利用原系统的东西,因为,库文件不是“程序”!

这时候,编译器B/连接器B/库文件B都做好了。但是我们知道,这编译器和连接器不正宗。需要进行“过滤”处理:
这时,用编译器B利用库文件B自己再一次编译编译器B,这回利用的是新的正宗的库文件B。
LIB-B+GCC-B+LD-B==>GCC-B2
然后是连接器
LIB-B+GCC-B2+LD-B==>LD-B2
这时新生成的编译器和连接器,都用了新的库文件。我们可以认为它们是正宗的了。其实,这时候它们已经和原来的系统脱离关系了。

接下来,我们会用到一个虚根环境。这是一个利用现有系统的硬件来运行,但是所有的程序和库和配置文件都独立于原系统的环境。之所以用这个环境,是因为内核还没有被编译,很多应用程序还没有编译,机器还是不能启动的。为了使用这个虚根环境,会用LIB-B+GCC-B2+LD-B2这套开发工具编译出很多新的程序。

这时候不知道你会不会问:既然新的一套工具出来了,我直接编译内核不就得了?还那么麻烦?是的,我开始也这么想的,同时也是这么做的。我也建议好奇心强的LINUX FANS这么做看看是什么结果。
结果我可以告诉你:内核是编译好了,也可以启动内核,但是却没有办法控制。为什么?因为你没有BASH这个控制台。
你这时是不是才恍然大悟:天啊,我以为一个内核就能够完全开机并操作的呢!

内核启动了,需要一个init程序来进行初始化。
这个init就是所谓的“根进程”。没有这个程序,一切程序都无法运行。然后这个进程开始挂载、运行相应的程序。比如BASH。有了BASH还不行。 BASH只是一个外壳(SHELL),它没有任何东西,比如我们经常打的ls命令,根本没有。因为ls本身就是个程序文件!还有mkdir等等命令,全部都是程序文件,都没有。也没有办法控制机器。因此这些程序全部都要从源码编译出来。

这时你可能还会问,为什么要用虚根环境?我直接在现有的环境下编不就成了?反正我用的是新的开发工具。
原因是:如果你没有搞好设置,新的开发工具可能还是会用到原有系统的东西,甚至会把编译好的程序安装到原来的系统,从而能破坏原来的系统。当然如果你非常清楚如何进行每一项设置的话是可以的,但是你有这样的水平,你用的估计已经就是你自己做出来的LFS系统了。为了避免不必要的麻烦(重定位程序、连接器等等操作是非常复杂的),才会使用虚根环境,直接与原系统隔离。

有了虚根环境,还会再一次编译库文件。这是因为之前编译的LIB-B是经过重定位装在别的地方的(可见重定位的麻烦),
你要编译一个新的没有重定位的库文件,装在默认的地方,以便将来你的程序都可以利用它。这时生成了LIB-C。
LIB-B+GCC-B2+LD-B2==>LIB-C。
然后,编译GCC和LD,将它们之前的重定位去掉。
LIB-C+GCC-B2+LD-B2==>LD-C
LIB-C+GCC-B2+LD-C==>GCC-C

这时候,最终的开发环境大功告成了。
现在,把所有内核启动需要的程序都进行编译。比如init,比如bash等。最后编译内核。设置好GRUB后用新内核、新程序
启动机器。至此,LFS工作全部完成。

6、在进行LFS时需要注意的关键地方和LFS6.3手册的一些BUG
第一,你需要注意的地方是你的环境变量PATH。你可以用命令:
echo $PATH
来查看。如果你和LFS手册一样建立的是/mnt/lfs/tools和/tools,那么你要确保:
在进入虚根环境之前,PATH的第一个必须要是/tools/bin,
如:
PATH=/tools/bin:/bin:/usr/bin
就是正确的。
在进入虚根环境之后,PATH的/tools/bin必须要是最后一个。

PATH=/bin:/usr/bin:/tools/bin
原因是PATH决定着系统在调用应用程序时的优先级,比如系统里同时有两个GCC,那么它会先用PATH排在前面的那个。这在LFS中被用来进行重定向了。如果你排错了顺序,那么将会用错程序,后面的步骤就会失败。

官方手册在第4章“设置工作环境”时,第一行的.bash_profile文件中没有将PATH进行设置,这是严重错误的地方,导致我第一次编译时失败,找了好久才找到原因。
因此,任何时候,都要确保你的PATH设置正确。

第二,你需要注意的是,如果你用的不是官方提供的2.6.22内核,而是用了更新的内核,比如我用了2.6.26.4。那么
这两个内核的头文件是不一样的。其中,2.6.26的内核在asm/目录下少了一个page.h的头文件。这个文件perl会用到。
因此为了欺骗perl,我拷贝了这个文件过来。新的内核用的机制有所不同,因此估计要等perl6出来了,我才可以删除这冒牌的头文件。

第三,官方的手册是6.3版本,上面的中文手册是6.2版本。这里面有一些地方是不太一样的。因此你要特别注意。
第四,没事不要用root来操作。这是为了防止出错毁掉你现在的系统。比如我进入了/mnt/lfs目录,想删除里面的bin目录,我了rm -fr /bin想删除,提示权限不够。这时我才发现,我打的是/bin,而不是bin。前者是“根目录”下的bin目录,后者是“当前目录”下的bin目录,这两个的差别是相当巨大的!我庆幸我使用的不是root,而是用了另外的用户名。否则现有的系统将由于失去了关键的二进制文件而直接崩溃!如果不信你试试!

第五,为了提高成功率,强烈建议用LFS官方的livecd6.3来开展工作。里面有所有需要的软件。而且就算你误操作删除了系统也不要紧,因为光盘是只读的,重启就又恢复了。(在光盘启动后输入startx会进入图形界面)

好了。你经过努力,终于完成了你的LINUX系统。其中不知道误操作了多少回,英文看不太懂猜了多少回。反正过程很艰苦,结果很幸福。

新系统和原来系统相比,有何优点?
速度!就是速度!
我的是华硕的笔记本,256MB内存,Intel Pentinum M 735,很垃圾的配置吧?但是就是这样一个垃圾机器,编译LINUX内核用了6分钟。而我之前在UBUNTU下用make-kpkg编译内核的时候, 128MB的机器用了4个小时。512MB内存,双核CPU联想品牌机用了35分钟。就是这个区别。
还有一个区别,就是小巧,我的新内核只有2.7MB,其他应用程序只有40来MB。当然现在硬盘大了也无所谓了。

接下来你可能还是不会满足,因为现在这个系统是命令行模式的,没有图形桌面,也不能看网页(没有装W3M)。
那么,进入下一章,就是BLFS,Beyond linux from scratch,超越LFS。
BLFS教你怎么在建立好LFS后,配置系统,安装相关的软件,构建X桌面平台等等。这一章就比较灵活和广泛,在你有了前面LFS的基础后,这些都是简单的工作了。
其中要说的一点就是,如果你不想装KDE和GNOME桌面,而是装XFCE桌面的话,比如我,那么去www.xfce.org下载软件包,一项项编译安装就可以了。如果要在XFCE中使用SCIM输入法的话,在BLFS的wiki上可以查到。
对于一个从源码安装了LINUX的人来说,安装和使用SCIM只是学好了武功,小试牛刀而已了。
安装SCIM相应的网页:
http://wiki.linuxfromscratch.org/blfs/wiki/InputMethods

在进行BLFS时候的小技巧:

如果你这时候打算完全使用自己建立的LFS,不使用LIVECD了,那么你首先需要装上w3m这个网页文本浏览器。因为LFS本身没有安装网页浏览器,也无法使用图形浏览器。浏览器的使用可以看UBUNTU上的WIKI。要装w3m,你需要libssl和libgpm,自己想办法去搞到,在 ubuntu.cn99.com/ubuntu上有下载的。我是先装了DPKG软件后,用DPKG直接安装deb包的。

在文本模式下如何复制粘贴:

你用w3m看英文的BLFS手册时,可能会发现这个命令相当长,想要复制粘贴。我是这么做的:先按S将当前网页保存到temp.txt文件,然后切控制台(你也可以用ctrl+z将w3m丢到后台,操作完成后用fg命令调回w3m,不过我喜欢切控制台,反正有6个。用ctrl+alt+F1-F6来切),切控制台后用vim来打开temp.txt,用v键可视化来选择相应的命令,选好后用:w temp写入temp文件(如果temp已经存在,用:w! temp强制写),然后ctrl+z放VIM到后台,用命令source temp就运行复制的命令了。别忘记了vim还在后台,你fg调出来,又可以继续复制运行这个网页上的所有命令了。

你看着是不是很头大?复制粘贴运行命令那么麻烦?可能是我本人没有找到更好的方法吧,但是我熟练后觉得并不慢,因为vim本身就是一个操作起来相当快速的编辑器。如果有人找到了更好的方法,麻烦贴出来给大家分享。


最后,可能你想要一个和UBUNTU差不多的系统,可以用DPKG和APT来管理软件包。我一开始也是这么想的。
于是我安装了DPKG,但是运行不了,需要sysv软件包的内容,于是我下载了sysv的软件包,发现只有.deb包的,没有tar压缩包的,弄了好久才发现dpkg用不了,但是dpkg-deb可以用来解deb包的(dpkg-deb -x命令)。于是解压后把相关程序拷贝
到了相关地方,dpkg可以用了!运行得和UBUNTU下一模一样。安装好包之后,用dpkg -l可以清楚地列出所有安装好的软件包。
我系统上用的wget和w3m就用了UBUNTU版本的(建议用dapper版本,hardy版本需要更新的glibc,意味着你需要编译新的库文件),但是我安装的APT不能用,提示无法识别系统的包类型。如果不能用APT,而仅仅用dpkg来安装出X桌面的话,意味着你要下载300多个.deb的包。。。。
后来我看了apt的源代码,发现在init.cc中有一段对系统进行判断。我想改掉内核的版本代码(改为ubuntu),来欺骗apt,没有成功。
我又想改掉apt的代码,不过由于本人的C++水平如此之烂,导致改变的代码不能用。后面只能放弃安装apt了。要是你C++厉害的话,估计这不成问题。
即使没有APT,用dpkg来安装一些简单的包也是不错的了。

做你从未做过的事,想怎么样就怎么样,这就是LINUX的魅力所在。最后,祝广大的初学者功力能够更进一层,早日成功!

PS:
本人的LFS在官方站点的排名是20180位。后来搞定BLFS后再注册了一个 是20220位。。。全世界搞LFS的人还不是很多啊。
linux-sir是我见过的最牛的中国LINUX站点了。只有国外的英文站点才能超过它的水平。只是好长时间上不了,估计是天妒英才吧,哈哈。
 楼主| 发表于 2008-9-27 12:19:49 | 显示全部楼层
本人目前的系统情况:
硬件:华硕笔记本M5200NP
      CPU:Intel Pentium M Processor 735
      内存:256MB
      显卡:825集成显卡(够垃圾的,在XP下都认不出来,用   的是默认驱动)
      
软件:XP/LFS双系统
     LINUX内核:2.6.26.4
     对应LFS版本:6.3
     桌面:xfce4.4.2
     中文输入法:scim
     中文字体:arphic/文泉驿
     QQ软件:QQ for linux preview
     网页浏览器:w3m/firefox
     虚拟软件:wine(用来玩梦幻西游。比在XP下玩的还要流畅)
     其他的软件基本没装了。准备装个TeX来学习一下。
回复 支持 反对

使用道具 举报

发表于 2008-9-28 08:37:29 | 显示全部楼层
LFS 的精髓博大精深,還有許多的可讓人探索的呢,呵呵!

PS:並非每個 LFSer 都去註冊的,本區多位斑竹及常客都無註冊,因此實際人數是遠超過註冊人數的
回复 支持 反对

使用道具 举报

发表于 2008-9-28 08:49:22 | 显示全部楼层
lz 辛苦,写了这么长,写得很不错,很适合新手。
回复 支持 反对

使用道具 举报

发表于 2008-11-5 14:25:16 | 显示全部楼层
Post by ti8er;1887610

后来我看了apt的源代码,发现在init.cc中有一段对系统进行判断。我想改掉内核的版本代码(改为ubuntu),来欺骗apt,没有成功。
我又想改掉apt的代码

呵呵,兄弟已经找到 apt的代码啊,我一直在找,可是没有找到(在接触LFS之前就找过),呵呵

能给我一份apt的代码吗?
回复 支持 反对

使用道具 举报

发表于 2008-11-5 19:29:24 | 显示全部楼层
apt 的源码可以到 packages.debian.org 里找
回复 支持 反对

使用道具 举报

发表于 2008-11-25 21:04:18 | 显示全部楼层
我的是华硕的笔记本,256MB内存,Intel Pentinum M 735,很垃圾的配置吧?但是就是这样一个垃圾机器,编译LINUX内核用了6分钟。

ti8er,这个你确定是6分钟吗?就是make menuconfig 后,从下达make命令开始到make完成.6分钟?
我的机器 CM370(1.5GHz),1.5G(1G+512M)内存 make 一次内核(2.6.27.7)花费半个多小时.

这....
P
回复 支持 反对

使用道具 举报

发表于 2008-11-26 03:05:10 | 显示全部楼层
人家双核 CPU 都要 35 min,估计是笔误而矣,可能是 60 分钟吧

FYI,我用 Sempron64 3000+/1G RAM 编译 2.6.27.7 内核,gcc-4.3.2 大约是 23 min,当然已瘦身,不过还有可减的空间

gcc 的版本及优化等级对编译时间也有影响的
回复 支持 反对

使用道具 举报

发表于 2008-11-26 08:41:00 | 显示全部楼层
Post by qufo;1913704
我的是华硕的笔记本,256MB内存,Intel Pentinum M 735,很垃圾的配置吧?但是就是这样一个垃圾机器,编译LINUX内核用了6分钟。

ti8er,这个你确定是6分钟吗?就是make menuconfig 后,从下达make命令开始到make完成.6分钟?
我的机器 CM370(1.5GHz),1.5G(1G+512M)内存 make 一次内核(2.6.27.7)花费半个多小时.

这....
P


qufo,你确定你对kernel进行过配置?
CM1.73的编译一次不超过10分钟,vmlinuz+modules不超过4M
选项本身也是一个因素。。。
如果你全选的话1个多小时都有可能
回复 支持 反对

使用道具 举报

发表于 2008-11-26 15:03:26 | 显示全部楼层
Post by goodstarting;1913879
qufo,你确定你对kernel进行过配置?
CM1.73的编译一次不超过10分钟,vmlinuz+modules不超过4M
选项本身也是一个因素。。。
如果你全选的话1个多小时都有可能


kernel 当然经过配置,把一些不要的选项去掉了。比如我连 Selinux 也不要了。

又加了 BordCom 43XX 的无线网卡驱动,直接加到内核了,因为没有网络我几乎什么都干不了。

这样要经过 半个多小时 才能编译完成。

莫非我操作错误?

我是解开
linux-2.6.27.7.tar.gz
cd linux-2.6.27.7
make mrproper
然后
make menuconfig
此时会出现一个图形化的配置界面,去掉及加入一些配置选项,然后在这个界面的最下面有一个Save....什么的,保存为 .kernel
然后退出,退出后可以在当前文件夹下找到这个.kernel
然后执行make
此时我发现一些我没有要的配置,也跟着编译了,比如
CC drivers/ne2000.o <-记不清了,反正没选的。
然后,一切正常。
我回去看看内核的大小,这个我还真没关注。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表