字体颜色:
T_RED="\\033[1;31m" # bold+red
T_GREEN="\\033[1;32m" # bold+green
T_YELLOW="\\033[1;33m" # bold+yellow
T_BLUE="\\033[1;34m" # bold+blue
T_CYAN="\\033[1;36m" # cyan
T_BOLD="\\033[1;37m" # bold+white
T_NORM="\\033[0;39m" # normal
系统启动流程:
POST-->BIOS(Boot Sequence)--> BootLoader(MBR)--> Kernel(initrd,initramfs)--> init (/etc/inittab)
首先加电自检,加电自检是怎么完成的,计算机本身不会执行程序,由此先去载入一段程序,系统刚刚启动的时候,它能够实现将某个RAM中的程序映射到CPU可以寻址的地址空间中去,并且让CPU能够执行其中的指令,这些指令无法是完成系统检测,当检测完成以后,如果所有的硬件或基本硬件、核心硬件没有问题的话,接下来进入下一步根据BIOS当中所设定的系统启动流程去找那个对应设备上的MBR,根据引导次序去挨个逐个的去找那个对应的存储设备上的MBR,如果说MBR存在的话,则回去读取MBR中的bootloader,bootloader是一段程序,对于早些的设备来讲这个bootloader空间,或者MBR留给bootloader空间一共是512bytes,但是用于bootloader有446bytes,在bootloader当中配置了所要引导的操作系统的内核的位置,因此BIOS被载入内存以后,当它实现将控制权限转交给bootloader以后,那么bootloader就接收了整个系统的控制权限,而后根据用户的选择去读取相应操作系统的内核,将内核装载进内存当中合适的位置,解压缩,并完成内核初始化以后,接下来bootloader会将控制权限转交给内核,内核在初始化时主要完成硬件探测、装载驱动、这个驱动程序可能在内核当中,也可能在另外一个辅助文件当中initrd(RHEL 5 ramdisk、RHEL 6 ramfs),在RHEL 6中叫initramfs,这里面有内核所需要依赖到的额外的其他的设备驱动,尤其是根文件系统的驱动,接下来挂载根文件系统,当根文件系统挂载完成之后,接下来启动用户空间中的第一个进程叫init,这是内核初始化的基本任务,如果内核要完成初始化,它需要依赖于驱动程序,这些驱动程序如果没有被直接做在内核当中,那就需要到某个文件系统路径下去装载这个驱动程序,但是在真正根文件系统被挂载之前就出现一个难题,如果内核访问这个根文件系统那个设备,需要用到某个驱动程序的话,内核中没有,它就需要到文件系统当中找这个驱动程序,但是这个文件系统本身又没有挂载,所以要想访问文件系统得先找到驱动,要访问驱动得先找到文件系统,所以出现这样的难题,就是借助与initrd为内核提供访问真正的根文件系统所需要基本驱动程序,所以initrd是个辅助性的、过渡性的中间层,它能够实现将kernel和真正的根文件系统连接起来,所以当连接完成之后,它就没有意义了,当kernel初始化完成以后接下来执行init进程,而init本身的配置文件是/etc/inittab,在RHEL 6上不再是传统的init,而是upstart,而upstart的配置文件是/etc/inittab和/etc/init*.conf,upstart是个项目名称,这个程序为了兼容它依然较Init,也就意味着RHEL 6上的init不再是传统的init了,它是一个被称作较upstart的init程序,这个程序和传统的有着巨大的区别,而upstart本身它的配置文件/etc/inittab和/etc/init/*.conf文件,依然以RHEL 5来讲,init主要完成那些工作,这主要取决于inittab文件;
RHEL 6:
upstart(项目名称) --> init
/etc/inittab
/etc/init*.conf
内核初始化:
硬件探测
装载驱动
挂载根文件系统(rootfs)
启用用户空间中的第一个进程init
/etc/inittab:
设定默认运行级别
系统初始化(/etc/rc.d/rc.sysinit)
运行指定级别的服务脚本
/etc/rc.d/init.d/
/etc/rc.d/rc#.d
rc0.d--rc6.d
K*
S*
00-99:运行次序
启动虚拟终端
启动图形终端
/etc/rc.d/rc.sysinit: 系统初始化脚本
检测并以读写方式重新挂载根文件系统;
设定主机名;
检测并挂载/etc/fstab中的其它文件系统;
启动swap分区;
初始化外围硬件设备的驱动;
根据/etc/sysctl.conf设定内核参数;
激活udev和selinux;
激活LVM和RAID设备;
清理过期锁和PID文件;
装载键映射;
/etc/inittab
id:3:initdefault: (默认运行级别)
si::sysinit:/etc/rc.d/rc.sysinit (系统初始化脚本)
/etc/rc.d/rc.sysinit
echo
insmod
ifconfig
/bin/bash
shutdown -r -h
halt 关机
reboot 重启
poweroff 关机
init 0 关机
init 6 重启
1、关机和重启;
2、主机名;
3、运行对应服务脚本;
4、启动终端;
5、运行用户;
6、定义单用户级别;
7、装载网卡驱动,启用网络功能;
8、提供一个web服务器;
9、设定内核参数;
busybox: 二进制程序,1M大小,能模拟数百个命令的使用;
Kernel:
RHEL5, RHEL6
定制安装:
自动化安装
定制引导盘
mount
-n: 挂载时不更新/etc/mtab文件;
cat /proc/mounts
脚本编程知识点:
1、变量中字符的长度:${#VARNAME}
小Linux制作过程:
在现有linux虚拟机增加一块20G的IDE硬盘,并对磁盘进行分区和创建文件系统,将创建的文件系统挂载到/mnt/boot和/mnt/sysroot目录;
[root@localhost ~]# fdisk -l(查看系统上磁盘及分区情况)
Disk /dev/hda: 21.4 GB, 21474836480 bytes
15 heads, 63 sectors/track, 44384 cylinders
Units = cylinders of 945 * 512 = 483840 bytes
Disk /dev/hda doesn't contain a valid partition table
Disk /dev/sda: 53.6 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 13 104391 83 Linux
/dev/sda2 14 2624 20972857+ 83 Linux
/dev/sda3 2625 2755 1052257+ 82 Linux swap / Solaris
[root@localhost ~]# fdisk /dev/hda(管理磁盘分区,进入交互式模式)
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
The number of cylinders for this disk is set to 44384.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): n(创建分区)
Command action
e extended
p primary partition (1-4)
p(主分区)
Partition number (1-4): 1(分区编号)
First cylinder (1-44384, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-44384, default 44384): +20M(创建20M分区)
Command (m for help): n(创建分区)
Command action
e extended
p primary partition (1-4)
p(主分区)
Partition number (1-4): 2(分区编号)
First cylinder (43-44384, default 43):
Using default value 43
Last cylinder or +size or +sizeM or +sizeK (43-44384, default 44384): +512M(创建512M分区)
Command (m for help): w(保存退出)
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@localhost ~]# partprobe /dev/hda(让内核重新扫描分区表)
[root@localhost ~]# fdisk -l /dev/hda(查看/dev/hda分区情况)
Disk /dev/hda: 21.4 GB, 21474836480 bytes
15 heads, 63 sectors/track, 44384 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 1101 500377+ 83 Linux
[root@localhost ~]# mke2fs -j /dev/hda1(将/dev/hda1创建为带日志的文件系统,即ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
4968 inodes, 19812 blocks
990 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=20447232
3 block groups
8192 blocks per group, 8192 fragments per group
1656 inodes per group
Superblock backups stored on blocks:
8193
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost ~]# mke2fs -j /dev/hda2(将/dev/hda2创建为带日志的文件系统,即ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost ~]# mkdir /mnt/{boot,sysroot}(创建/mnt/boot目录和/mnt/sysroot目录,花括号{}展开)
[root@localhost ~]# mount /dev/hda1 /mnt/boot/(将/dev/hda1挂载到/mnt/boot/目录)
[root@localhost ~]# mount /dev/hda2 /mnt/sysroot/(将/dev/hda2挂载到/mnt/boot/目录)
[root@localhost ~]# mount(查看系统所有挂载的文件系统)
/dev/sda2 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/hda1 on /mnt/boot type ext3 (rw)
/dev/hda2 on /mnt/sysroot type ext3 (rw)
[root@localhost ~]# tree /mnt/(查看/mnt目录树)
/mnt/
|-- boot
| `-- lost+found
`-- sysroot
`-- lost+found
4 directories, 0 files
提供内核:
[root@localhost ~]# cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz(复制vmlinuz-2.6.18-308.el5到/mnt/boot/目录叫vmlinuz)
制作initrd文件:
[root@localhost ~]# mkdir test(创建test目录)
[root@localhost ~]# cd test/(切换到test目录)
[root@localhost test]# zcat /boot/initrd-2.6.18-308.el5.img | cpio -id(不解压initrd文件查看内容将结果送给管道,通过cpio展开到当前目录)
12218 blocks
[root@localhost test]# ls(查看当前目录文件及子目录)
bin dev etc init lib proc sbin sys sysroot
[root@localhost test]# vim init(编辑init程序)
mkrootdev -t ext3 -o defaults,ro /dev/hda2(以只读方式挂载根文件系统)
#echo "Loading dm-mem-cache.ko module"
#insmod /lib/dm-mem-cache.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-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(没有scsi盘,所以也注释掉)
#resume LABEL=SWAP-sda3(注释掉交换分区)
:.,+20s@^@#@g(搜索当前行向下加20行,搜索所有行首的添加#号)
提示:装载dm(Device Mapper逻辑卷设备)模块其实对我们都没有用,因为我们并没有把根文件系统做在一个所谓的逻辑卷上;
[root@localhost test]# cd lib/(切换到lib目录)
[root@localhost lib]# ls(查看当前目录文件及子目录)
ahci.ko dm-mem-cache.ko dm-raid45.ko ext3.ko libata.ko mptspi.ko scsi_transport_spi.ko
ata_piix.ko dm-message.ko dm-region_hash.ko firmware mptbase.ko ohci-hcd.ko sd_mod.ko
dm-log.ko dm-mod.ko ehci-hcd.ko jbd.ko mptscsih.ko scsi_mod.ko uhci-hcd.ko
[root@localhost lib]# rm -f dm-*(强制删除dm开头的所有文件)
[root@localhost lib]# ls
ahci.ko ehci-hcd.ko firmware libata.ko mptscsih.ko ohci-hcd.ko scsi_transport_spi.ko uhci-hcd.ko
ata_piix.ko ext3.ko jbd.ko mptbase.ko mptspi.ko scsi_mod.ko sd_mod.ko
[root@localhost test]# find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz(查找当前目录的所有文件,将结果通过管道送给cpio
归档,-H指定备份时欲使用的文件格式,newc指cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按原有的路径格式进行保存,并且
能够支持多于512200个文件,默认情况下cpio归档所支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quie表示静默模式,不输出信息
,-o表示创建归档文件,将结果送给管道通过gzip进行压缩,-9指定压缩级别,保存至/mnt/boot/目录较initrd.gz)
[root@localhost lib]# ls -lh /mnt/boot/(查看/mnt/boot目录文件详细信息,并进行单位换算)
total 2.3M
-rw-r--r-- 1 root root 374K Dec 2 02:48 initrd.gz
drwx------ 2 root root 12K Dec 2 02:14 lost+found
-rw-r--r-- 1 root root 1.9M Dec 2 02:17 vmlinuz
安装grub:
[root@localhost ~]# grub-install --root-directory=/mnt/ /dev/hda(安装grub,根目录/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 ~]# ls /mnt/boot/(查看/mnt/boot目录文件及子目录)
grub initrd.gz lost+found vmlinuz
提示:检测/mnt/boot目录有没有刚安装的grub;
提供grub配置文件:
[root@localhost ~]# vim /mnt/boot/grub/grub.conf(编辑grub.conf配置文件)
default=0
timeout=3
title Smoke Linux(2.6.18)
root(hd0,0)
kernel /vmlinuz
initrd /initrd.gz
提供真正的根文件系统:
[root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@localhost sysroot]# mkdir -pv etc/rc.d/init.d bin sbin proc sys dev lib root mnt media var/{log,run,lock/subsys,tmp} usr/
{bin,sbin,local} tmp home opt boot(添加系统所需要的目录)
mkdir: created directory `etc'
mkdir: created directory `etc/rc.d'
mkdir: created directory `etc/rc.d/init.d'
mkdir: created directory `bin'
mkdir: created directory `sbin'
mkdir: created directory `proc'
mkdir: created directory `sys'
mkdir: created directory `dev'
mkdir: created directory `lib'
mkdir: created directory `root'
mkdir: created directory `mnt'
mkdir: created directory `media'
mkdir: created directory `var'
mkdir: created directory `var/log'
mkdir: created directory `var/run'
mkdir: created directory `var/lock'
mkdir: created directory `var/lock/subsys'
mkdir: created directory `var/tmp'
mkdir: created directory `usr'
mkdir: created directory `usr/bin'
mkdir: created directory `usr/sbin'
mkdir: created directory `usr/local'
mkdir: created directory `tmp'
mkdir: created directory `home'
mkdir: created directory `opt'
mkdir: created directory `boot'
提示:etc/{rc.d/init.d} bin sbin proc sys dev是最核心的,var usr可以独立分区,未必是必须的,lib得有,tmp home可以单独分区,root不能单独分区,
管理员家目录此时没有管理员的概念,所以不是核心的,usr可以单独分区,所以也不是核心的,mnt media不能分区,是挂载点,boot是在真正的根上挂载hda1的;
[root@localhost sysroot]# ls(查看你当前目录文件及子目录)
bin boot dev etc home lib lost+found media mnt opt proc root sbin sys tmp usr var
创建配置文件:
[root@localhost sysroot]# vim etc/inittab(编辑inittab文件)
id:3:initdefault:(启动默认级别)
si::sysinit:/etc/rc.d/rc.sysinit(初始化脚本)
[root@localhost sysroot]# vim etc/rc.d/rc.sysinit(边界初始化脚本)
#!/bin/bash
#
echo -e "\tWelcome to \033[34Smoke\033[0m Linux"(\t缩进一个TAB键)
/bin/bash
[root@localhost sysroot]# chmod +x etc/rc.d/rc.sysinit(给rc.sysinit文件执行权限)
通过脚本抑制命令和命令依赖的库文件:
[root@localhost ~]# cat bincopy.sh(查看bincopy.sh脚本)
#!/bin/bash
#
DEST=/mnt/sysroot
libcp() {
LIBPATH=${1%/*}
[ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH
[ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished."
}
bincp() {
CMDPATH=${1%/*}
[ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH
[ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH
for LIB in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`;do
libcp $LIB
done
}
read -p "Your command:" CMD
until [ $CMD == 'q' ];do
! which $CMD && echo "Wrong command" && read -p "Input againe" CMD && continue
COMMAND=`which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
bincp $COMMAND
echo "copy $COMMAND finishd."
read -p "Continue:" CMD
done
[root@localhost ~]# ./bincopy.sh(执行移植命令和依赖的库文件脚本)
Your command:init
/sbin/init
copy lib /lib/libsepol.so.1 finished.
copy lib /lib/libselinux.so.1 finished.
copy lib /lib/libc.so.6 finished.
copy lib /lib/libdl.so.2 finished.
copy lib /lib/ld-linux.so.2 finished.
copy /sbin/init finishd.
Continue:bash
/bin/bash
copy lib /lib/libtermcap.so.2 finished.
copy /bin/bash finishd.
Continue:ls
/bin/ls
copy lib /lib/librt.so.1 finished.
copy lib /lib/libacl.so.1 finished.
copy lib /lib/libpthread.so.0 finished.
copy lib /lib/libattr.so.1 finished.
copy /bin/ls finishd.
Continue:q
[root@localhost ~]# sync(同步磁盘写入)
[root@localhost ~]# sync(同步磁盘写入)
[root@localhost ~]# sync(同步磁盘写入)
测试通过切换根文件系统:
[root@localhost ~]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# ls
bin boot dev etc home lib lost+found media mnt opt proc rc.d root sbin sys tmp usr var
bash-3.2# ls /etc/
inittab rc.d
bash-3.2# exit
exit
测试:将虚拟机挂起,将制作好的小Linux系统的IDE的硬盘添加到新创建的虚拟机系统;

通过echo一段话保存到/tmp/a.txt文件里面,提示只读文件系统,所以根文件系统是只读的;

切换到宿主机:
[root@localhost ~]# ./bincopy.sh(当前目录执行bincopy.sh脚本,复制命令及命令依赖的库文件) Your command:touch /bin/touch copy /bin/touch finishd. Continue:mkdir /bin/mkdir copy /bin/mkdir finishd. Continue:rm /bin/rm copy /bin/rm finishd. Continue:mv /bin/mv copy /bin/mv finishd. Continue:cp /bin/cp copy /bin/cp finishd. Continue:cat /bin/cat copy /bin/cat finishd. Continue:mount /bin/mount copy lib /lib/libblkid.so.1 finished. copy lib /lib/libuuid.so.1 finished. copy lib /lib/libdevmapper.so.1.02 finished. copy /bin/mount finishd. Continue:umount /bin/umount copy /bin/umount finishd. Continue:vi /bin/vi copy /bin/vi finishd. Continue:vim /usr/bin/vim copy lib /usr/lib/libncurses.so.5 finished. copy lib /usr/lib/libgpm.so.1 finished. copy lib /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so finished. copy lib /lib/libresolv.so.2 finished. copy lib /lib/libutil.so.1 finished. copy lib /lib/libm.so.6 finished. copy lib /lib/libnsl.so.1 finished. copy lib /lib/libcrypt.so.1 finished. copy /usr/bin/vim finishd. Continue:chmod /bin/chmod copy /bin/chmod finishd. Continue:chown /bin/chown copy /bin/chown finishd. Continue:ping /bin/ping copy /bin/ping finishd. Continue:ifconfig /sbin/ifconfig copy /sbin/ifconfig finishd. Continue:insmod /sbin/insmod copy /sbin/insmod finishd. Continue:modprobe /sbin/modprobe copy /sbin/modprobe finishd. Continue:rmmod /sbin/rmmod copy /sbin/rmmod finishd. Continue:route /sbin/route copy /sbin/route finishd. Continue:halt /sbin/halt copy /sbin/halt finishd. Continue:reboot /sbin/reboot copy /sbin/reboot finishd. Continue:shutdown /sbin/shutdown copy /sbin/shutdown finishd. Continue:hostname /bin/hostname copy /bin/hostname finishd. Continue:q [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入)
挂载宿主机,切换到小Linux系统:
注意:启动小Linux系统完成之后,它没法自动完成将根文件系统重新挂载为可读写,所以应该编写rc.sysinit配置文件,让它可读写;

挂载为可读写:
mount -o remount,rw / :读写方式挂载根文件系统,-o指定额外的挂载选项,也即指定文件系统启用的属性,大部分选项都可以使用no option进行关闭此功能,如果指定多个功能属性,选项之间通过逗号隔开即可,remount重新挂载当前文件系统,把卸载和挂载一块来使用,先卸载再挂载,重新挂载可以不指定挂载点,rw读写挂载;

提示:报错,/etc/mtab追踪当前系统挂载每一个文件系统,不带任何选项的mount命令所显示的内容被保存在/etc/mtab当中,以后挂载的每一个文件系统只要挂载都会保存到/etc/mtab当中,卸载一个文件系统,它会从/etc/matb当中删除,但是此时整个根都是只读的,所以挂载文件系统,不能将挂载的内容写入到/etc/mtab当中,那怎么办,mount有个-n选项,在挂载的时候不更新/etc/mtab文件,

mount
-n: 挂载时不更新/etc/mtab文件;
cat /proc/mounts:mounts文件也会显示当前系统上所挂载的所有文件系统;

通过mount -n -o remount,rw /重新挂载根文件系统:不让报can't create locak file /etc/mtab~520: Read-only file system (use -n flag ride)错误;

提示:又报错,读取不到/etc/fastab文件,说明重新挂载也会读取/etc/fstab文件,但是挂载已经完成了;

提示:创建/tmp/a.txt文件成功,但是/tmp目录的权限应该是1777的;
测试halt命令关机:

提示:halt命令会自动完成切换到级别0,只是把当前进程关掉了,它没办法完成切断电源的,如何切断电源halt有个-p选项,在执行关机的时候,能够直接切断电源的;但是切断电源以后,它仍然无法把bash进程,halt命令是在bash进程中提示执行的,那就意味着halt是bash的子进程,所以使用halt命令只能关闭子进程自身,对父进程没有关系,如果让父进程一并关掉的话,有个命令叫exec

查看exec命令帮助:

提示:执行Exec文件,而且执行的时候是以当前bash直接替换为那个进程(简单来讲,默认情况下,我们所谓在bash命令下执行halt进程,它就在bash下执行一个子进程,而当我们使用exec的时候,不是这样的,当在命令提示符执行halt命令以后,halt进程一起来,这个父进程就没有了,它以子进程直接替换父进程的,而不是成为父进程的子进程,exec表示让启动的子进程直接替换原有的进程,而不是作为它的子进程来执行的,这样一来halt一结束,这样的bash也就结束了)
exec halt -p:让exec命令启动halt命令而且直接替换原有的bash进程;

提示:还是不行,事实上当指定halt命令它会切换到0级别下去了,根当前级别没有关系,所以还要执行对应级别下的操作才可以,那于是应该把halt命令放到对应级别下可执行文件里面,并且执行halt命令的时候,或者执行关机命令的时候,它能够自动去完成那个执行对应级别下的K*开头的脚本和S*开头的脚本,把S*开头的脚本都start起来,把K*开头的脚本都stop掉,所以还要修改它的执行流行,由此可见使用命令关机是关不掉的;
切换到宿主机:
给小Linux系统提供一个脚本:
关机:
[root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录) [root@localhost sysroot]# ls(查看当前目录文件及子目录) bin boot dev etc home lib lost+found media mnt opt proc root sbin sys tmp usr var [root@localhost sysroot]# vim etc/rc.d/rc.sysdone(编辑rc.sysdone脚本) #!/bin/bash # sync(当执行关键命令时候,如果此前写入一些内容进去,需要将这些内容从内存同步到磁盘上去) sleep 2(睡眠2秒) sync(再同步一次,确保所有的文件都同步完成) exec /sbin/halt -p(使用halt绝对路径,不使用绝对路径可能找不到,因为不登录,它可能没有path环境变量) [root@localhost sysroot]# chmod +x etc/rc.d/rc.sysdone(给rc.sysdone文件执行权限) [root@localhost sysroot]# cd(切换到根用户家目录) 通过脚本移植sync和sleep命令: [root@localhost ~]# ./bincopy.sh(当前目录执行bincopy.sh脚本) Your command:sync /bin/sync copy /bin/sync finishd. Continue:sleep /bin/sleep copy /bin/sleep finishd. Continue:q [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入) [root@localhost ~]# sync(同步磁盘写入) 提示:此时还没有做完整,还需要编辑etc/inittab文件 [root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录) [root@localhost sysroot]# vim etc/inittab(编辑inittab文件) id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc.sysdone(运行在0级别的时候执行/etc/rc.d/rc.sysdone脚本) [root@localhost sysroot]# sync(同步磁盘写入) [root@localhost sysroot]# sync(同步磁盘写入) [root@localhost sysroot]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
使用init 0可以正常关机;

重启:
[root@localhost ~]# cd /mnt/sysroot/(切换到/mntsysroot目录) [root@localhost sysroot]# vim etc/inittab(编辑inittab文件) id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc.sysdone l6:6:wait:/etc/rc.d/rc.reboot(在6级别下执行rc.reboot脚本) [root@localhost sysroot]# vim etc/rc.d/rc.reboot(编辑rc.reboot脚本) #!/bin/bash # sync sleep 1 sync exec /sbin/reboot [root@localhost sysroot]# chmod +x etc//rc.d/rc.reboot(给rc.reboot脚本执行权限) [root@localhost sysroot]# sync(同步磁盘写入) [root@localhost sysroot]# sync(同步磁盘写入) [root@localhost sysroot]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
使用init 6可以正常重启;

提示:如果在此处修改小Linux系统,再回到宿主机可能会出现文件系统崩溃的,因为两个主机改一个磁盘,而且那个主机是挂起的,所以刚才改的内容,宿主机不知道;
实现对应级别下的服务脚本实现关机和重启:
[root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@localhost sysroot]# vim etc/rc.d/init.d/halt(编辑halt脚本)
#!/bin/bash
#
case $0 in ($0取得脚本路径名称,通过脚本名称来判断重启还是关机)
*reboot)
COMMAND=`/sbin/reboot ;;
*halt)
COMMAND=`/sbin/halt -p ;;
*)
echo "Only call this script by *reboot OR *halt;"
;;
esac
case $1 in
start)
;;
stop)
;;
*)
echo "Usage: `basename $0` {start|stop}" (basename $0获取脚本名称)
;;
esac
exec $COMMAND
[root@localhost sysroot]# chmod +x etc/rc.d/init.d/halt(给halt脚本执行权限)
[root@localhost sysroot]# cd etc/rc.d/(切换到etc/rc.d目录)
[root@localhost rc.d]# mkdri rc0.d rc6.d(创建rc0.d和rc6.d目录)
[root@localhost rc.d]# cd rc0.d/(切换到rc0.d目录)
[root@localhost rc0.d]# ln -sv ../init.d/halt S99halt(给../init.d/halt文件创建软连接叫S99halt,并显示创建过程,99代表最后关机)
create symbolic link `S99halt' to `../init.d/halt'
提示:S99halt,S代表start在相应级别下启动该脚本,,当执行S99halt,脚本取得halt选择关机
[root@localhost rc0.d]# ll(查看当前目录文件及子目录)
total 1
lrwxrwxrwx 1 root root 14 Nov 22 04:07 S99halt -> ../init.d/halt
[root@localhost rc0.d]# cd ../rc6.d/(切换到rc6.d目录)
[root@localhost rc6.d]# ln -sv ../init.d/halt S99reboot(给../init.d/halt文件创建软连接叫S99reboot,并显示创建过程,99代表最后重启)
create symbolic link `S99reboot' to `../init.d/halt'
提示:S99reboot,S代表start在像应级别下启动该脚本,当执行S99reboot,脚本取得reboot选择重启;
[root@localhost rc6.d]# cd ..(切换到上级目录)
[root@localhost rc.d]# rm -f rc.reboot rc.sysdone(强制删除rc.reboot和rc.sysdone脚本)
[root@localhost rc.d]# ls(查看当前目录文件及子目录)
init.d rc0.d rc6.d rc.sysinit
[root@localhost rc.d]# sync(同步磁盘写入)
[root@localhost rc.d]# sync(同步磁盘写入)
[root@localhost rc.d]# sync(同步磁盘写入)
[root@localhost rc.d]# vim rc(编辑rc脚本)
#!/bin/bash
#
RUNLEVEL=$1(接受一个参数,相当于运行级别)
for I in /etc/rc.d/rc$RUNLEVEL.d/K*;do
$I stop
done
for I in /etc/rc.d/rc$RUNLEVEL.d/S*;do
$I start
done
提示:当RUNLEVEL参数为0执行/etc/rc.d/rc0.d/K*所有脚本停止,执行/etc/rc.d/rc0.d/S*所有脚本启动,当RUNLEVEL参数为6执行/etc/rc.d/rc6.d/K*所有脚本停止,
执行/etc/rc.d/rc6.d/S*所有脚本启动;
[root@localhost rc.d]# chmod +x rc(给rc脚本执行权限)
[root@localhost rc.d]# cd ..(切换到上级目录)
[root@localhost etc]# vim inittab(编辑inittab脚本)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
[root@localhost etc]# sync(同步磁盘写入)
[root@localhost etc]# sync(同步磁盘写入)
[root@localhost etc]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
测试重启,可以正常重启;

测试关机,可以正常关机;

提示:由于没有K*开头的脚本所以提示报错;
如何实现在对应级别下启动服务:
[root@localhost sysroot]# vim etc/inittab(编辑etc/inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
[root@localhost sysroot]# cd etc/rc.d/(切换到etc/rc.d目录)
[root@localhost rc.d]# mkdir rc3.d(创建rc3.d目录)
[root@localhost rc.d]# ls(查看当前目录文件及子目录)
init.d rc rc0.d rc3.d rc6.d rc.sysinit
[root@localhost rc.d]# vim init.d/tserver(编辑tserver脚本)
#!/bin/bash
#
prog=`basename $0`(取得脚本路径的基名,也就是脚本名称)
lockfile=/var/lock/subsys/$prog
start() {
echo "Starting $prog ..."
touch $lockfile
}
stop () {
echo "Stopping $prog ..."
rm -f $lockfile
}
status() {
if [ -f $lockfile ];then
echo "Running..."
else
echo "Stopped..."
fi
}
usage() {
echo "Usage: $prog {start|stop|status|restart}"
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
;;
esac
提示:如果tserver文件存在说明服务启动,不存在说明服务没启动,关闭服务删除tserver文件;
[root@localhost rc.d]# chmod +x init.d/tserver(给tserver执行权限)
[root@localhost rc.d]# init.d/tserver start(执行tserver脚本)
Starting tserver ...
[root@localhost rc.d]# ls /var/lock/subsys/tserver(查看/var/lock/subsys/tserver文件存在)
/var/lock/subsys/tserver
[root@localhost rc.d]# init.d/tserver stop(执行tserver脚本)
Stopping tserver ...
[root@localhost rc.d]# ls /var/lock/subsys/tserver(查看/var/lock/subsys/tserver文件不存在)
ls: /var/lock/subsys/tserver: No such file or directory
[root@localhost rc.d]# init.d/tserver status(执行tserver脚本)
Stopped...
[root@localhost rc.d]# init.d/tserver statuss(执行tserver脚本)
Usage: tserver {start|stop|status|restart}
将脚本做成chkconfig调用的脚本:
[root@localhost rc.d]# vim init.d/tserver
#!/bin/bash
#
# chkconfig: 35 66 33 (chkconfig调用的服务脚本,35代表3和5级别启动,66代表启动优先次序,33代表关闭优先次序)
# description: test service script (描述信息)
prog=`basename $0`
lockfile=/var/lock/subsys/$prog
start() {
echo "Starting $prog ..."
touch $lockfile
}
stop () {
echo "Stopping $prog ..."
rm -f $lockfile
}
status() {
if [ -f $lockfile ];then
echo "Running..."
else
echo "Stopped..."
fi
}
usage() {
echo "Usage: $prog {start|stop|status|restart}"
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
;;
esac
让脚本在3级别启动起来:
[root@localhost rc.d]# cd rc3.d/(切换到rc3.d目录)
[root@localhost rc3.d]# ln -sv ../init.d/tserver S66tserver(创建软连接,并显示创建过程,创建为S66tserver)
create symbolic link `S66tserver' to `../init.d/tserver'
提示:S66tserver中的S代表启动,66代表启动优先次序,其中66要和服务脚本中chkconfig 35 66 33中的启动优先次序的数字要一样;
[root@localhost rc3.d]# ll(查看当前目录文件及子目录详细信息)
total 1
lrwxrwxrwx 1 root root 17 Nov 22 05:08 S66tserver -> ../init.d/tserver
[root@localhost rc3.d]# cd ..(切换到上层目录)
[root@localhost rc.d]# cd rc0.d/(切换到rc0.d目录)
[root@localhost rc0.d]# ln -sv ../init.d/tserver K33tserver(创建软连接,并显示创建过程,创建为K33tserver)
create symbolic link `K33tserver' to `../init.d/tserver'
提示:K33tserver中的K代表停止,33代表停止优先次序,其中33要和服务脚本中chkconfig 35 66 33中的停止优先次序的数字要一样;
[root@localhost rc0.d]# cd ../rc6.d/(切换到上层目录下的rc6.d目录)
[root@localhost rc6.d]# ln -sv ../init.d/tserver K33tserver(创建软连接,并显示创建过程,创建为K33tserver)
create symbolic link `K33tserver' to `../init.d/tserver'
提示:K33tserver中的K代表停止,33代表停止优先次序,其中33要和服务脚本中chkconfig 35 66 33中的停止优先次序的数字要一样;
[root@localhost rc6.d]# ll(查看当前目录文件及子目录)
total 2
lrwxrwxrwx 1 root root 17 Nov 22 05:16 K33tserver -> ../init.d/tserver
lrwxrwxrwx 1 root root 14 Nov 22 04:10 S99reboot -> ../init.d/halt
[root@localhost rc6.d]# sync(同步磁盘写入)
[root@localhost rc6.d]# sync(同步磁盘写入)
[root@localhost rc6.d]# sync(同步磁盘写入)
提示:此时3级别仍然没有用的;
[root@localhost rc6.d]# cd ../../(切换到上层目录的上层目录)
[root@localhost etc]# ls(查看当前目录文件及子目录)
inittab rc.d
[root@localhost etc]# vim inittab(编辑inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
提示:当执行到si的时候,会执行etc/rc.d/rc.sysinit脚本,这个脚本直接启动了/bin/bash,因此3级别的脚本不会执行,为什么0级别和6级别会执行,我们使用init切
换过去而已,所以此时3级别不可能会随系统启动的,因为执行流程不到这里,到si::sysinit:/etc/rc.d/rc.sysinit已经完成系统启动了,因为在rc.sysinit脚本已经直
接执行了/bin/bash了,那么RHEL 5的系统是如何启动的,为什么它会执行呢,它不是在/etc/rc.d/rc.sysinit登录的系统,而是在inittab文件里面还有几个tty终端,所
以它们的执行流程是正常的,我们此时执行流程不正常,那该怎么办?
[root@localhost etc]# man mingetty(查看mingetty的man帮助文档)
[root@localhost etc]# cat /etc/inittab(查看inittab文件)
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
提示:系统的/etc/inittab文件在不同级别下的脚本执行完成以后开始执行1:2345:respawn:/sbin/mingetty tty1-6:2345:respawn:/sbin/mingetty tty6(在23
45级别下,都启动了6个终端),使用/sbin/mingetty命令启动的,所以当执行完si::sysinit:/etc/rc.d/rc.sysinit脚本以后,它会继续往下执行3级别下的l3:3:wait
:/etc/rc.d/rc 3这个脚本的,而si::sysinit:/etc/rc.d/rc.sysinit脚本里面是没有启动/bin/bash的,我们让它启动了/bin/bash这是不合理的;
[root@localhost etc]# vim inittab(编辑inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty tty1(当是2345级别就启动respawn,执行/sbin/mingetty tty1)
2:2345:respawn:/sbin/mingetty tty2
提示:当执行mingetty程序的时候,mingetty会启动一个tty终端,并启动终端之后在这个终端上再执行一个程序较login程序,login就打印一个提示符,让你输入帐号密码
登录,我们现在没有帐号和密码;
[root@localhost ~]# man mingetty(查看mingetty的man帮助文档)
mingetty:
--loginprog=/bin/login:定义让谁当作登录程序的,默认使用/bin/login;
[root@localhost etc]# vim inittab(编辑inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty1(当是2345级别就启动respawn,执行/sbin/mingetty tty1)
2:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty2
[root@localhost etc]# vim rc.d/rc.sysinit(编辑rc.sysinit脚本)
#!/bin/bash
#
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
[root@localhost ~]# ./bincopy.sh(执行bincopy.sh脚本)
Your command:mingetty
/sbin/mingetty
copy /sbin/mingetty finishd.
Continue:q
提示:移植mingetty程序;
[root@localhost ~]# ./bincopy.sh(执行bincopy.sh脚本)
Your command:basename
/bin/basename
copy /bin/basename finishd.
Continue:q
提示:移植basename程序;
[root@localhost ~]# cd /mnt/sysroot/bin/(切换到/mnt/sysroot/bin目录)
[root@localhost bin]# ln -sv bash sh(给bash脚本创建软链接叫sh,并显示创建过程)
create symbolic link `sh' to `bash'
[root@localhost bin]# ll(查看当前目录文件及子目录详细信息)
total 1963
-rwxr-xr-x 1 root root 18644 Nov 22 06:16 basename
-rwxr-xr-x 1 root root 730092 Nov 22 02:12 bash
-rwxr-xr-x 1 root root 20776 Nov 22 02:19 cat
-rwxr-xr-x 1 root root 36220 Nov 22 02:19 chmod
-rwxr-xr-x 1 root root 41608 Nov 22 02:19 chown
-rwxr-xr-x 1 root root 68248 Nov 22 02:19 cp
-rwxr-xr-x 1 root root 10140 Nov 22 02:21 hostname
-rwxr-xr-x 1 root root 93560 Nov 22 02:12 ls
-rwxr-xr-x 1 root root 27208 Nov 22 02:18 mkdir
-rwsr-xr-x 1 root root 53836 Nov 22 02:19 mount
-rwxr-xr-x 1 root root 78188 Nov 22 02:19 mv
-rwsr-xr-x 1 root root 35832 Nov 22 02:20 ping
-rwxr-xr-x 1 root root 43156 Nov 22 02:18 rm
lrwxrwxrwx 1 root root 4 Nov 22 06:21 sh -> bash
-rwxr-xr-x 1 root root 17192 Nov 22 02:57 sleep
-rwxr-xr-x 1 root root 15220 Nov 22 02:56 sync
-rwxr-xr-x 1 root root 40728 Nov 22 02:18 touch
-rwsr-xr-x 1 root root 34928 Nov 22 02:19 umount
-rwxr-xr-x 1 root root 593160 Nov 22 02:19 vi
[root@localhost etc]# sync(同步磁盘写入)
[root@localhost etc]# sync(同步磁盘写入)
[root@localhost etc]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;

提示:可以正常登录到小Linux系统,并且有认证提示符,可以使用CTRL+ALT+F2切换另一个定义的tty终端,不能直接启动/bin/bash,服务一定是启动起来了,(none)由于没有主机名;
让根文件系统能够在sysinit脚本中完成以读写方式重新挂载,让它能够使用终端:
[root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@localhost sysroot]# vim etc/fstab(编辑fstab文件)
/dev/hda2 / ext3 defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
[root@localhost sysroot]# vim etc/rc.d/rc.sysinit(编辑rc.sysinit文件)
#!/bin/bash
#
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
echo "Remount rootfs..."
mount -n -o remount,rw / (以读写方式重新挂载根文件系统,-n挂载设备时,不把信息写入/etc/mtab文件,-o指定额外的挂载选项)
[root@localhost sysroot]# mkdir etc/sysconfig(创建etc/sysconfig目录)
[root@localhost sysroot]# vim etc/sysconfig/network(编辑network文件)
HOSTNAME=minlinux.Smoke.com
[root@Smoke sysroot]# vim etc/rc.d/rc.sysinit(编辑rc.sysinit系统初始化文件)
#!/bin/bash
#
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
echo "Remount rootfs..."
mount -n -o remount,rw /
echo "Set the hostname..."
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network (判断network文件是否存在,存在;就将network文件读取进来,点.或者source读取文件)
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost(判断$HOSTNAME是否为空,或者$HOSTNAME等于(none)字符串,则执行HOSTNAME
等于localhost)
/bin/hostname $HOSTNAME
[root@localhost sysroot]# chroot /mnt/sysroot/(切换根文件系统到/mnt/sysroot)
bash-3.2# /etc/rc.d/rc.sysinit(执行rc.sysinit脚本)
Welcome to Smoke Linux
Remount rootfs...
Set the hostname...
bash-3.2# exit
exit
[root@localhost sysroot]# sync(同步磁盘写入)
[root@localhost sysroot]# sync(同步磁盘写入)
[root@localhost sysroot]# sync(同步磁盘写入)
[root@localhost ~]# man mingetty(查看mingetty命令man帮助文档)
agetty
mgetty
[root@localhost ~]# man agetty(查看agetty命令man帮助文档)
agetty:
-l:指定登录程序
baud rate:速率
term:指定那个终端
[root@localhost ~]# man mgetty(查看mgetty命令man帮助文档)
提示:agetty模拟的是getty,getty是在串行终端上,设备有两种类型块设备和字符设备,显示器是字符设备,它是把整个字符信息一个一个显示出来的,而且是串行的,所以串
行设备都得有速率,每秒钟显示多少个字符;
[root@localhost ~]# man stty(查看stty命令的man帮助文档)
stty:显示终端线的设定;
-F:指定设备;
size:能显示终端大小;
ospedd:设定速率
speed:显示速率
[root@localhost ~]# stty -F /dev/console size(显示物理终端大小)
25 80
[root@localhost ~]# stty -F /dev/console speed(显示物理终端的速率)
38400
[root@localhost ~]# ./bincopy.sh(执行bincopy.sh脚本)
Your command:agetty
/sbin/agetty
copy /sbin/agetty finishd.
Continue:q
提示:移植agetty命令;
[root@localhost ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@localhost sysroot]# vim etc/inittab(编辑etc/inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/agetty -l /bin/bash 38400 tty1(agetty选项-l指定登录程序,38400速率)
2:2345:respawn:/sbin/agetty -l /bin/bash 38400 tty2

切换到宿主机,对文件系统进行修复:
此时使用e2fsck就能修复,专用于修复ext2/ext3文件系统,但是inittab文件整个会丢失,所以不建议这样修复,最简单办法:
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定备份
时使用的文件格式,newc指cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多余5122
00各文件,默认情况下cpio归档所支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quit表示静默模式,不输出信息,-o表示创建归
档文件,将结果通过管道送给gzip,-9指定压缩级别,保存至/root目录较sysroot.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke sysroot]# cd(切换到根用户家目录)
[root@Smoke ~]# umount /dev/hda2(卸载/dev/hda2设备)
umount: /mnt/sysroot: device is busy
umount: /mnt/sysroot: device is busy
提示:卸载不掉,提示设备忙;
[root@Smoke ~]# fuser -km /dev/hda2(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
/dev/hda2: 14951c 15737c 15933c 16444c 16586c
[root@Smoke ~]# umount /dev/hda2(卸载/dev/hda2设备)
[root@Smoke ~]# mke2fs -j /dev/hda2(将/dev/hda2格式化为ext3类型文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 23 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@Smoke ~]# mount /dev/hda2 /mnt/sysroot/(将/dev/hda2挂载到/mnt/sysroot目录)
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# zcat /root/sysroot.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
18880 blocks
[root@Smoke sysroot]# ls(查看当前目录文件及子目录)
bin boot dev etc home lib lost+found media mnt opt proc root sbin sys tmp usr var
[root@Smoke sysroot]# cat etc/fstab(查看etc/fstab文件)
/dev/hda2 / ext3 defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
[root@Smoke sysroot]# cat etc/inittab(查看etc/inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/agetty -l /bin/bash 38400 tty1
2:2345:respawn:/sbin/agetty -l /bin/bash 38400 tty2
[root@Smoke sysroot]# sync(同步磁盘写入)
[root@Smoke sysroot]# sync(同步磁盘写入)
[root@Smoke sysroot]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
还是需要登录;

[root@minlinux ~]# man agetty(查看agetty命令的man帮助文档) -n:需要和-l一块使用,不让用户输入登录名; [root@minlinux ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录) [root@minlinux sysroot]# vim etc/inittab(编辑inittab文件) id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc 0 l6:6:wait:/etc/rc.d/rc 6 l3:3:wait:/etc/rc.d/rc 3 1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1(agetty -n -l不让用户输入登录名) 2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2 [root@minlinux mnt]# sync(同步磁盘写入) [root@minlinux mnt]# sync(同步磁盘写入) [root@minlinux mnt]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
成功登录,使用CTRL+ALT+F2或F1能够成功切换tty终端;

测试:关机,服务tserver是否会停止,服务K33tserver正常停止;

让服务启动显示OK,启动不了显示failed等相关信息:
[root@minlinux ~]# cat /etc/rc.d/init.d/functions(查看functions脚本)
提示:宿主机所带脚本,functions函数,这里面定义了一堆函数,它通过函数让这些功能脚本所需要用到的功能通过函数的方式来实现,比如要显示绿色OK该怎么显示,显示
为红色的failed该怎么显示,怎么让一个服务在脚本启动的时候能够显示这样的相应的字符串,让服务脚本更接近红帽的运作方式;
[root@minlinux ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
提示:既然是函数,它需要通过其他人载入,不需要自己执行,只有函数,没有其他的主程序,所以不需要写/bin/bash了,只需要定义函数即可;
#!/bin/bash
echo -e "\033[32mOK\033[0m" (-e:激活转义字符,显示OK字符串并显示为绿色)
[root@minlinux sysroot]# chmod +x etc/rc.d/init.d/functions(给functions脚本执行权限)
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
OK
提示:正常显示为绿色OK;
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
echo -e "[ \033[32mOK\033[0m ]"
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
[ OK ]
提示:正常显示为绿色OK,并带中括号;
#!/bin/bash
echo -e "[ \033[1;32mOK\033[0m ]"(1;粗体显示)
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
[ OK ]
提示:正常显示为粗体绿色OK,并带中括号;
让[ OK ]显示到某个字符串后面:
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
echo -e " [ \033[1;32mOK\033[0m ]"(给字符串前面加空格)
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
[ OK ]
提示:正常显示为空格粗体绿色OK,并带中括号,但前面信息怎么办?
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
echo -n "Starting tserver" (不换行显示)
echo -e " [ \033[1;32mOK\033[0m ]"
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
Starting tserver [ OK ]
提示:正常将Starting tserver和绿色粗体OK显示为一行,并带中括号,如果把这种功能用在不同的服务上面,它前面所写的服务名字符串长度是不一样的,但是红帽系统
中无论前面字符串长度多长,前面服务名字符串长一点中间空格就隔的少一点,字符短一点中间空格就隔的多一点,反正所有服务的OK是对齐的,这如何显示;
[root@minlinux sysroot]# A="Starting tserver"(定义变量A,并赋值为Starting tserver)
[root@minlinux sysroot]# echo ${#A}(显示变量A有多少个字符)
16
提示:在一个变量名称引用的时候,在名称间加个#井号,表示取变量中所包含字符串的长度,让整个屏幕的宽度长度减去字符串的长度,就是最右侧的长度,或者说是中间
空白字符的长度,还要减去[ OK ]字符串长度,就是中间空白字符串长度,那么屏幕应该是多宽?
[root@minlinux sysroot]# stty -F /dev/console size(显示物理终端屏幕大小)
25 80
提示:这是标准屏幕大小,25表示宽度25行,80表示列,80才是我们需要真正屏幕的宽度,把这个值取出来就是整个屏幕的有效宽度,怎么把它取出来?
[root@minlinux sysroot]# stty -F /dev/console size | cut -d' ' -f2(显示物理终端屏幕大小,将结果通过管道送给cut使用空格作为分隔符,只显示第二段)
80
[root@minlinux sysroot]# stty -F /dev/console size | awk '{print $2}'(显示物理终端屏幕大小,将结果通过管道送给awk默认使用空格作为分隔符,只显示第二段)
80
[root@minlinux sysroot]# A=`stty -F /dev/console size`(使用命令引用将命令结果保存到A变量里面)
[root@minlinux sysroot]# echo $A(显示变量$A的赋值)
25 80
[root@minlinux sysroot]# echo ${A#* }(以空格作为分隔符,截取一个字符串以空格为分隔符,从左往右取,取消从左往右第一个空格前面的内容)
80
[root@minlinux sysroot]# echo ${A##* }(以空格作为分隔符,从左往右取消从左往右最后一个空格前面的内容)
80
[root@minlinux sysroot]# A='25 80 100 90'(定义变量A,并赋值为'25 80 100 90')
[root@minlinux sysroot]# echo ${A#* }(以空格作为分隔符,截取一个字符串以空格为分隔符,从左往右取,取消从左往右第一个空格前面的内容)
80 100 90
[root@minlinux sysroot]# echo ${A##* }(以空格作为分隔符,从左往右取消从左往右最后一个空格前面的内容)
90
[root@minlinux sysroot]# echo ${A% *}(以空格作为分隔符,从右往左取消从右往左第一个空白字符后面的内容)
25 80 100
[root@minlinux sysroot]# echo ${A%% *}(以空格作为分隔符,从右往左取消从右往左最后一个空白字符后面的内容)
25
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
SCREEN=`stty -F /dev/console size` (显示物理终端屏幕大小,并将结果赋予变量SCREEN)
COLUMNS=${SCREEN#* } (以空格作为分隔符,从右往左取消从右往左第一个空格分割符前面内容,将结果赋予变量COLUMNS)
SPA_COL=$[$COLUMNS-12] (取得的屏幕列数减去,[ failed ]字符串长度12,将结果赋予变量SPA_COL)
success() { (定义函数success)
string=$1 (让用户输入参数,将参数赋予变量string)
RT_SPA=$[$SPA_COL-${#string}] (SPA_COL屏幕列数减去[ failed ]字符串的长度,再减去用户输入参数字符串的长度,就是中间空格的字符长度)
echo -n "$string" (不换号显示变量string用户输入的参数)
for I in `seq 1 $RT_SPA`;do (for循环,从1到中间空格字符长度)
echo -n " " (不换行显示空格)
done
echo -e "[ \033[32mOK\033[0m ]" ((-e:激活转义字符,显示OK字符串并显示为绿色)
}
success "starting tserver" (调用success函数,给它传递参数,中间有空白字符需要用引号引起来)
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
starting tserver [ OK ]
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
SCREEN=`stty -F /dev/console size`
COLUMNS=${SCREEN#* }
SPA_COL=$[$COLUMNS-12]
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ \033[32mOK\033[0m ]"
}
success "starting tserver"
success "String hello world how are you"
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
starting tserver [ OK ]
String hello world how are you [ OK ]
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
SCREEN=`stty -F /dev/console size`
COLUMNS=${SCREEN#* }
SPA_COL=$[$COLUMNS-12]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
success "starting tserver"
success "String hello world how are you"
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
SCREEN=`stty -F /dev/console size`
COLUMNS=${SCREEN#* }
SPA_COL=$[$COLUMNS-12]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[${RED}FAILED${NORMAL}]"
}
success "starting tserver"
success "String hello world how are you"
failure "String tserver"
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
starting tserver [ OK ]
String hello world how are you [ OK ]
String tserver [FAILED]
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
#!/bin/bash
SCREEN=`stty -F /dev/console size`
COLUMNS=${SCREEN#* }
SPA_COL=$[$COLUMNS-14]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${RED}FAILED${NORMAL} ]"
}
success "starting tserver"
success "String hello world how are you"
failure "String tserver"
[root@minlinux sysroot]# etc/rc.d/init.d/functions(执行functions脚本)
starting tserver [ OK ]
String hello world how are you [ OK ]
String tserver [ FAILED ]
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
SCREEN=`stty -F /dev/console size`
COLUMNS=${SCREEN#* }
SPA_COL=$[$COLUMNS-14]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${RED}FAILED${NORMAL} ]"
}
提示:定义为函数,不需要/bin/bash;
如何让写的tserver服务脚本也能显示为这样:
[root@minlinux sysroot]# vim etc/rc.d/init.d/tserver(编辑tserver脚本)
#!/bin/bash
#
# chkconfig: 35 66 33
# description: test service script
. /etc/rc.d/init.d/functions (装载functions函数脚本文件)
prog=tserver
lockfile=/var/lock/subsys/$prog
start() {
touch $lockfile (创建$lockfile文件)
[ $? -eq 0 ] && success "Starting $prog" || failure "String $prog" (创建lockfile文件成功,$?返回上个命令状态返回值,如果等于0,
就执行函数sucess或函数failure)
}
stop () {
rm -f $lockfile (删除$lockfile文件
[ $? -eq 0 ] && success "Starting $prog" || failure "String $prog" (删除lockfile文件成功,$?返回上个命令状态返回值,如果等于0,
就执行函数sucess或函数failure)
}
status() {
if [ -f $lockfile ];then
echo "Running..."
else
echo "Stopped..."
fi
}
usage() {
echo "Usage: $prog {start|stop|status|restart}"
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
;;
esac
[root@minlinux sysroot]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# /etc/rc.d/init.d/tserver start(执行tserver脚本)
/etc/rc.d/init.d/functions: line 1: stty: command not found
Starting tserver/etc/rc.d/init.d/functions: line 12: seq: command not found
[ OK ]
bash-3.2# exit
exit
提示:没有seq命令;
[root@minlinux sysroot]# /root/bincopy.sh(执行bincopy.sh脚本)
Your command:seq
/usr/bin/seq
copy /usr/bin/seq finishd.
Continue:q
提示:移植seq命令
[root@minlinux sysroot]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# /etc/rc.d/init.d/tserver start(执行tserver脚本)
/etc/rc.d/init.d/functions: line 1: stty: command not found
Starting tserver[ OK ]
bash-3.2# exit
exit
提示:没有stty命令;
[root@minlinux sysroot]# /root/bincopy.sh(执行bincopy.sh脚本)
Continue:stty
/bin/stty
copy /bin/stty finishd.
Continue:q
提示:移植stty命令;
[root@minlinux sysroot]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# /etc/rc.d/init.d/tserver start(执行tserver脚本)
stty: /dev/console: No such file or directory
Starting tserver[ OK ]
bash-3.2# exit
exit
提示:没有/dev/console文件;
[root@minlinux sysroot]# vim etc/rc.d/init.d/functions(编辑functions脚本)
SCREEN=`stty -F /dev/console size 2>/dev/null`(显示终端屏幕大小,将错误结果送给/dev/mull)
COLUMNS=${SCREEN#* }
[ -z $COLUMNS ] && COLUMNS=80(如果$COLUMNS变量值为空,则赋予值为80)
SPA_COL=$[$COLUMNS-14]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033\34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
}
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in `seq 1 $RT_SPA`;do
echo -n " "
done
echo -e "[ ${RED}FAILED${NORMAL} ]"
}
[root@minlinux sysroot]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# /etc/rc.d/init.d/tserver start(执行tserver脚本)
Starting tserver [ OK ]
bash-3.2# /etc/rc.d/init.d/tserver stop(执行tserver脚本)
Starting tserver [ OK ]
bash-3.2# exit
exit
[root@minlinux sysroot]# vim etc/rc.d/init.d/tserver(编辑tserver脚本)
#!/bin/bash
#
# chkconfig: 35 66 33
# description: test service script
. /etc/rc.d/init.d/functions
prog=tserver
lockfile=/var/lock/subsys/$prog
start() {
touch $lockfile
[ $? -eq 0 ] && success "Starting $prog" || failure "String $prog"
}
stop () {
rm -f $lockfile
[ $? -eq 0 ] && success "Stopping $prog" || failure "Stopping $prog"
}
status() {
if [ -f $lockfile ];then
echo "Running..."
else
echo "Stopped..."
fi
}
usage() {
echo "Usage: $prog {start|stop|status|restart}"
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
;;
esac
[root@minlinux sysroot]# chroot /mnt/sysroot/(切换根文件系统)
bash-3.2# /etc/rc.d/init.d/tserver stop(执行tserver脚本)
Stopping tserver [ OK ]
bash-3.2# /etc/rc.d/init.d/tserver start(执行tserver脚本)
Starting tserver [ OK ]
bash-3.2# /etc/rc.d/init.d/tserver restart(执行tserver脚本)
Stopping tserver [ OK ]
Starting tserver [ OK ]
bash-3.2# exit
exit
[root@minlinux sysroot]# sync(同步磁盘写入)
[root@minlinux sysroot]# sync(同步磁盘写入)
[root@minlinux sysroot]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
文件系统出错;

修复文件系统:
[root@minlinux sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.2.gz(查找当前目录所有文件通过管道送给cpio打包,
-H指定备份时使用的文件格式,newc指cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能
够支持多余512200各文件,默认情况下cpio归档所支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quit表示静默模式,不输
出信息,-o表示创建归档文件,将结果通过管道送给gzip,-9指定压缩级别,保存至/root目录较sysroot.2.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@minlinux sysroot]# cd (切换到root用户家目录)
[root@minlinux ~]# fuser -km /mnt/sysroot/(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
/mnt/sysroot/: 4348c
[root@minlinux ~]# umount /mnt/sysroot/(卸载/mnt/sysroot目录挂载的文件系统)
[root@minlinux ~]# e2fsck -f /dev/hda2(e2fsck专用修复ext2/ext3文件系统,-f强制检查,没问题也检查)
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/hda2: 117/125488 files (0.9% non-contiguous), 36029/500376 blocks
提示:如果修复错误太多,可以重新将文件系统格式化;
[root@minlinux ~]# mke2fs -j /dev/hda2(格式化/dev/hda2文件系统,-j带日志文件系统ext3)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@minlinux ~]# mount /dev/hda2 /mnt/sysroot/(挂载/dev/hda2到/mnt/sysroot目录)
[root@minlinux ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@minlinux sysroot]# zcat /root/sysroot.2.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
19022 blocks
[root@minlinux sysroot]# sync(同步磁盘写入)
[root@minlinux sysroot]# sync(同步磁盘写入)
[root@minlinux sysroot]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
测试成功,服务正常启动,而且按照红帽格式显示启动方式;

测试:关机测试;
测试成功,服务正常停止;

如何让小系统具有IP地址:
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# mkdir lib/modules(创建modules目录)
[root@Smoke sysroot]# modinfo pcnet32(查看pcnet32模块信息)
filename: /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko
license: GPL
description: Driver for PCnet32 and PCnetPCI based ethercards
author: Thomas Bogendoerfer
srcversion: F81443556AAE169CBF80F55
alias: pci:v00001023d00002000sv*sd*bc02sc00i*
alias: pci:v00001022d00002000sv*sd*bc*sc*i*
alias: pci:v00001022d00002001sv*sd*bc*sc*i*
depends: mii (依赖于mii模块)
vermagic: 2.6.18-308.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
parm: debug:pcnet32 debug level (int)
parm: max_interrupt_work:pcnet32 maximum events handled per interrupt (int)
parm: rx_copybreak:pcnet32 copy breakpoint for copy-only-tiny-frames (int)
parm: tx_start_pt:pcnet32 transmit start point (0-3) (int)
parm: pcnet32vlb:pcnet32 Vesa local bus (VLB) support (0/1) (int)
parm: options:pcnet32 initial option setting(s) (0-15) (array of int)
parm: full_duplex:pcnet32 full duplex setting(s) (1) (array of int)
parm: homepna:pcnet32 mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet (array of int)
module_sig: 883f3504f2326fedc995cc0b59af121112c9240a0888050bfd72bf9d5ba34fa2b2d35ad9c599dc2b509f6fc0ce174c811a747cc9292d8
a4d837983e5b14
[root@Smoke sysroot]# cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/(复制pcnet32.ko文件
到/mnt/sysroot/lib/modules目录)
提示:复制pcnet32.ko模块到/mntsysroot/lib/modules目录;
[root@Smoke sysroot]# modinfo mii(查看mii模块相关信息)
filename: /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko
license: GPL
description: MII hardware support library
author: Jeff Garzik <jgarzik@pobox.com>
srcversion: 16DCEDEE4B5629C222C352D
depends:
vermagic: 2.6.18-308.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
module_sig: 883f3504f23273dc995cc0b59af12111211c809f6f79961e4a84bc133b97d3d32bb217be64af3d1c09d11dbf04e53225fd698ce
3def9448666b2a5a31
[root@Smoke sysroot]# cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules/(复制mii.ko文件到
/mnt/sysroot/lib/modules目录)
提示:复制mii.ko模块到/mnt/sysroot/lib/modules目录;
让系统启动自动装载pcnet32.ko和mii.ko模块:
[root@Smoke sysroot]# vim etc/rc.d/rc.sysinit(编辑rc.sysinit文件)
#!/bin/bash
#
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
echo "Remount rootfs..."
mount -n -o remount,rw /
echo "Set the hostname..."
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
echo "Initializing network device..."
/sbin/insmod /lib/modules/mii.ko (开机装载mii.ko模块)
/sbin/insmod /lib/modules/pcnet32.ko (开机装载pcnet32.ko模块)
[root@Smoke sysroot]# mkdir -pv etc/sysconfig/network-scripts(创建etc/sysconfig/network-scripts目录,-p递归创建,-v显示创建过程)
mkdir: created directory `etc/sysconfig/network-scripts'
[root@Smoke sysroot]# vim etc/sysconfig/network-scripts/ifcfg-eth0(编辑ifcfg-eth0模块)
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.100.5
NETMASK=255.255.0.0
GATEWAY=172.16.0.1
ONBOOT=yes
[root@Smoke sysroot]# vim etc/rc.d/init.d/network(编辑network脚本)
#!/bin/bash
#
prog=network
. /etc/rc.d/init.d/functions (将functions函数读取进脚本)
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0
. $CONF (将ifcfg-eth0文件中定义的变量读取进脚本中)
start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add default gw $GATWAY (判断$GATEWAY变量是否存在值,存在为真,添加路由)
}
stop() {
ifconfig eth0 down
}
status() {
ifconfig eth0
}
usage() {
echo "$prog: {start|stop|restart|status}"
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
stop
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status
;;
*)
usage
exit 1
;;
esac
[root@Smoke sysroot]# chmod +x !$(给network脚本执行权限)
chmod +x etc/rc.d/init.d/network
[root@Smoke sysroot]# cd etc/rc.d/rc0.d/(切换到etc/rc.d/rc0.d目录)
[root@Smoke rc0.d]# ln -sv ../init.d/network K90network(给netowrk文件创建软链接叫K90network)
create symbolic link `K90network' to `../init.d/network'
提示:K90network,K代表Stop,90代表停止次序;
[root@Smoke rc0.d]# cd ../rc6.d/(切换到上级目录下的rc6.d目录)
[root@Smoke rc6.d]# ln -sv ../init.d/network K90network(给netowrk文件创建软链接叫K90network)
create symbolic link `K90network' to `../init.d/network'
[root@Smoke rc6.d]# cd ../rc3.d/(切换到上级命令下的rc3.d目录)
[root@Smoke rc3.d]# ln -sv ../init.d/network S09network(给network文件创建软连接较S09network)
create symbolic link `S09network' to `../init.d/network'
提示:S09network,S代表Start,09代表启动次序;
[root@Smoke rc3.d]# cd ..(切换到上级目录)
[root@Smoke rc.d]# vim init.d/network(编辑init.d目录下的network脚本)
#!/bin/bash
#
# chkconfig: 35 09 90 (chkconfig调用服务脚本,35代表3和5级别启动,启动号09,停止号90)
# description: network service (描述信息)
prog=network
. /etc/rc.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0
. $CONF
start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add default gw $GATWAY
}
stop() {
ifconfig eth0 down
}
status() {
ifconfig eth0
}
usage() {
echo "$prog: {start|stop|restart|status}"
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
stop
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status
;;
*)
usage
exit 1
;;
esac
[root@Smoke rc.d]# chroot /mnt/sysroot/(切换根文件系统到/mnt/sysroot目录)
Usage:
ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]
[add <address>[/<prefixlen>]]
[del <address>[/<prefixlen>]]
[[-]broadcast [<address>]] [[-]pointopoint [<address>]]
[netmask <address>] [dstaddr <address>] [tunnel <address>]
[outfill <NN>] [keepalive <NN>]
[hw <HW> <address>] [metric <NN>] [mtu <NN>]
[[-]trailers] [[-]arp] [[-]allmulti]
[multicast] [[-]promisc]
[mem_start <NN>] [io_addr <NN>] [irq <NN>] [media <type>]
[txqueuelen <NN>]
[[-]dynamic]
[up|down] ...
<HW>=Hardware Type.
List of possible hardware types:
loop (Local Loopback) slip (Serial Line IP) cslip (VJ Serial Line IP)
slip6 (6-bit Serial Line IP) cslip6 (VJ 6-bit Serial Line IP) adaptive (Adaptive Serial Line IP)
strip (Metricom Starmode IP) ash (Ash) ether (Ethernet)
tr (16/4 Mbps Token Ring) tr (16/4 Mbps Token Ring (New)) ax25 (AMPR AX.25)
netrom (AMPR NET/ROM) rose (AMPR ROSE) tunnel (IPIP Tunnel)
ppp (Point-to-Point Protocol) hdlc ((Cisco)-HDLC) lapb (LAPB)
arcnet (ARCnet) dlci (Frame Relay DLCI) frad (Frame Relay Access Device)
sit (IPv6-in-IPv4) fddi (Fiber Distributed Data Interface) hippi (HIPPI)
irda (IrLAP) ec (Econet) x25 (generic X.25)
infiniband (InfiniBand)
<AF>=Address family. Default: inet
List of possible address families:
unix (UNIX Domain) inet (DARPA Internet) inet6 (IPv6)
ax25 (AMPR AX.25) netrom (AMPR NET/ROM) rose (AMPR ROSE)
ipx (Novell IPX) ddp (Appletalk DDP) ec (Econet)
ash (Ash) x25 (CCITT X.25)
Config network eth0 [ OK ]
提示:没有网卡;
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统:
网卡没有装载进来,

修复文件系统:
[root@Smoke modules]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.3.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定备
份时使用的文件格式,newc指cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多余512
200各文件,默认情况下cpio归档所支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quit表示静默模式,不输出信息,-o表示创建归
档文件,将结果通过管道送给gzip,-9指定压缩级别,保存至/root目录较sysroot.2.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke sysroot]# cd(切换到root用户家目录)
[root@Smoke ~]# fuser -km /dev/hda2 /(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
/dev/hda2: 10192c
[root@Smoke ~]# umount /dev/hda2(卸载/dev/hda2)
[root@Smoke ~]# mke2fs -j /dev/hda2(格式化/dev/hda2文件系统,-j格式化为ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@Smoke ~]# mount /dev/hda2 /mnt/sysroot/(挂载/dev/hda2文件系统到/mnt/sysroot目录)
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# zcat /root/sysroot.3.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
19132 blocks
[root@Smoke sysroot]# cd lib/modules/(切换到lib/modules目录)
[root@Smoke modules]# ls(查看当前目录文件及子目录)
mii.ko pcnet32.ko
[root@Smoke modules]# cd(切换到根用户家目录)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统:

还是没有地址,没有配置上去;

bash-3.2# cat /etc/rc.d/init.d/network (查看network脚本) bash-3.2# /etc/rc.d/init.d/network start (手动启动网卡) 提示:ifconfig命令语法有错,掩码配置应该是172.16.100.5/26 bash-3.2# ifconfig eth0 172.16.100.5/255.255.0.0(配置网卡eth0地址) 提示:使用172.16.100.6/255.255.0.0不行;
手动配置网卡:

编辑network脚本:
bash-3.2# vi /etc/rc.d/init.d/network (编辑network脚本)
#!/bin/bash
#
# chkconfig: 35 09 90
# description: network service
prog=network
. /etc/rc.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0
. $CONF
NETMASK=16 (直接定义NETMASK等于16)
start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add default gw $GATWAY
}
stop() {
ifconfig eth0 down
}
status() {
ifconfig eth0
}
usage() {
echo "$prog: {start|stop|restart|status}"
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
stop
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status
;;
*)
usage
exit 1
;;
esac
测试:网卡;

测试:关机;

1、关机和重启;
2、终端
3、主机名
4、IP地址(模块的装载和服务的实现)
5、functions
6、终端提示信息
/etc/issue文件的内容
7、rc.sysinit:挂载/etc/fstab中定义的其它文件系统;
8、设定内核参数
/etc/sysctl.conf
sysctl -p:让/etc/sysctl.conf中的参数生效;
9、用户
PAM: Pluggable Authentication Module 可插入式的认证模块,有许许多多的配置文件;
/etc/pam.d/*:红帽系统上PAM配置文件路径;
绕过PAM:不基于PAM的认证方式;
/bin/login:登录操作系统所显示的login信息打印程序文件,还能够实现用户验证,这个程序在编译的时候是依赖PAM的;
对操作系统而言,为了能够验证用户帐号,要附加很多的安全法则,验证用户帐号,当用户输入用户名的时候,用户名是否正常,当用户输入密码的时候,用户密码是不是在有效期内,用户修改密码的时候,它的密码是不是符合密码复杂度要求等等,这些信息都必须得验证;
用户:UID
组: GID
login: 验正
nsswitch: Network Service Switch 网络服务转换;
框架:/etc/passwd, /etc/shadow, /etc/group
库:libnss_file.so(/etc/passwd认证的库), libnss_nis.so(NIS数据库认证的库), libnsss_ldap.so(LDAP数据库认证的库)
配置文件: /etc/nsswitch.conf
/etc/passwd, /etc/shadow
NIS, LDAP, MySQL
/etc/mypasswd
/etc/passwd
/etc/group
nsswitch名称解析是如何工作的?
将用户的用户名转换成ID号到那里去找,将组名转换成ID号到那里去找,将主机名转换成IP地址到那里去找等等,都要靠/etc/nsswitch.conf文件;
10、单用户模式
init 1:级别1
如何让系统打印显示登录之前的信息:这些信息一般都是由终端程序来实现打印的,无论是mingetty、agetty还是mgetty都能实现,事实它们是一个文件的内容,/etc/issue文件内容,因此只需要提供一个etc/issue文件,并在里面写上一些信息,就能够实现让用户登录的时候,或打印一个终端的时候,就显示类似信息,但是etc/issue给的可不是登录前显示的信息。
终端提示信息:
[root@Smoke ~]# awk '{print $1}' /etc/fstab(awk默认以空格分隔符显示第一段,显示fstab文件中的设备名)
LABEL=/
LABEL=/boot
tmpfs
devpts
sysfs
proc
LABEL=SWAP-sda3
提示:但是这些设备里面并非每一个设备都需要挂载,因为有些已经挂载过了,如果是交换分区,不能简单对其进行挂载,还要使用swapon来进行激活;
[root@Smoke ~]# cat /etc/fstab(查看/etc/fstab文件内容)
LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda3 swap swap defaults 0 0
把第二段为swap的去掉:
[root@Smoke ~]# grep -v "\<swap\>" /etc/fstab(通过grep选项-v显示没有被swap匹配到的行,\<锚定词首,\>锚定词尾)
LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@Smoke ~]# grep -v "\<swap\>" /etc/fstab | awk '{print $1}'(通过grep选项-v显示没有被swap字符串匹配到的行,\<锚定词首,\>锚定词尾,将结果
通过管道送给awk,默认以空格为分隔符只显示第一段)
LABEL=/
LABEL=/boot
tmpfs
devpts
sysfs
proc
[root@Smoke ~]# grep -E -v "\<swap|proc|sysfs\>" /etc/fstab | awk '{print $1}'(通过grep -E扩展正则表达式选项-v显示没有被swap或者proc或者
sysfs字符串匹配到的行,,\<锚定词首,\>锚定词尾,将结果通过管道送给awk,默认以空格为分隔符只显示第一段)
LABEL=/
LABEL=/boot
tmpfs
devpts
[root@Smoke ~]# grep -E -v "\<swap|proc|sysfs\>" /etc/fstab | awk '{print $1}' | while read LINE;do awk '{print $1}' /proc/mounts
| grep "^$LINE$";done(通过grep -E扩展正则表达式选项-v显示没有被swap或者proc或者sysfs字符串匹配到的行,,\<锚定词首,\>锚定词尾,将结果通过管道送
给awk,默认以空格为分隔符只显示第一段,将结果通过管道送给while循环,读取结果中的每一段放到LINE变量里面分别进行处理,通过awk显示/proc/mounts文件中第一段
,通过管道送给grep判断是否存在$LINE所在的段)
tmpfs
devpts
[root@Smoke ~]# mount -a(挂载/etc/fstab文件中的所有文件系统)
提示:简单办法mount -a挂载/etc/fstab中的所定义的所有文件系统,但这个命令在有时候会出错,所以事实上也可以不使用脚本,但是建议使用脚本,可以简单的解决有些问题;
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# vim etc/rc.d/rc.sysinit(编辑etc/rc.d/rc.sysinit系统初始化文件)
#!/bin/bash
#
. /etc/rc.d/init.d/functions(读取functions函数)
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
echo "Remount rootfs..."
mount -n -o remount,rw /
[ $? -eq 0 ] && success "Remount rootfs" || failure "Remount rootfs"
mount -a
[ $? -eq 0 ] && success "Mount others filesystem." || failure "Mount others filesystem"(某一个文件系统挂载失败,会导致这里显示所有文件系
统挂载失败,因为没办法判定是那个文件系统是挂载失败的,所以这就是使用mount -a的坏处,它也会试图重新挂载sysfs、proc文件系统这时候会报错的)
#Set the hostname...
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
[ $? -eq 0 ] && success "Set the hostname" || failure "Set the hostname"
#Initializing network device...
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
[ $? -eq 0 ] && success "Initializing network device" || failure "Initialization network device"
ifconfig lo 127.0.0.1/8
[ $? -eq 0 ] && success "Activating loopback network device" || failure "Activating loopback network device"
提示:最好能把
[root@Smoke ~]# grep -E -v "\<swap|proc|sysfs\>" /etc/fstab | awk '{print $1}' | while read LINE;do awk '{print $1}' /proc/mounts
| grep "^$LINE$";done写入到rc.sysinit脚本中挂载文件系统可能会好很多;
[root@Smoke sysroot]# cat etc/fstab(查看etc/fstab文件)
/dev/hda2 / ext3 defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
提示:小Linux系统的fstab文件;
设定内核参数:
[root@Smoke sysroot]# /root/bincopy.sh
Your command:sysctl
/sbin/sysctl
copy lib /lib/libproc-3.2.7.so finished.
copy /sbin/sysctl finishd.
Continue:q
提示:移植sysctl命令和它所依赖的库文件;
提供sysctl.conf脚本:
[root@Smoke sysroot]# vim etc/sysctl.conf(编辑sysctl.conf脚本)
net.ipv4.ip_forward = 1 (设定网卡之间的转发功能)
[root@Smoke sysroot]# cat /etc/sysctl.conf(查看宿主机内核参数sysctl.conf文件)
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1
# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536
# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456
[root@Smoke sysroot]# vim etc/rc.d/rc.sysinit(编辑系统初始化脚本rc.sysinit)
#!/bin/bash
#
. /etc/rc.d/init.d/functions
echo -e "\tWelcome to \033[34mSmoke\033[0m Linux"
echo "Remount rootfs..."
mount -n -o remount,rw /
[ $? -eq 0 ] && success "Remount rootfs" || failure "Remount rootfs"
mount -a
[ $? -eq 0 ] && success "Mount others filesystem." || failure "Mount others filesystem"
#Set the hostname...
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
[ $? -eq 0 ] && success "Set the hostname" || failure "Set the hostname"
#Initializing network device...
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
[ $? -eq 0 ] && success "Initializing network device" || failure "Initialization network device"
ifconfig lo 127.0.0.1/8
[ $? -eq 0 ] && success "Activating loopback network device" || failure "Activating loopback network device"
sysctl -p &> /dev/null (让/etc/sysctl.conf内核参数生效,将执行结果送给/dev/null)
[ $? -eq 0 ] && success "Set kernel parameter" || failure "Set kernel parameter"
提示:所有想要开机生效的脚本都必须写在/etc/rc.d/rc.d/rc.sysinit配置中;
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# logout(退出终端)
测试:挂起宿主机,开启小Linux系统;
文件系统坏掉,测试失败;
文件系统修复:
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.6.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定
备份时使用的文件格式,newc指cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多余
512200各文件,默认情况下cpio归档所支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quit表示静默模式,不输出信息,-o表示
创建归档文件,将结果通过管道送给gzip,-9指定压缩级别,保存至/root目录较sysroot.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke ~]# fuser -km /mnt/sysroot/(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
[root@Smoke ~]# umount /mnt/sysroot/(卸载/mnt/sysroot目录下挂载的文件系统)
[root@Smoke ~]# mke2fs -j /dev/hda2(将/dev/hda2格式化为ext3类型文件系统,-j带日志)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 38 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@Smoke ~]# mount /dev/hda2 /mnt/sysroot/(挂载/dev/hda2文件系统到/mnt/sysroot目录)
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# zcat /root/sysroot.6.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
19264 blocks
精简系统:
[root@Smoke ~]# vim /mnt/boot/grub/grub.conf(编辑/mnt/boot/grub/grub.conf配置文件)
default=0
timeout=3
title Smoke Linux(2.6.18)
root(hd0,0)
kernel /vmlinuz ro root=/dev/hda2 quiet(ro只读,告诉内核根文件系统在/dev/hda2上,quiet静默方式,就不会输出BIOS初始化时候,或内
核初始化的时候大多数信息)
initrd /initrd.gz
提示:小Linux启动的GRUB配置文件;
[root@Smoke ~]# cd test/
[root@Smoke test]# ls
bin dev etc init lib proc sbin sys sysroot
[root@Smoke test]# vim init(编辑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-mem-cache.ko module"
#insmod /lib/dm-mem-cache.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-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
#resume LABEL=SWAP-sda3
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
提示:去掉initrd文件中绝大多数装载模块指令,只留下insmod /lib/jbd.ko、insmod /lib/ext3.ko两个模块;
[root@Smoke lib]# ls(查看lib目录下文件及子目录)
ext3.ko firmware jbd.ko
提示:将lib目录下绝大多少模块都删除,只留下ext3.ko firmware jbd.ko三个模块;
[root@Smoke lib]# ls -lh /mnt/boot/(查看/mnt/boot目录下文件及子目录)
total 4.4M
drwxr-xr-x 2 root root 1.0K Dec 3 09:56 grub
-rw-r--r-- 1 root root 1.8M Nov 22 02:08 initrd.gz
drwx------ 2 root root 12K Nov 22 02:02 lost+found
-rw-r--r-- 1 root root 1.9M Nov 22 02:04 vmlinuz
提示:做出来的initrd.gz文件只有1.8M大小;
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,开启小Linux系统;
没有打印issue中的信息,是因为没有让用户登录;当要求用户登录就会显示了,不然默认会清除这些信息,或者man agetty明确说明让它读取/etc/issue配置文件也成,这需要agetty一些选项专门来进行指定

验证内核参数是否生效:
内核参数设定生效,默认为0

关机:
正常关机;

支持用户帐号:
[root@Smoke ~]# cat /etc/nsswitch.conf(查看nsswitch配置文件) # # /etc/nsswitch.conf # # An example Name Service Switch config file. This file should be # sorted with the most-used services at the beginning. # # The entry '[NOTFOUND=return]' means that the search for an # entry should stop if the search in the previous entry turned # up nothing. Note that if the search failed due to some other reason # (like no NIS server responding) then the search continues with the # next entry. # # Legal entries are: # # nisplus or nis+ Use NIS+ (NIS version 3) # nis or yp Use NIS (NIS version 2), also called YP # dns Use DNS (Domain Name Service) # files Use the local files # db Use the local database (.db) files # compat Use NIS on compat mode # hesiod Use Hesiod for user lookups # [NOTFOUND=return] Stop searching if not found so far # # To use db, put the "db" in front of "files" for entries you want to be # looked up first in the databases # # Example: #passwd: db files nisplus nis #shadow: db files nisplus nis #group: db files nisplus nis passwd: files(找用户密码到files中找,files表示/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow,passwd表示在/etc/passwd中找, shadow表示在/etc/shadow中找,grub标识在/etc/group中找) shadow: files(可以定义多个,比如files ldap自左而右找着为止) group: files #hosts: db files nisplus nis dns hosts: files dns (主机名转换IP地址,/etc/hosts文件,如果/etc/hosts文件没有,再通过dns服务器查找,谁写在前面谁的优先级高) # Example - obey only what nisplus tells us... #services: nisplus [NOTFOUND=return] files #networks: nisplus [NOTFOUND=return] files #protocols: nisplus [NOTFOUND=return] files #rpc: nisplus [NOTFOUND=return] files #ethers: nisplus [NOTFOUND=return] files #netmasks: nisplus [NOTFOUND=return] files bootparams: nisplus [NOTFOUND=return] files ethers: files netmasks: files networks: files protocols: files rpc: files services: files netgroup: nisplus publickey: nisplus automount: files nisplus aliases: files nisplus sudoers: files ldap [root@Smoke ~]# ping www.baidu.com (ping测试 www.baidu.com ) PING www.a.shifen.com (180.97.33.107) 56(84) bytes of data. 64 bytes from 180.97.33.107: icmp_seq=1 ttl=128 time=47.1 ms 64 bytes from 180.97.33.107: icmp_seq=2 ttl=128 time=46.6 ms --- www.a.shifen.com ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 46.686/46.904/47.122/0.218 ms [root@Smoke ~]# cat /etc/resolv.conf(查看dns服务器配置文件内容) ; generated by /sbin/dhclient-script search localdomain nameserver 192.168.223.2 [root@Smoke ~]# cat /etc/hosts(查看/etc/hosts文件内容,本地域名解析) # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 [root@Smoke ~]# vim /etc/hosts(编辑/etc/hosts文件) # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 172.16.100.1 www.baidu.com (定义172.16.100.1的域名为 www.baidu.com ) [root@Smoke ~]# ping www.baidu.com (Ping测试 www.baidu.com ) PING www.baidu.com (172.16.100.1) 56(84) bytes of data. 64 bytes from www.baidu.com (172.16.100.1): icmp_seq=1 ttl=64 time=5.21 ms 64 bytes from www.baidu.com (172.16.100.1): icmp_seq=2 ttl=64 time=0.101 ms 64 bytes from www.baidu.com (172.16.100.1): icmp_seq=3 ttl=64 time=0.040 ms --- www.baidu.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.040/1.784/5.213/2.424 ms 提示:现在IP地址和名称解析以/etc/hosts文件为准,因此/etc/hosts文件的优先级高于DNS服务器的优先级; 复制nsswitch所依赖的库文件: [root@Smoke ~]# ls -l /lib/libnss*(查看/lib/libnss开头任意长度任意字符结束的文件详细信息) -rwxr-xr-x 1 root root 36416 Jan 20 2012 /lib/libnss_compat-2.5.so lrwxrwxrwx 1 root root 20 Nov 22 09:22 /lib/libnss_compat.so.2 -> libnss_compat-2.5.so -rwxr-xr-x 1 root root 825028 Apr 9 2010 /lib/libnss_db-2.2.so lrwxrwxrwx 1 root root 16 Nov 22 09:23 /lib/libnss_db.so.2 -> libnss_db-2.2.so -rwxr-xr-x 1 root root 21948 Jan 20 2012 /lib/libnss_dns-2.5.so lrwxrwxrwx 1 root root 17 Nov 22 09:22 /lib/libnss_dns.so.2 -> libnss_dns-2.5.so -rwxr-xr-x 1 root root 50848 Jan 20 2012 /lib/libnss_files-2.5.so lrwxrwxrwx 1 root root 19 Nov 22 09:22 /lib/libnss_files.so.2 -> libnss_files-2.5.so -rwxr-xr-x 1 root root 22764 Jan 20 2012 /lib/libnss_hesiod-2.5.so lrwxrwxrwx 1 root root 20 Nov 22 09:22 /lib/libnss_hesiod.so.2 -> libnss_hesiod-2.5.so -rwxr-xr-x 1 root root 3208576 Dec 4 2011 /lib/libnss_ldap-2.5.so lrwxrwxrwx 1 root root 18 Nov 22 09:25 /lib/libnss_ldap.so.2 -> libnss_ldap-2.5.so -rwxr-xr-x 1 root root 46568 Jan 20 2012 /lib/libnss_nis-2.5.so -rwxr-xr-x 1 root root 55804 Jan 20 2012 /lib/libnss_nisplus-2.5.so lrwxrwxrwx 1 root root 21 Nov 22 09:22 /lib/libnss_nisplus.so.2 -> libnss_nisplus-2.5.so lrwxrwxrwx 1 root root 17 Nov 22 09:22 /lib/libnss_nis.so.2 -> libnss_nis-2.5.so -rwxr-xr-x 1 root root 19500 Jan 19 2012 /lib/libnss_winbind.so.2 -rwxr-xr-x 1 root root 987544 Jan 19 2012 /lib/libnss_wins.so.2 提示:库文件有很多,它们都以libnss开头,不同的库文件实现到不同的地方找用户名转换成ID号,我们主要用到的是/lib/libnss_files-2.5.so; [root@Smoke ~]# ls -l /usr/lib/libnss*(查看/usr/lib/libnss开头任意长度任意字符结尾的文件详细信息) -rwxr-xr-x 1 root root 1205444 Jan 14 2012 /usr/lib/libnss3.so (lib主库、核心库) -rwxr-xr-x 1 root root 435184 Jan 14 2012 /usr/lib/libnssckbi.so lrwxrwxrwx 1 root root 24 Nov 22 09:23 /usr/lib/libnss_db.so -> ../../lib/libnss_db.so.2 lrwxrwxrwx 1 root root 26 Nov 22 09:25 /usr/lib/libnss_ldap.so -> ../../lib/libnss_ldap.so.2 -rwxr-xr-x 1 root root 102788 Jan 14 2012 /usr/lib/libnssutil3.so lrwxrwxrwx 1 root root 24 Nov 22 09:25 /usr/lib/libnss_winbind.so -> /lib/libnss_winbind.so.2 lrwxrwxrwx 1 root root 21 Nov 22 09:25 /usr/lib/libnss_wins.so -> /lib/libnss_wins.so.2 提示:/usr/lib/libnss*也是nsswitch文件所依赖的库文件,有很多都是链接直接指到/lib/libnss*,但是有三个/usr/lib/libnssutil3.so、/usr/lib/lib nss3.so (lib主库、核心库)、/usr/lib/libnssckbi.so这三个没有链接,对我们而言只要复制/usr/lib/libnssutil3.so、/usr/lib/libnss3.so (lib主库 、核心库)、/usr/lib/libnssckbi.so、/lib/libnss_files-2.5.so,并且给/lib/libnss_files-2.5.so创建一个链接,同样在/usr/lib/也给它创建链接, 才能确保万无一失的;
复制链接文件:
cp:复制文件
-P
-d:当复制符号连接时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录;
[root@Smoke ~]# cp -d /usr/lib/libnss_ldap.so /root/(复制libnss_ldap.so文件到/root目录,-d)
[root@Smoke ~]# ll(查看当前目录文件及子目录)
total 23700
-rw------- 1 root root 1074 Nov 22 09:31 anaconda-ks.cfg
-rwxr-xr-x 1 root root 708 Nov 22 06:20 bincopy.sh
drwxr-xr-x 2 root root 4096 Dec 3 08:14 Desktop
-rw-r--r-- 1 root root 6255616 Nov 22 01:55 initrd-2.6.18-308.el5.img
-rw-r--r-- 1 root root 28330 Nov 22 09:31 install.log
-rw-r--r-- 1 root root 3672 Nov 22 09:30 install.log.syslog
lrwxrwxrwx 1 root root 26 Dec 3 11:20 libnss_ldap.so -> ../../lib/libnss_ldap.so.2
-rw-r--r-- 1 root root 4451652 Dec 3 04:19 sysroot.2.gz
-rw-r--r-- 1 root root 4471965 Dec 3 06:13 sysroot.3.gz
-rw-r--r-- 1 root root 4503956 Dec 3 09:46 sysroot.6.gz
-rw-r--r-- 1 root root 4416990 Nov 22 07:44 sysroot.gz
drwxr-xr-x 9 root root 4096 Dec 3 10:09 test
提示:libnss_ldap.so仍然保持链接../../lib/libnss_ldap.so.2;
[root@Smoke ~]# rm libnss_ldap.so(删除libnss_ldap.so文件)
rm: remove symbolic link `libnss_ldap.so'? y
[root@Smoke ~]# cp -d /lib/libnss_files* /mnt/sysroot/lib/(复制/lib/linss_files*开头的所有文件到/mnt/sysroot/lib目录,-d保持链接)
[root@Smoke ~]# ls -l /mnt/sysroot/lib/(查看/mnt/sysroot/lib/目录下文件及子目录详细信息)
total 3175
-rwxr-xr-x 1 root root 129476 Dec 3 09:51 ld-linux.so.2
-rwxr-xr-x 1 root root 24180 Dec 3 09:51 libacl.so.1
-rwxr-xr-x 1 root root 14488 Dec 3 09:51 libattr.so.1
-rwxr-xr-x 1 root root 36708 Dec 3 09:51 libblkid.so.1
-rwxr-xr-x 1 root root 43616 Dec 3 09:51 libcrypt.so.1
-rwxr-xr-x 1 root root 1690404 Dec 3 09:51 libc.so.6
-r-xr-xr-x 1 root root 163324 Dec 3 09:51 libdevmapper.so.1.02
-rwxr-xr-x 1 root root 18812 Dec 3 09:51 libdl.so.2
-rwxr-xr-x 1 root root 214572 Dec 3 09:51 libm.so.6
-rwxr-xr-x 1 root root 107924 Dec 3 09:51 libnsl.so.1
-rwxr-xr-x 1 root root 50848 Dec 3 11:32 libnss_files-2.5.so
lrwxrwxrwx 1 root root 19 Dec 3 11:32 libnss_files.so.2 -> libnss_files-2.5.so
-rwxr-xr-x 1 root root 54340 Dec 3 09:51 libproc-3.2.7.so
-rwxr-xr-x 1 root root 135928 Dec 3 09:51 libpthread.so.0
-rwxr-xr-x 1 root root 83048 Dec 3 09:51 libresolv.so.2
-rwxr-xr-x 1 root root 46144 Dec 3 09:51 librt.so.1
-rwxr-xr-x 1 root root 91892 Dec 3 09:51 libselinux.so.1
-rwxr-xr-x 1 root root 243928 Dec 3 09:51 libsepol.so.1
-rwxr-xr-x 1 root root 11828 Dec 3 09:51 libtermcap.so.2
-rwxr-xr-x 1 root root 13492 Dec 3 09:51 libutil.so.1
-rwxr-xr-x 1 root root 14472 Dec 3 09:51 libuuid.so.1
drwxr-xr-x 2 root root 1024 Dec 3 09:51 modules[root@Smoke ~]# ls /mnt/sysroot/usr/(查看/mnt/sysroot/usr/目录文件及子目录)
bin lib local sbin
提示:确保/mnt/sysroot/usr/下有lib目录;
[root@Smoke ~]# cp -d /usr/lib/libnss_files.so /mnt/sysroot/usr/lib/(复制libnss_files.so文件到/mnt/sysroot/lib目录)
[root@Smoke ~]# cp -d /usr/lib/libnss3.so /usr/lib/libnssckbi.so /usr/lib/libnssutil3.so /mnt/sysroot/usr/lib/(复制/usr/lib/
libnss3.so /usr/lib/libnssckbi.so /usr/lib/libnssutil3.so到/mntsysroot/usr/lib目录)
[root@Smoke ~]# ls -l /mnt/sysroot/usr/lib/(查看/mnt/sysroot/usr/lib目录)
total 2036
-rwxr-xr-x 1 root root 19620 Dec 3 09:51 libgpm.so.1
-rwxr-xr-x 1 root root 295984 Dec 3 09:51 libncurses.so.5
-rwxr-xr-x 1 root root 1205444 Dec 3 11:42 libnss3.so
-rwxr-xr-x 1 root root 435184 Dec 3 11:42 libnssckbi.so
lrwxrwxrwx 1 root root 27 Dec 3 11:50 libnss_files.so -> ../../lib/libnss_files.so.2
-rwxr-xr-x 1 root root 102788 Dec 3 11:42 libnssutil3.so
drwxr-xr-x 3 root root 1024 Dec 3 09:51 perl5
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
编辑nsswitch.conf文件:
[root@Smoke ~]# cp /etc/nsswitch.conf /mnt/sysroot/etc/(复制nsswitch.conf文化到/mnt/sysroot/etc/目录)
[root@Smoke ~]# vim /mnt/sysroot/etc/nsswitch.conf(编辑nsswitch.conf文件)
passwd: files
shadow: files
group: files
hosts: files dns
.,$d(删除当前行到最后一行)
1,.d(删除第一行到当前行)
创建用户:
[root@Smoke ~]# cat /etc/passwd(查看/etc/passwd文件内容)
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news :
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
pcap:x:77:77::/var/arpwatch:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
avahi:x:70:70:Avahi daemon:/:/sbin/nologin
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
avahi-autoipd:x:100:101:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin
gdm:x:42:42::/var/gdm:/sbin/nologin
sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin
Smoke:x:500:500:Smoke:/home/Smoke:/bin/bash
[root@Smoke ~]# useradd hadoop(创建hadoop用户)
[root@Smoke ~]# passwd hadoop(给hadoop创建密码为redhat)
Changing password for user hadoop.
New UNIX password:
BAD PASSWORD: it is based on a dictionary word
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/passwd(通过grep选择-E扩展正则表达式匹配/etc/passwd文件中行首为root或hadoop并锚定词尾)
root:x:0:0:root:/root:/bin/bash
hadoop:x:501:501::/home/hadoop:/bin/bash
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/passwd > /mnt/sysroot/etc/passwd(通过grep选择-E扩展正则表达式匹配/etc/passwd文件中行首
为root或hadoop并锚定词尾,将结果通过输出重定向给/mnt/sysroot/etc/passwd文件)
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/shadow (通过grep选项-E扩展正则表达式匹配/etc/shadow文件中行首为root或者hadoop并做词尾锚定)
root:$1$0Z0BvYRX$JAeOXhKNyI.bNKq8siKMn.:16396:0:99999:7:::
hadoop:$1$mhz6DHSq$67ifZI/VecoFC4jG6Ve/e0:16407:0:99999:7:::
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/shadow > /mnt/sysroot/etc/shadow(通过grep选项-E扩展正则表达式匹配/etc/shadow文件中行
首为root或者hadoop并做词尾锚定,将结果通过输出重定向到/mnt/sysroot/etc/shadow文件)
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/group(通过grep选项-E扩展正则表达式匹配/etc/group文件中行首为root或者hadoop并做词尾锚定)
root:x:0:root
hadoop:x:501:
[root@Smoke ~]# grep -E "^(root|hadoop)\>" /etc/group > /mnt/sysroot/etc/group(通过grep选项-E扩展正则表达式匹配/etc/group文件中行首
为root或者hadoop并做词尾锚定,将结果通过输出重定向到/mnt/sysroot/etc/group文件)
移植所需的命令:
[root@Smoke ~]# ./bincopy.sh(当前目录执行bincopy.sh文件移植命令和命令所依赖的库文件)
Your command:mingetty
/sbin/mingetty
copy /sbin/mingetty finishd.
Continue:useradd
/usr/sbin/useradd
copy lib /lib/libaudit.so.0 finished.
copy /usr/sbin/useradd finishd.
Continue:passwd
/usr/bin/passwd
copy lib /usr/lib/libuser.so.1 finished.
copy lib /lib/libgobject-2.0.so.0 finished.
copy lib /lib/libgmodule-2.0.so.0 finished.
copy lib /lib/libglib-2.0.so.0 finished.
copy lib /usr/lib/libpopt.so.0 finished.
copy lib /lib/libpam_misc.so.0 finished.
copy lib /lib/libpam.so.0 finished.
copy /usr/bin/passwd finishd.
Continue:userdel
/usr/sbin/userdel
copy /usr/sbin/userdel finishd.
Continue:usermod
/usr/sbin/usermod
copy /usr/sbin/usermod finishd.
Continue:groupadd
/usr/sbin/groupadd
copy /usr/sbin/groupadd finishd.
Continue:q
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# vim etc/inittab(编辑etc/inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
提示:将登录终端更换为mingetty;
[root@Smoke sysroot]# cd bin/(切换到bin目录)
[root@Smoke bin]# lftp 172.16.0.1(连接ftp服务器172.16.0.1)
lftp 172.16.0.1:~> cd pub/(切换到pub目录)
lftp 172.16.0.1:/pub> get login(下载login文件)
lftp 172.16.0.1:/pub> bye(退出)
[root@Smoke bin]# ls(查看当前目录文件及子目录)
basename cat chown hostname ls mount ping sh stty touch vi
bash chmod cp login mkdir mv rm sleep sync umount
提示:下载的login文件;
[root@Smoke bin]# chmod +x login(给login文件执行权限)
[root@Smoke bin]# ldd login(查看login命令所依赖的库文件)
linux-gate.so.1 => (0x0069b000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x022f8000)
libm.so.6 => /lib/libm.so.6 (0x00548000)
libc.so.6 => /lib/libc.so.6 (0x003ec000)
/lib/ld-linux.so.2 (0x003cd000)
[root@Smoke bin]# ls ../lib/(查看/lib目录下的库文件)
ld-linux.so.2 libcrypt.so.1 libgmodule-2.0.so.0 libnss_files.so.2 libresolv.so.2 libutil.so.1
libacl.so.1 libc.so.6 libgobject-2.0.so.0 libpam_misc.so.0 librt.so.1 libuuid.so.1
libattr.so.1 libdevmapper.so.1.02 libm.so.6 libpam.so.0 libselinux.so.1 modules
libaudit.so.0 libdl.so.2 libnsl.so.1 libproc-3.2.7.so libsepol.so.1
libblkid.so.1 libglib-2.0.so.0 libnss_files-2.5.so libpthread.so.0 libtermcap.so.2
提示:确保login命令所依赖的库文件/lib目录都存在;
[root@Smoke bin]# sync(同步磁盘写入)
[root@Smoke bin]# sync(同步磁盘写入)
[root@Smoke bin]# sync(同步磁盘写入)
[root@Smoke bin]# chroot /mnt/sysroot/(切换根文件系统到/mnt/sysroot目录)
bash-3.2# login(认证)
Smoke.com login: root(用户)
Password: (密码)
-bash-3.2# exit(退出)
logout
bash-3.2# exit(再退出)
exit
[root@Smoke bin]# sync(同步磁盘写入)
[root@Smoke bin]# sync(同步磁盘写入)
[root@Smoke bin]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
文件系统坏掉,测试失败;
文件系统修复:
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.7.gz(查找当前目录所有文件通过管道送给cpio打包,-H
指定备份时使用的文件格式,newc指定cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够
支持多余512200个文件,默认情况下cpio归档支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quiet表示静默模式,不输出信
息,-o表示创建归档文件,将结果通过管道送给gzip,-9指定压缩级别,保存/root目录叫sysroot.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke sysroot]# cd(切换到/root家目录)
[root@Smoke ~]# fuser -km /mnt/sysroot/(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
[root@Smoke ~]# umount /mnt/sysroot/(卸载/mntsysroot目录挂载的文件系统)
[root@Smoke ~]# mke2fs -j /dev/hda2(格式化/dev/hda2文件系统,-j格式化ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 38 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@Smoke ~]# mount /dev/hda2 /mnt/sysroot/(挂载/dev/hda2文件系统到/mnt/sysroot目录)
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# zcat /root/sysroot.7.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
26283 blocks
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
测试成功,可以使用root帐号和它的密码登录,可以通过CTRL+ALT+F1或CTRL+ALT+F2切换终端,但是登录以后成-bash-3.2#,因为/root家目录权限不对,还有它还缺乏PS1环境变量;
-bash-3.2# cd /root(切换到/root家目录) -bash-3.2# vi .bash_profile(编辑.bash_profile文件) PS1='[\u@\h \W]\$' 提示:声明PS1环境变量;
测试:退出,测试登录;

[root@minlinux ~]# cd /root [root@minlinux ~]# vi .bash_profile PS1='[\u@\h \W]\$' export PS1 提示:PS1用来定义用户命令提示符前面的提示信息的,\u表示替换为用户名,\h表示主机名,\W大写W表示工作目录,而且是工作目录的基名,\w小写w表示全名,
关机测试:
正常关机;

修复文件系统:
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.7.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定备份
时使用的文件格式,newc指定cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多余512200
个文件,默认情况下cpio归档支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quiet表示静默模式,不输出信息,-o表示创建归档文件,
将结果通过管道送给gzip,-9指定压缩级别,保存/root目录叫sysroot.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke sysroot]# cd(切换到/root家目录)
[root@Smoke ~]# fuser -km /mnt/sysroot/(终止正在访问此挂载点的所有进程,会连访问用户的bash都踢出)
[root@Smoke ~]# umount /mnt/sysroot/(卸载/mntsysroot目录挂载的文件系统)
[root@Smoke ~]# mke2fs -j /dev/hda2(格式化/dev/hda2文件系统,-j格式化ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 38 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@Smoke ~]# mount /dev/hda2 /mnt/sysroot/(挂载/dev/hda2文件系统到/mnt/sysroot目录)
[root@Smoke ~]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# zcat /root/sysroot.7.gz | cpio -id(不解压sysroot.gz文件查看内容将结果通过管道送给cpio展开到当前目录)
26283 blocks
[root@Smoke sysroot]# chmod -R og=--- root/(修改root/目录权限,其他和组为什么权限都没有,-R递归修改)
[root@Smoke sysroot]# ll(查看当前目录文件及子目录)
total 44
drwxr-xr-x 2 root root 1024 Dec 3 13:14 bin
drwxr-xr-x 2 root root 1024 Dec 3 13:14 boot
drwxr-xr-x 2 root root 1024 Dec 3 13:14 dev
drwxr-xr-x 4 root root 1024 Dec 3 13:14 etc
drwxr-xr-x 2 root root 1024 Dec 3 13:14 home
drwxr-xr-x 3 root root 1024 Dec 3 13:14 lib
drwx------ 2 root root 12288 Dec 3 13:13 lost+found
drwxr-xr-x 2 root root 1024 Dec 3 13:14 media
drwxr-xr-x 2 root root 1024 Dec 3 13:14 mnt
drwxr-xr-x 2 root root 1024 Dec 3 13:14 opt
drwxr-xr-x 2 root root 1024 Dec 3 13:14 proc
drwx------ 2 root root 1024 Dec 3 13:14 root
drwxr-xr-x 2 root root 1024 Dec 3 13:14 sbin
drwxr-xr-x 2 root root 1024 Dec 3 13:14 sys
drwxr-xr-x 2 root root 1024 Dec 3 13:14 tmp
drwxr-xr-x 6 root root 1024 Dec 3 13:14 usr
drwxr-xr-x 6 root root 1024 Dec 3 13:14 var
提示:查看修改的/root目录权限;
[root@Smoke sysroot]# vim root/.bash_profile(编辑.bash_profile文件)
PS1='[\u@\h \W]\$'
export PS1
提示:给root用户提供配置文件,$管理员显示为#号,普通用户显示为$符号,或者可以通过复制/etc/skel目录下的所有文件到用户家目录,提供用户的环境变量配置文件;
提供单用户模式:
[root@Smoke sysroot]# vim etc/inittab(编辑etc/inittab文件)
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
提示:提供1级别要执行;
[root@Smoke sysroot]# ls etc/rc.d/init.d/(查看etc/rc.d/init.d目录下文件及子目录)
functions halt network tserver
[root@Smoke sysroot]# cd etc/rc.d/(切换到etc/rc.d目录)
[root@Smoke rc.d]# mkdir rc1.d(创建rc1.d目录)
[root@Smoke rc.d]# cd rc1.d/(切换到rc1.d目录)
[root@Smoke rc1.d]# ln -sv ../init.d/network K90network(创建软连接,并显示创建过程,创建为K90network)
create symbolic link `K90network' to `../init.d/network'
提示:K90network中的K代表停止,90代表停止次序;
[root@Smoke rc1.d]# ln -sv ../init.d/tserver K33tserver(给../init.d/tserver文件创建软连接,并显示创建过程,创建为K33tserver)
create symbolic link `K33tserver' to `../init.d/tserver'
提示:K33tserver中的K代表停止,33代表停止次序;
[root@Smoke rc1.d]# ll(查看当前目录文件及子目录)
total 2
lrwxrwxrwx 1 root root 17 Dec 3 13:38 K33tserver -> ../init.d/tserver
lrwxrwxrwx 1 root root 17 Dec 3 13:38 K90network -> ../init.d/network
提示:创建的好的服务链接;
[root@Smoke rc1.d]# cd ..(切换到上级目录)
[root@Smoke rc.d]# ls(查看当前目录文件及子目录)
init.d rc rc0.d rc1.d rc3.d rc6.d rc.sysinit
[root@Smoke rc.d]# man init(查看init命令的man帮助文档)
SYNOPSIS
/sbin/init [ -a ] [ -s ] [ -b ] [ -z xxx ] [ 0123456Ss ]:/sbin/init后面跟上S、s、1都表示单用户模式,
/sbin/telinit [ -t sec ] [ 0123456sSQqabcUu ]:-t指定秒钟,停顿几秒钟再设定也行;
[root@Smoke rc.d]# less /etc/init.d/single(查看宿主机/etc/init.d/single文件)
#!/bin/bash
#
#
# rc.single This file is executed by init when it goes into runlevel
# 1, which is the administrative state. It kills all
# deamons and then puts the system into single user mode.
# Note that the file systems are kept mounted.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Damien Neil
#
. /etc/init.d/functions
if [ "$1" != "start" ]; then
exit 0
fi
# this looks nicer
[ -x /usr/bin/clear ] && /usr/bin/clear
# Now go to the single user level.
echo $"Telling INIT to go to single user mode."
exec init -t1 S
[root@Smoke rc.d]# cd ..(切换到上级目录)
[root@Smoke etc]# vim rc.d/init.d/single(编辑single文件)
#!/bin/bash
#
# chkconfig:
# description:
#
case $1 in
start)
;;
*)
echo "Usage:single start"
;;
esac
exec /sbin/init S(让exec命令启动init名而且直接替换原有的bash进程,执行完退出终端)
提示:编辑单用户脚本;
[root@Smoke etc]# chmod +x rc.d/init.d/single(给single文件执行权限)
[root@Smoke rc1.d]# ln -sv ../init.d/single S98single(给../init.d/single文件创建软连接,并显示创建过程叫S98single)
create symbolic link `S98single' to `../init.d/single'
提示:S98single,S代表启动,启动次序为98;
[root@Smoke rc1.d]# ll(查看当前目录文件及子目录详细信息)
total 3
lrwxrwxrwx 1 root root 17 Dec 3 13:38 K33tserver -> ../init.d/tserver
lrwxrwxrwx 1 root root 17 Dec 3 13:38 K90network -> ../init.d/network
lrwxrwxrwx 1 root root 16 Dec 3 13:59 S98single -> ../init.d/single
[root@Smoke sysroot]# find . | cpio -H newc --quiet -o | gzip > /root/sysroot.8.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定备份
时使用的文件格式,newc指定cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多余512200
个文件,默认情况下cpio归档支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quiet表示静默模式,不输出信息,-o表示创建归档文件,
将结果通过管道送给gzip,-9指定压缩级别,保存/root目录叫sysroot.gz)
提示:备份/mnt/sysroot下面的所有文件到/root目录;
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,切换到小Linux系统;
切换到6级别,让系统重启;

自动重启;

敲e键;

再敲e键,在grub edit > kernel /vmlinuz ro root=/dev/hda2 quiet后面输入空格1,然后点击回车,切换到级别1;

敲b键引导,不需要输入密码,通过passwd更改用户密码,再通过init 3切换到级别3;

BUSYBOX:
官方网站 http://www.busybox.net/
内核编译:
busybox: 通过二进制程序busybox模拟许许多多的命令;
编译安装完成之后能够在/bin目录下,生成一个busybox的二进制程序,其他文件都是它的符号链接,它能模拟几乎上百个常见命令,还能模拟几个shell,如ash、hush等等,在/sbin目录下也会模拟众多的其他命令,但是它却很小,只有1.6M,因此在一些存储设备容量非常小的环境当中,比如智能手机,安卓智能手机的背后其实就是内核加busybox来进行工作的,只不过没有给root,也看不到busybox,也登录不进去,但是这些命令都有,要想往自己手机灌一个系统,完全通过这种方式可以实现,自己交叉编译一个内核,导进手机里面,编译一个busybox导进手机里面,可以让手机当作linux来工作,甚至可以在里面提供一个服务器,如果说能够在收集提供一块网卡,插根网线的话,在网上就能照常工作起来;只要手机能够被正常驱动,完全可以在当前主机上编译内核,当然要交叉编译,看手机是什么硬件,主板的类型,各种接口类型,把那些驱动都能够编译进去,事实上这些操作在手机上也都能够实现,安卓手机就是一个kernel加一个busybox,在busybox基础上让它启动java虚拟机,在java虚拟机上所运行的安卓系统本身就是个java程序而已;
树莓派:以太网接口,可以在里面装linux内核,装一个busybox当服务器,插上网线照样能工作起来;
由此可以有了kernel加上busybox就能够完全模拟出来一个基本上属于功能比较齐备的操作系统了;
busybox就是ROOTFS(根文件系统),它完全能够提供一个模拟的根文件系统,这个根文件系统能够提供我们的包括init程序,包括其他你所需要的一切程序;
内核要想装载根文件系统有时候还依赖initrd(ramdisk),此前我们是把系统上原有的解压开,在里面修改后再封装起来,其实ramdisk里面无非也就是一个完整意义上的小系统而已,这个小系统的目的主要是装载内核所需要的额外模块,它没有额外的其它功能,事实上这一切功能完全可以使用busybox来实现的,在debian或ubuntu的系统上它们用的不是像红帽一样,用了叫nash来完成的,它其实用的就是busybox;
如果我们有kernel,编译好一个busybox,把这个busybox做成initrd,完全可以来使用,再加上一个busybox来做真正的根文件系统,完全可以实现,有两个busybox,一个用作initrd,一个用作真正的根文件系统,busybox提供了ash、hash,但是没有bash,如果想要用bash,可以把bash移植过来照样可以跑起来,也就意味着在busybox的基础上,虽然它很小,很有可能不够用,如果不够用,完全可以给它在这个基础上给它移植其他的busybox没有提供的命令经来,也能够完全工作起来,所以接下来过程,可以依赖当前系统所提供的内核,在加上手动编译的busybox,再使用busybox制作一个根文件系统,完全可以制作起来一个比以前制作的体积更小的,但命令更完善的Linux出来,但是到这部位置,这个内核依然是红帽提供给我们的编号好的,我们也完全可以自己手动编译一个内核出来,给它定制出来各种属性,把不需要的功能统统给它移除,把需要的功能直接给它做进内核,甚至不需要任何额外的模块,也能够跑起来;
Kernel+ROOTFS()
kernel+initrd(ramdisk)
kernel+
busybox-->initrd
kernel+initrd(busybox)-->rootfs(busybox)
kenrel
RHEL5.8 + busybox(initrd) + rootfs(busybox)
查看本机硬件设备信息:
1、cat /proc/cpuinfo:查看cpu类型;
2、lsusb:查看usb类型
3、lspci:查看pci总线设备类型
4、hal-device:查看硬件更详细的信息
Hardware Abstract Layer:硬件抽象层
把每一个硬件信息统计下来,下次编译内核的时候,就可以照着需求选择硬件驱动;
驱动的编译方式:
做进内核:装载速度比较快,会使内核体积增大,永不着也得放进内存运行
做成模块:
所以根据需要选择,一般来讲核心硬件,比如硬盘最好做进内核,而像网卡这样的设备驱动最好做成模块,至少能够把IDE驱动做进内核,SCSI做成模块,因为SCSI比较大一点,LVM更要做成模块,核心文件系统ext2要做进内核,ext3、ext4、reiserfs可以做成模块;
编译内核:
1、配置
make menuconfig:字符界面
make gconfig
make kconfig
make oldconfig:根据当前系统所用到的版本来进行编译,在红帽系统不支持,在debian支持,依赖于/proc/config.gz文件,红帽不提供,需要复制/boot下.config配置文件;
make config:遍历,所有都会进行提问选择;
保存为.config
2、
make:将会编译整个内核,选的模块,还有核心等等;
make modules_install:安装模块
make install
make modules_install模块安装位置:/lib/modules/KERNEL_VERSION/
这种编译方式,make将会编译整个内核,选的模块,还有核心等等,统统都会编译,但有些时候只需要编译内核的一部分,比如只编译内核不编译模块,或只编译某个模块不编译核心了,内核已经编译好了,突然发现make menuconfig忘了选择某一个模块,我又把它重新选上,现在又想编译那个模块,要从头编译这个内核比较麻烦,完全可以实现只编译一个模块,也可以实现只编译某个子目录下的所有模块,都可以实现;
如何实现部分编译:
1、只编译某子目录下的相关代码:
make dir/:dir代表指定目录下的内容;
make arch/:跟硬件平台相关的内核核心,除了模块以外的所有内容,不包括模块的内核核心,注意:编译核心它也会编译模块,因为那些模块选了,那些模块不选,内核支持那些模块,需要让内核知道,它也会遍历一遍所有的模块的,遍历模块可能不会编译,可能也不会安装;
make drivers/net/:只编译跟网络相关的驱动程序,make drivers只编译驱动,编译完没办法哪来直接用,会编译成ko文件或者编译成.o文件;
2、只编译部分模块
make M=drivers/net/:只编译部分模块,M代表模块,把net目录下的所有功能都编译成q模块,这些q模块拿来可以直接使用,M不写也可以用,大多数场景下;
3、只编译某一模块
make drivers/net/pcnet32.ko:只编译pcnet32.ko模块,指定那个模块在什么地方;
4、将编译完成的结果放置于别的目录中
make O=/tmp/kernel:默认放到当前目录,O=/tmp/kernel编译好的内容放到/tmp/kernel目录下;
5、交叉编译
make ARCH=:
如何编译busybox:
make menuconfig:配置busybox
make install:编译安装
IDE:
/dev/hda1: ext3 /boot
/dev/hda2: ext3 /
在当前系统做一个程序,编译出来以后,这个程序要运行依赖于很多库文件,这就意味着移植这个命令过去,同时要抑制它相关的库文件以后才能正常运行,比如移植bash,移植init,都要使用ldd判定它依赖那些库,这是因为我们使用的是动态链接的方式去编译程序,事实上也完全可以实现将它所依赖的库直接编译进这个程序,这样会导致程序体积变大,但有一个好处程序拿到那里都能够运行,因为它所依赖的库都直接做进它本身了,编译busybox的时候,为了能让busybox它的移植过程尽可能简化,我们就直接编译busybox的时候,把它编译成静态的方式,不做动态链接了,直接把它所依赖的所有库做进busybox;
busybox最新版本:
20 January 2014 -- BusyBox 1.22.1 (stable):稳定版
23 December 2014 -- BusyBox 1.23.0 (unstable):开发版,非稳定版
IDE:
/dev/hda1: ext3 /boot
/dev/hda2: ext3 /
需要在hda1上安装GRUB,安装GRUB的第二阶段,提供grub.conf配置文件,提供内核,提供initrd文件,initrd文件由我们自己建立,内核复制系统的;
小Linux制作过程:
在现有linux虚拟机增加一块20G的IDE硬盘,为系统上的新硬盘建立分区,这里根据需要先建立一个大小为100M的主分区作为新建系统的boot分区和一个512M的分区作为目标系统(即正在构建的新系统,后面将沿用此名称)的根分区;100M的分区格式化后将其挂载至/mnt/boot目录下;512M的分区格式化后将挂载至/mnt/sysroot目录;
[root@localhost ~]# fdisk -l(查看系统上磁盘及分区情况)
Disk /dev/hda: 21.4 GB, 21474836480 bytes
15 heads, 63 sectors/track, 44384 cylinders
Units = cylinders of 945 * 512 = 483840 bytes
Disk /dev/hda doesn't contain a valid partition table
Disk /dev/sda: 53.6 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 13 104391 83 Linux
/dev/sda2 14 2624 20972857+ 83 Linux
/dev/sda3 2625 2755 1052257+ 82 Linux swap / Solaris
[root@localhost ~]# fdisk /dev/hda(管理磁盘分区,进入交互式模式)
The number of cylinders for this disk is set to 44384.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): n(创建分区)
Command action
e extended
p primary partition (1-4)
p(主分区)
Partition number (1-4): 1(分区号)
First cylinder (1-44384, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-44384, default 44384): +100M(创建100M分区)
Command (m for help): n(创建分区)
Command action
e extended
p primary partition (1-4)
p(驻俄分区)
Partition number (1-4): 2(分区号)
First cylinder (209-44384, default 209):
Using default value 209
Last cylinder or +size or +sizeM or +sizeK (209-44384, default 44384): +512M(创建512M分区)
Command (m for help): w(保存退出)
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@localhost ~]# partprobe /dev/hda(让内核重新扫描分区表)
[root@localhost ~]# fdisk -l /dev/hda(查看/dev/hda分区情况)
Disk /dev/hda: 21.4 GB, 21474836480 bytes
15 heads, 63 sectors/track, 44384 cylinders
Units = cylinders of 945 * 512 = 483840 bytes
Device Boot Start End Blocks Id System
/dev/hda1 1 208 98248+ 83 Linux
/dev/hda2 209 1267 500377+ 83 Linux
[root@localhost ~]# mke2fs -j /dev/hda1(将/dev/hda1创建为带日志的文件系统,即ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
24576 inodes, 98248 blocks
4912 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
12 block groups
8192 blocks per group, 8192 fragments per group
2048 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost ~]# mke2fs -j /dev/hda2(将/dev/hda2创建为带日志的文件系统,即ext3文件系统)
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
125488 inodes, 500376 blocks
25018 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
62 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 35 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost ~]# mkdir /mnt/{boot,sysroot}(创建/mnt/boot目录和/mnt/sysroot目录,花括号{}展开)
[root@localhost ~]# mount /dev/hda1 /mnt/boot/(将/dev/hda1挂载到/mnt/boot/目录)
[root@localhost ~]# mount /dev/hda2 /mnt/sysroot/(将/dev/hda2挂载到/mnt/boot/目录)
[root@localhost ~]# mount(查看系统所有挂载的文件系统)
/dev/sda2 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/hda1 on /mnt/boot type ext3 (rw)
/dev/hda2 on /mnt/sysroot type ext3 (rw)
[root@Smoke bin]# lsusb(列出本机USB属性信息)
Protocol spec without prior Class and Subclass spec at line 4297
Bus 001 Device 001: ID 0000:0000
Bus 002 Device 013: ID 0e0f:0008 VMware, Inc.
Bus 002 Device 001: ID 0000:0000
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
[root@Smoke bin]# lspci(查看所有pci总线类型)
00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)(桥设备)
00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)(VGA设备,显卡类型)
00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 08)(ISA接口)
00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)(IDE接口)
00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)(ACPI)
00:07.7 System peripheral: VMware Virtual Machine Communication Interface (rev 10)
00:0f.0 VGA compatible controller: VMware SVGA II Adapter(SVGA显示接口,模拟)
00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)(SCSI口,vmware模拟的
SCSI控制器)
00:11.0 PCI bridge: VMware PCI bridge (rev 02)
00:15.0 PCI bridge: VMware PCI Express Root Port (rev 01)(vmware模拟的各种PCI)
00:15.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.7 PCI bridge: VMware PCI Express Root Port (rev 01)
02:00.0 USB controller: VMware USB1.1 UHCI Controller(USB1.1控制器,UHCI)
02:01.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)(网卡,AMD,PCnet32)
02:02.0 Multimedia audio controller: Ensoniq ES1371 [AudioPCI-97] (rev 02)(声卡,PCI-97)
02:03.0 USB controller: VMware USB2 EHCI Controller(USB2,EHCI)
02:05.0 SATA controller: VMware Device 07e0
02:06.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)
[root@Smoke bin]# hal-device | head -10(查看硬件更详细信息,只显示前10行)
0: udi = '/org/freedesktop/Hal/devices/usb_device_e0f_8_000650268328_usbraw'(设备类型)
info.udi = '/org/freedesktop/Hal/devices/usb_device_e0f_8_000650268328_usbraw' (string)(设备名称)
linux.device_file = '/dev/bus/usb/002/013' (string)
linux.subsystem = 'usb_device' (string)
linux.hotplug_type = 2 (0x2) (int)
usbraw.device = '/dev/bus/usb/002/013' (string)
info.product = 'USB Raw Device Access' (string)
info.capabilities = { 'usbraw' } (string list)
info.category = 'usbraw' (string)
info.parent = '/org/freedesktop/Hal/devices/usb_device_e0f_8_000650268328' (string)
下载busybox:
[root@Smoke ~]# lftp 172.16.0.1(连接ftp服务器)
lftp 172.16.0.1:~> cd pub/Sources/busybox/
lftp 172.16.0.1:/pub/Sources/Busybox> get busybox-1.20.2.tar.bz2(下载busybox)
2186738
lftp 172.16.0.1:/pub/Sources/Busybox> bye(退出)
[root@Smoke ~]# ls(查看当前目录文件及子目录)
anaconda-ks.cfg Desktop install.log.syslog sysroot.2.gz sysroot.7.gz sysroot.mage.8.gz
bincopy.sh initrd-2.6.18-308.el5.img libnss_files-2.5.so sysroot.3.gz sysroot.8.gz test
busybox-1.20.2.tar.bz2 install.log mage_sysroot sysroot.6.gz sysroot.gz
提示:下载的busybox-1.20.2.tar.bz2稳定版;
[root@Smoke ~]# yum groupinstall -y "Development Tools" "Development Libraries" (安装开发工具和开发库)
[root@Smoke ~]# tar xf busybox-1.20.2.tar.bz2(解压busybox,x展开,f后面跟文件,并调用bzip2解压)
[root@Smoke ~]# cd busybox-1.20.2(切换到busybox)
[root@Smoke busybox-1.20.2]# make menuconfig(编译)
提示:busybox编译过程,跟内核一样,需要先执行make menuconfig,因为它有很多功能需要让选择,一个一个进行选择太麻烦,所以它提供了一个目录;

选择Coreutils(核心模块),点击回车键,它会模拟很多命令,比如cat、date、basename、id,那些命令想模拟都可以进行选择,默认基本上就够用了;

双击ESC,返回上级菜单,选择Busybox Settings,点击回车键;

选择Build Options(编译选项),点击回车键;

选择Build BusyBox as a static binary (no shared libs) (NEW)(静态二进制程序),通过空格选择上;

其他功能都不用动了,通过双击ESC返回上级菜单,选择Installation Options ("make install" behavior)(使用make install安装到那里),点击回车;

当执行make install安装到busybox自己当前目录下创建一个以_install的目录,我们最终期望安装到/mnt/sysroot目录下,安装到./_install也可以,先不进行修改;

返回到主菜单,双击ESC,选择Yes保存退出;

busybox已经配置好了,接下来编译busybox:
[root@Smoke busybox-1.20.2]# make install(编译安装)
提示:这里可能会报错,因为最新版本的busybox依赖于更新的内核头文件,我们现在内核是2.6.18的,2.6.18当中不具备新版busybox所提供的某些功能,所以编译过程中很可能
会出错,如果出错就需要下载一个更新版本的内核,比如2.6.28以上的更新的版本,我们这里使用linux-2.6.38.5.tar.bz2的版本;
[root@Smoke ~]# ls(查看当前目录文件及子目录)
anaconda-ks.cfg initrd-2.6.18-308.el5.img mage_sysroot sysroot.8.gz
bincopy.sh install.log sysroot.2.gz sysroot.gz
busybox-1.20.2 install.log.syslog sysroot.3.gz sysroot.mage.8.gz
busybox-1.20.2.tar.bz2 libnss_files-2.5.so sysroot.6.gz test
Desktop linux-2.6.38.5.tar.bz2 sysroot.7.gz
提示:下载的linux-2.6.38.5.tar.bz2内核文件;
[root@Smoke ~]# tar xf linux-2.6.38.5.tar.bz2 -C /usr/src/(解压linux-2.6.35.5.tar.bz2文件,-C改变解压目录到/usr/src)
[root@Smoke ~]# cd /usr/src/(切换到/usr/src目录)
[root@Smoke src]# ls(查看当前目录文件及子目录)
debug kernels linux-2.6.38.5 redhat
提示:解压后的linux-2.6.38.5内核;
[root@Smoke src]# cd linux-2.6.38.5/(切换到/linux-2.6.38.5)
提示:我们需要这个目录里面有个头文件,在这个目录当中有一个叫include目录;
[root@Smoke linux-2.6.38.5]# cd include/(切换到include目录)
提示:在include目录下有各叫mtd目录;
[root@Smoke include]# cd mtd/(切换到mtd目录)
[root@Smoke mtd]# ls
inftl-user.h Kbuild mtd-abi.h mtd-user.h nftl-user.h ubi-user.h
提示:这里面有个文件叫做ubi-user.h,就需要这一个文件就不会报错,需要把这个文件复制过滤,复制到busybox的源码目录下;
[root@Smoke mtd]# cd /root/busybox-1.20.2(切换到/busybox-1.20.2目录)
[root@Smoke busybox-1.20.2]# ls(查看当前目录文件及子目录)
applets configs editors libbb Makefile.custom printutils shell
applets_sh console-tools examples libpwdgrp Makefile.flags procps sysklogd
arch coreutils findutils LICENSE Makefile.help README testsuite
archival debianutils include loginutils miscutils runit TODO
AUTHORS docs init mailutils modutils scripts TODO_unicode
Config.in e2fsprogs INSTALL Makefile networking selinux util-linux
提示:在busybox目录下也有一个叫include目录;
[root@Smoke busybox-1.20.2]# cd include/(切换到include目录)
[root@Smoke include]# mkdir mtd(创建目录mtd)
[root@Smoke include]# cp /usr/src/linux-2.6.38.5/include/mtd/ubi-user.h mtd/(复制ubi-user.h文件到当前目录下的mtd目录)
提示:把内核目录中的ubi-user.h复制过来;
[root@Smoke include]# cd ..(切换到上级目录)
提示:回到busybox源码目录;
[root@Smoke busybox-1.20.2]# make install(编译安装)
[root@Smoke busybox-1.20.2]# ls(查看当前目录文件及子目录)
applets Config.in include Makefile.custom scripts
applets_sh configs init Makefile.flags selinux
arch console-tools _install Makefile.help shell
archival coreutils INSTALL miscutils sysklogd
AUTHORS debianutils libbb modutils testsuite
busybox docs libpwdgrp networking TODO
busybox.links e2fsprogs LICENSE printutils TODO_unicode
busybox_unstripped editors loginutils procps util-linux
busybox_unstripped.map examples mailutils README
busybox_unstripped.out findutils Makefile runit
提示:安装完成之后,它会在当前目录下创建一个_install目录,所有安装好的文件都在这里面,我们以它为蓝本,开始创建一些我们所需要的功能,第一需要以它来创建initrd
文件,第二需要用它来创建真正的根文件系统,用它创建initrd文件,我们给它一个临时目录;
[root@Smoke busybox-1.20.2]# cp -a _install/ /tmp/busybox(复制_install目录到/tmp较busybox,-a归档复制,保留文件原来的所有的属性)
[root@Smoke busybox-1.20.2]# cd /tmp/busybox/(切换到/tmp/busybox目录)
[root@Smoke busybox]# ls(查看当前目录文件及子目录)
bin linuxrc sbin usr
[root@Smoke busybox]# rm linuxrc(删除linuxrc文件)
rm: remove symbolic link `linuxrc'? y
提示:linuxrc是/bin/busybox二进制程序链接文件,我们用不着;
[root@Smoke busybox]# ls(查看当前目录文件及子目录)
bin sbin usr
提示:这里我们需要的很多目录/proc、/sys都没有,需要手动创建;
[root@Smoke busybox]# mkdir -pv proc sys etc dev sysroot lib/modules tmp(创建sys、etc、dev、sysroot、lib/modules、tmp目录,并显示创建过程,
递归创建)
mkdir: created directory `proc'
mkdir: created directory `sys'
mkdir: created directory `etc'
mkdir: created directory `dev'
mkdir: created directory `sysroot'
mkdir: created directory `lib'
mkdir: created directory `lib/modules'
mkdir: created directory `tmp'
[root@Smoke busybox]# ls(查看当前目录文件及子目录)
bin dev etc lib proc sbin sys sysroot usr tmp
提示:我们打算使用红帽提供的内核,但是这个内核不支持ext3文件系统,怎么办?内核不支持ext3,意味着它没法访问真正的根文件系统,因此我们这个initrd需要给它提供,
initrd本来的主要存在目的就是为内核提供所需要依赖访问的根文件系统所依赖的模块,因此需要借助于initrd(busybox)装载ext3模块;
提供ext3文件系统模块:
[root@Smoke busybox]# modinfo ext3(查看ext3文件系统模块信息)
filename: /lib/modules/2.6.18-308.el5/kernel/fs/ext3/ext3.ko
license: GPL
description: Second Extended Filesystem with journaling extensions
author: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others
srcversion: 26DC008FC415305C5F65313
depends: jbd
vermagic: 2.6.18-308.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
module_sig: 883f3504f2326dddc995cc0b59af121112b66609f56f4d643dcbbde3384fc7aee2342f5b331f631b09d15ace08361a0e2dfa6ec1ec46718
b122bde923
提示:ext3文件系统依赖于jbd;
[root@Smoke busybox]# modinfo jbd(查看jbd模块信息)
filename: /lib/modules/2.6.18-308.el5/kernel/fs/jbd/jbd.ko
license: GPL
srcversion: 11842879E04FE2392B988CC
depends:
vermagic: 2.6.18-308.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
module_sig: 883f3504f2326dcdc995cc0b59af121112a9509d1d376cb3f07503612b0236e17947cc804b2e6909e3d31e223c8ae8dc3083a2d932d532
9bef38115a
提示:jbd不依赖任何模块;
[root@Smoke busybox]# cp /lib/modules/2.6.18-308.el5/kernel/fs/jbd/jbd.ko lib/modules/(复制jbd.ko模块到lib/modules目录)
[root@Smoke busybox]# cp /lib/modules/2.6.18-308.el5/kernel/fs/ext3/ext3.ko lib/modules/(复制ext3.ko模块到lib/modules目录)
提示init脚本:
[root@Smoke busybox]# vim init(编辑init文件)
#!/bin/sh
#
mount -t proc proc /proc(挂载proc文件系统)
mount -t sysfs sysfs /sys(挂载sysfs文件系统)
insmod /lib/modules/jbd.ko(装载模块ext3文件系统模块)
insmod /lib/modules/ext3.ko
mdev -s (扫描/sys和/dev/目录获取所有额外的硬件设备)
mount -t ext3 /dev/hda2 /mnt/sysroot(挂载根文件系统)
exec switch_root /mnt/sysroot /sbin/init(执行切换真正的根/mnt/sysroot到/sbin/init)
提示:它没有bash,也没有nash,但它有个sh,这是个链接指向hush的,有时候我们可能需要系统来探测额外的其他硬件,并触发这些硬件设备,在红帽系统上有个较udev,
而busybox给我们提供命令叫做mdev;
[root@Smoke busybox]# ls sbin/(查看sbin目录下的文件及子目录)
acpid fdisk ifconfig losetup mkfs.vfat rmmod switch_root
adjtimex findfs ifdown lsmod mkswap route sysctl
arp freeramdisk ifenslave makedevs modinfo runlevel syslogd
blkid fsck ifup man modprobe setconsole tunctl
blockdev fsck.minix init mdev nameif slattach udhcpc
bootchartd getty insmod mkdosfs pivot_root start-stop-daemon vconfig
depmod halt klogd mke2fs poweroff sulogin watchdog
devmem hdparm loadkmap mkfs.ext2 raidautorun swapoff zcip
fbsplash hwclock logread mkfs.minix reboot swapon
提示:sbin/mdev是busybox提供的探测额外硬件设备的命令;
[root@Smoke busybox]# sbin/mdev(执行sbin/mdev程序)
BusyBox v1.20.2 (2014-12-04 11:06:54 CST) multi-call binary.
Usage: mdev [-s]
mdev -s is to be run during boot to scan /sys and populate /dev.(mdev -s就能够扫描/sys目录和/dev目录获取所有的硬件设备)
Bare mdev is a kernel hotplug helper. To activate it:
echo /sbin/mdev >/proc/sys/kernel/hotplug
It uses /etc/mdev.conf with lines
[-]DEVNAME UID:GID PERM [>|=PATH]|[!] [@|$|*PROG]
where DEVNAME is device name regex, @major,minor[-minor2], or
environment variable regex. A common use of the latter is
to load modules for hotplugged devices:
$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"
If /dev/mdev.seq file exists, mdev will wait for its value
to match $SEQNUM variable. This prevents plug/unplug races.
To activate this feature, create empty /dev/mdev.seq at boot.
[root@Smoke busybox]# chmod +x init(给init文件执行权限)
[root@Smoke busybox]# mkdir -pv mnt/sysroot(创建mnt/sysroot目录,显示创建过程,递归创建)
mkdir: created directory `mnt'
mkdir: created directory `mnt/sysroot'
[root@Smoke busybox]# ls(查看当前目录文件及子目录)
bin dev etc init lib mnt proc sbin sys sysroot usr
[root@Smoke busybox]# rm -rf sys(删除sys目录强制删除,递归删除)
手动创建dev/console和/dev/null文件:
[root@Smoke busybox]# mknod dev/console c 5 1(创建字符设备文件dev/console,c字符设备,主设备号为5,次设备号为1)
[root@Smoke busybox]# mknod dev/null c 1 3(创建字符设备文件dev/null,c字符设备,主设备号为1,次设备号为3)
[root@Smoke busybox]# tree dev/(查看dev目录树)
dev/
|-- console
`-- null
0 directories, 2 files
[root@Smoke busybox]# find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定
备份时使用的文件格式,newc指定cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多于512200
个文件,默认情况下cpio归档支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quiet表示静默模式,不输出信息,-o表示创建归档文件,将
结果通过管道送给gzip,-9指定压缩级别,保存至/mnt/boot/目录叫initrd.gz;)
[root@Smoke busybox]# ls -lh /mnt/boot/initrd.gz(查看initrd.gz文件详细信息,并做单位换算)
-rw-r--r-- 1 root root 951K Dec 4 13:10 /mnt/boot/initrd.gz
复制内核:
[root@Smoke busybox]# cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz(复制vmlinuz-2.6.18-308.el5到/mnt/boot叫vmlinuz)
安装grub:
[root@Smoke busybox]# grub-install --root-directory=/mnt/ /dev/hda(安装grub,根目录在/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@Smoke busybox]# ls /mnt/boot/(查看/mnt/boot目录文件及子目录)
grub initrd.gz lost+found vmlinuz
提示:安装好的grub;
[root@Smoke busybox]# vim /mnt/boot/grub/grub.conf(编辑grub.conf配置文件)
default=0
timeout=3
title Smoke Linux (2.6.18)
root(hd0,0)
kernel /vmlinuz ro root=/dev/hda2
initrd /initrd.gz
准备真正的根文件系统:
[root@Smoke busybox]# cd(切换到根用户家目录)
[root@Smoke ~]# cd busybox-1.20.2(切换到busybox-1.20.2目录)
[root@Smoke busybox-1.20.2]# cp -a _install/* /mnt/sysroot/(复制_install/*所有文件到/mnt/sysroot目录,-a归档复制,保存文件原来所有的属性)
[root@Smoke busybox-1.20.2]# cd /mnt/sysroot/(切换到/mnt/sysroot目录)
[root@Smoke sysroot]# ls(查看当前目录文件及子目录)
bin linuxrc lost+found sbin usr
[root@Smoke sysroot]# rm linuxrc(删除linuxrc文件)
rm: remove symbolic link `linuxrc'? y
[root@Smoke sysroot]# mkdir -pv proc sys dev tmp var/{log,lock,run} lib/modules etc/rc.d/init.d root boot mnt media(创建proc
sys dev tmp var/{log,lock,run} lib/modules etc/rc.d/init.d root boot mnt media目录,并显示创建过程,递归创建)
mkdir: created directory `proc'
mkdir: created directory `sys'
mkdir: created directory `dev'
mkdir: created directory `tmp'
mkdir: created directory `var'
mkdir: created directory `var/log'
mkdir: created directory `var/lock'
mkdir: created directory `var/run'
mkdir: created directory `lib'
mkdir: created directory `lib/modules'
mkdir: created directory `etc'
mkdir: created directory `etc/rc.d'
mkdir: created directory `etc/rc.d/init.d'
mkdir: created directory `root'
mkdir: created directory `boot'
mkdir: created directory `mnt'
mkdir: created directory `media'
[root@Smoke sysroot]# ls sbin/(查看sbin目录文件及子目录)
acpid devmem getty ifup lsmod mkfs.minix poweroff slattach syslogd
adjtimex fbsplash halt init makedevs mkfs.vfat raidautorun start-stop-daemon tunctl
arp fdisk hdparm insmod man mkswap reboot sulogin udhcpc
blkid findfs hwclock klogd mdev modinfo rmmod swapoff vconfig
blockdev freeramdisk ifconfig loadkmap mkdosfs modprobe route swapon watchdog
bootchartd fsck ifdown logread mke2fs nameif runlevel switch_root zcip
depmod fsck.minix ifenslave losetup mkfs.ext2 pivot_root setconsole sysctl
提供系统运行级别配置文件:
[root@Smoke sysroot]# vim etc/inittab(编辑inittab文件)
::sysinit:/etc/rc.d/rc.sysinit(系统初始化脚本)
console::respawn:-/bin/sh
::ctrlaltdel:/sbin/reboot(ctrl+alt+del重启系统)
::shutdown:/bin/umount -a -r(执行shutdown卸载所有文件系统,-r:若无法成功卸除,则尝试以只读的方式重新挂入文件系统;)
提示:busybox支持的inittab文件格式和红帽的不太一样,不需要设定级别,此时不支持级别概念;
提供fstab配置文件:
[root@Smoke sysroot]# vim etc/fstab(编辑fstab文件)
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
/dev/hda2 / ext3 defaults 1 1
[root@Smoke sysroot]# mknod dev/console c 5 1(创建dev/console设备文件,c字符设备,主设备号5,次设备号1)
[root@Smoke sysroot]# mknod dev/null c 1 3(创建/dev/null设备文件,c字符设备,主设备号1,次设备号3)
提示:主次设备号不能乱改,这是事先注册好的;
提示系统初始化脚本:
[root@Smoke sysroot]# vim etc/rc.d/rc.sysinit(编辑rc.sysinit脚本)
#!/bin/sh
echo -e "\tWelcome to \033[34mSmoke \033[0m Linux"(-e激活转义字符,\t插入tab)
echo -e "Remounting the root filesystem ...........[ \033[32mOK\033[0m ]"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o remount,rw /(重新挂载根文件系统,读写挂载)
echo -e "Creating the files of device .............[ \033[32mOK\033[0m ]"
mdev -s(扫描硬件设备)
echo -e "Mounting the filesystem ..................[ \033[32mOK\033[0m ]"
mount -a
swapon -a(启用交换分区)
[root@Smoke sysroot]# chmod +x !$(给etc/rc.d/rc.sysinit执行权限)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
[root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,开启小Linux系统;
测试失败;

提示:报错,mount:mounting /dev/hda2 on /mnt/sysroot failed: No such file or directory,切换到宿主机查找问题;
[root@Smoke ~]# cd /tmp/busybox/(切换到/tmp/busybox目录) [root@Smoke busybox]# mkdir sys(创建sys目录) [root@Smoke busybox]# ls bin dev etc init lib mnt proc sbin sys sysroot tmp usr [root@Smoke busybox]# rm -rf sysroot(删除sysroot目录) [root@Smoke busybox]# ls(查看当前目录文件及子目录) bin dev etc init lib mnt proc sbin sys tmp usr [root@Smoke busybox]# find . | cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz(查找当前目录所有文件通过管道送给cpio打包,-H指定 备份时使用的文件格式,newc指定cpio归档文件目录结构,把当前目录下每一个文件包括它的子目录整个映射路径统统给它按照原有路径格式进行保存,并且能够支持多于51 2200个文件,默认情况下cpio归档支持的文件个数非常少,newc表示新规范的方式来进行归档,支持更多的文件数量,--quiet表示静默模式,不输出信息,-o表示创建归档 文件,将结果通过管道送给gzip,-9指定压缩级别,保存至/mnt/boot/目录叫initrd.gz; [root@Smoke ~]# sync(同步磁盘写入) [root@Smoke ~]# sync(同步磁盘写入) [root@Smoke ~]# sync(同步磁盘写入)
测试:挂起宿主机,开启小Linux系统;
测试成功;

一步步手动构建小于10M的类嵌入式Linux系统
前提:
1、一个作为宿主机的Linux;本文使用的是Redhat Enterprise Linux 5.8;
2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,为了降低复杂度,这里添加使用一块IDE接口的新硬盘;
3、Linux内核源码,busybox源码;本文使用的是目前最新版的linux-2.6.38.5和busybox-1.20.2。
说明:本文是一个step by step的实做指南;
一、为系统上的新硬盘建立分区,这里根据需要先建立一个大小为100M的主分区作为新建系统的boot分区和一个512M的分区作为目标系统(即正在构建的新系统,后面将沿用此名称)的根分区;100M的分区格式化后将其挂载至/mnt/boot目录下;512M的分区格式化后将挂载至/mnt/sysroot目录;
说明:
1、此处的boot和sysroot的挂载点目录名称尽量不要修改,尤其是boot目录,否则您必须保证后面的许多步骤都做了相应的改动;
2、新建系统的boot目录也可以跟根目录在同一个分区,这种方式比独立分区还要简单些,因此这里将不对此种方法再做出说明;
二、编译内核源代码,为新系统提供一个所需的内核(本例中的源代码包都位于/usr/src目录中)
# cd /usr/src # tar jxvf linux-2.6.38.5.tar.bz2 # ln -sv linux-2.6.38.5 linux # cd linux
然后下载 ftp://172.16.0.1/pub/Sources/kernel/kernel-2.6.38.1-i686.cfg 至当前目录中,并重命名为.config。
# make menuconfig
根据您的实际和规划选择所需要的功能;本实例计划制作一个具有网络的功能的微型linux且不打算使用内核模块,因此,这里选择把本机对应的网卡驱动直接编译进了内核。作者使用的是vmware Workstation虚拟机,所以,所需的网上驱动是pcnet32的,其它的均可按需要进行选择。选择完成后需要保存至当前目录下.config文件中。
# make SUBDIR=arch/ # cp arch/x86/boot/bzImage /mnt/boot # make menuconfig
提示:为了实现后面的功能,请务必将文件系统中的ext3和网卡的驱动程序直接编译进内核;否则,就需要手动装载这些相关文件系统的模块;
三、编译busybox
# cd /usr/src # tar -jxvf busybox-1.20.2.tar.bz2 # cd busybox-1.20.2 # mkdir include/mtd # cp /usr/src/linux/include/mtd/ubi-user.h include/mtd/ # make menuconfig
说明:
1、此处需要选择 Busybox Settings --> Build Options --> Build BusyBox as a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库的静态二进制文件,从而避免了对宿主机的共享库产生依赖;但你也可以不选择此项,而完成编译后把其依赖的共享库复制至目标系统上的/lib目录中即可;这里采用后一种办法。
2、修改安装位置为/mnt/sysroot;方法为:Busybox Settings --> Installation Options --> (./_install) BusyBox installation prefix,修改其值为/mnt/sysroot。
# make install
安装后的文件均位于/mnt/sysroot目录中;但为了创建initrd,并实现让其启动以后将真正的文件系统切换至目标系统分区上的rootfs,您还需要复制一份刚安装在/mnt/sysroot下的busybox至另一个目录,以实现与真正的根文件系统分开制作。我们这里选择使用/mnt/temp目录;
# mkdir -pv /tmp/busybox # cp -r /mnt/sysroot/* /tmp/busybox
四、制作initrd
# cd /tmp/busybox
1、建立rootfs:
# mkdir -pv proc sys etc/init.d tmp dev mnt/sysroot
2、创建两个必要的设备文件:
# mknod dev/console c 5 1 # mknod dev/null c 1 3
3、为initrd制作init程序,此程序的主要任务是实现rootfs的切换,因此,可以以脚本的方式来实现它:
# rm linuxrc # vim init
添加如下内容:
#!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys insmod /lib/modules/jbd.ko insmod /lib/modules/ext3.ko mdev -s mount -t ext3 /dev/hda2 /mnt/sysroot exec switch_root /mnt/sysroot /sbin/init
给此脚本执行权限:
chmod +x init
4、制作initrd
# find . | cpio --quiet -H newc -o | gzip -9 -n > /mnt/boot/initrd.gz
五、建立真正的根文件系统
# cd /mnt/sysroot
1、建立rootfs:
# mkdir -pv proc sys etc/rc.d/init.d tmp dev/pts boot var/log usr/lib
2、创建两个必要的设备文件:
# mknod dev/console c 5 1 # mknod dev/null c 1 3
3、建立系统初始化脚本文件
# vim etc/rc.d/rc.sysinit
添加如下内容:
#!/bin/sh echo -e "\tWelcome to \033[31mMageEdu\033[0m Linux" echo -e "Remounting the root filesystem ..." mount -t proc proc /proc mount -t sysfs sysfs /sys mount -o remount,rw / echo -e "Creating the files of device ..." mdev -s echo -e "Mounting the filesystem ..." mount -a swapon -a echo -e "Starting the log daemon ..." syslogd klogd echo -e "Configuring loopback interface ..." ifconfig lo 127.0.0.1/24 ifconfig eth0 172.16.100.9/16 # END
而后让此脚本具有执行权限:
chmod +x etc/init.d/rc.sysinit
4、配置init及其所需要inittab文件
# cd /mnt/sysroot # rm -f linuxrc
为init进程提供配置文件:
# vim etc/inittab
添加如下内容:
::sysinit:/etc/rc.d/rc.sysinit console::respawn:-/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
5、为系统准备一个"文件系统表"配置文件/etc/fstab
# vim etc/fstab
添加如下内容:
sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 /dev/hda1 /boot ext3 defaults 0 0 /dev/hda2 / ext3 defaults 1 1
6、由于在rc.sysinit文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示于控制台;这将会经常性的打断正在进行的工作,为了避免这种情况,我们这里为日志进程建立配置文件,为其指定将日志发送至/var/log/messages文件;
# vim etc/syslog.conf
添加如下一行:
*.info /var/log/messages
六、好了,至此一个简易的基于内存运行的小系统已经构建出来了,我们接下来为此系统创建所需的引导程序
# grub-install --root-directory=/mnt /dev/hda
说明:此处的/dev/hda为目标系统所在的那块新磁盘;
接下来为grub建立配置文件:
# vim /mnt/boot/grub/grub.conf
添加类似如下内容:
default 0 timeout 3 color light-green/black light-magenta/black title MageEdu Linux (2.6.38.5) root (hd0,0) kernel /bzImage ro root=/dev/hda2 quiet initrd /initrd.gz
接下来将此块硬盘接入一个新的主机(这里使用的是虚拟机),启动一下并测试使用。
七、为新构建的ToyLinux启用虚拟控制台
这个可以通过宿主机来实现,也可以直接启动刚构建成功的小Linux进行配置。我们这里采用通过宿主机的方式(重新启动宿主机):
# cd /mnt/sysroot
将 etc/inittab文件改为如下内容:
::sysinit:/etc/init.d/rc.sysinit tty1::askfirst:/bin/sh tty2::askfirst:/bin/sh tty3::askfirst:/bin/sh tty4::askfirst:/bin/sh tty5::askfirst:/bin/sh tty6::askfirst:/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
好了,接下来就可以测试验正六个虚拟控制台的使用了。
八、尽管上述第七步已经实现了虚拟控制台,但其仍是直接进入系统,且系统没有用户帐号等安全设施,这将不利于系统的安全性。因此,接下来的这步实现为系统添加用户帐号(这里仍然基于宿主机实现)。
1、为目标主机建立passwd帐号文件
# cd /mnt/sysroot # vim etc/passwd
添加如下内容:
root:x:0:0::/root:/bin/sh
而后为root用户创建"家"目录:
# mkdir root
2、为目标主机建立group帐号文件
# vim etc/group
添加如下内容:
root:x:0:
3、为目标主机建立shadow影子口令文件,这里采用直接复制宿主机的shadow文件中关于root口令行的行来实现
# grep "^root" /etc/shadow > etc/shadow
注:等目标主机启动时,root用户的口令也是宿主机的root用户的口令。您可以在目标主机启动以后再动手更改root用户的口令。
4、将 etc/inittab文件改为如下内容:
::sysinit:/etc/init.d/rc.sysinit ::respawn:/sbin/getty 9600 tty1 ::respawn:/sbin/getty 9600 tty2 ::respawn:/sbin/getty 9600 tty3 ::respawn:/sbin/getty 9600 tty4 ::respawn:/sbin/getty 9600 tty5 ::respawn:/sbin/getty 9600 tty6 ::shutdown:/bin/umount -a -r ::ctrlaltdel:/sbin/reboot
好了,接下来就可以重新启动目标主机进行验正了。
九、在系统登录时提供banner信息
这个可以通过宿主机来实现,也可以直接在目标主机上进行配置。这里采用直接在目标主机上配置的方式:
# vi /etc/issue
添加如下内容:
Welcome to MageEdu Linux(http://www.magedu.com)... Kernel \r
注:这里的内容可以根据你的需要进行修改。
十、在系统启动时为系统提供主机名称:
这个可以通过宿主机来实现,也可以直接在目标主机上进行配置。这里采用直接在目标主机上配置的方式:
1、创建保存主机名称的配置文件
# mkdir /etc/sysconfig # vi /etc/sysconfig/network
添加如下内容:
HOSTNAME=marion.example.com
2、编辑系统初始化脚本,实现开机过程中设定主机名称
# vi /etc/init.d/rc.sysinit
在文件尾部添加如下行:
HOSTNAME=
[ -e /etc/sysconfig/network && -r /etc/sysconfig/network ] && source /etc/sysconfig/network
[ -z ${HOSTNAME} ] && HOSTNAME="localhost"
/bin/hostname ${HOSTNAME}
十一、通过dropbear为系统提供ssh远程连接服务
注:以下过程在宿主机上实现。
1、编译安装dropbear
# tar xf dropbear-2013.56.tar.bz2 # cd dropbear-2013.56 # ./configure # make # make install
2、移植dropbear至目标系统
移植二进制程序及其依赖的库文件,方能实现其在目标系统上正常运行。建议使用脚本进行(这里将其保存为bincp.sh),其会自动移植指定的命令及依赖的库文件。
#!/bin/bash
#
read -t 30 -p "Target System Directory[/mnt/sysroot]: " DEST
DEST=${DEST:-/mnt/sysroot}
libcp() {
LIBPATH=${1%/*}
[ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH
[ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished."
}
bincp() {
CMDPATH=${1%/*}
[ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH
[ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH
for LIB in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do
libcp $LIB
done
}
read -p "Your command: " CMD
until [ $CMD == 'q' ]; do
! which $CMD && echo "Wrong command" && read -p "Input again:" CMD && continue
COMMAND=` which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
bincp $COMMAND
echo "copy $COMMAND finished."
read -p "Continue: " CMD
done
接下来运行此脚本,分别输入dropbear、dropbearkey和dbclient即可;这些命令会被存储于目标系统的/usr/local/sbin或/usr/local/bin目录中。
3、为远程登录的用户提供伪终端设备文件
编辑/mnt/sysroot/etc/fstab,添加如下一行:
devpts /dev/pts devpts mode=620 0 0
创建所需要的目录:
# mkdir /mnt/sysroot/dev/pts
4、为目标系统的dropbear生成主机密钥
默认情况下,dropbear到/etc/dropbear目录中查找使用的rsa格式主机密钥(默认名称为dropbear_rsa_host_key)和dss格式的主机密钥(默认名称为dropbear_dss_host_key)。其中,rsa格式可使用不同长度的密钥,但dss格式只使用1024位的密钥。
# mkdir /mnt/sysroot/etc/dropbear # dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048 # dropbearkey -t rsa -f /etc/dropbear/dropbear_dss_host_key
在生成rsa格式的key时,其长度指定部分-s 2048可以省略,也可以为其指定为其它长度,但长度需要为8的整数倍。
说明:此步骤也可以在目标主机上进行,但路径要做相应的修改。
5、定义安全shell
安全起见,dropbear默认情况下仅允许其默认shell出现在/etc/shells文件中的用户远程登录,因此,这里还需要创建/etc/shells文件,并添加所有允许的shell。
# cat >> /mnt/sysroot/etc/shells << EOF /bin/sh /bin/ash /bin/hush /bin/bash EOF
6、为目标主机提供网络服务转换机制
在宿主机上使用默认选项编译的dropbear将依赖nsswitch实现用户名称解析,因此,还需要为目标主机提供nss相关的库文件及配置文件。
# cat >> /mnt/sysroot/etc/nsswitch.conf << EOF passwd: files shadow: files group: files hosts: files dns EOF
复制所需要的库文件:
# cp -d /lib/libnss_files* /mnt/sysroot/lib/ # cp -d /usr/lib/libnss3.so /usr/lib/libnss_files.so /mnt/sysroot/usr/lib/
7、测试
启动目标主机,设定好网络属性后,使用如下命令启动dropbear服务即可。
# /usr/local/sbin/dropbear
接下来就可以远程进行连接测试了。
十二、通过nginx提供web服务
1、在宿主机编译安装nginx-1.2.5
# tar nginx-1.2.5.tar.gz # cd nginx-1.2.5 # ./configure --prefix=/usr/local --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --user=nginx --group=nginx --http-log-path=/var/log/nginx/access.log --without-pcre --without-http_rewrite_module --without-http_geo_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module --without-http_upstream_keepalive_module --http-log-path=/var/log/nginx # make # make install
2、移植nginx至目标系统
(1) 移植二进制程序及其依赖的库文件,方能实现其在目标系统上正常运行。建议使用前面的bincp.sh脚本进行。
(2) 移植配置文件至目标系统
# mkdir /mnt/sysroot/etc/nginx/
# cp /etc/nginx/{nginx.conf,mime.types} /mnt/sysroot/etc/nginx/
(3) 移植测试页面至目标系统,当然,也可以不采用下面的步骤而在目标系统上直接创建。
# mkdir /mnt/sysroot/usr/local/ # cp -r /usr/local/html /mnt/sysroot/usr/local/
3、测试
启动目标主机,首先配置好网络属性,并使用adduser为其添加nginx用户和nginx组。
然后使用如下命令启动nginx,即可通过浏览器测试访问。
# /usr/local/nginx
浙公网安备 33010602011771号