在前一篇《Linux系统基础-管理之系统启动过程及系统初始化学习总结 》当中已经了解到了系统的一些基本启动过程和初始化过程,这篇文章是结合前面的知识而做的一个小实验。


一、说明

1、实验拓扑:

wKioL1Ma_xPQaBnrAAF3ZrfeoJI777.jpg

2、实验环境:

  • 操作系统:CentOS-6.5 x86_64

  • 虚拟机版本VMware Workstation 10.0.0 build-1295980

  • HOST主机名station10.example.com    

   如上图我们需要有一台上面装有CentOS 6.5-x86_64系统的的PC Server以下我简称为"HOST"以及一台没有操作系统,没有硬盘的PC客户端,以下简称"Target",有朋友这时会问了,Target既没有系统、也没有硬盘那怎么可能启动呀?我们的实验目的是通过一台本身安装有操作系统的主机上通过对当前系统或者说借助当前系统我们裁剪出一个微型的Linux系统,并使之能启动起来。

下面就看我详细的操作步骤吧...


二、操作步骤:

1HOST上面添加一块20G的硬盘HOST上为被识别为sdb;

wKiom1MaHyeSuib4AAIID00ixJ0284.jpg

2在/mnt下创建两个目录(/mnt/sysroot,/mnt/boot)用来挂载作为微系统的boot和真正的根文件系统对此磁盘分区,格式化为ext4格式的文件系统,并将其分别挂载分区至/mnt/boot./mntsysroot;

当然我们可以先写一个脚本(Autoparti。sh)较为方便自动的达到我们分区,格式化和挂载的目的。

   以下为脚本内容(小生shell脚本编写能力有限,望各位勿喷。)

#---------------CopyRight--------------
#   Name:AutopartitionMount
#   Version Number:1.00
#   Type:Tools
#   Language:bash shell
#   Date:2014-03-9
#   Author:Maoqiuguo
#   Email:guomaoqiu@sina.com
#--------------Environment-------------
#   Terminal: Xmanager SLS (Registered)
#   Linux 2.6.32-431.el6.x86_64
#   GNU Bash 4.1.2
#--------------------------------------
#!/bin/bash
function MOUNT {    
           mke2fs -t ext4 "$d_path"1 &>/dev/null
           mke2fs -t ext4 "$d_path"2 &>/dev/null
           mount "$d_path"1 /mnt/boot &> /dev/null
           mount "$d_path"2 /mnt/sysroot &> /dev/null
           [ $? -eq 0 ] && echo -e "\033[44;37;5m Partition the mount has been completed!\033[0m" || echo -e "\033[31mError...\033[0m"
}
read -p "Please input a device file path:" d_path
while ! [[ $d_path == "quit" ]];do
        if [ -z $d_path ] || ! [ -b $d_path ];then
             echo -e "\033[31mInput Error...\033[0m"
             read -p "Please input a device file path again:" d_path
        else
             echo -e "\033[5;31mThe following will clear the data in the disk, whether or not to continue!\033[0m"
             read -p "Sure,enter[y|yes]:" anwser
                 anwser=`echo $anwser | tr 'A-Z' 'a-z'`
                 if [[ $anwser == "y" ]] || [[ $anwser == "yes" ]];then
                         dd if=/dev/zero of=$d_path bs=510 count=1 &> /dev/null
                         echo -e 'n\np\n1\n \n+200M \nn\np\n2\n \n+10G\nw' | fdisk $d_path &> /dev/null
                                if  [ -d /mnt/boot ] && [ -d /mnt/sysroot ];then
                                        MOUNT
                                else
                                     mkdir /mnt/{boot,sysroot}
                                        MOUNT
                               fi
                else
                        exit 8
                fi
                    exit
        fi
done
exit 9

下图是该脚本执行后的结果:

wKioL1MaH3_DzzkUAAU4sbOCH0U549.jpg

4安装grub至稍后作为Target的硬盘上/dev/sdb;

wKiom1MaH-zgSg8tAAQidyimFEI139.jpg

5将HOST上的内核文件vmlinuzinitrd文件initramfs复制到/mnt/boot目录下

wKioL1MaIGrjoGFiAAFrfd_H64w193.jpg

6./mnt/sysroot目录下创建目标主机Target的根文件系统

wKiom1MaIWfzLRA2AAHdzkcFzMU410.jpg

7下面这个cp.sh脚本是为了从HOST上面移植命令和所依赖的各种库文件到微型系统里面使用的;

#---------------CopyRight--------------
#   Name:cp.sh
#   Version Number:3.00
#   Type:Tools
#   Language:bash shell
#   Date:2014-03-9
#   Author:Maoqiuguo
#   Email:guomaoqiu@sina.com
#--------------Environment-------------
#   Terminal: Xmanager SLS (Registered)
#   Linux 2.6.32-431.el6.x86_64
#   GNU Bash 4.1.2
#--------------------------------------
#!/bin/bash
target=/mnt/sysroot
clearCmd() {
if which$cmd &> /dev/null; then
cmdPath=`which --skip-alias $cmd`
else
echo"No such command"
return 5
fi
}
cmdCopy() {
cmdDir=`dirname $1`
[ -d${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
[ -f${target}${1} ] || cp $1 ${target}${cmdDir}
}
libCopy() {
forlib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`; do
libDir=`dirname $lib`
[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
[ -f ${target}${lib} ] || cp $lib ${target}${libDir}
done
}
while true; do
read -p"Enter a command: " cmd
if [ "$cmd" == 'quit' ] ;then
echo"quit"
exit0
fi
clearCmd$cmd
[ $? -eq 5] && continue
cmdCopy$cmdPath
libCopy$cmdPath
done

下图是cp.sh脚本执行界面:

wKioL1May9GB_dwzAAQ51cb5UQE667.jpg

此时我们需要切换到微型系统真正更目录系统下面的bin目录为bash创建一个软连接;

wKiom1MalaejezE3AAMCC7bM8dQ228.jpg

8为Target的Grub提供配置文件(可参考宿主主机的grub文件进行创建);

wKiom1MaI17QtoNJAAE-gYW1SOM514.jpg

9现在已经准备得差不多了,我现在先创建一个Target;

对于朋友们来说对新建一个虚拟机不陌生了吧,那我在创建过程当中需要注意的事项给贴出来吧;

注意版本的选择

wKioL1ManGCyj0hgAAFcfeeKiB0904.jpg

我们选择的就是挂载在HOST上面的那块盘,而无需新建

wKioL1Maz6uChwbwAAGBCQnnGMY776.jpg

wKiom1ManlCBnnKtAAE5mf9Ro7s005.jpg

最后完成我们Target的创建。

wKioL1ManyXBSJgwAAJKUJRPBnc936.jpg

10此时我将HOST给挂起,因为他们不能共同使用一个硬盘设备,然后将sdb挂载至Target

,调整BIOS选项,让其从硬盘启动,看一下是否能启动;

wKioL1MaoEKQ_v3qAAIKhCmm8lw354.jpg

grub引导界面

wKiom1MaoGrhtKCTAAFloAMGOkY721.jpg

系统初始化过程...

wKioL1MaoEOSSOaZAANZq2jS-Fw927.jpg

wKioL1MaoQDj3UTlAAHIN10oYTE599.jpg

晕!内核恐慌了,系统告诉我找不到init程序。那我就为它创建一个吧。

13将Target关机,让HOST启动。首先我们知道init存放的位置是超级用户二进制程序的目录下,它也和其他程序放在一起的,也就是微型系统的根目录下的sbin目录了,我们手动写一个就行了:

wKioL1MaoqvQNCUSAABPBmhKm1k893.jpg

wKioL1MaoqrR5NEKAADaDYDLJrw749.jpg

修改之后我们需要为它赋予执行权限

wKiom1MaotHQeSZJAABu--MnRBI414.jpg

然后我还需要修改grub.conf文件,因为grub需要引导着内核去找init程序。

wKiom1MaotHw-gMTAAEt4B1_Rt4557.jpg

最后重复上面的步骤10。

wKioL1Map9qhQif_AAMCMVX19W0556.jpg

好了,已经成功的进入了,命令也可以使用了。

14最后我们装载网卡驱动模块,让其具有网络功能;还是得先将Target关机,让HOST启动;

①为微型系统创建存放驱动模块的目录,将HOST上的网卡驱动模块copy至Target:

wKioL1MaqMajV0DGAAGyvVMxNa0739.jpg

将HOST挂起,让Target启动并装载网卡驱动模块;

wKiom1MaviHx1N73AAPTl6n2wtU931.jpg

wKioL1MavfvCRrlsAAEW70K_qU0490.jpg

③我先测试一下ping 回环地址能通,如果能通说明网卡驱动模块装载成功。

wKioL1Mav5PBOCghAADalbo1BN0282.jpg

④接下来为网卡eth0配置IP,并测试能否连到我的windows ip。

wKiom1MawmPg4e20AAIwd37Bs-I338.jpg

wKiom1MawhXRLo0qAALL6dgMiP4978.jpg

⑤再次证明了我的网卡驱动模块装载成功了,但是有个问题问题,就是每次我重启之后都要去装载网卡驱动模块和手动配置IP地址,显得还不够自动化,如果能将这些操作都写到一个配置文件中让它在系统启动、初始化的时候就为我把这些都做了那多好;上篇博客中也提到了,在系统初始化的时候有个配置文件是专门用来设定系统一些配置的这个文件就是/etc/rc.d/rc.sysinit;但是我的微型系统里面并没有这个文件;那此时我也可以写到init这个程序文件当中;

15、将Target关机,让HOST启动,再次编辑微型系统的init程序文件:

wKioL1MaoqvQNCUSAABPBmhKm1k893.jpg

wKioL1McbkLTWJj7AAIF2iHH1bw264.jpg

16将HOST挂起,让Target启动;  验证结果:

wKioL1MayBKgPmKuAAO5H5eGIjc864.jpg

wKioL1MayEmR5vwHAAEEYwi-lqQ530.jpg

好了,到此为止一个具有简单网络功能的微型Linux的系统已完成,后续会逐渐完善它的功能。




t_0022.gif小生总结能力有限,望各位大神多多指教。