打造屬於自己的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這個外部命令!