当你对操作系统早已有了基本的掌握;并且对Linux也有了初步的了解,但是,假如你是一个程序员,你肯定还是会感觉局促不安:Linux究竟是如何回事?
求知和求实是程序员的天性,我们其实有义务满足自己的天性,所以,相关的实践必需在此展开。而且,我们究竟要实践些哪些呢?
不如从搭建Linux系统开始。
在搭建的时侯,我们须要制做一个root文件系统:你很清楚了,所有必须的软件和数据都在里面,只要我们选取的范围合适,这么哪些是操作系统最核心的组成部分在我们实验之后似乎会一清二楚;我们须要制做一个内核镜像:没有内核,操作系统将会如何?并且没有(不包含)用不到的内核功能,操作系统肯定会安然无恙。实验之后,你肯定会清楚内核究竟要做些哪些!内核和文件系统都有了,那不就OK了?稍等,如何把二者绑定到一块呢?还有硬件启动的麻烦事,如何能够让系统真正开始工作呢?
“安得倚天抽宝剑,将汝截为三段!”一段编译,一段创建,一段自己连…
好了,不开玩笑了,让我们开始吧。
搭建的基础?
首先我们必须作出一个基本决定,究竟是从源代码开始搭建呢?还是从现有系统上裁减出一个系统呢?假如是从源代码开始搭建,这么我们须要对所有的软件包进行下载、编译、链接和安装,这中间步骤十分繁杂,在这儿我们不希望选定这些方法。说实话,虽然这方面有特别不错的Howto文档LinuxFromScrach(有翻译好的英文文档),你完全可以根据该文档进行搭建。
然而手把手教你构建自己的linux系统,我们的考虑是用最小的代价--消耗时间最短、相关硬件需求最少--来完成操作,但是整个过程必须保证安全可靠,虽然初学者出现一些误操作,也不应当影响原先安装好的系统。所以,我们决定从现有的系统上抽出我们所需的原料。
分三步构建系统
十分遗憾,搭建Linux操作系统的人基本上都是diyer,所以不存在哪些标准流程。并且大体流程都邯郸小异,无非是:首先编译内核——将内核源代码编译成一个可执行的镜像文件,其实LINUX社区,此时可能就会须要编译一些模块,这要取决于你是怎样配置内核的。
有了编译好的内核还远远不够,由于你还没有能容纳系统程序和应用程序的文件系统,所以接出来须要创建一个root文件系统。文件系统要包含哪些?第二步会有详尽的说明。
内核与文件系统都有了,如今是万事具备,只欠东风了。只要将内核和文件系统邦定到一起,让机器启动后载入我们编译的内核,从而安装root文件系统,之后执行其中的初始化程序,我们的工作就大功告成了。说来轻松,可这个扫尾动作难度系数还是蛮高的,初学者常常都在这儿要栽跟头--你必须对系统启动过程了如指掌能够左右逢源。
搭建一个操作系统是我们深入了解Linux系统的一个特别好的途径。其实,因为操作系统这门学科本身囊括面十分广,而实际的操作系统软件又庞大不堪。所以,一开始从任何层面着手实践肯定还会有盲区,有不能理解的地方,虽然不用着急,随着内容的逐步展开,希望您和我们一起阐述,共同解开这种疑虑。
后面提及过,我们希望搭建的过程安全方便,但不是每位同学都能找到空硬碟或则c盘(瞧瞧你的机器,恐怕连软盘都没有)来做新系统的。并且为了避免初学的同学不留神误操作,新开分区等危险操作也应当竭力防止。所以,我们决定在系统启动时使用RAM盘来储存根文件系统。
提醒:这些实现似乎在嵌入式系统中经常用到,许多嵌入系统并没有光驱,只有容量很小的ROMdisk,上面储存压缩过的数据;并且运行中根本就不须要向c盘储存任何数据。
如今开始,我们一齐做个这样的实验小系统,你要付出些代价是:时间+无数次击健。
编译内核
第一步要做的工作是选购一个合适版本的内核源代码包,之后编译它。不要以为编译内核很神秘手把手教你构建自己的linux系统,虽然它和编译普通程序差不多,内核源代码虽然就是“一大堆”程序,它也是通过编译一个个的文件,之后将它们链接成一个可执行镜像文件。这个镜像就是你在/boot目录下看见的vmlinuz-*。(假如你悉心的话,一定能发如今该目录下还有一个叫vmlinux的文件。虽然这两个文件是一回事,后面那种不过是经过压缩的罢了。)
正如第一部份所提及过的,Linux内核具有很强的伸缩性,在编译内核时,你很容易能够发觉这一点:好多功能是可选的,假若系统须要它,就可以将其编译到内核。不过加入太多的功能会使内核迅速膨胀上去。一种取代的方法是将个别功能编译成模块,放到文件系统里,等你真正须要它时,再把它载入到显存中供内核使用。
其实是个实验系统,但我们希望它支持尽可能多的硬件和实现尽可能多的功能。所以我们配置内核编译选项时,不仅支持最基本的ext2文件系统,PCI插口,手动装载模块机制以外,又把ext3,JFS,即插即用,网路,SCSI,USB等比较常用的部份加入到内核中(我们的系统不大,所以,为了便捷起见把它们都直接编译到了内核。不过也留下网卡驱动以模块方式编译,好让你们印证一下模块手动载入机制)。据悉,为了能在虚拟显存中构建root文件系统,内核还必须支持Ramdisk和initrd。
内核网路设备选项里包含大量网卡驱动程序,你必须晓得自己的网卡类型能够正确选择,通常情况下都将网卡驱动编译为模块,在系统启动后载入。我们的实验系统运行在vmware下,而vmware虚拟网卡驱动为pcnet32,因而只包含这个驱动模块。
编译步骤
巧妇难为无米之炊,首先得去下载一份内核源代码。即使仍然是饭来张嘴,也别指望我能给你提供内核源码,自己到网站上下载一个想要版本的内核源代码吧。若果是gz结尾的压缩源文件,就使用tarxvzflinux-2.6.x.tar.gz解开,若果是bz2结尾的,就用tarxvjflinux-2.6.x.tar.bz2解开。
内核版本编号而且有点讲求的,简单的说,质数为稳定版本,偶数为开发版本。我们选用的是2.4.18版,希望你们下载最新版本2.6.32。
步入解开后的内核源代码目录(标准系统默认情况下在目录/usr/src/linux下储存该系统的内核源代码,假如你自己解压源码包,这么若果不指明具体的目录,默认解压到当前目录的linux目录下),执行命令makemenuconfig,进行内核编译选项的配置,选择须要的功能,以模块方式编译或直接编译到内核。配置信息默认情况下保存在蕴涵文件.config中,你也可以选择将其保存到指定的文件中linux内核,例如可以把信息记录在MiniSys.config中,在之后重新配置内核时可以便捷地导出指定的配置文件(虽然是老鸟,配置内核有时也会出现问题,致使编译失败。我们建议初学者从默认情况开始,逐渐加减内核编译选项,小步修改,多次练习,逐渐把握内核配置本领)。
makemenucofig提供给你一个终端图形界面的配置菜单,其中列举了内核所能提供的全部功能,假如你在选项前打上*标号,这么该选项被编译到内核中,假如打上M标号则被编译为模块,对于你不清楚的选项的意义,可以使用?查看它的帮助文档。不仅用makemeunconfig外,假如你有百搭情怀的话,可以试试使用makeconfig,它完成同样的功能,不过你得有足够得耐心去忍受洪灾通常涌过的命令行信息,同时不厌其烦对功能项进行抉择(选或)。假如你在X环境下(桌面环境),不妨使用makexconfig配置,相比前两种方式,它更容易认清楚一些,推荐目光不好的网友使用。
保存内核配置后,就执行makedep,该操作检测代码之间的互相依赖关系,例如引用的头文件是不是都被包含了。
makeclean,该操作拿来清乘以前编译内核时遗留出来的生成物。采取这个步骤是习惯问题,现今新版本的内核早已不是必需的了。
makebzImage或makezImage,编译内核——bzimage和zImage两种内核之间最大的差异是对于内核容积大小的限制。zImage内核须要置于实模式1MB的显存之内,所以其容积遭到了限制。而bzImage的内核没有1MB显存限制,因而一般用它。
编译过程漫长并且无趣(起码在我的vmware虚拟机中特别慢),尤其厌恶的是,要是你选择功能不当,那编译时才会出错,中止编译过程。这时你不得不从头开始,更改选项,重新编译,好不麻烦。所以每次配置都不要追求骁勇精进,最好参考我们的建议,逐渐添加功能,保存配置信息,以防不测。
注意,内核编译完了,还要编译模块。虽然您在配置内核时没有使用任何模块,最好也不要跳过此步骤,在编译完内核后立即编译并安装模块是个好习惯。其实,假若您确实没有配置哪些模块的话,这部份工作很快都会结束。
makemodules,编译内核模块,但凡在配置内核时标记为M的部份都将被编译为模块。
makemodules_install,将编译好的内核模块安装到正确的位置上,通常会置于/lib/modules//这个目录下。其实,假如你想改变模块的安装目录,可以更改Makefile文件,通过设置INSTALL_MOD_PATH来改变模块的安装目录。
等蝗虫一样的字符风暴在屏幕上停息后(其实不是满屏的出错信息!),你真的拥有新内核了。它藏在内核源码目录下的子目录arch/i386/boot下,叫作bzImage或zImage(按照你的make操作而定),模块也被安装到了相应的位置上。