打造属于自己的Linux系统!

1:以下的实现过程都使用VM虚拟机,在这上面实现的。

2:实现打造属于自己的Linux系统,其实用的是将现有的完整的Linux系统精简,然后打包做成不到10M的系统。

3:我所用的Linux系统为Redhat Enterprise Linux 5(内核为 2.6.18)

=======================================================================

首先,我们要知道,一个linux的系统之所以能够启动,需要什么?

1.需要一个boot loader,以确保能够带起硬盘 

2.需要一个内核。(废话-。-)

3.需要一个小型的能够加载内核文件系统的程序(initrd)

4.需要一个能够定义如何启动的文件(inittab)

5.需要inittab中供启动的rc.sysinit文件

其实,一个linux能够启动,需要的也就是这么多,那接下来,我们开始一步步着手准备!

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

第一步:准备工作,并创建引导文件!

既然我们需要boot loader能够带起硬盘,那么我们总要先有个硬盘吧?

好,调用虚拟机,给我们的现有的linux额外增加一块新硬盘,这块硬盘可以不用太大,够用就好,比如?嗯……8G,够你用了吧?

点击Add,添加一块新的硬盘,设置大小为8G,其他默认,然后点ok~

进入我们的Linux系统。使用fdisk -l 命令,我们看到了一块完整的未经开垦的硬盘:

  1. Disk /dev/sdc: 8589 MB, 8589934592 bytes  
  2. 255 heads, 63 sectors/track, 1044 cylinders  
  3. Units = cylinders of 16065 * 512 = 8225280 bytes  
  4.   
  5.    Device Boot      Start         End      Blocks   Id  System  

它的名字叫/dev/sdc

于是,我们开始给他分区,首先我们要给他分一块主分区,专门放置我们的小系统的内核等重要的文件。

然后我们要分一块稍微大一点的分区,这是我们的应用分区,我们以后所有的各种文件都将放在这个分区里。

使用fdisk /dev/sdc 设置我们硬盘的各个分区之后,确认,于是硬盘成了这个样子:

  1. Disk /dev/sdc: 8589 MB, 8589934592 bytes  
  2. 255 heads, 63 sectors/track, 1044 cylinders  
  3. Units = cylinders of 16065 * 512 = 8225280 bytes  
  4.   
  5.    Device Boot      Start         End      Blocks   Id  System  
  6. /dev/sdc1               1          13      104391   83  Linux  
  7. /dev/sdc2              14         136      987997+  83  Linux  

好的~,我们将其格式化成ext3文件系统,然后分别将两块硬盘挂载在我们新建的两个目录上,

1.我们将/dev/sdc1挂载在/mnt/root中(这就是我们的存放内核等重要文件的分区)

2.我们将/dev/sdc2挂载在/mut/sysroot下(而这个,就是我们日常应用的分区)


好的,接下来。我们就要开始将boot loader,整个磁盘的引导信息写入我们新的硬盘中了。

Linux为我们提供了grub这个好用的写入也是读取更是引导程序。我们只需要使用命令:

  1. [[email protected] ~]# grub-install --root-directory=/mnt /dev/sdc  

即可将grub安装在了我们的sdc上,并且默认给他的目录是/mnt。为什么是/mnt而不是/mnt/boot呢?

因为 grub安装后,会自动在那个磁盘的根目录下创建/boot目录,所以我们只需要指定它的父目录,即/mnt即可。

于是,我们看看刚才安装的/mnt下有

  1. total 14  
  2. drwxr-xr-x 2 root root  1024 Aug  3 07:45 grub  
  3. drwx------ 2 root root 12288 Aug  3 07:42 lost+found  

而进入grub里,则是已经安装在我们这里的文件
  1. total 197  
  2. -rw-r--r-- 1 root root     60 Aug  3 07:45 device.map  
  3. -rw-r--r-- 1 root root   7584 Aug  3 07:45 e2fs_stage1_5  
  4. -rw-r--r-- 1 root root   7456 Aug  3 07:45 fat_stage1_5  
  5. -rw-r--r-- 1 root root   6720 Aug  3 07:45 ffs_stage1_5  
  6. -rw-r--r-- 1 root root   6720 Aug  3 07:45 iso9660_stage1_5  
  7. -rw-r--r-- 1 root root   8192 Aug  3 07:45 jfs_stage1_5  
  8. -rw-r--r-- 1 root root   6880 Aug  3 07:45 minix_stage1_5  
  9. -rw-r--r-- 1 root root   9248 Aug  3 07:45 reiserfs_stage1_5  
  10. -rw-r--r-- 1 root root    512 Aug  3 07:45 stage1  
  11. -rw-r--r-- 1 root root 104988 Aug  3 07:45 stage2  
  12. -rw-r--r-- 1 root root   7072 Aug  3 07:45 ufs2_stage1_5  
  13. -rw-r--r-- 1 root root   6272 Aug  3 07:45 vstafs_stage1_5  
  14. -rw-r--r-- 1 root root   8904 Aug  3 07:45 xfs_stage1_5  

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

第二步 :搞定内核的相关配置。

好的,我们的硬盘已经准备好了,那么内核怎么办呢?这里我们使用Redhat自带的内核

它在/boot目录下,名字叫“vmlinuz-2.6.18-164.el5”。

我们用cp复制命令直接将其复制到我们的主分区下,并命名为一个简单的不带版本号得名字vmlinuz:

  1. [[email protected] grub]# cp /boot/vmlinuz-2.6.18-164.el5 /mnt/boot/vmlinuz  

之后,我们的内核有了,但是拿什么来调用它呢?这就需要Redhat中的一个能在内存上加载的驱动根目录文件系统的一个文件了:

它就是:lintrd.

它在/root/下静静的放着。每当系统需要启动的时候就会悄悄的执行一下。

用file命令查看它发现他是个gzip文件。

  1. [[email protected] linuxmini]# file initrd-2.6.18-164.el5.img   
  2. initrd-2.6.18-164.el5.img: gzip compressed data, from Unix, last modified: Wed Jul 20 15:23:58 2011, max compression  

好吧,虽然它的确是img格式结尾的,但那不影响我们发现他的伪装,于是我们改名后用gunzip将其解压:
  1. [[email protected] linuxmini]# mv initrd-2.6.18-164.el5.img initrd-2.6.18-164.el5.img.gz  
  1. [[email protected] linuxmini]# gunzip initrd-2.6.18-164.el5.img.gz  
解压后的我们再用file命令查看它,发现它又变成了一个cpio文件
  1. [[email protected] linuxmini]# file initrd-2.6.18-164.el5.img   
  2. initrd-2.6.18-164.el5.img: ASCII cpio archive (SVR4 with no CRC)  
cpio文件是一种古老的归档工具,它可以原封不动的将多个文件归档,在制作光盘镜像的时候尤其有用。

那么我们使用cpio的命令将它展开:

  1. [[email protected] linuxmini]# cpio -id < initrd-2.6.18-164.el5.img  
终于,我们看到了它的真正明面,ll一下:
  1. [[email protected] linuxmini]# ll  
  2. total 68  
  3. drwx------ 2 root root 4096 Aug  3 07:58 bin  
  4. drwx------ 3 root root 4096 Aug  3 07:58 dev  
  5. drwx------ 3 root root 4096 Aug  3 07:58 etc  
  6. -rwx------ 1 root root 2861 Aug  3 07:59 init  
  7. drwx------ 3 root root 4096 Aug  3 07:58 lib  
  8. drwx------ 2 root root 4096 Aug  3 07:58 proc  
  9. lrwxrwxrwx 1 root root    3 Aug  3 07:58 sbin -> bin  
  10. drwx------ 2 root root 4096 Aug  3 07:58 sys  
  11. drwx------ 2 root root 4096 Aug  3 07:58 sysroot  
看到了么,这就是一个这样精简的加载在内存里的用来临时充当系统的文件。

我们需要修改一些参数以被我们使用:

用vim打开init这个文件。在最下面找到一行:

  1. mkrootdev -t ext3 -o defaults,ro /dev/vol0/root  
这个是最后要引导的硬盘分区目录。

我们因为要打造自己的,所以需要改成引导我们自己的

于是:

  1. mkrootdev -t ext3 -o defaults,ro sda2  
如果你问,为什么是sda2而不是sdc2,那么我要说的是,因为我们这个系统是最后要移植到其他的机器上的, 那时候,对于那个机子来说,我们这里的sdc2会在那里被识别成sda2,所以我们索性直接将其改为sda2就好。
修改完后,我们要将其重新打包:
  1. [[email protected] linuxmini]# find . | cpio -H newc -o --quiet | gzip -9 > /mnt/boot/initrd.gz  
我们将其打包,并直接写成了initrd.gz并放在/mnt/boot下。

好的,我们看一下此时此刻我们创建的主分区到底有哪些东西:

  1. total 5.0M  
  2. drwxr-xr-x 2 root root 1.0K Aug  3 07:47 grub  
  3. -rw-r--r-- 1 root root 3.2M Aug  3 08:01 initrd.gz  
  4. drwx------ 2 root root  12K Aug  3 07:42 lost+found  
  5. -rw-r--r-- 1 root root 1.8M Aug  3 07:48 vmlinuz  
嗯,主分区基本上就这样了。

第三步:搞定工作分区,搞定启动流程,搞定各项文件。

进入工作分区/mnt/sysroot/创建那些真正linux中的文件夹:

  1. [[email protected] sysroot]# mkdir {bin,sbin,usr/{bin,sbin},proc,sys,home,root,mnt,media,var,lib,etc,dev,boot,tmp} -pv  
  1. [[email protected] sysroot]# ls  
  2. bin   dev  home  lost+found  mnt   root  sys  usr  
  3. boot  etc  lib   media       proc  sbin  tmp  var  
我们有各种文件夹之后,就需要考虑系统启动需要的那个主进程init:
  1. [[email protected] sysroot]# cp /sbin/init /mnt/sysroot/sbin/  
将这个文件复制到我们的/sbin目录下。

其实它就是我们的主shell,但是运行它还需要很多链接库文件,它们都在/lib目录下,我们为了能在微型系统上也运行,则需要将它所需要的那些库文件都一一的复制过来。于是:我们使用:ldd命令来查看到底init需要什么库文件:

  1. [[email protected] sysroot]# ldd /sbin/init  
  2.     linux-gate.so.1 =>  (0x00ccb000)  
  3.     libsepol.so.1 => /lib/libsepol.so.1 (0x0021d000)  
  4.     libselinux.so.1 => /lib/libselinux.so.1 (0x00203000)  
  5.     libc.so.6 => /lib/libc.so.6 (0x004cb000)  
  6.     libdl.so.2 => /lib/libdl.so.2 (0x00613000)  
  7.     /lib/ld-linux.so.2 (0x004a8000)  
我们需要将这些库文件一一复制进我们自己的/lib目录里。
  1. [[email protected] sysroot]# cp /lib/libsepol.so.1 /mnt/sysroot/lib/  
  2. [[email protected] sysroot]# cp /lib/libselinux.so.1 /mnt/sysroot/lib/  
  3. [[email protected] sysroot]# cp /lib/libc.so.6 /mnt/sysroot/lib/      
  4. [[email protected] sysroot]# cp /lib/libdl.so.2 /mnt/sysroot/lib/  
  5. [[email protected] sysroot]# cp /lib/ld-linux.so.2 /mnt/sysroot/lib/  
之后我们有了主进程,还需要我们的bash命令,同理,我们也将/bin/bash复制进我们自己的/bin/目录里。并用ldd命令查看bash需要什么样的库文件,然后一一复制进去。则:
  1. [[email protected] sysroot]# cp /bin/bash /mnt/sysroot/bin/  
  2. [[email protected] sysroot]# ldd /bin/bash   
  3.     linux-gate.so.1 =>  (0x005ff000)  
  4.     libtermcap.so.2 => /lib/libtermcap.so.2 (0x00642000)  
  5.     libdl.so.2 => /lib/libdl.so.2 (0x00613000)  
  6.     libc.so.6 => /lib/libc.so.6 (0x00110000)  
  7.     /lib/ld-linux.so.2 (0x004a8000)  
  8. [[email protected] sysroot]# cp /lib/libtermcap.so.2 /mnt/sysroot/lib/  
有了bash,可以说我们已经完全可以进入自己的小系统了。但是系统启动后是先运行sh的,那么我们没有sh怎么办?不复制了,我们直接将sh连接成bash,等于让他启动就直接使用bash。则,我们做一个链接:
  1. [[email protected] bin]# ln -sv bash sh  
  2. create symbolic link `sh' to `bash'  
  3. [[email protected] bin]# ll  
  4. total 732  
  5. -rwxr-xr-x 1 root root 735004 Aug  3 08:08 bash  
  6. lrwxrwxrwx 1 root root      4 Aug  3 08:10 sh -> bash  
此时,我们ll看一下我们的/bin目录,则已经有了一个链接文件,sh -> bash。这时,我们的小系统可以说已经是可以运行了。

但是,进去之后我们什么都不能干,只能做一些bash的内部命令,比如……cd...echo.....等等,所以我们还想加入一个ls命令,能够查看目录。

那么这时的你是否会如何往自己的系统内加入一个命令呢?

是的,复制那个/bin或者/sbin下的你要的那个命令到我们自己的/bin或者/sbin下,然后用ldd命令查看运行这个命令需要的基本库文件,然后再将库文件一一复制就好。

那么添加ls命令的过程应该是这样的:

  1. [[email protected] ~]# cp /bin/ls /mnt/sysroot/bin/  
  2. [[email protected] ~]# ldd /bin/ls  
  3.     linux-gate.so.1 =>  (0x00b9f000)  
  4.     librt.so.1 => /lib/librt.so.1 (0x0065b000)  
  5.     libacl.so.1 => /lib/libacl.so.1 (0x00666000)  
  6.     libselinux.so.1 => /lib/libselinux.so.1 (0x00203000)  
  7.     libc.so.6 => /lib/libc.so.6 (0x004cb000)  
  8.     libpthread.so.0 => /lib/libpthread.so.0 (0x00642000)  
  9.     /lib/ld-linux.so.2 (0x004a8000)  
  10.     libattr.so.1 => /lib/libattr.so.1 (0x00265000)  
  11.     libdl.so.2 => /lib/libdl.so.2 (0x00613000)  
  12.     libsepol.so.1 => /lib/libsepol.so.1 (0x0021d000)  
  13. [[email protected] ~]# cp /lib/librt.so.1 /mnt/sysroot/lib/  
  14. [[email protected] ~]# cp /lib/libacl.so.1 /mnt/sysroot/lib/  
  15. [[email protected] ~]# cp /lib/libpthread.so.0 /mnt/sysroot/lib/  
  16. [[email protected] ~]# cp /lib/libattr.so.1 /mnt/sysroot/lib/  
此时的你,可以考虑使用

“chroot /mnt/sysroot/ ”这条命令,进入自己的小系统悄悄的看看哟,而且还是可以使用ls命令的哟!

呵呵,那么如何让他能够随开机启动呢?

第四步:搞定开机启动的各项配置:

开机需要读取/etc/inittab所以我们进入我们的小系统手动创建一个inittab文件:

  1. [[email protected] ~]# cd /mnt/sysroot/etc/  
  2. [[email protected] etc]# vim inittab  
在里面写入:
  1. id:3:initdefault  
  2. si::sysinit:/etc/rc.d/rc.sysinit  
这定义了开机之后以第3中模式(即命令行模式进入系统)
并启动系统sysinit,而如何启动呢?在/etc/rc.d/rc.sysinit中定义:

于是我们又需要手动创建/etc/rc.d/rc.sysinit文件

创建相关目录并创建文件:rc.sysinit
进入文件,写入:

  1. #!/bin/bash  
  2. echo -e "===================================="  
  3. echo -e "  \033[31mWelcome to WeiYan's Little Linux\033[0m"  
  4. echo -e "===================================="  
  5. /bin/bash  
这是定义了系统启动后好后,显示的内容,以及启用的shell是什么,我们这里让他直接/bin/bash

写好这个之后,保存退出,别忘了给它执行权限:

  1. [[email protected] rc.d]# chmod +x rc.sysinit   
  2. [[email protected] rc.d]# ll  
  3. total 8  
  4. -rwxr-xr-x 1 root root 178 Aug  3 08:24 rc.sysinit  
最后,我们就要定义,系统如何启动了。

进入/mnt/boot/grub下,找到grub.conf,这个文件定义了开机加电自检之后,系统读取了bootloarder,如何去加载内核等相关信息:

我们修改它:

  1. default=0  
  2. timeout=10  
  3. title WeiYan's Little Linux  
  4.         root (hd0,0)  
  5.         kernel /vmlinuz ro root=/dev/sda2  
  6.         initrd /initrd.gz  
这句定义了root在哪个磁盘,内核在哪里,内核的root目录在哪,使用什么来启动内核。这些信息。

当你定义到这的时候,可以说
你已经大功告成了!

接下来,我们就要真正的将这块磁盘予以应用了!

最后一步:实现吧!梦想的少年!

我们新建一个虚拟系统,使用自定义设置,默认workstation 6.


选择另外版本2.6内核的linux。


在自己制定路径,选择核心,选择分配给的内存大小之后。进入选择硬盘的阶段,我们选择,使用一块已有的硬盘:


下一步,选择我们之前挂载在真正linux上的那个硬盘。


好的,点击完成。

接下来,就可以启动我们的小linux了!


经过一系列的内部运行,终于:我们看到了我们自己制作的linux~!


到这里,我们的所有工作都已经做完了,你已经创建出了一个属于自己的,大小不足10M的linux操作系统!!

而且这个系统里还有ls这个外部命令!