这是一些学习笔记,存在不足之处,请指正。
平台:vmware 12 操作系统:centos5.1

  • 硬盘

准备硬盘,20G
分区
  1. fdisk /dev/sdb

格式化分区
  1. mke2fs -j /dev/sdb1
  2. mkswap /dev/sdb2
  3. mke2fs -j /dev/sdb3
挂载硬盘
  1. mkdir /mnt/{boot,sysroot}
  2. mount /dev/sdb1 /mnt/boot
  3. mount /dev/sdb3 /mnt/sysroot
生成grub
  1. grub-install --root-directory=/mnt /dev/sdb
/mnt:可以理解为根分区
/dev/sdb1:挂在到/mnt/boot下的分区
  1. ls -l /mnt/boot
  2. drwxr-xr-x 2 root root  1024 Aug  3 07:45 grub 
  3. drwx------ 2 root root 12288 Aug  3 07:42 lost+found

  • 内核相关配置

vmlinuz
此处为了方便,不编译内核,,直接复制现有的内核
  1. cp /boot/vmlinuz-2.6.18-398.el5 /mnt/boot/vmlinuz
initrd
initrd是在内存上加载的驱动根目录文件系统的一个文件,要在现有的/boot/initrd-2.6.18-398.el5.img稍作修改即可
  1. file initrd-2.6.18-398.el5.img  
  2. initrd-2.6.18-398.el5.img: gzip compressed data, from Unix, last modified: Wed Jul 20 15:23:58 2011, max compression

initrd-2.6.18-398.el5.img为压缩文件,先复制为gzip可以识别的格式,再解压
  1. cp /boot/initrd-2.6.18-398.el5.img /~/initrd-2.6.18-164.el5.img.gz
  2. cd
  3. gunzip initrd-2.6.18-164.el5.img.gz
说明
initrd也可以这样操作,更加简便。在/root/test下
  1. zcat  /boot/initrd-2.6.18-398.el5.img | cpio -id
然后就可以看到文件的内容:
  1. ls
  2. bin  dev  etc  init  lib  proc  sbin  sys  sysroot

initrd-2.6.18-398.el5.img为cpio归档文件
  1. file initrd-2.6.18-164.el5.img  
  2. initrd-2.6.18-164.el5.img: ASCII cpio archive (SVR4 with no CRC)
  3. mkdir test
  4. cd !$
 
在一个单独的文件夹下进行解压
  1. cpio -id < initrd-2.6.18-164.el5.img

修改init文件
  1. vim init
  2. 找到
  3. mkrootdev -t ext3 -o defaults,ro /dev/vol0/root
  4. 改为
  5. mkrootdev -t ext3 -o defaults,ro /dev/sda3
说明:当硬盘挂载到新的虚拟机上时,/根所在分区会被识别为/dev/sda3
 
重新打包,并放到/mnt/boot下
  1. find . | cpio -H newc -o --quiet | gzip -9 > /mnt/boot/initrd.gz

  • 建立系统启动相关文件

在/mnt/sysroot/创建/根下的文件夹
  1. mkdir -pv bin sbin usr/{bin,sbin,local} boot proc sys home root mnt media lib etc/rc.d var/{log,run,lock/subsys,tmp}
  1. mkdir -pv bin sbin etc/{rc.d/init.d,sysconfig} lib proc dev sys root home boot

init
系统启动需要/sbin/init
  1. cp /sbin/init /mnt/sysroot/sbin/
init还需要一些库文件的支持
  1. ldd /sbin/init
  2. linux-vdso.so.1 =>  (0x00007fff3adc4000)
  3. libsepol.so.1 => /lib64/libsepol.so.1 (0x0000003f67a00000)
  4. libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003f67600000)
  5. libc.so.6 => /lib64/libc.so.6 (0x0000003f5f800000)
  6. libdl.so.2 => /lib64/libdl.so.2 (0x0000003f60000000)
  7. /lib64/ld-linux-x86-64.so.2 (0x0000003f5f400000)

这样复制命令和库文件较为麻烦,因此写了如下的脚本,只要将需要复制的命令名称输入,即可复制对应命令库文件
  1. #!/bin/bash
  2. #
  3. dst=/mnt/sysroot
  4. libcp(){
  5. lib_path=${1%/*}
  6. [ ! -d $dst$lib_path ] && mkdir -p $dst$lib_path
  7. [ ! -e $dst$1 ] && cp $1 $dst$lib_path && echo "copy $1 finished."
  8. }
  9. bincp(){
  10. cmd_path=${1%/*}
  11. [ ! -d $dst$cmd_path ] && mkdir -p $dst$cmd_path
  12. [ ! -e $dst$1 ] && cp $1 $dst$cmd_path
  13. for lib in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do
  14. libcp $lib
  15. done
  16. }
  17. read -p "Enter the command that you want to copy: " user_cmd
  18. until [ $user_cmd == "q" ]; do
  19. ! which $user_cmd && echo -e "\e[31;5m\tWrong Command!\e[0m" && read -p "Enter the command that you want to copy: " user_cmd && continue
  20. cmd_real_path=`which $user_cmd | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
  21. bincp $cmd_real_path
  22. echo "Command $user_cmd copy finished."
  23. echo -e "\e[32m##########################################################\e[0m"
  24. read -p "Enter the command that you want to copy: " user_cmd
  25. done
在这里我复制的命令有bin下:
basename  cat chown  date  hostname  mkdir  mv rm sleep sync  touch bash chmod  cp gzip  ls mount  ping  sh(软连接到bash)  stty tar tree seq ln
sbin下
agetty  halt  ifconfig  init  insmod  mingetty  modinfo  modprobe  poweroff  reboot  route  shutdown
到此处,可以使用chroot /mnt/sysroot/ 切换到其中,可以发现,刚才复制的命令都可以使用。

inittab
  1. cd /mnt/sysroot/etc/ 
  2. vim inittab 
  3. #在里面写入:
  4. id:3:initdefault: 
  5. si::sysinit:/etc/rc.d/rc.sysinit 

  1. # 2016-04-19
  2. id:3:initdefault:
  3. si::sysinit:/etc/rc.d/rc.sysinit
  4. 10:0:wait:/etc/rc.d/rc 0
  5. 13:3:wait:/etc/rc.d/rc 3
  6. 16:6:wait:/etc/rc.d/rc 6
  7. 20:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1
  8. 21:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2

这定义了开机之后以第3中模式(即命令行模式进入系统),并启动系统sysinit

rc.sysinit
  1. vim /etc/rc.d/rc.sysinit
  2. #!/bin/bash 
  3. echo -e "====================================" 
  4. echo -e "  \e[31;5mWelcome to MY Linux\3[0m" 
  5. echo -e "  \e[32m`date`\e[0m"  
  6. echo -e "===================================="  
  7. insmod /lib/modules/mii.ko 
  8. insmod /lib/modules/pcnet32.ko
  9. ifconfig eth0 192.168.8.61/16
  10. ifconfig lo 127.0.0.1
  11. /bin/bash 

  1. #!/bin/bash
  2. . /etc/rc.d/functions
  3. echo -e "===================================="
  4. echo -e " \e[31;1m\tWelcome to My Linux Space\e[0m"
  5. echo -e " \e[32;1m\t`date`\e[0m"
  6. echo -e "===================================="
  7. echo "Remount rootfs..."
  8. mount -n -o remount,rw /
  9. success "Remount rootfs"
  10. echo "Set hostname"
  11. [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
  12. [ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
  13. /bin/hostname $HOSTNAME
  14. success "Set hostname"
  15. echo "Initializing network device..."
  16. insmod /lib64/modules/mii.ko && success mii.ko || failed mii.ko
  17. insmod /lib64/modules/pcnet32.ko && success pcnet32.ko || failed pcnet32.ko

定义了系统启动后好后,显示的内容,以及启用的shell,这里是/bin/bash
说明:这两个模块和网络驱动相关
     insmod /lib/modules/mii.ko 
insmod /lib/modules/pcnet32.ko

增加执行权限
  1. chmod +x rc.sysinit  

grub.conf
进入/mnt/boot/grub下,找到grub.conf,编辑
  1. default=0 
  2. timeout=5  
  3. title My Linux 
  4.         root (hd0,0) 
  5.         kernel /vmlinuz ro root=/dev/sda3 quiet
  6.         initrd /initrd.gz 
这个文件定义了开机加电自检之后,系统读取了MBR中bootloarder,如何去加载内核等相关信息

到此,制作完成。
在vmware中新建一个虚拟机,使用刚才制作的硬盘启动,OK。