一个完整的linux系统所需最小条件:
/boot
grub
initrd.gz
vmlinuz(kernel)
...
/sysroot
init
linux常用目录
linux常用命令
...
创建精简内核实例:
1.磁盘分区并挂载
#fdisk /dev/sdb
/dev/sdb1
/dev/sdb2
#partprobe /dev/sdb
#mke2fs -j /dev/sdb1
#mke2fs -j /dev/sdb2
#mkdir /mnt/{boot,sysroot}
#mount /dev/sdb1 /mnt/boot
#mount /dev/sdb2 /mnt/sysroot
2.复制内核
#cp /boot/vmlinuz-xxxx /mnt/boot/vmlinuz
3.制作initrd.gz文件
#mkdir test
#cd test
#zcat /boot/initrd-`uname -r`.img | cpio -id
#vim init
mkrootdev -t ext3 -o defaults,ro /dev/sdb2
创建根设备
#resume LABLE=SWAP-sdaxx
因没有swap分区,所以注释掉此行。
注释掉不需要的模块。
...
cd lib/
#rm -r dm-* 删除dm文件,进一步缩小系统大小。
#find . | cpio -H newc --quiet -o |gzip -9 > /mnt/boot/initrd.gz 重新打包initrd文件。
4.安装grub并配置grub.conf
#grub-install --root-directory=/mnt /dev/sdb
#vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title My Linux(KERNELVERSION)
root (hd0,0)
kernel /vmlinuz quiet
启动时不想显示启动信息使用quiet
initrd /initrd.gz
5.创建相关目录
#cd /mnt/sysroot
#mkdir -pv lib/modules bin sbin proc sys dev etc/rc.d/init.d root mnt media
核心目录,不能单独分区。此时还没有root的概念,root文件夹其实可以单独分区。
#mkdir -pv root tmp home var/{log,run,lock/subsys,tmp} usr/{bin,sbin,local} opt boot
非核心目录,可以单独分区。
6.编辑etc/inittab文件
#vim etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
7.复制相关模块的库。
#copy /lib/modules/KERNELVERSION/kernel/drivers/net/mii.ko /mnt/sysroot/lib/modules
#copy /lib/modules/KERNELVERSION/kernel/drivers/net/penet.ko /mnt/sysroot/lib/modules
8.编辑rc.sysinit文件并添加x权限。
#vim etc/rc.d/rc.sysinit
#!/bin/bash
echo -e "\tWelcom to \033[31mMY Team\033[0m Linux "
insmod /lib/modules/mii.ko
insmod /lib/modules/pcnet32.ko
ifconfig eth0 192.168.1.32/24
if lo 127.0.0.1/8
/bin/bash
#chmod +x etc/rc.d/rc.sysinit
9.使用copylib.sh脚本添加常用命令和相关库文件
#copylib.sh
init
bash
...
10.将以上操作写入硬盘保存。
#sync
11.使用chroot命令验证添加命令是否能正常工作
#chroot /mnt/sysroot
ls
...
扩展精简内核实例1:
0.此时系统根分区仍然为ro,修改为rw。此步骤在精简内核上执行。
#mount -n -o remount.rw /
1.编写关机脚本和重启脚本
#cd /mnt/sysroot
#vim etc/rc.d/rc.sysdone
#!/bin/bash
sync
sleep 5
sync
sleep 5
exec /sbin/halt -p
#chmod +x etc/rc.d/rc.sysdone
#vim etc/rc.d/rc,sysreboot
#!/bin/bash
sync
sleep 5
sync
sleep 1
exec /sbin/reboot
#chmod +x etc/rc.d/rc.sysreboot
2.添加常用命令
#bash copylib.sh
sync
sleep
ls
touch
mv
cp
vim
mount
umount
...
3.修改 etc/inittab文件,添加关机脚本。
#vim etc/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.sysreboot
扩展精简内核实例2:
将关机和重启写成一个脚本:
#copylib.sh
basename
#vim etc/rc.d/init.d/halt
#!/bin/bash
case $0 in
*reboot)
COMMAND='/sbin/reboot'
;;
*halt)
COMMAND='/sbin/halt -p'
;;
*)
echo "use *reboot or *halt"
;;
seca
case $1 in
start)
;;
stop)
;;
restart)
;;
status)
;;
*)
echo "`basename $0` {start|stop|restart|status} "
;;
seca
esec $COMMAND
#chmod +x etc/rc.d/init.d/halt
#mkdir etc/rc.d/{rc0.d,rc6.d}
#ln -sv etc/rc.d/init.d/halt etc/rc.d/init.d/rc0.d/S99halt
#ln -sv etc/rc.d/init.d/halt etc/rc.d/init.d/rc6.d/S99reboot
#vim etc/rc.d/rc
#!/bin/bash
RUNLEVEL=$1
for I in /etc/rc.d/rc$RUNLEVNE.d/K*;do
if [-e /etc/rc.d/rc$RUNLEVNE.d/K*];then
$I stop
else
cuntinue
done
for I in /etc/rc.d/rc$RUNLEVNE.d/S*;do
if [-e /etc/rc.d/rc$RUNLEVNE.d/S*];then
$I start
else
cuntinue
done
#chmod +x etc/rc.d/rc
#vim 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
#sync
扩展精简内核实例3:
在对应的级别上启动服务,例如3级别:
#vim etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l3:3:wait:/etc/rc.d/rc 3
l6:6:wait:/etc/rc.d/rc 6
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
#cd etc/init.d/
#mkdir etc/rc.d/rc3.d
#vim tserver
#!/bin/bash
#chkconfig: 35 66 33
#description: test script
PROG=`basename $0`
LOCKFILE=/var/lock/subsys/$PROG
start(){
echo "starting $PROG"
touch $LOCKFIEL
}
stop(){
echo "stopping $PROG"
rm -f $LOCKFIEL
}
status(){
if [-f $LOCKFILE] ;then
echo "$PROG is running"
else
echo "stoped"
fi
}
usage(){
echo "only use start|stop|restart|status!"
}
case $1 in
start)
start()
;;
stop)
stop()
;;
restart)
stop()
start()
;;
stop)
stop()
;;
*)
usage()
;;
exit 1
esca
#chmod +x tesrver
#cd rc3.d
#ln -sv etc/init.d/tserver S66tserver
#ln sv etc/initd/tserver etc/init.d/rc0.d/K33tserver
#ln sv etc/initd/tserver etc/init.d/rc6.d/K33tserver
#bash copybin.sh
mingetty
basename
#sync
扩展精简内核实例4:
此时3模式还无法启动,因为在rc.sysinit中已经执行了/bin/bash,不会进入3模式。同时此时根文件系统仍为ro,无法创建锁文件。修复此问题。同时给系统写入主机名。
#vim etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l3:3:wait:/etc/rc.d/rc 3
l6:6:wait:/etc/rc.d/rc 6
1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1
2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2
#vim etc/rc.d/rc.sysinit
#!/bin/bash
echo -e "\tWelcom to \033[31mMY Team\033[0m Linux "
echo "remontu rootfs"
mount -n -o remount,rw /
echo "setting the hostname"
[-f /etc/sysconfig/network] && . /etc/sysconfig/network
[-z $HOSTNAME -o $HOSTNAME == '(none)'] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
insmod /lib/modlues/mii.ko
insmod /lib/modlues/pcnet32.ko
ifconfig eth0 192.168.1.32/24
if lo 127.0.0.1/8
#bash copybin.sh
mingetty
hostname
agetty
#cd /mnt/sysroot/bin
#ln -sv bash sh
#cd /mnt/sysroot
#vim etc/fstab
/dev/hda2 / ext3 defaults 0 0
/dev/sda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
#mdkir etc/sysconfig
#vim etc/sysconfig/network
HOSTNAME=mylinux.com
#sync
扩展精简内核实例5:
接上个扩展,此时由于编辑太频繁导致系统损坏,进行文件系统修复:
#cd /mnt/sysroot
#find . |cpio -H -newc --quiet -o |gzip > /root/sysroot.gz
#fuser -km /dev/sdb2
#umonut /dev/sdb2
#mke2fs -j /dev/sdb2
#mount /dev/sdb2 /mnt/sysroot
#cd /mnt/sysroot
#zcat /root/sysroot.gz| cpio -id
#sync
也可以在umount以后使用e2fsck修复。
#e2fsck -af /dev/sdb2
#cat etc/inittab 检查inittab文件是否损坏。
#sync
扩展精简内核实例6:
使用公共脚本来完善功能,让tserver启动或关闭时显示正常系统提示ok或者是failuer。公共脚本位置/etc/rc.d/init.d/functions。
#copybin.sh
seq
stty
#vim etc/rc.d/init.d/functions
SCREEN=`stty -F /dev/console size 2 > /dev/null`
COLNUM=${SCREEN#* }
[-z $COLNUM] && COLNUM=80
SPA_COL=$[$COLNUM-14]
这里的12是[ \033[1;32mfailure\033[0m ]的字符长度。这部分长度是固定的。[ \033[1;32mOK\033[0m ]长度为8个字符。
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
NORMAL='\033[0m'
scuess(){
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} ]"
}
failuer(){
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} ]"
}
#vim etc/rc.d/init.d/tserver
#!/bin/bash
#chkconfig: 35 66 33
#description : test script
. /etc/rc.d/init.d/functions
PROG=tserver
LOCKFILE=/var/lock/subsys/$PROG
start(){
touch $LOCKFIEL
[$? -eq 0] && success() "Starting $PROG" || failuer "Starting $PROG"
}
stop(){
rm -f $LOCKFIEL
[$? -eq 0] && sucess() "Stopping $PROG" ||failuer "Stopping $PROG"
}
status(){
if [-f $LOCKFILE] ;then
echo "$PROG is running"
else
echo "stoped"
fi
}
usage(){
echo "only use start|stop|restart|status!"
}
case $1 in
start)
start()
;;
stop)
stop()
;;
restart)
stop()
start()
;;
stop)
stop()
;;
*)
usage()
;;
exit 1
esca
#sync
扩展精简内核实例7:
使用脚本为精简系统增加ip地址。原来是通过在etc/rc.d/rc.sysinit中直接写入的方式。
第7步中已经将pcnet32.ko和mii.ko复制到/mnt/sysroot/lib/modules内。
#vim etc/rc.d/rc.sysinit
#!/bin/bash
echo -e "\tWelcom to \033[31mMY Team\033[0m Linux "
echo "remontu rootfs"
mount -n -o remount,rw /
echo "setting 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/modlues/mii.ko
/sbin/insmod /lib/modlues/pcnet32.ko
#mkdir -pv etc/sysconfig/network-scripts
#vim etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.100.5
NETMASK=255.255.0.0
GATEWAY=172.16.0.1
#vim etc/rc.d/init.d/network
#chkconfig 35 09 90
#description: network service
#!/bin/bash
FILE=/etc/sysconfig/network-scripts/ifcfg-eth0
. $FILE
. /etc/rc.d/init.d/functions
PROG=network
start(){
ifconfig eth0 $IPADDR $NETMASK up
[-z $GATEWAY] && router add default gw $GATEWAY
return 0
}
stop(){
ifconfig eth0 down
}
status(){
ifconfig eth0
[$? -eq 0] && echo "eth0 is ok"
}
usage(){
echo "$PROG use start|stop|restart|status]"
exit 1
}
case $1 in
start)
start()
success() "config network eth0 "
;;
stop)
stop()
success() "stop network eth0"
;;
restart)
stop()
start()
success() "restart network eth0"
status)
status()
;;
*)
usage()
;;
seca
#cd etc/rc.d/rc0.d
#ln -sv etc/rc.d/init.d/network K90network
#cd etc/rc.d/rc6.d
#ln -sv etc/rc.d/init.d/network K90network
#cd etc/rc.d/rc3.d
#ln -sv etc/rc.d/init.d/network S09network
#sync
此脚本仍然无法启动网卡,因为ifconfig接受子网掩码格式为IP/NETMASK,所以从文件中读取的信息不可用。可以手工指定。
扩展精简内核实例8:
创建系统启动后在登录账号前显示的终端提示信息。
#cp /etc/issue /mnt/sysroot/etc/
#vim /mnt/sysroot/etc/issue
扩展精简内核实例9:
实现挂载额外的文件系统。
系统启动时,/ /proc /sysfs都是自动挂载的。/etc/fstab中其他的文件系统都未自动挂载。当前已挂载的可以从/proc/mounts中查看。
#vim etc/rc.d/rc.sysinit
#!/bin/bash
. /etc/rc.d/init.d/functions
echo -e "\tWelcom to \033[31mMY Team\033[0m Linux "
echo "remontu rootfs"
mount -n -o remount,rw /
[$? -eq 0] && success() "Remount rootfs"||failuer() "Remount rootfs"
mount -a
grep -E -v "\<swap|proc|sysfs|\/dev\/mapper\>" /etc/fstab |awk '{print $1}'|
while read LINE;do
awk '{print $1}' /proc/mounts|grep "^$LINE$"
if [ $? -eq 0 ] ;then
success() "$LINE mount "
else
failure() "$LINE mount"
fi
done
echo "setting the hostname"
[-f /etc/sysconfig/network] && . /etc/sysconfig/network
[-z $HOSTNAME -o $HOSTNAME == '(none)'] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
[$? -eq 0] && success() "Setting Hostname"||failuer ()"Setting Hostname"
echo "Initializing network device ..."
/sbin/insmod /lib/modlues/mii.ko
[$? -eq 0] && success() "loading mii.ko"||failuer() "loading mii.ko"
/sbin/insmod /lib/modlues/pcnet32.ko
[$? -eq 0] && success() "loading penet32.ko"||failuer() "loading penet32.ko"
扩展精简内核实例10:
设定内核参数。配置文件为/etc/sysctl.conf,使用sysctl -p令配置生效。
#copylib.sh
sysctl
#vim etc/sysctl.conf
net.ipv4.ip_forward=1
#vim etc/rc.d/rc.sysinit
#!/bin/bash
. /etc/rc.d/init.d/functions
echo -e "\tWelcom to \033[31mMY Team\033[0m Linux "
echo "remontu rootfs"
mount -n -o remount,rw /
[$? -eq 0] && success() "Remount rootfs"||failuer() "Remount rootfs"
mount -a
grep -E -v "\<swap|proc|sysfs|\/dev\/mapper\>" /etc/fstab |awk '{print $1}'|
while read LINE;do
awk '{print $1}' /proc/mounts|grep "^$LINE$"
[ $? -eq 0 ] && success() "$LINE mount "||failure() "$LINE mount"
done
echo "setting the hostname"
[-f /etc/sysconfig/network] && . /etc/sysconfig/network
[-z $HOSTNAME -o $HOSTNAME == '(none)'] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
[$? -eq 0] && success() "Setting Hostname"||failuer ()"Setting Hostname"
echo "Initializing network device ..."
/sbin/insmod /lib/modlues/mii.ko
[$? -eq 0] && success() "loading mii.ko"||failuer() "loading mii.ko"
/sbin/insmod /lib/modlues/pcnet32.ko
[$? -eq 0] && success() "loading penet32.ko"||failuer() "loading penet32.ko"
sysctl -p &> /dev/null
[ $? -eq 0] && success "setting kernel parameter"||failuer "setting kernel parameter"
扩展精简内核实例11:
用户账号登陆相关。
跳过PAM认证。
0.重新编译/mnt/sysroot/bin/login,跳过PAM验证。
暂时不会,等待后续添加。
1.复制nssswitch所需的库文件
#cp -d /lib/libnss_files* /mnt/sysroot/lib
#cp -d /lib/libnss_files.so /mnt/sysroot/usr/lib
#cp -d /usr/libness3.so /mnt/sysroot/usr/lib
#cp -d /usr/libnessckib.so /mnt/sysroot/usr/lib
#cp -d /usr/libnessutil3.so /mnt/sysroot/usr/lib
2.编辑配置/etc/nsswitch.conf
#cp /etc/nsswitch.conf /mnt/sysroot/etc
#vim /mnt/sysroot/etc/nsswitch.conf
passwd: files
shadow: files
group: files
hosts: files dns
3.创建用户:
#vim /mnt/sysroot/etc/passwd
#vim /mnt/sysroot/etc/shadow
#vim /mnt/sysroot/etc/group
4.移植mingetty等相关库,此时可以不在使用agetty。
passwd等命令依靠PAM,所以作用不大。
#bash copylib.sh
mingetty
passwd
useradd
usermod
userdel
usermod
login
groupadd
...
5.修改/mnt/sysroot/etc/inittab,将agetty替换成mingetty
#vim /mnt/sysroot/etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l3:3:wait:/etc/rc.d/rc 3
l6:6:wait:/etc/rc.d/rc 6
1:2345:respawn:/sbin/mingetty /bin/bash 38400 tty1
2:2345:respawn:/sbin/mingetty /bin/bash 38400 tty2
6.设置账号登陆后,用户的环境变量:
#vim /mnt/sysroot/root/.bash_profile
export PS1='[\u@\h \W]\$'
7.设置/root目录权限
#chmod -R og=--- /mnt/sysroot/root
扩展精简内核实例12:
单用户模式
1.修改/etc/inittab文件,增加1级别。
#vim /mnt/sysroot/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
l3:3:wait:/etc/rc.d/rc 3
l6:6:wait:/etc/rc.d/rc 6
1:2345:respawn:/sbin/mingetty /bin/bash 38400 tty1
2:2345:respawn:/sbin/mingetty /bin/bash 38400 tty2
2.创建1模式下的相关脚本
#cd /mnt/sysroot/etc/rc.d/init.d
#mkdir rc1.d
#cd rc1.d
#ln -sv ../init.d/network K90network
#ln -sv ../init.d/tserver K33tserver
3.编辑1模式的脚本
#vim /mnt/sysroot/etc/rc.d/init.d/single
#!/bin/bash
#chkconfig:
#description:
case $1 in
start)
;;
*)
echo "usage:single start"
esca
exec /sbin/init S
#chmod +x /mnt/sysroot/etc/rc.d/init.d/single
#ln -sv /mnt/sysroot/etc/rc.d/init.d/single /mnt/sysroot/etc/rc.d/rc1.d/S99single
#sync
4.开机后在grub中进入单用户模式
按e键进行编辑启动条目,再按e键编辑kernel项,在后边输入1后回车,按b键引导。
/etc/issue
提供系统启动后在登录账号前显示的相关信息。
常见的逃逸字符含义:
mingetty:
\r 显示系统的发行号,相当于uname -r
\m 显示机器的平台架构,相当于uname -m
其他类似agetty等也有类似的逃逸字符定义,使用前先用man文档查看相关内容。
copylib.sh脚本:复制命令及相关的库文件。
/root/copylib.sh
#!/bin/bash
DEST=/mnt/sysroot
libcp(){
LIPPATH=${1%/*}
[!-d $DEST$LIPPAHT] && mkdir -p $DEST$LIBPATH
[!-e $DEST${1}] && cp $1 $DEST$LIBPAHT && echo "copy lib $1 ok"
}
bincp(){
CMDPAHT=${1%/*}
[!-d $DEST$CMDPAHT] && mkdir -p $DEST$CMDPAHT
[!-e $DEST${1}] && cp $1 $DEST$CMDPAHT
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 "cppy $COMMAND finished"
read -p "continue:"CMD
done
PAM:Pluggeable Authentication Module 可插入式认证模块。
配置文件:/etc/pam.d/*
nsswitch:Network Service Switch 网络服务切换。是一个中间层框架。
库:
/lib/libnss*.so
/usr/lib/libnss*.so
配置文件:
/etc/nsswitch.conf