本帖最后由 Anzyfly 于 2014-11-15 19:22 编辑
构建自已的Linux系统
目录:
-------------------------- 1:前言 2:准备工作 3:磁盘分区工作 4:安装Grub启动菜单工作 5:编译瑞士军刀Busybox工作 6:制作initrd映像系统工作 7:构建/boot启动分区工作 8:构建根分区工作 9:见证奇迹的时刻 10:后继的一点优化工作 11:再次启动运行看效果 12:制成虚拟机系统 13:畅想
1:前言 ---------------------------------- 目前Linux系统已经嵌入到了各种智能设备中,大到服务器集群,小到mp3设备,其中首先会涉及到一个问题就是Linux系统到底是如何裁剪定制的?Linux系统到底是怎么在这些设备上运行起来的?相信所有的 Linuxer 们对这个问题都很感兴趣,大家也都很想跃跃欲试的自已来构建这样的一个微型系统,兴趣就是我们最大的源动力,今天就带大家一步一步的构建我们自已的Linux系统。本人水平有限,只是初级实验者,如果大家发现有错误或是有待更正的地方,欢迎大家批评指正。
2:准备工作 ---------------------------------- 需要一台安装有Linux编译环境的宿主机,因为我们终级系统的每个文件、目录以及分区都是要在这台宿主机上面制作出来,并且要在其中编译Busybox,所以还需要busybox的开源包文件 busybox-1.22.1.tar.bz2 以及其编译所需要库文件 glibc-static-2.12.90-17.i686.rpm。 硬件需要准备一台带硬盘的PC机或是带CF卡的嵌入式平台,好用来验证我们制作好的Linux系统是否可以正常的启动运行。 我的宿主机是一台安装了 Fefora14的VMwareWorkstation 虚拟机,硬件是一台带512M的CF卡的嵌入式平台,还需要一个读卡器,好用来将此CF卡通过读卡器连接到宿主机中,因为VMware虚拟机支持USB设备,所以到时我们可以在宿主机中正确地将此CF卡识别出来,好对其进行分区等等后继操作。如果大家手中没有嵌入式设备那么直接用带硬盘的PC机是最好不过的,直接对硬盘分区效果更好一些,操作步骤都是一样的,大家领会精神、灵活掌握。闲话少叙,我们直奔主题。
3:磁盘分区工作 ---------------------------------- 我宿主机原来磁盘的分区如下: 接上带512M的CF卡后的磁盘分区显示: 我们将此CF卡分成两个区,一个分了100M的大小用来作将来的/boot挂载的启动分区/dev/sdb1,其余的空间全部用来作将来的/根挂载的分区/dev/sdb2,都格式化成ext4格式的,分好区后的分区格式显示如下: 分好区后我们就可以创建两个目录/mnt/boot 和/mnt/sysroot 分别用来挂载这个分区,挂载好后的模样如图所示:
4:安装Grub启动菜单工作 ---------------------------------- 要想让系统启动,必须要安装启动菜单,我们安装Linux下的Grub来作为引导我们Linux的启动工具,用 grub-install 命令就可以达成所愿,过程如下图所示: 安装完成后你会发现 /mnt/boot/ 目录下面已经被写入了一个grub/目录,并且下面存在一些引导要用到的文件,如下图所示: 其实 /mnt/boot/grub/ 目录下的stage1以及真正所用到的stage1_5文件已经被写入到了磁盘的0磁道的MBR和后继的几个扇区中,具体占用的扇区数如果是用 grub>setup 命令写入的时侯就会有提示,所以在此这几个文件全部不再需要,我们大可完全都删掉,只保留我们启动过程中真正会调用的 stage2 文件,全部删掉后的目录内容如下图所示:
5:编译瑞士军刀Busybox工作 ---------------------------------- 接下来编译Busybox来构建我们Linux系统的一些初始工具命令集,我从Busybox的官方网站下载最新版本 busybox-1.22.1.tar.bz2 来编译,编译之前需要先配置它的具体编译选项,它的配置方式和kernel内核很相似,都是先配置好后生成一个.config配置文件,我们只需要将默认配置改成以静态库的方式来编译,其它的配置不变,这样后继我们就不用再依次拷贝动态库文件来支持它运行了,配置过程如下图所示: 配置好后我们直接开始执行make编译busybox工具,编译过程中会发现提示缺少两个库文件-lcrypt和-lm,如下图所示: 我们会发现系统内是存在这两个动态库的,不知为什么编译不过? 呵呵,原因是因为这儿需要的是这两个静态库,而不是动态库,而我们 Fedora14 默认安装的只有动态库,所以我们需要从网站上下载一下这个版本的相应的 glibc-static-2.12.90-17.i686.rpm 安装包文件,你可以用 rpm -qpl 命令查看一下这个安装包主要包括哪些文件,如下图所示: 你会发现正好有我们需要的两个静态库文件 libcrypt.a 和 libm.a,OK,就它了,直接用 rpm -ivh 命令来安装,再回过头来编译busybox,直接通过。
6:制作initrd映像系统工作 ---------------------------------- Busybox编译好之后我们就可以利用其来制作我们自已的initrd映像文件了,我们将 /mnt/sysroot 目录作为我们制作initrd映像系统的主目录,所以需要先将busybox安装到此目录下,在busybox编译目录下执行 make CONFIG_PREFIX=/mnt/sysroot install 即可,你就会发现在 /mnt/sysroot 目录下已经生成了如下图所示各文件: 有了这些文件还不够,还需要再创建以下几个文件: /proc 手动创建此文件 /sys 手动创建此文件 /dev/console 可以用命令来创建:mknod dev/console c 5 1 /dev/null 可以用命令来创建:mknod dev/null c 1 3 这个两个设备文件既可以用命令来创建,也可以将宿主机系统的设备文件直接拷贝过来使用,同时lost+found 目录是由于挂载自动产生的,对启动没有任何作用,直接删掉,效果如图: /init 这个文件是initrd映像文件的核心文件,需要我们精心编辑来达到启动我们自定义Linux系统的启动的效果,这个文件代替掉了busybox为我们生成的linuxrc文件,所以在此可以把这个文件直接删掉,让kernel启动过程中直接执行我们精心编写的init脚本来达到我们想要的启动效果,我们现在就编辑init启动脚本: 最后还需要再给init脚本文件执行命令chmod+x init 加上可执行权限,好了,到目前为止制作initrd映像系统的文件已经全部就绪,我们看一下目前所有的目录如下: 执行命令 find . | cpio -o -c >../initrd.cpio 将这此文件打包成ininrd.cpio文件, 我们再调用压包命令 gzip initrd.cpio 生成最终我们需要的initrd映像系统 initrd.cpio.gz 文件,我们将其拷贝到启动分区所在的 /mnt/boot/grub 目录下,如下图所示:
7:构建/boot启动分区工作 ---------------------------------- 目前我们自定义系统的启动分区已经具备了Grub启动所需的stage2, initrd映像文件,还只差两个文件,分别是内核 kernel 和 grub.conf 启动菜单配置文件。内核这一块当然也是可以定制的,只是内容太多我们暂不提及,我们直接将宿主机的 /boot/vmlinuz-2.6.35.6-45.fc14.i686 拷贝过来改名成vmlinuz 就可以了,initrd.cpio.gz 也改名成initrd,这样我们编写 grub.conf 启动菜单也会简短一些,我们只需要根据我们实际的 kernel 和 initrd 编写即可,最后再把由于挂载自动产生的 /mnt/boot/lost+found 文件也删掉,这样我们的启动分区完全作好了,其内部各文件如下图所示:
8:构建根分区工作 ---------------------------------- 接下来再制作我们的根分区,根分区比initrd文件系统少了init启动文件,多了以下几个文件: /etc 这个目录通过命令 mkdir -p /mnt/sysroot/etc 来创建。 /etc/fstab 这个文件拷贝模板即可 /etc/inittab 这个文件拷贝模板即可 /etc/rcS 这个文件拷贝模板即可 可以将busybox的模板文件拷贝过来再修改成我们想要的内容,如下图所示: 先将 /etc/fstab、/etc/inittab、/etc/rcS 文件改成我们想要的内容: 至此根分区准备工作已经完成,让我们看一下根分区下面的各目录如下图所示:
9:见证奇迹的时刻 ----------------------------------  嘿嘿 ......见证奇迹的时刻到了,是该让这匹小野马儿跑起来的时侯了,把 /dev/sdb1 和 /dev/sdb2 分别从 /mnt/boot 和 /mnt/sysroot 卸载下来,然后将 CF卡从宿主机上取下来,插到嵌入式平台上开机 ......嘀 ......一声,心情是不是还有些激动呢?呵呵。。。看到启动菜单了有没有? 嘿嘿 ......敲 E键进去看看是不是我们自已编写的 Grub菜单呢?呵呵。。。 嘿嘿 ......等待是不是有些焦急漫长呢?敲 B键直接让它启动,呵呵。。。快看!!!进去了 嘿嘿  ......是不是有些手足无措呢,想不想试着敲两个命令呢,看看它听话不:) 我们试试敲两条命令看看好使不,用 df -h 看看它的磁盘挂载情况,用 uname -a 看看它运行什么版本的内核,呵呵。。 嘿嘿 ......貌似还挺听话的,那我们再把启动分区也挂载上,看看这两个分区总共有多大,看到了没有?根分区只有 1.7MB大小,而启动分区有 4.6MB大小,也就是说这个系统目前只有 6.3MB大小,呵呵,是不是有些小成就感呢???嘻嘻嘻嘻窃喜中:wink:
10:后继的一点优化工作 ---------------------------------- 目前我们的系统是可以欢快地跑起来了,还有没有可以稍微优化的地方呢  ??? 呵呵,目前嵌入式系统普遍用的都是 Flash存储系统,这种卡的读写次数都是有限的,太过频繁的直接读写 CF卡很快就会将 CF卡读写坏的,所以我们可以将此系统运行在内存中,根目录就直接挂在内存 RAM盘中,这样不但可以通过减少频繁读写 CF卡的次数达到延长了磁盘使用寿命,而且提高了系统的读写性能,内存的读写速度绝对不是 CF卡和硬盘能比的了的,所以这是很有用的一个方法,我们要坚决的  实现它!通过修改 initrd 映像系统中的 init 启动脚本就可以实现这个功能,我们将小系统关机后把 CF卡再次通过读卡器与宿主机系统相连,让宿主机识别出 CF卡的两个分区并且再次分别挂载到 /mnt/boot 和 /mnt/sysroot下,用命令行将 initrd映像系统文件还原在一个目录下,步骤如下图所示: 重新修改init脚本的内容如下图所示: 再重新用第6节提到的 cpio+gzip 的方法将其制作成新的initrd文件, 还需要重新修改一下 /mnt/sysroot/etc/fstab 文件的挂载根目录,修改后的fstab文件内容如下:
11:再次启动运行看效果 ---------------------------------- 再次将CF卡从宿主机上取下来插到我们的嵌入式平台上开机运行, 嘿嘿  。。。是不是还有点小兴奋呢? 开机后进入到Grub菜单再到进入系统打印我们设置的红色的”Linux“系统 banner 信息,看来系统启动没有问题,那我们就再执行一些小功能命令,看看我们的根分区只有1.7MB大呢,细节如下图所示: 再看看我们的根分区已经挂载至/dev/ram1上面了,说明我们的整个小可爱系统已经跑在内存RAM盘里了,不相信的话,可以在系统内部创建一个文件或目录后执行reboot命令重新开机后再观察这个文件是否存在就可以证明我们可爱的小系统是否已经运行在了内存之中了,呵呵。。。 :wink:
12:制成虚拟机系统 ---------------------------------- 对于没有嵌入式平台或台式PC机的朋友们可能这个实验不是很方便,所以又经过了一番折腾后终于找到了使之可以运行在虚拟机中的方法,我们常用的虚拟机软件一般是KVM或VMware,KVM用磁盘镜像直接就可以启动了,如果用VMware则还需要把磁盘镜像通过磁盘格式转换软件转换成vmware可以识别的磁盘格式就可以了。我们在此以VMware为例来说明,具体的步骤是先用WinHex软件的克隆磁盘功能将整个CF卡转换成一个映像文件,然后再用StarWindConverter软件将这个映像文件转化成vmware可以正确识别的vmdk格式。新建一个虚拟机,磁盘就用我们生成的这个虚拟磁盘文件作硬盘,开机启动后就会成功进入了,呵呵,这样大家就可以非常方便的在虚拟机中玩儿转我们的小系统了。我先重新生成了一下initrd,目的是将系统启动后根目录下让人讨厌的/lost+found目录去掉,修改的init脚本内容如下图所示: 然后再按上述步骤生成我们的虚拟机系统,点开机启动后的第一个画面如下图: GRUB启动菜单还是我们自定义的内容: 进入系统后的情况: 进入系统后再给回环设备配置上IP地址:
13:畅想 ---------------------------------- 这个系统终于可以正常启动运行了,虽然它很小,功能还很弱,甚至可以说还没有一点实用价值,但是它却完整的执行了 Linux的启动流程,完整的从开机按钮一刹那间逐步切换到了最终的保护模式下的用户态,已经具备了各种上层应用程序运行的必备条件。通过制作这个小系统可以让我们对 Linux系统的框架和启动流程有一个比较清晰的认识,目前遍布在各个实际应用领域中的各类设备很多都是类似的一个框架,具体的应用只不过是再把具体的功能软件模块往这个系统框架里面搭,就像搭积木一样,拷贝相应的执行文件,配置文件,执行文件依赖的库文件等,再或重新定制一下内核,添加内核中相应功能模块的底层支持、让 initrd加载相应的驱动模块支持等等,大同小异,有兴趣的童鞋可以在给这个小系统上逐步添加上网络功能、磁盘卷管理功能、软raid功能等功能,或是配置上sshd服务、telnet服务、apache服务、ftp等等服务、畅想一下通过在这个小系统上面逐步添加各功能模块就可以定制成为更有价值的一些设备,例如构建我们自已的交换机、路由器、防火墙、 Apache服务器、磁盘阵列服务器、视频监控服务器、负载均衡服务器系统等等。等等。。。。。那就请大家尽情的畅想哈   :wink:。。。呵呵 :)
|