一、定制属于自己的内核
1、在原有CentOS5.9中添加一块IDE硬盘,分2个磁盘并格式化为ext3文件系统
2、挂载分区
mkdir /mnt/boot
mkdir /mnt/sysroot
mount /dev/hda1 /mnt/boot
moutn /dev/hda2 /mnt/sysroot
3、复制系统内核到/mnt/boot下:cp /boot/vmlinuz-2.6.18-348.el5 /mnt/boot/vmlinuz
4、解压展开initrd文件:
mkdir test
cd test
zcat /boot/initrd-2.6.18-348.el5.img | cpio -id
5、编辑init文件vim init:(修改其中一行为mkrootdev -t ext3 -o defaults,ro /dev/hda2;注释掉#resume LABEL=SWAP-sda5;.,+20s@^@#@g;)
***lib下没用的dm开头的文件:
cd lib/
rm -f dm-*
6、切换到test目录制作新的initrd文件:
cd ..
find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz(按照原有文件格式归档)
ls -lh /mnt/boot(可查看initrd文件大小)
7、创建grub:
grub-install --root-directory=/mnt /dev/hda
ls /mnt/boot
8、编辑grub文件
vim /mnt/boot/grub/grub.conf
default=0
timeout=3
title Magedu Linux(2.6.18)
root (hd0,0)
kernel /vmlinuz
initrd /initrd.gz
9、创建核心的根文件系统(不能单独分区的):
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
10、创建系统初始化的inittab配置文件:
vim /mnt/sysroot/etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
11、创建rc.sysinit文件
vim /mnt/sysroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\tWelcome to \033[34mMageEdu Team\033[0m Linux."
/bin/bash
添加可执行脚本权限:chmod +x etc/rc.d/rc.sysinit
12、用脚本移植核心的可执行程序:
vim binary.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 && 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 binary.sh
执行脚本,移植如下命令:./binary.sh
init,bash,ls, touch,mkdir,rm,mv,cp ,cat,mount,umount,vi,vim,chmod,chown,ping,ifconfig,insmod,modprobe,rmmod,route,halt,reboot,shutdown,hostname
13、切换目录测试:chroot /mnt/sysroot/
14、同步数据到磁盘:sync
15、新建主机(内存为256即可)挂载第二块硬盘,启动测试效果(测试结果应该是能够正常启动,但仅能查看文件系统)。
二、系统启动流程回顾
1、系统启动流程:
POST(检测硬件)-->BIOS(Boot Sequence按照设备的引导次序找MBR)-->BootLoader(MBR)-->Kernel(RHEL5:initrd,RHEL6:initramfs)-->init(/etc/inittab)
RHEL6的init程序:
upstart项目的init程序:
/etc/inittab
/etc/init/*.conf
2、内核(Kernel)初始化完成的工作:
硬件探测
装载驱动
挂载根文件系统(rootfs)
启动用户空间中的第一个进程init
initrd文件是内核和根文件系统的中间层,起到连接作用。
3、/etc/inittab(init)完成的工作:
设定默认运行级别
系统初始化(依赖脚本/etc/rc.d/rc.sysinit进行)
运行指定级别的服务脚本:/etc/rc.d/init.d/
/etc/rc.d/rc#.d/下的链接文件链接的是init.d下的文件
rc0.d--rc6.d
K*
S*
00-99:运行次序,数字越小越先执行
启动虚拟终端
启动图形终端
4、/etc/rc.d/rc.sysinit系统初始化:
检测并以读写方式重新挂载根文件系统;
设定主机名;
检测并挂载/etc/fstab中的其它文件系统;
启动swap分区;
初始化外围硬件设备的驱动;
根据/etc/sysctl.conf设定内核参数;
激活udev和selinux;
激活LVM和RAID设备;
清理过期锁和PID文件;
装载键映射(键盘功能);
5、mount命令
-n: 挂载时不更新/etc/mtab文件;
cat /proc/mounts可查看当前挂载的所有设备
三、定制属于自己的内核(接一步骤)
如何解决新主机只读问题:
1、在新的主机上挂载根目录:mount -n -o remount,rw /
可创建文件touch /tmp/a.txt
可测试结果……
如何实现新主机重启和关机:
2、编辑脚本实现新主机关机前要做的任务:
cd /mnt/sysroot
vim etc/rc.d/rc.sysdone
#!/bin/bash
#
sync
sleep 1
sync
exec /sbin/halt -p
添加脚本执行权限:chmod +x etc/rc.d/rc.sysdone
执行移植脚本,移植sync和sleep命令;
3、编辑inittab初始化脚本在0级别的任务:
vim /mnt/sysroot/etc/inittab添加
4:0:wait:/etc/rc.d/rc.sysdone
测试新主机的关机功能:init 0
4、编辑脚本实现新主机重启前要做的任务:
cd /mnt/sysroot
vim etc/rc.d/rc.reboot
#!/bin/bash
#
sync
sleep 1
sync
exec /sbin/reboot
添加脚本执行权限:chmod +x etc/rc.d/rc.reboot
5、编辑inittab初始化脚本在6级别的任务:
vim /mnt/sysroot/etc/inittab添加
l6:6:wait:/etc/rc.d/rc.reboot
测试新重启的关机功能:init 6
如何做成执行对应级别下的服务脚本(如何实现一个脚本既能关机又能重启):
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
7、创建脚本链接:
cd /mnt/sysroot/etc/rc.d
ls
ls init.d/
mkdir rc0.d rc6.d
cd rc0.d/
ln -sv ../init.d/halt S99halt
cd ../rc6.d
ln -sv ../init.d/halt S99reboot
8、***原来编辑的重启和关机脚本:
cd ../
rm -f rc.reboot rc.sysdone
ls
sync
9、创建脚本实现把所有S开头的服务都start所有K开头的服务都stop:
vim 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
添加rc脚本执行权限:chmod +x rc
10、编辑inittab文件:
cd ../
vim inittab修改为:
l0:0:wait:/etc/rc.d/rc 0
16:6:wait:/etc/rc.d/rc 6
同步数据到磁盘:sync
11、启动新主机验证:init 6 ; init 0 ;
实现对应3级别下的服务:
12、添加3级别执行的脚本:
vim /mnt/sysroot/etc/inittab添加:
l3:3:wait:/etc/rc.d/rc 3
13、创建rc3.d目录:
cd /mnt/sysroot/etc/rc.d
mkdir rc3.d
14、创建系统启动服务的调用脚本:
vim init.d/tserver
#!/bin/bash
#
#chkconfig: 35 66 33 -->调用的脚本
#description: test service script
#
prog=`basename $0`
lockfile=/var/lock/subsys/$prog
start() {
echo "Starting $prog ..."
touch $lockfile
}
stop() {
echo "Stopping $prog ..."
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 init.d/tserver
15、在宿主机上运行脚本检测脚本是否能正常运行:
init.d/tserver start
ls -l /var/lock/subsys
init.d/tserver stop
ls -l /vat/lock/subsys
init.d/tserver status
16、在3级别下启动:
cd rc3.d/
ls
ln -sv ../init.d/tserver S66tserver
ll
17、脚本中35级别为启动,那么06级别则为关闭:
cd ..
cd rc0.d/
ln -sv ../init.d/tserver K33tserver
cd ..rc6.d/
ln -sv ../init.d/tserver K33tserver
ll
18、运行脚本binary移植basename:./binary.sh分别输入basename
19、启动新主机测试,注意观察启动过程中文件系统报错"Filesystem Only-read";
当运行init 3时,也报错"Filesystem Only-read"
实现在3级别下终端切换:
20、修改级别3的启动终端脚本:
cd /mnt/sysroot
vim etc/inittab添加(man mingetty的用法):
1:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty1
2:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty2
21、运行脚本binary移植mingetty:./binary.sh分别输入mingetty;
22、创建bash环境:
cd /mnt/sysroot/
vim etc/rc.d/rc.sysinit***最后一行的/bin/bash
cd /mnt/sysroot/bin
ln -sv bash sh
ll
sync
sync
23、启动新主机测试,屏幕显示"(none) login:",但ctrl+alt+F1|F2可实现终端切换;
解决新主机启动以读写方式挂载根文件系统:
24、宿主机上修改系统挂载文件:
cd /mnt/sysroot
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
添加脚本执行权限:chmod +x etc/fstab
25、实现开机自动挂载:
vim etc/rc.d/rc.sysinit添加:
echo "Remount rootfs..."
mount -n -o remount,rw /
/bin/bash
解决新主机开机自动设置主机名:
26、创建设置主机名文件:
mkdir etc/sysconfig
vim etc/sysconfig/network
HOSTNAME=minilinux.MegeEdu.com
27、实现开机自动设置hostname:
vim etc/rc.d/rc.sysinit添加:
echo "Set the hostname..."
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
28、测试:宿主机上切换chroot /mnt/sysroot,执行/etc/rc.d/rc.sysinit脚本测试是否有语法错误;
解决新主机让登录的问题(mingetty没有解决此问题):
man agetty
man stty,如:stty -F /dev/console size(当前使用的终端尺寸);stty -F /dev/console speed(当前使用的终端速率);
29、重新修改inittab文件:
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
30、运行脚本binary移植agetty:./binary.sh分别输入agetty
31、sync
32、启动测试新主机,注意观察如果没有异常那么登录问题解决;
33、在此测试0级别下是否还有报错:init 0 。
按照RedHat的法则,实现当系统启动成功显示OK,当系统启动失败显示failure:
34、编辑functions文件:
cd /mnt/sysroot
vim etc/rc.d/init.d/functions
#!/bin/bash
#
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} ]"
}
添加执行脚本权限:chmod +x etc/rc.d/init.d/functions
35、修改系统启动服务的调用脚本:
cd /mnt/sysroot/etc/rc.d
vim init.d/tserver
#!/bin/bash
#
#chkconfig: 35 66 33
#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 "Starting $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
36、执行脚本.binary.sh移植stty和seq命令
37、切换,测试脚本运行:
chroot /mnt/sysroot
/etc/rc.d/init.d/tserver start
如何实现小系统能够获取IP地址:
38、移植网卡模块:
cd /mnt/sysroot
mkdir lib/modules
modinfo pcnet32 -->查看模块依赖和文件路径
modinfo mii
cp /lib/modules/2.6.18-348.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules
cp /lib/modules/2.6.18-348.el5/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules
39、自动装载网络模块:
vim etc/rc.d/rc.sysinit添加:
echo "Initializing network device..."
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
40、创建网卡配置文件:
mkdir -pv etc/sysconfig/network-scripts
vim etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.100.5
NETMASK=255.255.0.0
GATEWAY=172.16.0.1
ONBOOT=yes
41、创建脚本启动网卡:
vim etc/rc.d/init.d/network
#!/bin/bash
#
prog=network
. /etc/rd.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0
. /CONF
NETMASK=16
start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add defaults gw $GATEWAY
}
stop() {
ifconfig eth0 down
}
status() {
ifconfig eth0
}
usage() {
echo "$prog: {start|stop|restart|status}"
}
case $1 in
start)
start
success "Config network card eth0"
;;
stop)
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
42、实现级别3下自动启动,级别0和级别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
43、编辑network脚本:
cd ..
ll
vim init.d/network在第3和4行添加:
#chkconfig: 35 09 90
#description: network service
44、启动新主机,测试效果;
service network start
ifconfig
service network stop
service network status
ifconfig
service network start
四、脚本编程知识点:
1、变量中字符的长度:${#VARNAME},如:A="String Test";echo ${#A}
2、获取屏幕的行和列的命令:stty -F /dev/console size
3、获取列的命令:
stty -F /dev/console size | cut -d' ' -f2
stty -F /dec/console size | awk '{print $2}'
A=`stty -F /dev/console size` && echo ${A#* }
五、VM虚拟机环境,修复解决VM找不到inittab文件(虚拟主机文件系统错乱)的问题:
1、打包所主机的/dev/hda2文件系统文件:
cd /mnt/sysroot
find . | cpio -H newc --quiet -o | gzip > /root/sysroot.gz
2、卸载/dev/hda2设备:
umount /dev/hda2-->如果不能被卸载
fuser -km /dev/hda2 -->强制卸载
umount /dev/hda2
3、修复/dev/hda2:
e2fsck -f /dev/hda2
4、重新挂载/dev/hda2:
mount /dev/hda2 /mnt/sysroot/
5、展开/dev/hda2文件系统:
cd /mnt/sysroot
zcat /root/sysroot.gz | cpio -id
6、检查inittab文件:
cat etc/inittab
7、sync
8、如果仍然不能修复,那么备份/dev/hda2文件系统后格式化/dev/hda2,然后重新挂载到宿主机的/mnt/sysroot下即可。