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