1. 程式人生 > >自制linux系統

自制linux系統

網絡 linux

本實驗以centos6為例


系統啟動流程說明

-->加載BIOS,通過BIOS程序加載CMOS的信息,並通過CMOS獲得硬件信息

-->開機自檢POST

-->讀取MBR的信息

-->grub引導系統啟動

-->開啟系統第一個進程init

-->用戶登陸

有幾點我們需要理解:

1、MBR是磁盤的第一個扇區,512字節,其中前446字節是boot loader引導加載程序,後64字節是分區表,最後2字節是MBR的結束位55aa

系統要啟動,就要加載內核、各種驅動,那linux的內核存放在/boot下,驅動文件存放在/lib/modules下,所以啟動流程第一步得先進入/boot加載內核文件,

而/boot是一個單獨的分區並使用ext4文件系統。也就是說要進入/boot加載內核得先有文件系統驅動,而要安裝文件系統驅動得先加載內核。如此進入一個死循環。

但是我們知道,實際情況是linux可以正常啟動的,這是什麽原因呢?

因為有MBR,MBR中前446字節的boot loader起引導作用,我們稱為grub stage1,接著進入stage1.5階段,此階段加載的信息在MBR512字節之後的27個扇區。

stage1.5結束後進入stage2階段,stage2階段會執行配置文件grub.conf,這份文件內容如下:

default=0  //默認加載的內核、initrd文件,0表示第一個title
timeout=5  //開機過程中出現的菜單選項超時時間
splashimage=(hd0,0)/grub/splash.xpm.gz  //啟動菜單選項的背景圖片
hiddenmenu  //隱藏菜單的後臺執行過程
title CentOS 6 (2.6.32-696.el6.x86_64)  //名字而已
        root (hd0,0)  //以第1塊磁盤的第1個分區為根,說白了就是/boot為根,此處的根為系統啟動使用,與啟動後的根/兩碼事
        kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=f1d8d9f5-4d1a-42e8-8a7f-600f668ce44f rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        //kernel 以只讀方式加載內核,此處的UUID是啟動結束後的根/的UUID
        initrd /initramfs-2.6.32-696.el6.x86_64.img
        //initrd 其中含有文件系統驅動,這樣就可以加載內核文件了

2、啟動系統第一個進程/sbin/init,其作用就是部署好軟件環境,即主機名稱、網絡配置、文件系統格式等

而實現這些功能,主要是由/etc/inittab和/etc/init.d/*.conf這些文件完成的(centos6版本)。centos5版本的這些功能全在/etcinittab這一個文件上。

其大致含義如下:

-->默認的runlevel,用戶登陸系統默認的級別

  • 0:關機

  • 1:單用戶模式

  • 2:多用戶模式,有些網絡功能不支持

  • 3:完全多用戶模式,字符界面

  • 4:預留

  • 5:圖形界面(默認runlevel)

  • 6:重啟

-->執行系統軟件運行環境的腳本/etc/rc.d/rc.sysinit

其作用就是準備好系統的運行環境,如掛載文件系統、swap、時鐘、加載外設驅動、激活sysctl.conf文件設置內核參數

-->7個不同runlevel,啟動可非啟動服務腳本的路徑

-->斷電和恢復供電的處理

-->終端tty的設置

-->界面運行設置

這些步驟完成了,用戶就可以登陸使用系統了;


我們做個實驗,加深下理解

自制linux系統

準備:一塊新的磁盤、一臺裝好系統的機器和一臺沒有系統的機器。可以在虛擬機上完成本實驗

步驟1、在本機對新磁盤建分區、文件系統

創建2個必要的分區 /dev/sdb1對應boot,/dev/sdb2對應/

fdisk /dev/sdb

創建文件系統,以ext4為例

mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2

blkid 命令可以檢查文件系統信息

步驟2、掛載boot

mkdir /mnt/boot
掛載目錄必須為boot,因為grub的stage2會專門找到boot目錄
mount /dev/sdb1 /mnt/boot/

步驟3、安裝grub

grub-install  --root-directory=/mnt /dev/sdb
stage1安裝在/dev/sdb磁盤上,stage2安裝在/mnt/boot目錄下

此時/mnt/boot裏面會有用於grub的stage2階段的目錄

步驟4、復制內核、initramfs

cp /boot/vmlinuz-2.6.32-696.el6.x86_64  /mnt/boot/
cp /boot/initramfs-2.6.32-696.el6.x86_64.img  /mnt/boot/

步驟5、編輯grub.conf

技術分享

圖中的內容上文基本都介紹過,本實驗中root=/dev/sda2,因為這塊磁盤是要作為另一臺機器的啟動磁盤自然是sdba2了

selinux=0,因為selinux可能會影響本實驗效果,所以開始就將其關閉

init=/bin/bash,我們使用bash作為第一個啟動進程

步驟6、掛載根/,並初始化

創建目錄並掛載根

mkdir /mnt/root
mount /dev/sdb2 /mnt/root/
mkdir /mnt/root/{etc,lib,sbin,tmp,var,sys,proc,dev,}  //創建root下對應的目錄

運行下述腳本,其作用是復制命令文件與庫文件到根目錄下(/mnt/root),前提是需要我們輸入常用的命令

我們輸入的命令就是自制的linux系統支持的命令

#! /bin/bash
title () {
        export CMD
        read -t 30 -p "input an exec cmd or press ‘quit‘: " CMD
        if [ "$CMD" = "quit" ];then
                exit
        else
                is_exec
        fi
        title
}
#判斷輸入的是可執行文件
is_exec () {
        if `which $CMD &> /dev/null` ;then
                copy_cmdfile
                copy_libfile
                echo "--->done"
        else
                echo "not a command"
                exit
        fi
}
#拷貝命令文件
copy_cmdfile () {
        EXEC_CMD=`which $CMD`
        if [ ! -e /mnt/root$EXEC_CMD ];then
                cp  --parents $EXEC_CMD /mnt/root
        fi
unset EXEC_CMD
}
#拷貝命令文件對應的庫文件
copy_libfile () {
        ldd `which $CMD` | grep -o  "/.*[0-9] " | while read line ;do
                if [ ! -e /mnt/root$line  ];then
                        cp  --parents $line  /mnt/root/
                fi
        done
unset line
}

title

至此實驗結束,然後關機,取出磁盤,裝到另一臺沒有系統的主機上,啟動即可

啟動後的界面如下:

技術分享


本文出自 “高攀” 博客,請務必保留此出處http://panpangao.blog.51cto.com/10624093/1962313

自制linux系統