废话不多说了,直接进入正题

对系统的裁剪首先要先了解系统的整个启动流程,明白其所需要的配置文件;这样在操作的时候才能清楚自己在做什么,以及需要做什么

启动流程详解

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. 1、首先进入/mnt/sysroot/下归档压缩所有文件到一个指定的地方 
  2. 2、如果直接卸载磁盘不成功的时候使用fuser -km /mnt/sysroot命令后再进行卸载 
  3. 3、卸载后使用e2fsck -f 命令,如果错误过多建议直接格式化 
  4. 4、然后重新挂载;进入/mnt/sysroot目录使用zcat FILE | cpio -id命令还原(FILE是文件路径) 

 裁剪准备,准备一块IDE磁盘,划分两个主分区即可,这里的IDE盘划分了两个主分区hda1与hda2两分区大小分别是20M和512M,/dev/hda1挂载点分别为/mnt/boot  /dev/hda2挂载点为/mnt/sysroot

 /mnt/boot/目录下文件准备

 
  
  1. 复制kernel 
  2. cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz 
  3. 制作initrd文件 
  4. 将本机系统的initrd文件解压到一个特定目录后编辑其中的init文件 
  5. init编辑内容如下(这里把模块的安装都给注释了, 
  6. #!/bin/nash 
  7. mount -t proc /proc /proc 
  8. setquiet 
  9. echo Mounting proc filesystem 
  10. echo Mounting sysfs filesystem 
  11. .........                      (这里省略了其中的配置文字,都是没有注释的) 
  12. mknod /dev/ttyS3 c 4 67 
  13. echo Setting up hotplug. 
  14. hotplug 
  15. echo Creating block device nodes. 
  16. mkblkdevs 
  17. #echo "Loading ehci-hcd.ko module" 
  18. ...                           (这两个#文字段都是注释的模块安装) 
  19. #stabilized --hash --interval 1000 /proc/scsi/scsi 
  20. mkblkdevs 
  21. echo Scanning and configuring dmraid supported devices 
  22. echo Creating root device. 
  23. mkrootdev -t ext3 -o defaults,ro /dev/hda2(在这里指定根文件系统挂载点) 
  24. echo Mounting root filesystem. 
  25. mount /sysroot 
  26. echo Setting up other filesystems. 
  27. setuproot 
  28. echo Switching to new root and running init. 
  29. switchroot 
  30. 删减一下initrd文件中lib目录下的文件剩下这三个就可以 
  31. ext3.ko  firmware  jbd.ko 
  32. 归档压缩到/mnt/boot/目录,命名为initrd.gz 
  33. find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd 

安装grub

 
  
  1. grub-install --root-directory=/mnt/ /dev/hda 

编辑grub下的配置文件

 
  
  1. vim /mnt/boot/grub/grub.conf 

grub.conf配置文件内容如下:

 
  
  1. default=0 
  2. timeout=3 
  3. title My Linux 
  4.   root(hd0,0) 
  5.   kernel /vmlinuz ro root=/dev/hda2 quiet 
  6.   initrd /initrd.gz 

/mnt/sysroot目录下文件准备

创建所需目录

 
  
  1. 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配置文件

 
  
  1. vim /mnt/sysroot/etc/inittab 内容如下:
  2. id:3:initdefault: 
  3. si::sysinit:/etc/rc.d/rc.sysinit 

编辑rc.sysinit脚本配置文件

 
  
  1. vim /mnt/sysrootetc/rc.d/rc.sysinit 内容如下:
  2. #!/bin/bash 
  3. echo -e "\tMy\033[34mMageTeam\033[0mLinux" 
  4. /bin/bash 
  5. chmod +x /mnt/sysrootetc/rc.d/rc.sysinit(添加执行权限) 

到这里小linux的简单配置就完成了下面我们用脚本复制命令及所依赖的库文件,脚本内容如下:

 
  
  1. #!/bin/bash 
  2. dest=/mnt/sysroot 
  3. libcp() { 
  4. libpath=${1%/*} 
  5. [ ! -d $dest$libpath ] && mkdir -p $dest$libpath 
  6. [ ! -e $dest${1} ] && cp $1 $dest$libpath && echo " copy lib $1 finished" 
  7. bincp() { 
  8. cmdpath=${1%/*} 
  9. [ ! -d $dest$cmdpath ] && mkdir -p $dest$cmdpath 
  10. [ ! -e $dest${1} ] && cp $1 $dest$cmdpath 
  11. for lib in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do 
  12. libcp $lib 
  13. done 
  14. read -p " your command:" cmd 
  15. until [ $cmd = 'q' ]; do 
  16. ! which $cmd && echo "wrong command" && read -p "input again:" cmd && continue 
  17. command=`which $cmd | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"
  18. bincp $command 
  19. echo "copy $command finished." 
  20. read -p "continue:" cmd 
  21. done 

 

启动裁剪的系统复制init bash这两个就能启动,其他的命令可在后用到后再进行添加(例如,touch,vim,chmod,chown,mkdir,rm,mv,cp,cat,mount,umount,ping,ifconfig,insmod,modprobe,rmmod,route,reboot,shutdown,hostname等)虚拟机完成的一定要多多sync哦,这个是很重要滴!!!

开机关机功能添加

 
  
  1. 开机关机功能配置流程 
  2. 编辑/mnt/sysroot/etc/inittab配置文件添加以下内容: 
  3. l0:0:wait:/etc/rc.d/rc 0 
  4. l6:6:wait:/etc/rc.d/rc 6 
  5. 在/mnt/sysroot/etc/rc.d/init.d/目录下创建一个脚本halt内容如下: 
  6. #!/bin/bash 
  7. case $0 in           
  8. *reboot) 
  9. COMMAND='/sbin/reboot' ;; 
  10. *halt) 
  11.  COMMAND='/sbin/halt -p' ;; 
  12. *) 
  13. echo "Only call this script by *reboot OR *halt;" 
  14. ;; 
  15. esac 
  16. exec $COMMAND 
  17. chmod +x /mnt/sysroot/etc/rc.d/init.d/halt 添加脚本执行权限
  18. 在rc.d目录下创建rc0.d与rc6.d目录: 
  19. 进入rc0.d目录创建链接: 
  20. ln -sv ../init.d/halt S99halt 
  21. 进入rc6.d目录创建链接: 
  22. ln -sv ../init.d/halt S99reboot 
  23. 在/mnt/sysroot/etc/rc.d/目录下创建rc脚本,内容如下(这里的rc脚本简单的定义了一下) 
  24. #!/bin/bash 
  25. RUNLEVEL=$1 
  26.  
  27. for I in /etc/rc.d/rc$RUNLEVEL.d/K*; do 
  28.   $I stop 
  29. done 
  30.  
  31. for I in /etc/rc.d/rc$RUNLEVEL.d/S*; do 
  32.   $I start 
  33. done 
  34. chmod +x /mnt/sysroot/etc/rc.d/rc 添加脚本执行权限

 

每一个步骤的完成建议都要测试一下,这样能更容易排错,并且容易熟悉一个功能的执行流程

切换级别自动开启或关闭相关服务的功能添加

 
  
  1. 在inittab中加入一个级别3 
  2. l3:3:wait:/etc/rc.d/rc 3 
  3.  
  4. 在init.d目录中创建一个服务脚本为tserver内容如下: 
  5. #!/bin/bash 
  6. # chkconfig: 35 66 33 
  7. # description: test service script 
  8. prog=tserver 
  9. lockfile=/var/lock/subsys/$prog 
  10.  
  11. start() { 
  12.   touch $lockfile 
  13.  
  14. stop() { 
  15.   rm -f $lockfile 
  16.  
  17. status() { 
  18.   if [ -f $lockfile ]; then 
  19.     echo "Running..." 
  20.   else 
  21.     echo "Stopped..." 
  22.   fi 
  23.  
  24. usage() { 
  25.   echo "Usage: $prog {start|stop|status|restart}" 
  26.  
  27. case $1 in 
  28. start) 
  29.   start ;; 
  30. stop) 
  31.   stop ;; 
  32. restart) 
  33.   stop 
  34.   start 
  35.   ;; 
  36. status) 
  37.   status 
  38.   ;; 
  39. *) 
  40.   usage 
  41.   exit 1 
  42. esac 
  43. 添加执行权限 chmod +x  /mnt/sysroot/rc.d/init.d/tserver 
  44. 在/mnt/sysroot/etc/rc.d/目录下创建rc3.d目录在其中添加链接: 
  45. ln -sv ../init.d/tserver S66tserver 
  46. 分别在rc0.d与rc6.d中添加链接: 
  47. ln -sv ../init.d/tserver K33tserver 
  48.  

补充

 
  
  1. 在inittab配置文件中3级别不会被启动,因为脚了本的第二行就定义了系统启动后就去执行rc.sysinit,然后启动 
  2. /bin/bash了 所以在inittab配置文件中需要设置启动终端命令(使用agetty命令,现在还没有用户)并且init在
  3. 启动时 
  4. 需要sh程序,这里需要为bash创建一个链接 
  5. 编辑inittab配置文件 添加以下代码 
  6. 1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1 
  7. 2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2 
  8. 进入到/mnt/sysroot/bin/目录下创建链接: 
  9. ln -sv bash sh 

挂载文件系统

 
  
  1. 在tserver脚本中需要创建锁文件,所以需要挂载文件系统 
  2. 编辑/mnt/sysroot/etc/fstab配置文件,内容如下: 
  3. /dev/hda2      /       ext3    defaults    0 0 
  4. /dev/hda1     /boot    ext3    defaults    0 0 
  5. proc          /proc    proc    defaults    0 0 
  6. sysfs         /sys     sysfs   defaults    0 0 
  7. 编辑/mnt/sysroot/et/rc.d/rc.sysinit脚本 添加一下代码即可
  8. echo "Remount rootfs...." 
  9. mount -n -o remount,rw / 
  10. mount -a 

到这里就可以登录这两个终端(ctl+alt+F1/F2命令可切换终端),并且在切换级别时能够实现相关服务的开启和关闭功能

登录陆界面的美化配置即function函数添加

 
  
  1. 在启动相关服务时,成功或失败时有“OK”或“failure” 信息显示
  2. 首先在/mnt/sysroot/rc.d/init.d/functions编写一个函数 
  3. vim /mnt/sysroot/rc.d/init.d/functions 内容如下: 
  4. CREEN=`stty -F /dev/console size 2>/dev/null
  5. COLUMNS=${SCREEN#* } 
  6. [ -z $COLUMNS ] && COLUMNS=80 
  7.  
  8. SPA_COL=$[$COLUMNS-14] 
  9.  
  10. RED='\033[31m' 
  11. GREEN='\033[32m' 
  12. YELLOW='\033[33m' 
  13. BLUE='\033\34m' 
  14. NORMAL='\033[0m' 
  15.  
  16. success() { 
  17.   string=$1 
  18.   RT_SPA=$[$SPA_COL-${#string}] 
  19.   echo -n "$string" 
  20.   for I in `seq 1 $RT_SPA`;do 
  21.     echo -n " " 
  22.   done 
  23.   echo -e "[   ${GREEN}OK${NORMAL}   ]" 
  24.  
  25. failure() { 
  26.   string=$1 
  27.   RT_SPA=$[$SPA_COL-${#string}] 
  28.   echo -n "$string" 
  29.   for I in `seq 1 $RT_SPA`; do 
  30.     echo -n " " 
  31.   done 
  32.   echo -e "[ ${RED}FAILED${NORMAL} ]" 
  33. 添加执行权限 chmod +x  /mnt/sysroot/rc.d/init.d/functios 
  34. 修改tserver脚本 只需改变tserver脚本中status函数上面的脚本,内容如下: 
  35. . /etc/rc.d/init.d/functions 
  36.  
  37. prog=tserver 
  38. lockfile=/var/lock/subsys/$prog 
  39.  
  40. start() { 
  41.   touch $lockfile 
  42.   [ $? -eq 0 ] && success "Starting $prog" || failure "Staring $prog" 
  43.  
  44. stop() { 
  45.   rm -f $lockfile 
  46.   [ $? -eq 0 ] && success "Stopping $prog" || failure "Stopping $prog" 

现在测试一下,是不是现在的小系统更像红帽了

注意:过程中要把脚本使用到的相应命令复制过去

为系统添加IP地址以及主机名

 
  
  1. 添加主机名: 
  2. mkdir /mnt/sysroot/etc/sysconfig 
  3. vim /mnt/sysroot/etc/sysconfig/network 内容如下 
  4. HOSTNAME=Minilinux 
  5. 编辑/mnt/sysroot/etc/rc.d/rc.sysinit 
  6. 添加以下内容 
  7. #Set the hostname..... 
  8. [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network 
  9. [ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost 
  10. /bin/hostname $HOSTNAME 
  11. 配置IP: 
  12. 首先要先移植所需模块 

 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相关配置就完成了

用户登陆界面显示信息设置

 
  
  1. vim /mnt/sysroot/etc/issue  直接编辑文件,添加下面这两行代码
  2. My Linux 
  3. Kernel \r on an \m 

设定内核参数

 
  
  1. vim /mnt/sysroot/etc/sysctl.conf 直接编辑文件添加一行代码即可 
  2. net.ipv4.ip_forward = 1 
  3.  
  4. 编辑/mnt/sysroot/etc/rc.d/rc.sysinit文件 添加以下内容 
  5. sysctl -p &> /dev/null 

添加用户功能

 
  
  1. 使用不依赖与PAM的login程序 (已经编译好的)
  2. 放到/mnt/sysroot/bin/目录下,之后赋予它执行权限 
  3. 登陆时是使用login程序来验证登陆的,实现用户认证是到特定的文件中去认证的,传统的方式都是 
  4. 放在/etc/passwd以及/etc/shadow 
  5. nsswitch是个框架,它能够完成配置到哪个去找用户的账号及密码;nsswitch就是依靠配置文件来定义的 
  6. nsswitch这个框架由库和相对应的配置文件来组成,在配置文件中可直接定义基于哪个库去去找相应的验证文件 
  7. 例如:在/ect/passwd认证所找的是libnss_file.so这样的库 
  8. vim /mnt/sysroot/etc/nsswitch.conf   内容如下: 
  9. passwd:     files 
  10. shadow:     files 
  11. group:      files 
  12. hosts:      files dns 
  13. 复制库文件 
  14. cp -d /lib/libness_file* /mnt/sysroot/lib/ 
  15. cp -d /usr/lib/libnss_files.so/mnt/sysroot/usr/lib/ 
  16. cp -d /usr/lib/libnss3.so /usr/lib/libnssckbi.so /usr/lib/libnssutil3.so /mnt/sysroot/lib/ 
  17. 创建用户 
  18. 这里直接从本系统上复制一个用户过来 
  19. grep -E "^root\> /etc/passwd > /mnt/sysroot/etc/passwd 
  20. grep -E "^root\> /etc/shadow > /mnt/sysroot/etc/shadow 
  21. grep -E "^root\> /etc/group> /mnt/sysroot/etc/group 
  22. 修改inittab文件,现在可以改为让输入用户的登陆方式了 
  23. vim /mnt/sysroot/etc/inittab 整体内容如下内容如下: 
  24. id:3:initdefault: 
  25. si::sysinit:/etc/rc.d/rc.sysinit 
  26.  
  27. l0:0:wait:/etc/rc.d/rc 0 
  28. l1:1:wait:/etc/rc.d/rc 1 
  29. l3:3:wait:/etc/rc.d/rc 3 
  30. l6:6:wait:/etc/rc.d/rc 6 
  31.  
  32. 1:2345:respawn:/sbin/mingetty tty1 
  33. 2:2345:respawn:/sbin/mingetty tty2 

到这里用户功能的添加就完成了

补充

 
  
  1. 对/mnt/sysroot/etc/rc.d/rc.sysinit配置的整体修改,来实现对界面的进一步美化,代码如下: 
  2.  
  3. #!/bin/bash 
  4. . /etc/rc.d/init.d/functions 
  5. echo -e "\tMy\033[34mMagedu.com\033[0mLinux" 
  6.  
  7. echo "Remount rootfs...." 
  8. mount -n -o remount,rw / 
  9. [ $? -eq 0 ] && success "Remount rootfs" || failure "Remount rootfs" 
  10.  
  11. mount -a 
  12. [ $? -eq 0 ] && success "Mount others filesystem" || failure "Mount others filesystem" 
  13.  
  14. #Set the hostname..... 
  15. [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network 
  16. [ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost 
  17. /bin/hostname $HOSTNAME 
  18. [ $? -eq 0 ] && success "Set the hostname" || failure "Set the hostname" 
  19. # Initializing network device.... 
  20. /sbin/insmod /lib/modules/mii.ko 
  21. /sbin/insmod /lib/modules/pcnet32.ko 
  22. [ $? -eq 0 ] && success "Initializing network device" || failure "Initialization network device" 
  23.  
  24. ifconfig lo 127.0.0.1/8 
  25. [ $? -eq 0 ] && success "Activating loopback network device" || failure "Activating loopback network device" 
  26.  
  27. sysctl -p &> /dev/null 
  28. [ $? -eq 0 ] && success "Set kernel parameter" || failure "Set kernel paramenter" 

到这里仅有5M大小小linux的裁剪过程就完成了,个人感觉把这个过程操作完成出来对linux的运行流程、配置文件的理解以及对其进一步的认识等会有所帮助的。

心动不如行动,开始裁剪您的小系统吧!!!