linux的裁剪過程

linux的裁剪過程,讓你的小linux更加完善,趕快試試吧!



一、系統啓動流程:

1、POST-->BIOS(Boot Sequence)--> BootLoader(MBR)--> Kernel(initrd,initramfs)--> init (/etc/inittab)

第一步首先加電自檢,計算機本身不會執行程序,由此它會載入一段程序,它會在開機時自動實現將某個RAM中的程序映射到cpu可以尋址的地址空間中去,並且可以讓cpu可以執行其中的指令,而這些指令是完成系統檢測的,檢測完成之後,當所有的硬件或基本的核心硬件沒有問題的話就進行BIOS。根據BIOS中所設定的程序啓動流程去找與其對應設備上的MBR,按照引導次序執行(Boot Sequence),根據引導次序逐個查找對應的存儲設備上的MBR,若MBR存在,則讀取MBR上的BootLoader,BootLoader是一段程序,早期的MBR總共512字節,但它留給BootLoader空間大小是446字節,在BootLoader當中配置了所有引導的操作系統的內核的位置,因此BIOS在載入內存以後,當它實現將控制流程或控制權限轉交給BootLoader以後,BootLoader就接收了整個系統的控制權限,而後根據用戶的選擇,去讀取相應操作系統的內核。第三步:將內核裝載進內核中合適的位置,解壓縮並完成內核初始化,BootLoader會把控制權限轉交給內核。第四步:如果內核訪問根文件系統的設備需要用到某個驅動程序,而內核中也沒有,就需要到根文件中去找這個驅動程序,但這文件系統本身又沒有掛載,因此要想訪問根文件系統得先找到驅動,要訪問驅動得先找到根文件系統,這就出現了一個難題,這時就要藉助於initrd,爲內核提供訪問真正的根文件系統所需要的基本驅動程序。因此initrd是一個輔助性的、過渡性的中間層。它能夠實現將kernel與真正的根文件系統連接起來,當連接完成之後它就沒有任何意義了。第五步:執行init進程,而init程序本身的配置文件是/etc/inittab(而在紅帽6上init不在是傳統的init,而是upstart,而upstart的配置文件在/etc/inittab和/etc/init/.*conf下的所有文件

2、(kernel)內核初始化:

硬件探測

裝載驅動

掛載根文件系統(rootfs)

啓動用戶空間中的第一個進程init

3、init所要完成的工作主要取決於/etc/inittab,而 /etc/inittab所要完成的任務有很多:設定默認運行級別;系統初始化腳本(/etc/rc.d/rc.sysinit);運行指定級別的服務腳本:/etc/rc.d/init.d/。連接到:/etc/rc.d/rc#.d(rc0.d--rc6.d),而鏈接文件比較獨特,有的是以K開頭的文件,有的是以S開頭的文件,這兩種文件的後面都跟有一個數字(00-99),而這些數字是運行次序或者說是執行次序。一般來說數字越小,運行級別越高(越先被執行)。而這些鏈接文件都是通過chkconfig實現的。run運行指定級別的腳本完成之後,設定Ctrl、Alt、Delete三個鍵的意義,還有設定突然斷電時怎麼辦?電源又恢復的時候怎麼辦?但這些任務對我們來說並不是最關鍵的,接下來啓動虛擬終端、啓動圖形終端

4、/etc/rc.d/rc.sysinit:系統初始化,大概執行以下任務:(注意:內核在裝載根文件系統時爲了避免文件損壞,是以只讀方式掛載的)

檢測並以讀寫方式重新掛載根文件系統;設定主機名;檢測並掛載/etc/fstab中的其它文件系統;啓動swap分區;初始化外圍硬件設備的驅動;根據/etc/sysctl.conf設定內核參數;激活udev和selinux;激活LVM和RAID設備;清理過期鎖和PID文件;裝載鍵映射;

二、製作自己的小linux:

1、學了那麼久的linux了,我們也應該有一個屬於自己製作的小linux了,而小linux所要實現的功能有一下幾部分:

1)、關機和重啓;shutdown -r now 重啓;shutdown -h now:關機; halt關機; reboot重啓; poweroff關機

2)、主機名;

3)、運行對應服務腳本;

4)、啓動終端;

5)、運行用戶;

6)、定義單用戶級別;

7)、裝載網卡驅動,啓用網絡功能;

8)、提供一個web服務器;

9)、設定內核參數;

這些做完後我們的小linux就算是真正的完成了,但我們發現這個小linux每用到一個命令都要移植,這是比較麻煩的,因爲你不僅要移植命令還要移植文件所依賴的庫,那接下來我們就做到linux真正的裁剪和定製。

2、我們有一個項目叫busybox,它是一個命令也是一個二進制程序,但是他有很多鏈接,不到1M大小,一個命令可以模擬幾百個命令使用,例如你拿它當ls用,它就是ls等等、、、、我們可以使用一個1M的busybox手動製作一個內核(kernel),因此我們不需要移植太多的模塊,只需要移植一些最最基本的就可以了。

下面我們就來製作一個屬於自己的小linux

開始之前先把虛擬機安裝好,這裏我用的是linux-5.8的版本,安裝好後,再添加一個盤進來,爲了便於區別我安裝了一塊IDE的盤

1、創建分區(在這裏我們創建2個2G的主分區)

partprobe /dev/hda #重讀磁盤分區

cat /proc/partitions #查看分區列表

2、創建掛載點,mkdir /mnt/{boot,sysroot}其中hda1掛載在/mnt/boot;hda2掛載在/mnt/sysroot

mkdir /mnt/{boot,sysroot} -pv # 創建掛載點

mke2fs -j /dev/hda1 #格式化

mke2fs -j /dev/hda2

mount /dev/hda1 /mnt/boot #掛載設備

mount /dev/hda2 /mnt/sysroot

mount #查看是否掛載成功

3、切記雖然掛載好了,但掛載點裏面沒有任何文件,下面我們複製內核

cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz

爲了便於解壓縮,我在這裏建一個test目錄

mkdir test

cd test

zcat /boot/initrd-2.6.18-308.el5.img | cpio -id

vim init #編輯配置文件

clip_image002

cd lib/ #裏面有很多的dm模塊,沒有用,就刪了

clip_image004

rm -f dm-*     #刪除dm開頭的模塊文件

find . | cpio -H newc --quit -o | gzip -9 > /mnt/boot/initrd.gz   #(先備份出來)

ls -lh /mnt/boot/     #檢驗

grub-install --root-directory=/mnt /dev/hda    #安裝grub

ls /mnt/boot     #校驗一下是否有grub

vim /mnt/boot/grub/grub.conf #編輯配置文件

default=0

timeout=5

title my linux(2.6.18)

root (hd0,0)

kernel /vmlinuz

initrd /initrd.gz

提供真正的根文件系統

cd /mnt/sysroot

mkdir etc/rc.d/init.d bin sbin proc sys dev lib root mnt media var/{log,run,lock/subsys,tmp} usr/{bin,sbin,local} tmp home opt boot -pv #創建所需的根文件系統

vim etc/inittab # 編輯配置文件

id:3:initdefault: #設定默認運行級別

si::sysinit:/etc/rc.d/rc.sysinit #系統初始化腳本

vim etc/rc.d/rc.sysinit #編輯編輯初始化腳本

#!/bin/bash

echo -e "\tWelcome to \033[1;34mMagedu linux\033[0m"

/bin/bash #執行/bin/bash

chmod +x etc/rc.d/rc.sysinit #給配置文件執行權限

複製命令的腳本:在根目錄下編輯bincp.sh

vim bincp.sh #複製二進制程序及其依賴的庫文件的腳本

#!/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 &> /dev/null && 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

chmod +x bincp.sh #給文件執行權限

複製這些命令:init,bash,ls,touch,mkdir,cat ,mount,umount,vim,vi,chmod,chown,cp,ping,route,reboot,halt,shutdown,hostname注意每添加一個命令都要複製過來

sync(多同步幾次)

驗證:

clip_image006

4、新建一個虛擬機,使用我們剛纔添加的IDE盤,驗證一下看能否啓動:

clip_image008

clip_image010

注意:啓動小linux完成之後它無法自動完成將根文件系統掛載可讀寫

而mount –n:掛載時不更新/etc/mtab文件

clip_image012

我們在touch一個文件:

clip_image014

5、現在這個小系統還不能關機,重啓,接下來我們就讓它可以實現關機,重啓的功能:切回到宿主機:給我的小系統提供腳本,來實現系統關機、重啓的功能

cd /mnt/sysroot

etc/rc.d/rc.sysdone #腳本,可用於實現微型的Linux系統關機

#!/bin/bash

#

sync

sleep 2

sync

mount | awk '{print $3}' | grep -v -E "\/(dev|proc|sys)?$" | sort -r | while read LINE; do

umount -n -f $LINE

[ $? -eq 0 ] && echo "Unmount $LINE finished." || echo "Can not unmount $LINE."

done

mount | awk '{print $3}' | while read LINE; do

mount -n -o remount,ro $LINE

[ $? -eq 0 ] && echo "Remount $LINE finished." || echo "Can not remount $LINE."

done

exec /sbin/halt -p

chmod +x etc/rc.d/rc.sysdone #給腳本一個執行權限

注意每添加一個命令都要通過bincp.sh腳本複製過去

vim etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc.sysdone #切換到0級別時要執行/etc/rc.d/rc.sysdone

l6:6:wait:/etc/rc.d/rc.reboot #切換到6級別時要執行/etc/rc.d/rc.reboot

vim etc/rc.d/rc.reboot #編輯reboot腳本(重啓腳本)

#!/bin/bash

#

sync

sleep 1

sync

exec /sbin/reboot #執行這個腳本

chmod +x etc/rc.d/rc.reboot #給執行權限

vim etc/rc.d/rc.sysdone #關機腳本

#!/bin/bash

#

sync

sleep 2

sync

exec /sbin/halt -p

chmod +x etc/rc.d/rc.sysdone

驗證關機與重啓功能:

clip_image016

clip_image018

注意:注意如果在此處修改小系統,再回到宿主機,系統可能會崩潰,如果崩潰就用下面的命令修復

cd /mnt/sysroot/

find . | cpio -H newc --quiet -o | gzip > /root/sysroot.gz(把所有的大小打包起來)

cd

umount /mnt/sysroot(若卸不掉就使用fuser -km /dev/hda2)

mke2fs -j /dev/hda2 #重新格式化

mount /dev/hda2 /mnt/sysroot/ #重新掛載

cd /mnt/sysroot

zcat /root/sysroot.gz | cpio -id (展開所有打包的文件)

sync(多執行幾次)

6、我們也可以用一個腳本即完成關機又完成重啓:

cd /mnt/sysroot/

vim 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

case $1 in

start) ;;

stop) ;;

*)

echo "Usage:`basename $0` {start|stop}" ;;

esac

exec $COMMAND

chmod +x etc/rc.d/init.d/halt

爲halt創建鏈接:

cd etc/rc.d/

mkdir rc0.d rc6.d #創建兩個目錄

cd rc0.d/

ln -sv ../init.d/halt S99halt

cd ..

cd rc6.d/

ln -sv ../init.d/halt S99reboot

而rc.reboot rc.sysdone這時已經沒用了,那我們就把它刪了

rm -rf rc.sysdone rc.reboot

創建rc腳本:把所有S開頭的都start,把所有K開頭的都stop

vim etc/rc.d/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 etc/rc.d/rc

vim etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0

l3:3:wait:/etc/rc.d/rc 3 #爲3級別創建目錄

l6:6:wait:/etc/rc.d/rc 6

cd etc/rc.d/

mkdir rc3.d

vim etc/rc.d/init.d/tserver #腳本,測試SysV服務的定義格式:

#!/bin/bash

#

# chkconfig: 35 66 33 #通過chkconfig控制

# description: test service script

#

. /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"

}

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 init.d/tserver

cd rc3.d #爲3級別創建鏈接文件

ln -sv ../init.d/tserver S66tserver

ln -sv ../init.d/tserver S33tserver

vim etc/inittab #添加終端

1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1

2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2

注意每添加一個功能都要在小系統中驗證一下

7、要想讓根文件系統重新掛載可讀寫,先編輯etc/fstab配置文件

vim 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

vim etc/rc.d/rc.sysinit

#!/bin/bash

#

echo -e "\tWelcome to \033[34mMageEdu\033[0m Linux"

echo "Remount rootfs..."

mount -n -o remount,rw /

echo "Set the hostname..."(設定主機名)

[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network #判定文件是否存在

[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost #判定主機名是否存在或爲空

/bin/hostname $HOSTNAME

echo "Initializing network device..."

/sbin/insmod /lib/modules/mii.ko #cp 模塊以後添加進來

/sbin/insmod /lib/modules/pcnet32.ko

mkdir etc/sysconfig

vim etc/sysconfig/network

HOSTNAME=minilinux.magedu.com #添加主機名

vim etc/rc.d/init.d/functions 可用於控制服務腳本的信息顯示:

SCREEN=`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} ]"

}

mkdir lib/modules #創建模塊文件

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/

8、添加IP地址

mkdir -pv etc/sysconfig/network-scripts #先創建目錄

vim etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0

BOOTPROTO=static

IPADDR=192.168.1.150

NETMASK=255.255.255.0

GATEWAY=172.16.0.1

ONBOOT=yes

vim etc/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 $CATEWAY

}

stop() {

ifconfig eth0 down

}

status() {

ifconfig eth0

}

usage() {

echo "$prog:{start|stop|restart|status}"

}

case $1 in

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 etc/rc.d/init.d/network #執行權限

要想能在級別0,3,6下啓動,需要創建鏈接

cd etc/rc.d/rc0.d/

ln -sv ../init.d/network K90network

cd ../rc6.d/

ln -sv ../init.d/network K90network

cd ../rc3.d/

ln -sv ../init.d/network S09network

用戶登陸時顯示的信息設置

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 #IP地址立即生效

9、添加用戶功能

使用不依賴與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"

屬於自己的小linux就做好了,雖然不是很完善,但是也很好用的,趕快試試吧!


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