linux系统裁剪一summary
原料和工具
一台pc机(我用的redhat5)
kernel6.18
busybox版本:1.20.1
系统启动流程图
小系统制作流程分析
一些脚本及配置文件的意义
kernel初始化
1.设备探测;
2.驱动初始化,可能会从(initrd(initramfs)中装载驱动模块即访问真正根文件系统的驱动列如ext3.ko)
3.以只读方式挂载根文件系统;
4.装载第一个用户空间init进程(PID:1)
/etc/inittab的配置文件意义
1.设置默认启动级别;
2.系统初始化;
3.执行指定级别下的服务;
4.设置ctrl+alt+delete组合键的作用;
5.设置UPS电源在大电故障或恢复时的操作;
6.启动虚拟终端;
7.启动图形终端;
/etc/rc.d/rc.sysinit脚本的作用
1.#激活udev和selinux;
2.根据/etc/sysctl.conf文件,来设定内核参数;
3.设置主机名;
4.以读写方式重新挂载根文件系统;
5.根据/etc/fstab,挂载其他文件系统;
6.#设置时钟;
7.#装载键盘映射;
8.#启用交换分区;
9.#启用磁盘配额;
10.#激活RAID和LVM设备;
11.#清理过期的锁和PID文件;
tips:前面打#号代表我还没有设置。
/etc/fstab配置文件的作用
在挂载其他文件系统时,会读取此配置文件;
/etc/mtab文件
此文件会记录当前系统挂载的所有文件系统,当系统在挂载或卸载了文件系统时都会记录在此文件里,mount使用-n选项时不会记录在此表中。
具体流程
1.在linux pc上添加上一块空的硬盘(我设置的容量大小为10G)我这里添加了一块IDE类型的磁盘,将其分两个主分区(/dev/hda1,/dev/hda2),并以ext3格式化,然后在/mnt目录下创建/boot和/sysroot两个目录并挂载上。
// An highlighted block
[root@localhost ~]# fdisk -l
Disk /dev/hda: 10.7 GB, 10737418240 bytes
15 heads, 63 sectors/track, 22192 cylinders
Units = cylinders of 945 * 512 = 483840 bytes
Disk /dev/hda doesn't contain a valid partition table
#分区
[root@localhost ~]# fdisk -l
Disk /dev/hda: 10.7 GB, 10737418240 bytes
15 heads, 63 sectors/track, 22192 cylinders
Units = cylinders of 945 * 512 = 483840 bytes
Device Boot Start End Blocks Id System
/dev/hda1 1 42 19813+ 83 Linux
/dev/hda2 43 308 125685 83 Linux
#格式化成ext3格式并挂载到目录(/mnt/boot,/mnt/sysroot)
[root@localhost ~]# mke2fs -j /dev/hda1
[root@localhost ~]# mke2fs -j /dev/hda2
[root@localhost ~]# mkdir /mnt/{boot,sysroot}
[root@localhost ~]# mount /dev/hda1 /mnt/boot
[root@localhost ~]# mount /dev/hda2 /mnt/sysroot/
#解压busybox&linux2.6.38.8内核
[root@localhost src]# tar -xf busybox-1.20.1.tar.bz2
[root@localhost src]# xz -d linux-2.6.38.tar.xz
[root@localhost src]# ls
busybox-1.20.1 busybox-1.20.1.tar.bz2 debug kernels linux-2.6.38.tar redhat
[root@localhost src]# tar -xf linux-2.6.38.tar
#复制头文件ubi-user.h到busybox的incude/mtd下
[root@localhost busybox-1.20.1]# mkdir include/mtd
[root@localhost busybox-1.20.1]# cp ../linux-2.6.38/include/mtd/
inftl-user.h Kbuild mtd-abi.h mtd-user.h nftl-user.h ubi-user.h
[root@localhost busybox-1.20.1]# cp ../linux-2.6.38/include/mtd/ubi-user.h include/mtd/
#制作initrd
[root@localhost busybox-1.20.1]# make menuconfig
此处注意选择编译库时,以静态方式(此方式会增加命令占用的空间)编译,方便移植命令;
[root@localhost busybox-1.20.1]# make install
且编译好的命令安装在_install下
[root@localhost busybox-1.20.1]# cp -a _install/ /tmp/initrd
[root@localhost initrd]# ls
bin linuxrc sbin usr
[root@localhost initrd]# mkdir -pv dev lib/modules proc sys lib64 etc
[root@localhost initrd]# ls
bin dev etc lib lib64 linuxrc proc sbin sys usr
[root@localhost initrd]# rm -f linuxrc
[root@localhost sysroot]# ls /tmp/initrd/lib/modules/
ext3.ko jbd.ko
#编写init脚本,用于内核初始化执行
[root@localhost initrd]# ls
bin dev etc init lib lib64 proc sbin sys usr
[root@localhost initrd]# find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz #将制作好的initrd.gz放到/mnt/boot下
#复制内核到/mnt/boot下
[root@localhost initrd]# cp /boot/vmlinuz-2.6.18-398.el5 /mnt/boot/vmlinuz
#安装grub并配置
[root@localhost initrd]# grub-install --root-directory=/mnt /dev/hda
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/hda
(hd1) /dev/sda
[root@localhost boot]# ls
grub initrd.gz lost+found vmlinuz
[root@localhost boot]# ls grub/
device.map ffs_stage1_5 minix_stage1_5 stage2 xfs_stage1_5
e2fs_stage1_5 iso9660_stage1_5 reiserfs_stage1_5 ufs2_stage1_5
fat_stage1_5 jfs_stage1_5 stage1 vstafs_stage1_5
[root@localhost boot]# vim grub/grub.conf
default=0
timeout=5
title myTinyLinux
root (hd0,0)
kernel /vmlinuz ro root=/dev/hda1
initrd /initrd.gz
挂载虚根文件系统的目的是装载访问真正根文件系统所需要的模块ext3.ko,所以这里还需要将ext3.ko及其以来的模块一并放置到lib/modules下
#制作真正的根文件系统
[root@localhost boot]# cp /usr/src/busybox-1.20.1/_install/ /mnt/sysroot -a
[root@localhost boot]# cd /mnt/sysroot/
[root@localhost sysroot]# ls
bin linuxrc lost+found sbin usr
[root@localhost sysroot]# rm -rf linuxrc
[root@localhost sysroot]# mkdir -pv dev home lib64 mnt proc sys usr boot etc/rc.d lib/modules opt root srv tmp var/{log,run,lock}
#为了识别网卡,此处还要放入识别网络设备的模块及其依赖模块(pcnet32.ko,mii,ko;我这里是e1000.ko;可以通过dmesg | grep eth0看到网卡驱动模块)
[root@localhost ~]# ls /mnt/sysroot/lib/modules/
ext3.ko jbd.ko mii.ko pcnet32.ko e1000.ko
#再编写/etc/inittab,/etc/rc.d/rc.sysinit,/etc/fstab文件
[root@localhost etc]# tree
.
|-- fstab
|-- group
|-- hostname
|-- inittab
|-- issue
|-- passwd
|-- rc.d
| `-- rc.sysinit
|-- shadow
`-- sysctl.conf
总结
这篇博客现在只是把大概的流程梳理了一下,还有很多细节还没有做完,列如添加磁盘配额,键盘映射,激活交换分区,激活RAID和LVM设备,清理过期锁和PID文件;。写这篇博客的目的是想完整记录linux系统裁剪的具体过程,然后也希望看了这边博客的人也能学到一点(大神请绕道0_0),当你了解了这个过程后,linux系统启动的工作原理你将会心知肚明。
好了!!!,今天就写到这里了,已经很晚了,明天继续。
一些有用的脚本和配置文件
/etc/inittab
[root@localhost etc]# cat inittab
::sysinit:/etc/rc.d/rc.sysinit
::respawn:/sbin/getty 9600 tty1
::respawn:/sbin/getty 9600 tty2
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
/etc/rc.d/rc.sysinit
[root@localhost etc]# cat rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\tWelcome to \033[032mtianming tiny linux\033[0m"
echo "mount /proc and /sys..."
mount -t proc proc /proc
mount -t sysfs sysfs /sys
echo "remount rootfs filesystem by rw."
mount -n -o remount,rw /
echo "detect and export other hardware information..."
mdev -s
echo "Set hostname..."
[ -f "/etc/hostname" ] && . /etc/hostname
[ -z "$HOSTNAME" -o $HOSTNAME == "(none)" ] && HOSTNAME=localhost
hostname $HOSTNAME
echo "load Ethernet interface module and set ip..."
#insmod /lib/modules/mii.ko
#insmod /lib/modules/pcnet32.ko
insmod /lib/modules/e1000.ko
ifconfig eth0 192.168.2.233/24
ifconfig lo 127.0.0.1/8
echo "mount other filesystem..."
mount -a
echo "set kernel paraments..."
sysctl -p
/etc/fstab
[root@localhost etc]# cat fstab
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
/dev/hda2 / ext3 defaults 0 0
/grub/grub.conf
[root@localhost boot]# cat grub/grub.conf
default=0
timeout=5
title Linux in U device
root (hd0,0)
kernel /vmlinuz ro root=/dev/sdb3 #root指定的是根文件系统所在的位置。
initrd /initrd.gz
复制命令及命令依赖的库脚本
[root@localhost ~]# cat cmdcp.sh
#!/bin/bash
#
# description: This script aim to copy command you want and its share lib to destination dir
# cp command
DEST=/mnt/sysroot
cmdcp() {
CMDPATH=${1%/*}
[ ! -d ${DEST}$CMDPATH ] && mkdir ${DEST}$CMDPATH
[ -e ${DEST}$1 ] && echo "$1 exists..." && return 1
[ ! -e ${DEST}$1 ] && cp $1 ${DEST}$CMDPATH && echo "copy $1 success..." && return 0
}
libcp() {
LIBPATH=${1%/*}
[ ! -d ${DEST}$LIBPATH ] && mkdir -p ${DEST}$LIBPATH
[ -e ${DEST}$1 ] && echo "$1 exists..." && return 2
[ ! -e ${DEST}$1 ] && cp $1 ${DEST}$LIBPATH && echo "copy $1 success..." && return 0
}
read -p "please input command: " yi
until [ ${yi} == "q" ];do
yi=`which $yi | grep -v "alias"`
cmdcp $yi
for l in `ldd $yi | grep -o -E "/.*lib(64){0,1}/[^[:space:]]{1,}"`;do
#echo $l
libcp $l
done
read -p "please input command: " yi
done
exit 0
当文件系统发生错乱时,用此脚本恢复
[root@localhost ~]# cat mount_sysroot.sh
#!/bin/bash
#
echo "Kill processes accessing the file in /dev/hda2..."
fuser -km /dev/hda2 &> /dev/null
[ $? -eq 0 ] && echo "kill processes successfully..." || echo "kill process failed..."
echo "umount /dev/hda2/"
umount /dev/hda2
[ $? -eq 0 ] && echo "umount /dev/hda2 successfully..." || echo "umount /dev/hda2 failed..."
echo "init /dev/hda2 device..."
mke2fs -j /dev/hda2
[ $? -eq 0 ] && echo "init /dev/hda2 successfully..." || echo "init /dev/hda2 failed..."
echo "mount /dev/hda2..."
mount /dev/hda2 /mnt/sysroot
[ $? -eq 0 ] && echo "mount /dev/hda2 successfully..." || echo "mount /dev/hda2 failed..."
cd /mnt/sysroot
zcat /root/sysroot$1.gz | cpio -id
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。