对系统的裁剪首先要先了解系统的整个启动流程,明白其所需要的配置文件;这样在操作的时候才能清楚自己在做什么,以及需要做什么
启动流程详解
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文件
开始裁剪
注意事项:演示这个过程我用的是VMware Workstation 9.0,【相关阅读:VMware Workstation 9.0正式版下载(附注册机+序列号激活码) http://www.linuxidc.com/Linux/2012-11/73743.htm】在做的过程中由于虚拟机的数据同步问题会容易出错的,希望大家在做时速度不要过快,并且多多的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
附件Login程序下载
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2013年资料/5月/18日/Linux系统教程:定制5M的RedHat 5.8系统
设定内核参数
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的运行流程、配置文件的理解以及对其进一步的认识等会有所帮助的。
心动不如行动,开始裁剪您的小系统吧!