在上一篇开机启动顺序的博客里,自己混乱的大脑抗不住了。回头看自己写的博文,实在是难以入目。在随后深入了解系统内核原理之后,这里通过动手实验,在原有centos6.0基础上,裁剪出来一个简单的Linux系统,以动手带动对整个系统启动、系统内核的了解。
本文主要的实验环境:vmware9.0,host主机使用centos6.0系统,装载有一块硬盘sda;
主要的实验步骤:给host主机添加一块新的硬盘,分成两个分区,挂载至/mnt/boot,/mnt/sysroot。然后使用grub工作创建启动磁盘,将host的内核文件和initrd文件复制至/mnt/boot中来,配置grub.conf文件。在/sysroot下创建简单的文件系统(这里指的是文件目录结构);然后使用实现准备好的复制命令的脚本复制相关工具,如bash、cp、cat等命令还有基本的网卡模块,至/sysroot目录下;编写init脚本,实现系统开机后的简单初始化。最后,新建虚拟机,使用制作好的硬盘作为启动盘;主要过程见下图所示:
一、添加新硬盘、分区、格式化、挂载
1.给host主机(制作裁剪系统使用的模板系统,“母机”)添加一块硬盘。具体步骤这里不再赘述,选择默认配置即可,这里需要注意的是,要选择“作为单个文件存储虚拟磁盘”。
这里要注意选择好新建磁盘的物理路径,稍后我们新建虚拟机使用的就是这块新添加的磁盘。这里也一定能够要注意,虚拟磁盘后缀是vmdk。
2.然后我们创建新的磁盘分区
#创建/sdb1 100M [root@station47 ~]# echo ' > n > p > 1 > > +100M > w ' | fdisk /dev/sdb WARNING: DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode (command 'c') and change display units to sectors (command 'u'). Command (m for help): Command (m for help): Command action e extended p primary partition (1-4) Partition number (1-4): First cylinder (1-2610, default 1): Using default value 1 Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): Command (m for help): The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks. [root@station47 ~]#
#创建分区sdb2,大小2G [root@station47 ~]# echo ' > n > p > 2 > > +2G > w ' | fdisk /dev/sdb WARNING: DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode (command 'c') and change display units to sectors (command 'u'). Command (m for help): Command (m for help): Command action e extended p primary partition (1-4) Partition number (1-4): First cylinder (15-2610, default 15): Using default value 15 Last cylinder, +cylinders or +size{K,M,G} (15-2610, default 2610): Command (m for help): The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks. [root@station47 ~]#
3.格式化新建的分区
#格式化sdb1 [root@station47 ~]# mke2fs -t ext4 /dev/sdb1 mke2fs 1.41.12 (17-May-2010) 8192 blocks per group, 8192 fragments per group 200 ............................................... #格式化sdb2 [root@station47 ~]# mke2fs -t ext4 /dev/sdb2 mke2fs 1.41.12 (17-May-2010) ................................................ [root@station47 ~]#
4.在/mnt目录下挂载新分区
在/mnt目录先创建目录boot,sysroot。分别挂载sdb1,sdb2至boot,sysroot.
[root@station47 mnt]# mount /dev/sdb1 /mnt/boot/ [root@station47 mnt]# mount /dev/sdb2 /mnt/sysroot/ [root@station47 mnt]# ls boot sysroot boot: lost+found sysroot: lost+found [root@station47 mnt]#
二、安装grub
制作启动磁盘最重要的步骤之一就是安装引导加载器至磁盘。这里使用最流行的grub。切换工作目录至/mnt/boot/,安装grub
#这里使用grub-install命令,root-directory指定bootloader安装的目录,不需要写boot,至根目录即可。 /dev/sdb指定安装引导程序至哪个磁盘 [root@station47 boot]# grub-install --root-directory=/mnt /dev/sdb Probing devices to guess BIOS drives. This may take a long time. Installation finished. No error reported. This is the contents of the device map /mnt/boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (fd0) /dev/fd0 (hd0) /dev/sda (hd1) /dev/sdb [root@station47 boot]#
三、复制内核与initrd文件至/mnt/boot目录
[root@station47 boot]# cp /boot/vmlinuz-2.6.32-358.el6.x86_64 /mnt/boot/vmlinuz [root@station47 boot]# cp /boot/initramfs-2.6.32-358.el6.x86_64.img /mnt/boot/initramfs.img
四、创建目标系统的根文件系统
[root@station47 sysroot]# mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib /modules,lib64,bin,sbin,boot,srv,mnt,media,home,root} mkdir: created directory `/mnt/sysroot/etc' mkdir: created directory `/mnt/sysroot/etc/rc.d' mkdir: created directory `/mnt/sysroot/usr' mkdir: created directory `/mnt/sysroot/var' mkdir: created directory `/mnt/sysroot/proc' mkdir: created directory `/mnt/sysroot/sys' mkdir: created directory `/mnt/sysroot/dev' mkdir: created directory `/mnt/sysroot/lib' mkdir: created directory `/mnt/sysroot/lib/modules' mkdir: created directory `/mnt/sysroot/lib64' mkdir: created directory `/mnt/sysroot/bin' mkdir: created directory `/mnt/sysroot/sbin' mkdir: created directory `/mnt/sysroot/boot' mkdir: created directory `/mnt/sysroot/srv' mkdir: created directory `/mnt/sysroot/mnt' mkdir: created directory `/mnt/sysroot/media' mkdir: created directory `/mnt/sysroot/home' mkdir: created directory `/mnt/sysroot/root'
移植相关命令至sysroot目录下相关目录,为后期使用准备。这里为了系统启动等移植了bash,ls,cat,vi,mkdir,cp,mv,mount,umount,chroot,ping,rmmod,insmod,ifconfig,ip等工具
移植命令。至于cp.sh脚本的工作原理,见博主稍后的博客,专门对该脚本进行全面的分析 [root@station47 tmp]# ./cp.sh Enter a command: bash Enter a command: ls Enter a command: cat Enter a command: vi Enter a command: mkdir Enter a command: cp Enter a command: mv Enter a command: mount Enter a command: umount Enter a command: ping Enter a command: chroot Enter a command: rmmod Enter a command: insmod Enter a command: ifconfig Enter a command: ip Enter a command: quit quit [root@station47 tmp]#
由于很多程序和脚本调用bash使用的都是sh,因此给bash做一个软件连接
[root@station47 bin]# ln -sv bash sh `sh' -> `bash' [root@station47 bin]#
由于后期需要使用网卡设备,我们将/lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000.ko复制到/mnt/sysroot/lib/modules下
[root@station47 ~]# cp /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/sysroot/lib/modules/
五、配置grub.conf文件
#系统开机默认系统 default=0 #等待用户选择系统时间 timeout=5 #显示名称 title test #系统所在分区 root(hd0,0) #内核位置,这里要说明的是root=/dev/sda,因为在当前系统是sdb,稍后哦我们用新虚拟机使用这个硬盘是它就是sda了 kernel /vmlinuz selinux=0 ro root=/dev/sda initrd /initramfs.img ~ ~ ~
六、编辑系统初始化脚本
在/mnt/sysroot/sbin目录下新建init脚本,赋予执行权限
[root@station47 sbin]# vim init #!/bin/bash echo "welcome to the world of Linux" mount -n -t proc proc /proc mount -n -t sysfs sysfs /sys insmod /lib/modules/e1000.ko ifconfig lo 127.0.0.1 ifconfig lo 172.16.251.224 /bin/bash
七、新建虚拟机
使用host主机上的sdb硬盘作为新虚拟机的启动盘。然后启动.
八、错误与反思
在制作的过程出现的问题:
1.启动后找不到init,这个是由于自己粗心,shebang写错了
2.报以大堆的错,回去检查所有的步骤及配置文件,发现在grub.conf中,root写的是sda,实际上应该是sda2,真正的根文件系统是在sda2上的,不是在系统的启动盘上。
3.系统启动之后一直无法连接上网络,但是网卡信息显示是正常的。很郁闷,同一个网段的是可以ping通的,但是不同网的ftp服务器仍然无法ping通。需解决
Version: 2014-3-5 原始版本