linux系統裁剪


l 要求:

裁剪一個裝載有網卡驅動可以上網並且使用到init的一個小系統

l 準備;

虛擬機,centos6.4

l 步驟;

一、在宿主機上添加一塊硬盤,併爲其安裝grub

1. 在宿主機上添加一塊硬盤,這裏添加的是sde這塊硬盤。

2. 使用fdisksde分兩個區,sde1 100M)  sde22G)

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了。所以後邊出來了(hd00)這樣的硬盤標號。第一個0代表硬盤編號,第二個表示分區


8. 此時硬盤sdegrub就算安裝成功了,我們看一下里邊的內容

  [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


        Grub3stage


      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開始編號


配置文件代表的意義

  1default=#: 指定默認啓動的內核或OS

  2timeout=#: 等待用戶選擇要啓動的內核或OS的時長,單位爲秒;

  3Kernel 後邊給的參數爲傳遞給內核的參數

  4Ro  表示以只讀的方式掛載

  5Seliunx=0 表示不啓用selinux ,因我們這裏的小系統只要內核和幾個簡單的命令,啓動不了selinux ,而gurb默認是開啓selinux的,這樣我們開機的時候會出現問題而無法啓動系統

  6Root=/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


執行這個腳本,分別將bashlscd vi cattreefdiskmvtouch,這些常用的命令複製到/mnt/sysroot中對用的路徑下。


此時將sde這塊硬盤放到一個其他的電腦上就已經可以啓動了,只不過有點簡陋。只能在bash shell中執行cp過去的幾個小命令。也沒有網絡功能,如果需要使用網絡功能,就需要通過下邊的幾個步驟繼續遷移網卡驅動模塊了。

      新建虛擬機,把sde這塊硬盤放到新虛擬機中當啓動盤。(注意:使用sde這看硬盤的時候要講原宿主機掛載)      


           無圖無真像,貼個圖給大家看看吧。


wKiom1MVsgORbhfiAAHfrUo_cXc420.jpg

wKioL1MVseqzMmpOAANfA77Ksmk044.jpg


五、遷移e1000 網卡驅動內核模塊

系統要想上網得需要有網卡驅動。而linux中網卡驅動不是在內核中自帶的,而是以模塊的方式在內核中裝載的,所以我們要想讓我們遷移的小linu能夠有網絡功能還必須爲其裝載網卡驅動模塊。

下邊列出關於管理內核模塊所用到的幾個命令,當然我們在做下邊操作之前還需要通過上邊的那個cp二進制的腳本來將幾個命令cp過去,另外別忘了複製ifconfigping這些我們等會可能會用到命令了。


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系統就做好了。


wKiom1MVspjxGGJwAAK4dzoRe3A415.jpg

wKioL1MVsnOTQh9aAAJ_bFPsMCo422.jpg


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指向此腳本所在的路徑。

wKiom1MVstaisbJFAAEq-dTIRAE715.jpg

wKiom1MVstnBxgKTAAP9u0MGnUo665.jpg


ok,這樣一個簡單的經過剪裁的小linux已經站在了我們的面前。當然,他有待提升加強的功能還有太多。讓我們在隨後的日子繼續學習來補充加強它吧~!!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章