對系統的裁剪首先要先了解系統的整個啟動流程,明白其所需要的配置文件;這樣在操作的時候才能清楚自己在做什麼,以及需要做什麼
啟動流程詳解
POST-->BIOS(Boot Sequence) -->MBR讀取BootLoader--->Kernel~initrd~-->init(/etc/inittab)
計算機本身不會執行程序,系統剛剛啟動的時候會將某個ROM中的程序映射到cpu可以尋址的地址空間中去並且能夠讓cpu能夠執行其中的指令,這些指令就是完成系統檢測的,檢測完成後如果核心硬件沒有問題時,緊接著根據BIOS中所設定的啟動流程去依次的尋找對應設備上的MBR;如果MBR存在就會讀取MBR中的Bootloader,Bootloader中配置了所有引導的操作系統的內核所在位置,然後將內核裝載到內存,進行解壓縮並完成內核初始化以後,Bootloader將控制權交給內核
內核初始化
內核初始化完成的工作;硬件探測-->裝載驅動-->掛載根文件系統-->啟動用戶空間的第一個進程(即init)。init本身的配置文件是/etc/inittab 紅帽6上是upstart(也稱呼為init,upstart的配置文件在/etc/inittab和/etc/init/*.conf的文件
initrd介紹
內核完成初始化要依賴於驅動程序,這些驅動程序如果沒有直接做在內核當中的時候,就需要到某個文件路徑去裝載這個驅動程序,當內核訪問根文件系統的設備,但是設備驅動沒有直接裝載到內核時,內核首先要到文件系統上找這個設備驅動,但是文件系統又沒有被掛載,initrd就是內核與文件系統的中間人。initrd有內核所依賴到的額外的設備驅動,最重要的是根文件系統的驅動內核是借助initrd為內核提供訪問真正的文件系統所需要的基本驅動程序所以initrd是個輔助性的過渡性的中間層,能夠實現將kernel與真正的文件系統連接起來的,連接之後,工作即完成了
init主要完成的工作
init的功能即是在inittab配置文件內容定義,主要是:設置默認運行級別、系統初始化腳本(依賴腳本/etc/rc.d/rc.sysinit)、運行指定級別的服務腳本(服務腳本在/etc/rc.d/init.d/目錄下,這些服務腳本都有鏈接,即鏈接到/etc/rc.d/rc#.d/目錄下,#代表是系統的運行級別(rc0.d--rc6.d),還有最後一個運行的腳本rc。local 設置ctrl+alt+delet組合鍵的意義 設置突然斷電時的程序 設置電源恢復後的程序然後啟動虛擬終端。(有了默認運行級別及初始化腳本,系統就可以跑起來的)
/etc/rc.d/rc.sysinit主要功能
在inittab執行的第二步是執行/etc/rc.d/rc.sysinit腳本程序,檢測,並且以讀寫方式重新掛載根文件系統;設定主機名;檢測並掛載/etc/fstab中的其他文件系統;激活交換分區;啟用swap分區初始化外圍硬件設備的驅動;根據/etc/sysctl.conf設定內核參數激活udev和selinux;激活lvm和RAID設備清理過期鎖和FID文件
開始裁剪
注意事項:演示這個過程我用的是vm9,在做的過程中由於虛擬機的數據同步問題會容易出錯的,希望大家在做時速度不要過快,並且多多的sync一下;當磁盤出錯時可使用歸檔壓縮有/mnt/sysroot(因為數據都是在這裡來回的寫入,這個盤很容易掛掉。磁盤損壞的修復方法如下:
1、首先進入/mnt/sysroot/下歸檔壓縮所有文件到一個指定的地方
2、如果直接卸載磁盤不成功的時候使用fuser -km /mnt/sysroot命令後再進行卸載
3、卸載後使用e2fsck -f 命令,如果錯誤過多建議直接格式化
4、然後重新掛載;進入/mnt/sysroot目錄使用zcat FILE | cpio -id命令還原(FILE是文件路徑)
裁剪准備,准備一塊IDE磁盤,劃分兩個主分區即可,這裡的IDE盤劃分了兩個主分區hda1與hda2兩分區大小分別是20M和512M,/dev/hda1掛載點分別為/mnt/boot /dev/hda2掛載點為/mnt/sysroot
/mnt/boot/目錄下文件准備
復制kernel
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz
制作initrd文件
將本機系統的initrd文件解壓到一個特定目錄後編輯其中的init文件
init編輯內容如下(這裡把模塊的安裝都給注釋了,
#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
echo Mounting sysfs filesystem
......... (這裡省略了其中的配置文字,都是沒有注釋的)
mknod /dev/ttyS3 c 4 67
echo Setting up hotplug.
hotplug
echo Creating block device nodes.
mkblkdevs
#echo "Loading ehci-hcd.ko module"
... (這兩個#文字段都是注釋的模塊安裝)
#stabilized --hash --interval 1000 /proc/scsi/scsi
mkblkdevs
echo Scanning and configuring dmraid supported devices
echo Creating root device.
mkrootdev -t ext3 -o defaults,ro /dev/hda2(在這裡指定根文件系統掛載點)
echo Mounting root filesystem.
mount /sysroot
echo Setting up other filesystems.
setuproot
echo Switching to new root and running init.
switchroot
刪減一下initrd文件中lib目錄下的文件剩下這三個就可以
ext3.ko firmware jbd.ko
歸檔壓縮到/mnt/boot/目錄,命名為initrd.gz
find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd
安裝grub
grub-install --root-directory=/mnt/ /dev/hda
編輯grub下的配置文件
vim /mnt/boot/grub/grub.conf
grub.conf配置文件內容如下:
default=0
timeout=3
title My Linux
root(hd0,0)
kernel /vmlinuz ro root=/dev/hda2 quiet
initrd /initrd.gz
/mnt/sysroot目錄下文件准備
創建所需目錄
mkdir mkdir bin sbin dev mnt media etc/rc.d/init.d boot root sys proc var/{log,lock/subsys,run,tmp} usr/{bin,sbin,src,local} lib/modules opt home -pv
編輯inittab配置文件
vim /mnt/sysroot/etc/inittab 內容如下:
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
編輯rc.sysinit腳本配置文件
vim /mnt/sysrootetc/rc.d/rc.sysinit 內容如下:
#!/bin/bash
#
echo -e "\tMy\033[34mMageTeam\033[0mLinux"
/bin/bash
chmod +x /mnt/sysrootetc/rc.d/rc.sysinit(添加執行權限)
到這裡小linux的簡單配置就完成了下面我們用腳本復制命令及所依賴的庫文件,腳本內容如下:
#!/bin/bash
#
dest=/mnt/sysroot
libcp() {
libpath=${1%/*}
[ ! -d $dest$libpath ] && mkdir -p $dest$libpath
[ ! -e $dest${1} ] && cp $1 $dest$libpath && echo " copy lib $1 finished"
}
bincp() {
cmdpath=${1%/*}
[ ! -d $dest$cmdpath ] && mkdir -p $dest$cmdpath
[ ! -e $dest${1} ] && cp $1 $dest$cmdpath
for lib in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do
libcp $lib
done
}
read -p " your command:" cmd
until [ $cmd = 'q' ]; do
! which $cmd && echo "wrong command" && read -p "input again:" cmd && continue
command=`which $cmd | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
bincp $command
echo "copy $command finished."
read -p "continue:" cmd
done
啟動裁剪的系統復制init bash這兩個就能啟動,其他的命令可在後用到後再進行添加(例如,touch,vim,chmod,chown,mkdir,rm,mv,cp,cat,mount,umount,ping,ifconfig,insmod,modprobe,rmmod,route,reboot,shutdown,hostname等)虛擬機完成的一定要多多sync哦,這個是很重要滴!!!
開機關機功能添加
開機關機功能配置流程
編輯/mnt/sysroot/etc/inittab配置文件添加以下內容:
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
在/mnt/sysroot/etc/rc.d/init.d/目錄下創建一個腳本halt內容如下:
#!/bin/bash
#
case $0 in
*reboot)
COMMAND='/sbin/reboot' ;;
*halt)
COMMAND='/sbin/halt -p' ;;
*)
echo "Only call this script by *reboot OR *halt;"
;;
esac
exec $COMMAND
chmod +x /mnt/sysroot/etc/rc.d/init.d/halt 添加腳本執行權限
在rc.d目錄下創建rc0.d與rc6.d目錄:
進入rc0.d目錄創建鏈接:
ln -sv ../init.d/halt S99halt
進入rc6.d目錄創建鏈接:
ln -sv ../init.d/halt S99reboot
在/mnt/sysroot/etc/rc.d/目錄下創建rc腳本,內容如下(這裡的rc腳本簡單的定義了一下)
#!/bin/bash
#
RUNLEVEL=$1
for I in /etc/rc.d/rc$RUNLEVEL.d/K*; do
$I stop
done
for I in /etc/rc.d/rc$RUNLEVEL.d/S*; do
$I start
done
chmod +x /mnt/sysroot/etc/rc.d/rc 添加腳本執行權限
每一個步驟的完成建議都要測試一下,這樣能更容易排錯,並且容易熟悉一個功能的執行流程
切換級別自動開啟或關閉相關服務的功能添加
在inittab中加入一個級別3
l3:3:wait:/etc/rc.d/rc 3
在init.d目錄中創建一個服務腳本為tserver內容如下:
#!/bin/bash
#
# chkconfig: 35 66 33
# description: test service script
#
prog=tserver
lockfile=/var/lock/subsys/$prog
start() {
touch $lockfile
}
stop() {
rm -f $lockfile
}
status() {
if [ -f $lockfile ]; then
echo "Running..."
else
echo "Stopped..."
fi
}
usage() {
echo "Usage: $prog {start|stop|status|restart}"
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
esac
添加執行權限 chmod +x /mnt/sysroot/rc.d/init.d/tserver
在/mnt/sysroot/etc/rc.d/目錄下創建rc3.d目錄在其中添加鏈接:
ln -sv ../init.d/tserver S66tserver
分別在rc0.d與rc6.d中添加鏈接:
ln -sv ../init.d/tserver K33tserver
補充
在inittab配置文件中3級別不會被啟動,因為腳了本的第二行就定義了系統啟動後就去執行rc.sysinit,然後啟動
/bin/bash了 所以在inittab配置文件中需要設置啟動終端命令(使用agetty命令,現在還沒有用戶)並且init在
啟動時
需要sh程序,這裡需要為bash創建一個鏈接
編輯inittab配置文件 添加以下代碼
1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1
2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2
進入到/mnt/sysroot/bin/目錄下創建鏈接:
ln -sv bash sh
掛載文件系統
在tserver腳本中需要創建鎖文件,所以需要掛載文件系統
編輯/mnt/sysroot/etc/fstab配置文件,內容如下:
/dev/hda2 / ext3 defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
編輯/mnt/sysroot/et/rc.d/rc.sysinit腳本 添加一下代碼即可
echo "Remount rootfs...."
mount -n -o remount,rw /
mount -a
到這裡就可以登錄這兩個終端(ctl+alt+F1/F2命令可切換終端),並且在切換級別時能夠實現相關服務的開啟和關閉功能
登錄陸界面的美化配置即function函數添加
在啟動相關服務時,成功或失敗時有“OK”或“failure” 信息顯示
首先在/mnt/sysroot/rc.d/init.d/functions編寫一個函數
vim /mnt/sysroot/rc.d/init.d/functions 內容如下:
CREEN=`stty -F /dev/console size 2>/dev/null`
COLUMNS=${SCREEN#* }
[ -z $COLUMNS ] && COLUMNS=80
SPA_COL=$[$COLUMNS-14]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`; do
echo -n " "
done
echo -e "[ ${RED}FAILED${NORMAL} ]"
}
添加執行權限 chmod +x /mnt/sysroot/rc.d/init.d/functios
修改tserver腳本 只需改變tserver腳本中status函數上面的腳本,內容如下:
. /etc/rc.d/init.d/functions
prog=tserver
lockfile=/var/lock/subsys/$prog
start() {
touch $lockfile
[ $? -eq 0 ] && success "Starting $prog" || failure "Staring $prog"
}
stop() {
rm -f $lockfile
[ $? -eq 0 ] && success "Stopping $prog" || failure "Stopping $prog"
}
現在測試一下,是不是現在的小系統更像紅帽了
注意:過程中要把腳本使用到的相應命令復制過去
為系統添加IP地址以及主機名
添加主機名:
mkdir /mnt/sysroot/etc/sysconfig
vim /mnt/sysroot/etc/sysconfig/network 內容如下
HOSTNAME=Minilinux
編輯/mnt/sysroot/etc/rc.d/rc.sysinit
添加以下內容
#Set the hostname.....
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
配置IP:
首先要先移植所需模塊
cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/
cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules/
開機裝載模塊設置
編輯/mnt/sysroot/etc/rc.d/rc.sysinit文件添加以下內容
# Initializing network device....
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
定義一下IP地址
mkdir -pv /mnt/sysroot/etc/sysconfig/network-scripts
vim /mnt/sysroot/etc/sysconfig/network-scripts/ifcfg-eth0 內容如下(這裡是用最簡易的方法來實現它)
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.51.51
NETMASK=255.255.255.0
GATEWAY=172.16.0.1
ONBOOT=yes
使用腳本來實現IP地址添加:
vim /mnt/sysroot/rc.d/init.d/network 內容如下:
#!/bin/bash
#
# chkconfig: 35 09 90
# description: network service
prog=network
. /etc/rc.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0
. $CONF
start() {
ifconfig eth0 $IPADDR/16 up
[ -z $GATEWAY ] && route add default gw $GATEWAY
}
stop() {
ifconfig eth0 down
}
status() {
ifconfig eth0
}
usage() {
echo "$prog: {start|stop|restart|status}"
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status ;;
*)
usage
exit 1
;;
esac
添加執行權限 chmod +x /mnt/sysroot/rc.d/init.d/network
為相應級別創建鏈接
進入rc0.d 輸入以下代碼;
ln -sv ../init.d/network K90netwrok
進入rc6.d 輸入以下代碼:
ln -sv ../init.d/network K90netwrok
(0級別與6級別不需要開啟網絡服務)
進入rc3.d 輸入以下代碼:
ln -sv ../init.d/network S09netwrok
到這裡裁剪後的系統IP相關配置就完成了
用戶登陸界面顯示信息設置
vim /mnt/sysroot/etc/issue 直接編輯文件,添加下面這兩行代碼
My Linux
Kernel \r on an \m
設定內核參數
vim /mnt/sysroot/etc/sysctl.conf 直接編輯文件添加一行代碼即可
net.ipv4.ip_forward = 1
編輯/mnt/sysroot/etc/rc.d/rc.sysinit文件 添加以下內容
sysctl -p &> /dev/null
添加用戶功能
使用不依賴與PAM的login程序 (已經編譯好的)
放到/mnt/sysroot/bin/目錄下,之後賦予它執行權限
登陸時是使用login程序來驗證登陸的,實現用戶認證是到特定的文件中去認證的,傳統的方式都是
放在/etc/passwd以及/etc/shadow
nsswitch是個框架,它能夠完成配置到哪個去找用戶的賬號及密碼;nsswitch就是依靠配置文件來定義的
nsswitch這個框架由庫和相對應的配置文件來組成,在配置文件中可直接定義基於哪個庫去去找相應的驗證文件
例如:在/ect/passwd認證所找的是libnss_file.so這樣的庫
vim /mnt/sysroot/etc/nsswitch.conf 內容如下:
passwd: files
shadow: files
group: files
hosts: files dns
復制庫文件
cp -d /lib/libness_file* /mnt/sysroot/lib/
cp -d /usr/lib/libnss_files.so/mnt/sysroot/usr/lib/
cp -d /usr/lib/libnss3.so /usr/lib/libnssckbi.so /usr/lib/libnssutil3.so /mnt/sysroot/lib/
創建用戶
這裡直接從本系統上復制一個用戶過來
grep -E "^root\> /etc/passwd > /mnt/sysroot/etc/passwd
grep -E "^root\> /etc/shadow > /mnt/sysroot/etc/shadow
grep -E "^root\> /etc/group> /mnt/sysroot/etc/group
修改inittab文件,現在可以改為讓輸入用戶的登陸方式了
vim /mnt/sysroot/etc/inittab 整體內容如下內容如下:
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l3:3:wait:/etc/rc.d/rc 3
l6:6:wait:/etc/rc.d/rc 6
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
到這裡用戶功能的添加就完成了
補充
對/mnt/sysroot/etc/rc.d/rc.sysinit配置的整體修改,來實現對界面的進一步美化,代碼如下:
#!/bin/bash
#
. /etc/rc.d/init.d/functions
echo -e "\tMy\033[34mMagedu.com\033[0mLinux"
echo "Remount rootfs...."
mount -n -o remount,rw /
[ $? -eq 0 ] && success "Remount rootfs" || failure "Remount rootfs"
mount -a
[ $? -eq 0 ] && success "Mount others filesystem" || failure "Mount others filesystem"
#Set the hostname.....
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
[ $? -eq 0 ] && success "Set the hostname" || failure "Set the hostname"
# Initializing network device....
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
[ $? -eq 0 ] && success "Initializing network device" || failure "Initialization network device"
ifconfig lo 127.0.0.1/8
[ $? -eq 0 ] && success "Activating loopback network device" || failure "Activating loopback network device"
sysctl -p &> /dev/null
[ $? -eq 0 ] && success "Set kernel parameter" || failure "Set kernel paramenter"
到這裡僅有5M大小小linux的裁剪過程就完成了,個人感覺把這個過程操作完成出來對linux的運行流程、配置文件的理解以及對其進一步的認識等會有所幫助的。
心動不如行動,開始裁剪您的小系統吧!!!
本文出自 “Fly*On*Sky” 博客,請務必保留此出處http://djy0000.blog.51cto.com/5816828/1167825