- 前言
操作系统为了能够更广泛的适用性,集成了众多的模块与功能,特别是一些驱动程序。但对于一台特定的机器来说,其中很多功能模块实际上是冗余的。系统越来越臃肿,启动慢,占用资源多。我们可以针对自己机器的硬件及所需的功能,自己进行定制。本文就是在VMware虚拟机上基于RHEL 5.8 来搭建一个小Linux系统,并且一步步进行完善。
一、前期准备
- 一台VMware中已装好RHEL5.8的虚拟机作为宿主机(宿主机本身为scsi盘)。
- 在宿主机中添加一个1G的磁盘,作为目标机(我们要搭建的Little Linux,下同)的磁盘。为了降低复杂度,这里添加一块IDE磁盘。
- 在宿主机中建立目标机磁盘挂载目录
mkdir /mnt/{boot,sysroot}
- 目标磁盘分区及格式化
fdisk /dev/hda
建立2个主分区,/dev/hda1 100M,剩余的空间分给/dev/hda2。然后格式化磁盘。
mke2fs -j /dev/hda1
mke2fs -j /dev/hda2
- 挂载到目标机
mount /dev/hda1 /mnt/boot
mount /dev/hda2 /mnt/sysroot
二、目标机boot分区制作
- 拷贝宿主机内核文件
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz
- 解压提取initrd文件
mkdir ~/tmp
cd ~/tmp
zcat /boot/initrd-2.6.18-308.el5.img | cpio -id
注:initrd文件是内核启动boot引导时所加载的一个临时根文件系统,里面包含了一些shell程序,init脚本,必须的驱动程序等。file /boot/initrd-2.6.18-308.el5.img 可以看到该文件为cpio归档,gzip压缩文件。上述步骤将/boot/initrd-2.6.18-308.el5.img中文件解压提取到~/tmp下。
- 修改init文件
vi ~/tmp/init
#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
echo Mounting sysfs filesystem
mount -t sysfs /sys /sys
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mkdir /dev/pts
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
mkdir /dev/shm
mkdir /dev/mapper
echo Creating initial device nodes
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mknod /dev/urandom c 1 9
mknod /dev/systty c 4 0
mknod /dev/tty c 5 0
mknod /dev/console c 5 1
mknod /dev/ptmx c 5 2
mknod /dev/rtc c 10 135
mknod /dev/tty0 c 4 0
mknod /dev/tty1 c 4 1
#mknod /dev/tty2 c 4 2
#mknod /dev/tty3 c 4 3
#mknod /dev/tty4 c 4 4
#mknod /dev/tty5 c 4 5
#mknod /dev/tty6 c 4 6
#mknod /dev/tty7 c 4 7
#mknod /dev/tty8 c 4 8
#mknod /dev/tty9 c 4 9
#mknod /dev/tty10 c 4 10
#mknod /dev/tty11 c 4 11
#mknod /dev/tty12 c 4 12
mknod /dev/ttyS0 c 4 64
mknod /dev/ttyS1 c 4 65
#mknod /dev/ttyS2 c 4 66
#mknod /dev/ttyS3 c 4 67
echo Setting up hotplug.
hotplug
echo Creating block device nodes.
mkblkdevs
#echo "Loading ehci-hcd.ko module"
#insmod /lib/ehci-hcd.ko
#echo "Loading ohci-hcd.ko module"
#insmod /lib/ohci-hcd.ko
#echo "Loading uhci-hcd.ko module"
#insmod /lib/uhci-hcd.ko
#mount -t usbfs /proc/bus/usb /proc/bus/usb
echo "Loading jbd.ko module"
insmod /lib/jbd.ko
echo "Loading ext3.ko module"
insmod /lib/ext3.ko
echo "Loading scsi_mod.ko module"
insmod /lib/scsi_mod.ko
#echo "Loading sd_mod.ko module"
#insmod /lib/sd_mod.ko
#echo "Loading scsi_transport_spi.ko module"
#insmod /lib/scsi_transport_spi.ko
#echo "Loading mptbase.ko module"
#insmod /lib/mptbase.ko
#echo "Loading mptscsih.ko module"
#insmod /lib/mptscsih.ko
#echo "Loading mptspi.ko module"
#insmod /lib/mptspi.ko
echo "Loading libata.ko module"
insmod /lib/libata.ko
echo "Loading ata_piix.ko module"
insmod /lib/ata_piix.ko
#echo "Loading ahci.ko module"
#insmod /lib/ahci.ko
#echo "Loading dm-mod.ko module"
#insmod /lib/dm-mod.ko
#echo "Loading dm-log.ko module"
#insmod /lib/dm-log.ko
#echo "Loading dm-mirror.ko module"
#insmod /lib/dm-mirror.ko
#echo "Loading dm-zero.ko module"
#insmod /lib/dm-zero.ko
#echo "Loading dm-snapshot.ko module"
#insmod /lib/dm-snapshot.ko
#echo "Loading dm-mem-cache.ko module"
#insmod /lib/dm-mem-cache.ko
#echo "Loading dm-region_hash.ko module"
#insmod /lib/dm-region_hash.ko
#echo "Loading dm-message.ko module"
#insmod /lib/dm-message.ko
#echo "Loading dm-raid45.ko module"
#insmod /lib/dm-raid45.ko
#echo Waiting for driver initialization.
#stabilized --hash --interval 1000 /proc/scsi/scsi
mkblkdevs
#echo Scanning and configuring dmraid supported devices
#echo Scanning logical volumes
#lvm vgscan --ignorelockingfailure
#echo Activating logical volumes
#lvm vgchange -ay --ignorelockingfailure vg00
#resume /dev/vg00/lvswap
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
注:上文是修改后的内容,将一些不需要的模块加载注释掉,如scsi、sata、USB、dm、raid相关模块。注释掉lvm扫描、scsi初始化、swap挂载等语句。最重要的一点,mkrootdev -t ext3 -o defaults,ro /dev/hda2,该局只读挂载真正的根文件系统,改成目标机根文件系统所在分区/dev/hda2。
4. 删除多余的驱动模块
rm -f ~/tmp/lib/*hci*
rm -f ~/tmp/lib/mpt*
rm -f ~/tmp/lib/dm*
...
注:最后只剩下5个模块 ata_piix.ko ext3.ko jbd.ko libata.ko scsi_mod.ko
5. 归档压缩制作initrd文件
cd ~/tmp
find . | cpio -H newc -o | gzip -9 > /mnt/boot/initrd.img
6. 创建grub引导信息
grub-install --root-directory=/mnt /dev/hda
7. 创建并编辑grub.conf文件
vi /mnt/boot/grub/grub.conf
default=0
timeout=1
title Little Linux Based on RHEL5.8 by HF
root (hd0,0)
kernel /vmlinuz
initrd /initrd.img
三、制作目标机root根文件系统
- 建立基本目录
cd /mnt/sysroot
mkdir -p proc sys etc/rc.d/init.d bin sbin lib usr/{bin,sbin,local} var/log home root dev boot
- 拷贝宿主机中bash程序及其依赖的库文件
- 拷贝宿主机中init程序及其依赖的库文件
- 拷贝其它外部命令shell脚本及其依赖的库文件:如ls cp mv vim insmod ifconfig ping shutdown halt reboot mkdir rmdir ....
注:2、3、4步骤我是用脚本完成的,脚本在这也贡献出来啦
#!/bin/bash
#
#This script may help you to transplant commands from host pc to destination pc
DestPath=/mnt/sysroot
E_nocmd=1
Usage(){
echo "Usage: `basename $0` command1 [command2] [command3] ..."
}
GetCmdPath(){
which $1 | grep -v alias | grep -o "/.*"
}
GetLibPaths(){
ldd $1 | grep -o "/[^[:space:]]*"
}
TransCmd(){
[ -d $DestPath${1%/*} ] || mkdir -p $DestPath${1%/*}
cp $1 $DestPath$1
}
TransLibs(){
for I in $LibPaths; do
[ -e $DestPath$I ] && continue
[ -d $DestPath${I%/*} ] || mkdir -p $DestPath${I%/*}
cp $I $DestPath$I
done
}
[ $# -lt 1 ] && Usage && exit $E_nocmd
until [ $# -lt 1 ]; do
! which $1 &> /dev/null && echo "No such command: $1" && shift 1 && continue
CmdPath=`GetCmdPath $1`
[ -e $DestPath$CmdPath ] && echo "$1 exits" && shift 1 && continue
TransCmd $CmdPath
LibPaths=`GetLibPaths $CmdPath`
TransLibs
echo "$1 and its dependent libraries were transplanted."
shift 1
done
5. 创建编辑inittab文件
vim /mnt/sysroot/etc/inittab
内容如下:
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
6.创建编辑sysinit脚本
vim /mnt/sysroot/etc/rc.d/rc.sysinit
内容如下:
#!/bin/bash
#
echo -e "Welcome to \033[31mLittle Linux Based on RHEL5.8 \033[0m by HF"
/bin/bash
然后给脚本赋执行权限。
chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit
注:到这我们的脚本基本就可以启动起来了。并且在“三.4”步骤中植入的命令也绝大多数都可以执行了(除关机命令还不能有效)。下面我们再给系统增加网络功能。
四、给Little Linux配置网络功能
- 移植宿主机网络相关驱动模块到目标机中
mkdir -p /mnt/sysroot/lib/modules/2.6.18-308.el5/kernel/drivers/net
cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko
cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko
注:pcnet32是VMware虚拟机虚拟网卡的驱动模块,mii是其所依赖的模块。我是用脚本搞定的了。主要是考虑到以后可能会用到其他模块,先把脚本写好方便。此脚本需要用到递归函数,下次贴出来跟大家一起讨论。
2. 设置开机自动加载网卡驱动,并配置网络。
编辑sysinit脚本
vim /mnt/sysroot/etc/rc.d/rc.sysinit
最终内容如下:
#!/bin/bash
#
echo loading net modules
insmod /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko
insmod /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko
echo loading ip config
ifconfig eth0 192.168.0.142 up
ifconfig lo 127.0.0.0 up
echo -e "Welcome to \033[31mLittle Linux Based on RHEL5.8 \033[0m by HF"
/bin/bash
五.测试
- 创建配置Little Linux虚拟机
在VMware中点击创建新的虚拟机,→下一步→下一步→选“稍后安装操作系统”→下一步→操作系统选Linux,版本选Red Hat Enterprise Linux 5→下一步→下一步→下一步→选“使用桥接网络”→下一步→选“LSI Logic”→下一步→选“IDE”→下一步→选“使用已有磁盘”→下一步→点浏览,找到刚刚做好的那块磁盘打开→下一步。。。
- 启动虚拟机。如果VMware提示是否尝试连接SATA设备之类的,选择否。等待启动完成,ping一下啊网关,通的啦。最后贴一张进入界面的图
注:完成上述网络功能,在“三.4”步骤中至少要添加如下命令:insmod ifconfig ping。
目前是直接进入控制台,没有开启虚拟终端,没有用户登录界面,没有用户、密码。。。还有很多需要完善的地方,我们会一步一步的来完善啦。敬请期待后篇。