现在的位置: 首页 > 综合 > 正文

安得倚天抽宝剑——搭建自己的Linux实验系统(一)

2013年11月02日 ⁄ 综合 ⁄ 共 3917字 ⁄ 字号 评论关闭

当你对操作系统已经有了基本的把握;而且对Linux也有了初步的了解,可是,如果你是一个程序员,你肯定还是会觉得惴惴不安:Linux到底是怎么回事?

求知和求实是程序员的天性,我们当然有义务满足自己的天性,所以,相关的实践必需在此展开。可是,我们到底要实践些什么呢?

不如从搭建Linux系统开始。

在搭建的时候,我们需要制作一个root文件系统:你很清楚了,所有必须的软件和数据都在上面,只要我们选定的范围合适,那么什么是操作系统最核心的组成部分在我们实验以后显然会一清二楚;我们需要制作一个内核镜像:没有内核,操作系统将会怎样?但是没有(不包含)用不到的内核功能,操作系统肯定会安然无恙。实验过后,你肯定会清楚内核到底要做些什么!内核和文件系统都有了,那不就OK了?稍等,怎么把两者绑定到一块呢?还有硬件启动的麻烦事,怎么才能让系统真正开始工作呢?

安得倚天抽宝剑,将汝截为三段!一段编译,一段创建,一段自己连

好了,不开玩笑了,让我们开始吧。 

搭建的基础?

    首先我们必须做出一个基本决定,到底是从源代码开始搭建呢?还是从现有系统上裁减出一个系统呢?如果是从源代码开始搭建,那么我们需要对所有的软件包进行下载、编译、链接和安装,这中间步骤非常繁琐,在这里我们不希望选取这种方式。说实话,其实这方面有非常不错的Howto文档LinuxFromScrach(有翻译好的中文文档),你完全可以按照该文档进行搭建。

    但是,我们的考虑是用最小的代价--消耗时间最短、相关硬件需求最少--来完成操作,而且整个过程必须保证安全可靠,即使初学者出现一些误操作,也不应该影响原来安装好的系统。所以,我们决定从现有的系统上抽出我们所需的原料。 

分三步建立系统

非常遗憾,搭建Linux操作系统的人基本上都是diyer,所以不存在什么标准流程。但是大体流程都大同小异,无非是:首先编译内核——将内核源代码编译成一个可执行的镜像文件,当然,此时可能还会需要编译一些模块,这要取决于你是如何配置内核的。

有了编译好的内核还远远不够,因为你还没有能容纳系统程序和应用程序的文件系统,所以接下来需要创建一个root文件系统。文件系统要包含什么?第二步会有详细的说明。

内核与文件系统都有了,现在是万事具备,只欠东风了。只要将内核和文件系统邦定到一起,让机器启动后载入我们编译的内核,进而安装root文件系统,然后执行其中的初始化程序,我们的工作就大功告成了。说来轻松,可这个收尾动作难度系数还是蛮高的,初学者往往都在这里要栽跟头--你必须对系统启动过程了如指掌才能左右逢源。

搭建一个操作系统是我们深入了解Linux系统的一个非常好的途径。当然,由于操作系统这门学科本身涵盖面非常广,而实际的操作系统软件又庞大不堪。所以,一开始从任何层面着手实践肯定都会有盲点,有不能理解的地方,其实不用着急,随着内容的逐渐展开,希望您和我们一起探讨,共同解开这些疑惑。

前面提到过,我们希望搭建的过程安全便捷,但不是每个朋友都能找到空硬盘或者磁盘(看看你的机器,也许连软驱都没有)来做新系统的。而且为了防止初学的朋友不小心误操作,新开分区等危险操作也应该尽力避免。所以,我们决定在系统启动时使用RAM盘来存放根文件系统。

提醒:这种实现其实在嵌入式系统中常常用到,许多嵌入系统并没有硬盘,只有容量很小的ROM disk,里面存放压缩过的数据;而且运行中根本就不需要向磁盘存储任何数据。

现在开始,我们一同做个这样的实验小系统,你要付出些代价是:时间 无数次击健。

编译内核 

    第一步要做的工作是挑选一个合适版本的内核源代码包,然后编译它。不要以为编译内核很神秘,其实它和编译普通程序差不多,内核源代码其实就是一大堆程序,它也是通过编译一个个的文件,然后将它们链接成一个可执行镜像文件。这个镜像就是你在/boot目录下看到的vmlinuz-*。(如果你细心的话,一定能发现在该目录下还有一个叫vmlinux的文件。其实这两个文件是一回事,前面那个不过是经过压缩的罢了。) 

    正如第一部分所提到过的,Linux内核具有很强的伸缩性,在编译内核时,你很容易就能发现这一点:很多功能是可选的,如果系统需要它,就可以将其编译到内核。不过加入太多的功能会使内核迅速膨胀起来。一种替代的方式是将某些功能编译成模块,放在文件系统里,等你真正需要它时,再把它载入到内存中供内核使用。

虽然是个实验系统,但我们希望它支持尽可能多的硬件和实现尽可能多的功能。所以我们配置内核编译选项时,除了支持最基本的ext2文件系统,PCI接口,自动装载模块机制以外,又把ext3JFS,即插即用,网络,SCSIUSB等比较常用的部分加入到内核中(我们的系统不大,所以,为了方便起见把它们都直接编译到了内核。不过也留下网卡驱动以模块形式编译,好让大家印证一下模块自动载入机制)。此外,为了能在虚拟内存中建立root文件系统,内核还必须支持Ramdisk initrd 

    内核网络设备选项里包含大量网卡驱动程序,你必须知道自己的网卡类型才能正确选择,一般情况下都将网卡驱动编译为模块,在系统启动后载入。我们的实验系统运行在vmware下,而vmware虚拟网卡驱动为pcnet32,因此只包含这个驱动模块。

编译步骤

巧妇难为无米之炊,首先得去下载一份内核源代码。就算一直是饭来张口,也别指望我能给你提供内核源码,自己到www.kernel.org网站上下载一个想要版本的内核源代码吧。如果是gz结尾的压缩源文件,就使用tar xvzf linux-2.6.x.tar.gz解开,如果是bz2结尾的,就用tar xvjf linux-2.6.x.tar.bz2解开。 

内核版本编号可是有点讲究的,简单的说,偶数为稳定版本,奇数为开发版本。我们选用的是2.4.18版,希望大家下载最新版本2.6.32。

进入解开后的内核源代码目录(标准系统默认情况下在目录/usr/src/linux下存放该系统的内核源代码,如果你自己解压源码包,那么如果不指明具体的目录,默认解压到当前目录的linux目录下),执行命令make menuconfig,进行内核编译选项的配置,选择需要的功能,以模块形式编译或直接编译到内核。配置信息默认情况下保存在隐含文件.config中,你也可以选择将其保存到指定的文件中,比如可以把信息记录在MiniSys.config中,在以后重新配置内核时可以方便地导入指定的配置文件(即使是老手,配置内核有时也会出现问题,导致编译失败。我们建议初学者从默认情况开始,逐步加减内核编译选项,小步更改,多次练习,逐步掌握内核配置本领) 

make menucofig提供给你一个终端图形界面的配置菜单,其中列出了内核所能提供的全部功能,如果你在选项前打上*标号,那么该选项被编译到内核中,如果打上M标号则被编译为模块,对于你不清楚的选项的意义,可以使用?查看它的帮助文档。除了用make meunconfig外,如果你有复古情结的话,可以试试使用make config,它完成同样的功能,不过你得有足够得耐心去忍受洪水一般涌过的命令行信息,同时不厌其烦对功能项进行取舍(选<y>或<n>)。如果你在X环境下(桌面环境),不妨使用make xconfig配置,相比前两种方法,它更容易看清楚一些,推荐眼神不好的网友使用。

保存内核配置后,就执行 make dep  ,该操作检查代码之间的相互依赖关系,比如引用的头文件是不是都被包含了。

make clean,该操作用来 清除以前编译内核时遗留下来的生成物。采取这个步骤是习惯问题,现在新版本的内核已经不是必需的了。

make bzImage make zImage 编译内核——bzimagezImage两种内核之间最大的差别是对于内核体积大小的限制。zImage内核需要放在实模式1MB的内存之内,所以其体积受到了限制。而bzImage的内核没有1MB内存限制,因此通常用它。

    编译过程漫长而且乏味(至少在我的vmware虚拟机中非常慢),尤其讨厌的是,要是你选择功能不当,那编译时就会出错,终止编译过程。这时你不得不从头开始,修改选项,重新编译,好不麻烦。所以每次配置都不要追求勇猛精进,最好参考我们的建议,逐步添加功能,保存配置信息,以防不测。

注意,内核编译完了,还要编译模块。即使您在配置内核时没有使用任何模块,最好也不要跳过此步骤,在编译完内核后立刻编译并安装模块是个好习惯。当然,如果您确实没有配置什么模块的话,这部分工作很快就会结束。

make modules编译内核模块,凡是在配置内核时标记为M的部分都将被编译为模块。

make modules_install ,将编译好的内核模块安装到正确的位置上,一般会放在/lib/modules/<内核版本号 >/这个目录下。当然,如果你想改变模块的安装目录,可以修改Makefile文件,通过设置INSTALL_MOD_PATH来改变模块的安装目录。

等蝗虫一样的字符风暴在屏幕上停歇后(当然不是满屏的出错信息!),你真的拥有新内核了。它藏在内核源码目录下的子目录arch/i386/boot下,叫作bzImagezImage(根据你的make操作而定 ),模块也被安装到了相应的位置上。

注:本文是康华曾为我们Linux内核之旅网站第一期电子杂志撰写的内容,之所以再次拿出来晾晒,是因为尽管很多初学者对Linux原理和代码也看了不少,但不知道如何动手,在云端漂浮。希望读者从云端跳下,站在地上实践。

抱歉!评论已关闭.