l 要求:
裁剪一個裝載有網卡驅動可以上網並且使用到init的一個小系統
l 準備;
虛擬機,centos6.4
l 步驟;
一、在宿主機上添加一塊硬盤,併爲其安裝grub
1. 在宿主機上添加一塊硬盤,這裏添加的是sde這塊硬盤。
2. 使用fdisk爲sde分兩個區,sde1 (100M) sde2(2G)
3. 創建目錄/mnt/boot /mnt/sysroot
mkdir -pv /mnt/{boot,sysroot}
4. 將/dev/sde1掛載到/mnt/boot ,/dev/sde2掛載到/mnt/sysroot
mount /dev/sde1 /mnt/boot/ mount /dev/sde2 /mnt/sysroot/ [root@station57 mnt]# mount ...... ...... /dev/sde1 on /mnt/boot type ext4 (rw) /dev/sde2 on /mnt/sysroot type ext4 (rw)
5. 當剪裁成功後sde2分區會當作新系統的跟分區,所以要給你sde2這個分區也就是/mnt/sysroot 這個目錄創建linux系統常用的幾個目錄
[root@station57 sysroot]# mkdir -pv mnt proc root home cat sys lib lib64 dev media sbin tmp var
6. 安裝gurb
注意此處的“--root-directory=/mnt”選項,sde1是掛載在/mnt/boot上邊的,不要寫成--root-directory=/mnt/boot 了。
[root@station57 mnt]# grub-install --root-directory=/mnt /dev/sde Installation finished. No error reported. This is the contents of the device map /mnt/boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (fd0)/dev/fd0 (hd0)/dev/sda (hd1)/dev/sdb (hd2)/dev/sdc (hd3)/dev/sdd (hd4)/dev/sde
7. 因爲我的宿主機上有五塊硬盤,所以此處列出了hd1--hd4.。我們的sde對應的硬盤是hd4,但是這個編號4僅僅對次主機有效,換到一個單獨的主機上的時候就是hd0了。所以後邊出來了(hd0,0)這樣的硬盤標號。第一個0代表硬盤編號,第二個表示分區
8. 此時硬盤sde的grub就算安裝成功了,我們看一下里邊的內容
[root@station57 mnt]# ls /mnt/boot/grub/ device.map iso9660_stage1_5 stage1 xfs_stage1_5 e2fs_stage1_5 jfs_stage1_5 stage2 fat_stage1_5 minix_stage1_5 ufs2_stage1_5 ffs_stage1_5 reiserfs_stage1_5 vstafs_stage1_5
Grub有3個stage,
1st stage: 位於MBR中,爲了引導2nd stage
1.5 stage: 位於boot基本磁盤分區中,爲識別內核文件所在的文件系統提供文件系統識別擴展
2nd stage: 位於boot基本磁盤分區中,GRUB的引導程序
二、複製內核vmlinuz和內核加載部分硬件所依賴的initramfs
1. [root@station57 mnt]# cp /boot/vmlinuz-2.6.32-358.el6.x86_64 /mnt/boot/ 2. [root@station57 mnt]# cp /boot/initramfs-2.6.32-358.el6.x86_64.img /mnt/boot/
三、添加gurb的配置文件
grub安裝完成了如果不添加配置文件,那麼每次啓動都要手動寫內核文件vmlinuz-和驅動相關的initramfs兩個文件的路徑,而且還要定義跟的位置,很不方便,於是就要用到gurb的配置文件grub.conf
[root@station57 mnt]# vim /mnt/boot/grub/grub.conf default=0 timeout=5 title CentOS (author:xuqimin) root (hd0,0) kernel /vmlinuz-2.6.32-358.el6.x86_64 ro selinux=0 root=/dev/sda2 init=/bin/bash initrd /initramfs-2.6.32-358.el6.x86_64.img
在grub中,硬盤以hd開頭緊跟一個數字做各磁盤設備的標記,從0開始編號
Part表示方式:代表分區,從0開始編號
配置文件代表的意義
1、default=#: 指定默認啓動的內核或OS;
2、timeout=#: 等待用戶選擇要啓動的內核或OS的時長,單位爲秒;
3、Kernel 後邊給的參數爲傳遞給內核的參數
4、Ro 表示以只讀的方式掛載
5、Seliunx=0 表示不啓用selinux ,因我們這裏的小系統只要內核和幾個簡單的命令,啓動不了selinux ,而gurb默認是開啓selinux的,這樣我們開機的時候會出現問題而無法啓動系統
6、Root=/dev/sda2 表示等系統系統的時候會以sda2 ,也就是剛剛我們掛載的sde2來當作系統的根目錄。
四、編寫複製命令及其對應的庫的腳本,並完成命令遷移
gurb和內核文件及驅動文件都已就緒,但是系統還只是一個只有內核的空殼而已,顯然我們還不能用它做任何事情。因此我們就需要把linux中常用到的命令複製到我們製作的小系統中,以讓它工作起來。
我們知道命令是由二進制文件,極其依賴的庫文件,再加上一些幫助文檔組成的。而且一個命令的庫文件不僅僅只有一個。所以我們單單手動複製起來的話勢必會很麻煩。因此此時就需要把我們前面學到的腳本知識發揮一下,用shell腳本實現命令的複製,遷移。下邊是我前幾天做的複製命令的腳本。
(腳本可能有不完善的地方,也可能在大神眼中顯得很臃腫,不喜勿噴)。
#!/bin/bash 2 3 function EnterCommand { 4 read -p "Enter a command:" command 5 while true;do 6 [[ "$command" == "quit" ]] && exit 2 7 if which $command &> /dev/null ;then 8 break 9 else 10 echo -e "\n\033[31mno such command,please try agiain.and quit to quit:\n\033[0m" 11 read -p "Enter a command:" command 12 fi 13 done 14 } 15 16 17 function bincp { 18 commandDir=`which --skip-alias $command` 19 distintion="/mnt/sysroot$commandDir" 20 if [ -e $distintion ];then 21 echo "bin of $command is already exist." 22 else 23 [ -d /mnt/sysroot`dirname $commandDir` ] || mkdir -p /mnt/sysroot`dirname $commandDir` 24 cp $commandDir /mnt/sysroot`dirname $commandDir` && echo "the bin cp ok.." || echo "cp bin error" 25 fi 26 } 27 28 29 function Libcp { 30 commandLib=`ldd $commandDir | grep -o "/lib.*[[:space:]]"` 31 32 for i in $commandLib ;do 33 distintionlib="/mnt/sysroot$i" 34 if [ -e $distintionlib ];then 5 echo "$i is exist." 36 37 else 38 39 [ -d /mnt/sysroot`dirname $i` ] || mkdir -p /mnt/sysroot`dirname $i` 40 cp $i /mnt/sysroot`dirname $i` && echo "lib co ok.." || echo "cp lib erro " 41 fi 42 done 43 } 44 45 46 47 48 EnterCommand 49 50 while true;do 51 bincp 52 Libcp 53 EnterCommand 54 done
執行這個腳本,分別將bash,ls,cd ,vi ,cat,tree,fdisk,mv,touch,這些常用的命令複製到/mnt/sysroot中對用的路徑下。
此時將sde這塊硬盤放到一個其他的電腦上就已經可以啓動了,只不過有點簡陋。只能在bash shell中執行cp過去的幾個小命令。也沒有網絡功能,如果需要使用網絡功能,就需要通過下邊的幾個步驟繼續遷移網卡驅動模塊了。
新建虛擬機,把sde這塊硬盤放到新虛擬機中當啓動盤。(注意:使用sde這看硬盤的時候要講原宿主機掛載)
無圖無真像,貼個圖給大家看看吧。
五、遷移e1000 網卡驅動內核模塊
系統要想上網得需要有網卡驅動。而linux中網卡驅動不是在內核中自帶的,而是以模塊的方式在內核中裝載的,所以我們要想讓我們遷移的小linu能夠有網絡功能還必須爲其裝載網卡驅動模塊。
下邊列出關於管理內核模塊所用到的幾個命令,當然我們在做下邊操作之前還需要通過上邊的那個cp二進制的腳本來將幾個命令cp過去,另外別忘了複製ifconfig,ping這些我們等會可能會用到命令了。
1. 查找我們需要的模塊在宿主機上的位置
Lsmod:查看內核轉載的模塊
Lspci:查看pci插口相關信息
Modproc:轉載相應模塊
Modproc -r :卸載模塊
Insmod:裝載模塊
Rmmod:卸載模塊
有了這些命令接下來讓我們找找網卡模塊在哪吧。
[root@station57 sysroot]# lsmod Module Size Used by autofs4 26513 3 8021q 25317 0 ipv6 321422 96 e1000 170646 0 sg 29350 0 ...... ...... dm_log 9930 2 dm_mirror,dm_region_hash dm_mod 82839 14 dm_mirror,dm_log
上邊的e1000就是我們要找的網卡模塊,你是不是該問,那還是沒有解決問題呀,e1000在哪呢。我們別忘了還有一個modinfo命令呢。
[root@station57 sysroot]# modinfo e1000 filename: /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko version: 7.3.21-k8-NAPI license: GPL description: Intel(R) PRO/1000 Network Driver author: Intel Corporation, <[email protected]> srcversion: 1D4F1E82BB99EA36D320B1B alias: pci:v00008086d00001000sv*sd*bc*sc*i* ........ depends: vermagic: 2.6.32-358.el6.x86_64 SMP mod_unload modversions parm: TxDescriptors:Number of transmit descriptors (array of int) ..... ......
好大一串數據呀,反正大多數我是不懂幹嘛的。暫時先不關心其他的內容吧,我們只關心這個路徑在哪、還有下邊的depends是此模塊所依賴的別的模塊。這裏的e1000不依賴別的模塊。
filename: /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
2. 複製該模塊到我們的小型linux中安裝
[root@station57 sysroot]# cp /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/sysroot/lib/modules/ [root@station57 sysroot]# ls /mnt/sysroot/lib/modules/ e1000.ko
3. 掛起宿主機,開啓目標主機,並用剛剛使用的sde來做啓動盤開啓主機。
使用insmod 裝載模塊,然後就可以使用ifconfig配置ip地址了。這樣我們的帶有網絡功能的小linux系統就做好了。
l 使用init自啓動服務腳本完成系統初始化
我們的帶有網絡功能的小系統已經做好,但是你有沒有發現每次重啓後我們的網絡模塊都要重啓裝載,而且ip地址也要重新配置。這真是一件頭疼的事情,有沒有一個腳本可以自動化的幫我們完成這些模塊的自動裝載和ip的自動分配呢,當然有,init就是爲了完成這個任務,但是init這個程序太過複雜,需要依賴的東西也太多,我們也不需要。那麼就讓我們來自己寫一個腳本來代替init完成我們的小系統初始化吧。
[root@station57 mnt]# vim /mnt/sysroot/sbin/init 1 #!/bin/bash 2 # 3 echo -e "\t\033[31;5mI am a simple Linux, but I'll grow up soon\033[0m" 4 5 insmod /lib/modules/e1000.ko && echo -e "Moduless e1000 loding\033[60G\033[32m[ ok ]\033[0m " || echo "Moduless e1000 loging error" 6 ifconfig lo 127.0.0.0/16 && echo -e "The ip lo add ...\033[60G\033[32m[ ok ]\033[0m " || echo "ip of lo add error" 7 ifconfig eth0 172.16.20.11/16 && echo -e "The ip eth0 add ...\033[60G\033[32m[ ok ]\033[0m " || echo "ip of eth0 add error" 8 /bin/bash :::::別忘了最後啓動shel呀!
這個腳本完成了對模塊e1000的自動掛載,並且自動配置ip的功能。
不過需要注意的是,如果想讓他開機自動生效,需要在grub.conf中定義,讓init指向此腳本所在的路徑。
ok,這樣一個簡單的經過剪裁的小linux已經站在了我們的面前。當然,他有待提升加強的功能還有太多。讓我們在隨後的日子繼續學習來補充加強它吧~!!