一、裁減說明及大體步驟
目标:裁減系統了解其工作原理,對linux系統運作的深入了解。讓linux 僅僅隻有bash 和幾個簡單的指令,并添加網卡子產品實作聯網功能。
1、分區格式化硬碟
2、将硬碟挂載到Linux主機上面,然後安裝grub、複制核心檔案、initrd檔案、安裝bash、網卡子產品、init及建立一些系統運作必要的檔案夾等
3、将做好的硬碟挂在另一台主機上面進行測試(注意:核心後面的參數)
二、準備
環境:
vmware 10.0 、Linux version 2.6.32-358.el6.x86_64(核心版本)--CentOS 6.4的發行版
開始之前我先大概介紹一下系統的啟運流程:
-->POST 加電自檢,載入一小段内置的程式完成初始化及各硬體的檢測
-->加載BIOS 并根據指定的引導次序引導(硬碟、網絡、移動裝置)
-->讀取MBR中的BootLoader,(Grub)
-->根據grub 找到核心所在分區加載核心及initrd的微型檔案系統
-->核心初始化之後去挂載真正的根
-->執行Init、/etc/inittab、/etc/rc.d/rc$RUNLEVEL
vmlinuz-2.6.32-358.el6.x86_64 --> linux 的核心檔案
initramfs-2.6.32-358.el6.x86_64.img --> 同核心一塊加載的一個臨時的根檔案系統,
用來支援兩階段的引導過程。initrd檔案中包含了各種可執行程式和驅動程式,它們可以用來挂載實際的
根檔案系統,然後再将這個initrd RAM磁盤解除安裝,并釋放記憶體
三、安裝過程
- 在現有系統上面加入一塊新的硬碟,ls /dev/sd*,确定你新加的硬碟的label(我這裡新加的硬碟是sdd,因為原來系統裡面已經有三塊硬碟了)
- 使用fdisk、mke2fs對硬碟分區格式化,然後fdiks -l /dev/sdd 進行檢視如下:
注意:我這裡把boot 單獨分區,便于接下來示範grub 的安裝,一般grub大小為200MB ,不要太小了。而其它分區你完全可以做成邏輯卷或者軟raid 等,都是沒有問題的。我的boot 所在分區是sdd1,sdd2為根分區,下文全部按照這樣的格式
- 對這兩個分區進行挂載使用
mkdir /mnt/{boot,sysroot} //挂載前先在mnt目錄下面建立兩個目錄作為boot ,root 的挂載點
mount -t ext4 /dev/sdd1 /mnt/boot
mount -t ext4 /dev/sdd2 /mnt/sysroot
這時時候可以mount 檢視一下挂載情況
如上則顯示挂載成功
- 接下來安裝grub,
grub-install --root-directory=/mnt/dev/sdd //注意root-directory 參數,指得是grub 安裝所在整個分區,也就是boot 所在挂載點(grub 安裝會預設安裝在具有$DIR/boot 的目錄下面),如果改寫成/mnt/boot,意思就是在在grub根分區裡面建一個boot 并安裝之,而grub根分區是boot ,就是在boot分區裡面又建一boot并安裝,這是不正确的。/dev/sdd 是裝置命是要把grub的第一階段放在哪塊硬碟的MBR中
然後拷貝核心、initrd 檔案至boot分區裡面
cp/boot/{vmlinuz-2.6.32-358.el6.x86_64,initramfs-2.6.32-358.el6.x86_64.img}/mnt/boot/
接下來編輯grub 配置檔案
vim /mnt/boot/grub.conf
default //default後加一個數字n,表明是第 n+1個。需要注意的是,GRUB中,計數是從0開始的,而default 0 表示預設的作業系統是這個第一個title 标注的系統
timeout //timeout表示預設等待的時間,這兒是5秒鐘。超過5秒,使用者還沒有作出選 擇的話,系統将自動選擇預設的作業系統。
title // 表示CentOS 的菜單項
root (hd0,0) //指目前系統的第一塊硬碟的一個分區,在grub中所有的硬碟辨別都是hd,
kernel //指明要grub引導要加載的核心檔案,而“/”即是boot 也就是上面标記的(hd0,0),
ro 為readonly ,root 是要加載的真正的根檔案系統後面跟路徑/dev/sda2,selinux=0 預設不開啟,因為我們載減了root, 是以要重新指定 init=/bin/bash ,或者為我們自己寫的一個腳本
initrd // 即init RAM 磁盤檔案所在位置。
提示:如果你忘記了grub.conf 的檔案内容格式,可以VIM 末行模式中輸入 r /boot/grub/grub.conf 即把原系統中的grub.conf檔案内容讀入到目前檔案中,進行修改
- 檢查boot分區制作完畢之後,就可以去裁根分區了
載之前我們要在根分區裡面建立一些系統運作的必要的檔案夾
mkdir /mnt/sysroot/{bin,dev,etc,home,lib,lib64,proc,root,sbin,srv,sys,usr,var}
為了簡單第一次就先把bash 移植到根分區上面,開機檢測看能不能跑起來,移值bash 不僅僅隻是移植二進制程式,重要的是二制程式運作所需要的一個動态庫,可以用ldd `which bash` 檢視。為了快速移植我這裡寫了一個shell 可以參考一下:
#!/bin/bash
#
shopt -s expand_aliases
DIRE='/mnt/sysroot'
exePath(){
local comRoad=`which --skip-alias $1`
local comPre=`dirname $comRoad`
# echo "this is a test ${DIRE}${1}"
if [[ -d ${DIRE}${comPre} ]];then
cp $(which --skip-alias $1) ${DIRE}${comPre}
else
mkdir -p ${DIRE}${comPre}
cp $(which --skip-alias $1) ${DIRE}${comPre}
fi
}
libCp(){
unalias $1 &> /dev/null
local i=1
alias ldd="ldd `which $1` | grep -o \"/[^[:space:]]\{1,\}.*o\.[^[:space:]]\{1,\}\""
local linNum=`ldd | wc -l`
while [[ $i -le $linNum ]];do
local nameLib=$(ldd | sed -n ${i}p)
local dirLib=$(dirname $nameLib)
if [[ -d ${DIRE}${dirLib} ]];then
cp $nameLib ${DIRE}${dirLib}
else
mkdir -p ${DIRE}${dirLib}
cp $nameLib ${DIRE}${dirLib}
fi
let i++
done
}
while true;do
read -p "Please input the COMMAND(no buitin):" comName
if which $comName &> /dev/null ;then
exePath $comName
libCp $comName
elif [[ "$comName" == "quit" ]] ;then
exit 4
fi
done
移植完之後關閉主控端,建立一個虛拟機指定剛才的硬碟為新主機的硬碟開機測試。成功的話你會看到一個bash 指令行
- 這時候僅僅隻能操作一些bash 功能,而我們要做的是實作微型主機開機自動上網功能。這裡就面要為微系統裡面安裝網卡子產品
lsmod //檢視目前系統已安裝的子產品
modinfo MOD_NAME //檢視該子產品的詳細資訊
找到網絡子產品e1000.ko所在位置并拷貝到/mnt/sysroot/lib64
為了實習檢視、安裝、檢測等功能再移植一些必要的指令(利用上面提供的腳本)ifconfig,mount,lsmod,cd,ls,cp,cat,mv,rm,rmmod,insmod
開機時候為了系統安全性root 所在分區是隻讀挂載,而且為了實作微系統實作開機自動加載網絡子產品并且實作配置有網絡屬性,這裡就需要自已定制init 實作其功能,grub.conf 中開機傳遞給核心的參數 init=/sbin/init
#!/bin/bash
#
mount-n -t proc proc /proc
mount-n -t sysfs sysfs /sys
mount-n -o remount,rw /dev/sda2 /
[[$? -eq 0 ]]&&echo "the / is success"
insmod/lib64/module/e1000.ko
ifconfigeth0 172.16.100.110/16
ifconfiglo 172.0.0.1/16
/bin/bash
把該腳本儲存在/sbin/init ,别忘加上可執行權限
- 關閉主控端,重新打開測試機ifconfig 檢視網卡是否存在ip 位址。至此一個簡單的系統就成功了。