在VMware上製作一個簡單的Linux
大體思路
boot | root |
initrd.gz grub vmlinuz-2.6.18-308.el5 | bin sbin lib etc proc sys dev boot |
有以上內容我們就可以運行一個非常簡單的Linux,隻需要往裏麵添加各種配置文件,就可以啟動我們所需要的各種服務。在製作之前,我們先做一些準備工作。
1、在VMware上添加一塊新的IDE磁盤
2、將這塊盤分區,/dev/hdb1 /dev/hdb2,之後格式化為ext3的文件係統
3、掛載/dev/hdb1到/mnt/boot;掛載/dev/hdb2到/mnt/sysroot
前提工作做完之後,我們就可以分別製作boot和root了!那麼我們就開始吧
製作boot分區:
●initrd.gz
initrd.gz其實是一個小的root,它也包含bin sbin lib etc proc sys dev mnt這些目錄,並且還有一個重要的腳本文件init,實現從這個小root到我們真正的root的轉換的功能。最終為了保證我們的Linux體積足夠小,我們就把以上的全部壓縮成了initrd.gz。
但是為了保證我們的小linux能夠實現各種功能,我們隻添加目錄是不夠的,因此我們使用busybox來虛擬bin sbin usr下的各種程序。因此我們要先製作一個busybox。
我們下載穩定版的busybox版本busybox-1.20.2.tar.bz2
- tar -xf busybox-1.20.2.tar.bz2 -C /tmp 把busybox-1.20.2.tar.bz2解壓到/tmp目錄下
- cd /tmp/busybox-1.20.2 切換到 /tmp/busybox-1.20.2目錄下
- make menuconfig 使用圖形窗口對busybox進行編譯
進入圖形界麵後,重要的一項是把busybox所依賴的庫文件做進busybox本身,這個庫隻提供給busybox調度使用;
- make install 要確保在/tmp/busybox-1.20.2/目錄下使用命令
但是我們會發現安裝並不成功
因此我需要下載一個更高版本的內核頭文件,然後把它放在/tmp/busybox-1.20.2/include/mtd/
,因為我虛擬機上有linux-2.6.38.5的內核頭文件,所以我就直接複製到上麵目錄下就可以了
- mkdir /tmp/busybox-1.20.2/include/mtd 創建mtd目錄
- cd /tmp/busybox-1.20.2/include/mtd/ 切換至該目錄下
- cp /usr/src/linux-2.6.38.5/include/mtd/ubi-user.h ./ 把頭文件複製到當前目錄下
- cd /tmp/busybox-1.20.2 再切回原busybox目錄下
- make install 繼續安裝就可以了
安裝完成後,會在/tmp/busybox-1.20.2/目錄下生成一個_install的目錄,這表明我們的busybox安裝成功了,並且_install目錄下有我們所需要的bin sbin usr目錄和各種程序腳本。
- cp ./_install/* /mnt/boot -a 把_install目錄下的所有文件複製到/mnt/boot目錄下
- cd /mnt/boot 在切換到/mnt/boot目錄下,即我們的小linux的boot
可以說現在才開始編寫我們真正的initrd.gz
我們發現/mnt/boot目錄下缺少很多目錄,所以我們手動添加幾個進去
- mkdir etc proc sys lib/modules/ dev mnt/sysroot tmp -p 創建mnt/sysroot是為了實現根的切換
創建我們的dev設備文件conlole和null
- mknod dev/console c 5 1
- mknod dev/null c 1 3
我為了能夠真正的驅動我們的根文件係統,因此我們需要讓initrd.gz有能夠驅動根分區的ext3模塊,因此我們需要複製ext3的模塊到/mnt/boot/lib/modules目錄下。
- modinfo ext3 查看ext3文件係統所以來的庫文件都有哪些
- modinfo jbd 查看jbd是否依賴其他的模塊
把ext3和jbd的模塊都放在對應的/mnt/lib/modules/目錄下
- cp /lib/modules/2.6.18-308.el5/kernel/fs/ext3/ext3.ko /mnt/lib/modules/
- cp /lib/modules/2.6.18-308.el5/kernel/fs/jbd/jbd.ko /mnt/lib/modules/
接下來是要編輯init的腳本文件,init關係到我們能否把initrd的root轉換成真正的root,關係到能否驅動我們真正的root文件係統,關係到能夠裝載我們已經安裝的ext3和jbd模塊,因此init腳本非常的重要,也是initrd.gz的核心。
- vim /mnt/boot/init 創建init腳本
- #!/bin/sh
- mount -t proc proc /proc 掛載小root上的proc到/proc,其文件係統為proc
- mount -t sysfs sysfs /sys 掛載小root上的sysfs到/sysfs,其文件係統為sysfs
- insmod /lib/modules/jbd.ko 裝載jbd模塊
- insmod /lib/modules/ext3.ko 裝載ext3模塊
- mdev -s 這是busybox提供的功能之一,用於探測dev下的所有設備文件和內核映射文件proc
- mount -t ext3 /dev/hda2 /mnt/sysroot 掛載root到/mnt/sysroot下
- exec switch_root /mnt/sysroot /sbin/init 完成從小root到真正的root的轉換
- chmod +x init 給init執行權限
至此我們看到的內容是:
我們把這些全部的內容都打包並且壓縮起來,就是我們一直所說的initrd.gz
- find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz
●grub
grub目錄下包含尋找內核和啟動內核所需要的各個階段的文件,這些文件不需要我們去編寫,隻要用grub-install命令就可以實現;但是我們需要寫grub的配置文件grub.conf來設定一些參數;
- grub-install --root-directory=/mnt /dev/hdb 創建grub目錄,指定我們的boot目錄的父目錄為/mnt,Boot在/dev/hdb磁盤上
- cd /mnt/boot/grub 切換到grub目錄下
我們來編寫配置文件grub.conf
- vim /mnt/boot/grub/grub.conf
- default=0 設定默認啟動第幾個內核,因為我們的小linux隻有一個內核,所以寫上0就可以了
- timeout=10 設定用戶選擇內核的時長,默認是10秒
- title YINSHUO Linux 這是我們內核的標題,可以任意編寫
- root (hd0,0) 標記了我們內核所在的分區的位置,這裏表示第一塊磁盤上的第一個分區上
- kernel /vmlinuz-2.6.18-308.el5 這是我們內核所在的位置
- initrd /initrd.gz 這是我們initrd文件所在的位置
到此我們的grub文件也算是配置完畢了
●vmlinuz-2.6.18-308.el5
因為內核的編譯複雜且緩慢,因此我並沒有自己編譯新的內核,而是使用的原有的vmlinuz-2.6.18-308.el5內核,所以我隻是把原有的/boot/vmlinuz-2.6.18-308.el5複製到了/mnt/boot/目錄下,因此內核中的各個模塊也沒有做任何修改;
- cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz-2.6.18-308.el5 複製到/mnt/boot/目錄下
到此為止我們所有的跟boot有關的文件都創建完畢了,之後就是創建真正的root分區的文件
製作root分區:
●bin sbin lib etc proc sys dev boot
在製作initrd.gz是時候我們使用busybox虛擬出了各種我們所需要的bin,sbin和usr目錄下我們所需要的腳本,在製作真正的root分區的時候我們也使用同樣的方法。
這些內容都在initrd.gz中提到
- cp /tmp/busybox-1.20.2/_install/* /mnt/sysroot/ -a
- cd /mnt/sysroot
- rm linuxrc -f
- mkdir -p proc sys etc/rc.d/init.d tmp dev/pts boot var/log lib/modules
- mknod /mnt/sysroot/dev/console c 5 1
- mknod /mnt/sysroot/dev/null c 1 3
內核初始化完成後就要進行init進程的管理,而管理init的配置文件是/etc/inittab文件,/etc/inittab定義了係統默認啟動級別,操作係統的初始化,虛擬終端的啟動等內容;而OS的初始化需要用到一個非常重要的配置文件,即/etc/rc.d/rc.sysinit,這個文件是操作係統能夠啟動的核心文件。因此我們在小linux中也要創建相對應目錄下的/mnt/sysroot/etc/inittab,/mnt/sysroot/etc/fstab,/mnt/sysroot/etc/sysctl.conf,和/mnt/sysroot/etc/rc.d/rc.sysinit這些個文件
我們先來編輯/mnt/sysroot/etc/inittab文件
- vim /mnt/sysroot/etc/inittab 創建inittab文件
- ::sysinit:/etc/rc.d/rc.sysinit 表示執行係統初始化,使用的是/etc/rc.d/rc.sysinit腳本
- ::respawn:-/bin/sh 表示係統一旦退出/bin/sh,則會立即重新啟動/bin/sh
- ::shutdown:/bin/umount -a -r 表示當執行shutdown的時候,係統卸載所有的文件係統
接下來編寫/mnt/sysroot/etc/fstab這個文件,它是保重係統初始化過程中掛載/etc/fstab中的所有設備
- vim /mnt/sysroot/etc/fstab 創建/fstab文件
設置fstab中的各項參數
- proc /proc proc defaults 0 0 表示把proc掛載至/proc,文件係統類型是proc,選項是默認選項,不備份也不檢查
- sysfs /sys sysfs defaults 0 0 表示把sysfs掛載至/sys,文件係統類型是sysfs,選項是默認選項,不備份也不檢查
- /dev/hda1 /boot ext3 defaults 0 0 表示把/dev/hda1掛載至/boot,文件係統類型是ext3,選項是默認選項,不備份也不檢查
- /dev/hda2 / ext3 defaults 0 0 表示把/dev/hda2掛載至/,文件係統類型是ext3,選項是默認選項,不備份也不檢查
隻要在/mnt/sysroot/etc/rc.d/rc.sysinit中使用mount -a的命令,就意味著,係統初始化啟動的時候會自動掛載/etc/fstab中我們所設置的這些設備,並掛載到相應的位置。
之後我們來編寫內核參數文件/mnt/sysroot/etc/sysctl.conf
- vim /mnt/sysroot/etc/sysctl.conf 創建內核參數文件
- net.ipv4.ip_forward = 1 1表示開啟網絡
- kernel.hostname=yinshuo.linuxtest 設置主機名為 yinshuo.linuxtest
我們再按照之前尋找ext3和jbd模塊的方法來複製pcnet32模塊和他所依賴的mii模塊,他們是VMware虛擬出的網卡驅動
- cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/pcnet32.ko
- cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules/mii.ko
現在我們來編寫係統初始化腳本文件/mnt/sysroot/etc/rc.d/rc.sysinit
- vim /mnt/sysroot/etc/rc.d/rc.sysinit 創建係統初始化文件
- #!/bin/sh
- echo -e "\t\033[31mYinShuo little Linux\033[0m" 以紅色字體顯示YinShuo little Linux
- mount -t proc proc /proc 掛載proc到/proc,文件係統類型為proc
- mount -t sysfs sysfs /sys 掛載sysfs到/sys,文件係統類型為sysfs
- mount -o remount,rw / 重新以讀寫的方式掛載根文件係統
- mdev -s 探測所有設備,並在dev下創建設備文件
- mount -a 掛載/etc/fstab下的所有設備
- sysctl -p 使內核參數文件/etc/sysctl.conf立即生效
- insmod /lib/modules/mii.ko 裝載內核模塊mii
- insmod /lib/modules/pcnet32.ko 裝載內核模塊pcnet32
- ifconfig lo 127.0.0.1/8 設置本地回環ip=127.0.0.1 netmask=255.0.0.0
- ifconfig eth0 172.16.106.9/16 設置網卡eth0的ip=172.16.106.9 netmask=255.255.0.0
- chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit 給/mnt/sysroot/etc/rc.d/rc.sysinit執行權限
至此我們的root分區的製作也製作完畢
創建虛擬機:
創建一個新的虛擬機,起名字為linuxtext
使用我們之前創建的IDE磁盤
選擇我們的IDE磁盤
我們的小虛擬機也創建完畢
我們製作的Linux的啟動流程:
步驟:
①:首先grub會去尋找內核所在的位置,根據grub.conf文件中配置的信息,會提示我們去選擇哪一個內核,這個選擇界麵會有10秒鍾的時間。
②:找到內核後,內核會進行初始化,探測所有硬件和加載它所需要的各種驅動,同時為了啟動真正的root文件係統,initrd.gz就要提供真正root所需要的ext3文件係統和模塊,掛載設備文件,initrd.gz的最後一步是轉換自己的小root到真正的root上,並完成自己的使命,然後內核會接著啟動用戶空間的第一個進程init,之後內核初始化結束。
③:在用戶空間中,首先會執行/etc/inittab中的內容,首先是啟動/etc/rc.d/rc.sysinit進行操作係統的初始化,包括顯示出"YinShuo little Linux"這個字樣;掛載偽文件;和重新掛載我們的根文件係統為讀寫的方式;探測所有的硬件設備,並創建設備文件;掛載/etc/fstab中所有的內容;設置網卡選項和設置主機名,最終操作係統初始化結束。
④/etc/rc.d/rc.sysinit任務完成後,/etc/inittab會啟動第二項內容,直接進入到/bin/sh界麵,提供用戶交互界麵,我們是可以用各種命令。
這便是我們簡單Linux的運作流程,我們來拭目以待吧!
見證奇跡的時刻:
運行我們的小Linux
看到這裏說明我們成功了!
我們來驗證一下
- ifconfig 查看啟動的網絡設備
- hostname 查看主機名
再驗證是否有busybox,是否能在小linux中有執行權限來創建文件
- ls /bin 查看/bin下的內容
- touch /tmp/chenggongde 在/tmp/目錄下創建文件名為chenggongde文件
至此,製作一個簡單的Linux就算告一段落了。當然,它非常的簡單,也有很多需要完善的地方,比如說內核的編譯和用戶的登錄,這些問題都沒有解決。本次製作Linux的目的更多的是在於認識和學習Linux的啟動過程,為Linux的理解有更清晰的框架。
此Linux雖小,但會有羽翼豐滿的一天的!
最後更新:2017-04-03 21:13:14