Linux系统启动流程
PC:OS(Linux)POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-->initrd-->(ROOTFS)/sbin/init(/etc/inittab)启动的服务不同:
运行级别:0-6
0:关机(halt)1:单用户模式(single user mode)启动以后不需要root密码,直接以管理员登录根(s ,S ,single ,1都表示1级别)2:多用户模式(multi user mode),不启用NFS3:正常多用户模式(multi user mode text mode)文本模式4:保留级别5:图形终端模式(multi user mode ,graphic mode)6:重启(reboot)
详解启动过程
bootloader(MBR)
LILO:Linux Loader 不支持8G以上的分区引导
GRUB:GRand Unified Bootloader
Stage1:MBR
Stage1_5:识别常见的不同的文件系统
Stage2:/boot/grub
grub.conf文件:
default=0 #设定默认启动的title的编号,从0开始
timeout=5 #等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz #grub的背景图片
hiddenmenu #隐藏菜单password --md5 $1$nTXq0/$87SaMxaKgOo.QWCGjA4FP. #此选项设置以后,启动编辑grub.conf需要输入此密码
title CentOS (2.6.32-642.3.1.el6.i686) #内核标题,或操作系统名称,字符串,可以自由修改
root (hd0,0) #内核文件所在的设备:对grub而言,所有类型硬盘一律hd:(hd#,N),#表示第几个磁盘;最后的N表示对应的磁盘分区
kernel /vmlinuz-2.6.32-642.3.1.el6.i686 ro root=UUID=7a707d58-36d1-4f7e-8f59-d306f79b96dc rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD quiet(屏蔽内核初始化大部分信息) SYSF rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM #内核文件路径,及传递给内核的参数
initrd /initramfs-2.6.32-642.3.1.el6.i686.img #ramdisk文件路径password --md5 $1$nTXq0/$87SaMxaKgOo.QWCGjA4FP. #此选项设置以后,启动内核需要输入密码
安装grub stage1
#grub
grub>root (hd0,0)
grub>setup (hd0)
安装grub第二种方式
#grub-install --root-directory=/path/to/boot's_parent_dir /PATH/TO/DEVICE
系统启动缺少grub.conf文件:
grub>find (查找内核文件)
grub>root (hd#,N) (root (hd0,然后按tab键,会有显示,把type 0x83的分区位置都得试一下)
grub>kernel /path/to/kernel_file ( kernel /vmlinuz-2.6.32-573.el6.x86_64 [如果出现 报错,就重启加上根分区磁盘 ro root=/dev/sda2])
grub>initrd /path/to/initrd_file (initrd /initramfs-2.6.32-573.el6.x86_64.img)
grub>boot
Kernel初始的过程:
1、设备探测
2、驱动初始化(可能会从initrd (initramfs))
3、以只读挂载根文件系统
4、装载第一个进程init (PID:1)
/sbin/init:(/etc/inittab)
upstart:Ubuntu 、redhat6.0+
/etc/inittab
/etc/init/*.conf
systemd:
id:runlevels:action:process
id:3:initdefault:
id:标识符
runlevels:在哪个级别运行此行
process:要运行的程序
ACTION:
initdefault:设定默认运行级别
sysinit:系统初始化
wait:等待级别切换完成
respawn:一旦程序终止,会重新启动
/etc/rc.d/rc.sysinit完成的任务:
1、激活udev和selinux
2、根据/etc/sysctl.conf文件,来设定内核参数
3、设定时钟时区
4、装载键盘映射
5、启用交换分区
6、设置主机名
7、根文件系统检测,并以读写方式重新挂载
8、激活RAID和LVM设置
9、启用磁盘配额
10、根据/etc/fstab ,检查并挂载其他文件系统
11、清理过期的锁和PID文件
for I in /etc/rc3.d/K*;do
$I stop
done
for I in /etc/rc3.d/S*;do
$I start
done
##:关闭或启动的优先次序,数据越小越优先被选定
先关闭以K开头的服务,后启动以S开头的服务OS初始化
10:0:wait:/etc/rc.d/rc 0
rc0.d/
K*
stop
S*
start
/etc/rc.d/init.d , /etc/init.d
服务类脚本:
start
SysV:/etc/rc.d/init.d
start|stop|restart|status
reload(不重启重新加载配置文件)|configtest(检查配置文件的语法是否有错误)chkconfig
# chkconfig :runlevels SS KK
当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevels表示默认创建为S*开头的连接,-表示没有级别默认为S*开头的连接;除此之外的级别默认创建K*开头的链接:
S后面的启动优先级为SS所表示的数字;K后面关闭的优先次序为KK所表示的数字
# description:用于说明此脚本的简单功能;\,续行符
chkconfig命令:
chkconfig --list :查看所有独立守护服务的启动设定:独立守护进程
chkconfig --list SERVICE_NAME 单独查看某个服务的启动设定
chkconfig --add SERVICE_NAME 添加到服务列表
chkconfig --del SERVICE_NAME 删除服务链接
chkconfig [--level RUNLEVELS] SERVICE_NAME {on|off}
如果省略级别指定,默认为2345级别
/etc/rc.d/rc.local:系统最后启动的一个服务,准确说:执行的一个脚本
/etc/inittab的任务(redhat5):
1、设定默认运行级别
2、运行系统初始化脚本( /etc/rc.d/rc.sysinit)
3、运行指定运行级别对应目录下的脚本
/etc/rc.d/init.d/
/etc/rc.d/rc#.d
4、设定Ctrl+Atl+Del组合键的操作
5、定义UPS电源在电源故障/恢复时执行的操作
6、启动虚拟终端(2345级别)
7、启动图形终端(5级别)
守护进程的类型:
独立守护进程
xinetd:超级守护进程,代理人
瞬时守护进程:不需要关联之运行级别
核心:/boot/vmlinux-version
内核模块(ko):/lib/modules/version
内核设计:
单内核:模块化设计
微内核
装载模块
insmod
modprobe
www.kernel.org
用户空间访问、监控内核的方式:
/proc, /sys
伪文件系统
/proc/sys:此目录中的文件很多是可读写的
/sys/: 某些文件可写
设定内核参数值的方法:
echo VALUE > /proc/sys/to/somefile
sysctl -w kernel.hostname=
能立即生效,但无法永久有效
永久有效,但不能立即生效/etc/sysctl.conf
修改文件完成之后,执行如下命令可立即生效:
sysctl -p
sysctl -a:显示所有的内核参数及其值
内核模块管理:
lsmod:查看
modprobe MOD_NAME:装载某模块
modprobe -r MOD_NAME:卸载某模块
modinfo MOD_NAME:查看模块的具体信息
insmod /PATH/TO/MODULE_FILE 装载模块
rmmod MOD_NAME 卸载模块
depmod /PATH/TO/MODLIES_DIR 保存依赖关系
内核中的功能除了核心功能之外,在编译时,大多功能都有三种选择
1、不使用此功能
2、编译成内核模块
3、编译进内核
如何手动编译内核:
make gconfig:Gnome桌面环境使用,需要安装图形开发库
make kconfig : KDE桌面环境使用,需要安装图形开发
make menuconfig(出错,安装yum install ncursesyum install ncurses-devel)
make
make modules_install
make install
如何实现部分编译:
1、只编译某子目录下的相关代码:
make dir/
make arch/
kake drivers/net/
2、只编译部分模块
make M=drivers/net/
3、只编译某一模块
make drivers/net/pcnet32.ko
4、将编译完成的结果放置于别的目录中
make O=/tmp/kernel
5、交叉编译
make ARCH=
screen命令:
screen -ls :显示已经建立的屏幕
screen:直接打开一个新的屏幕
Ctrl+a ,d:拆除屏幕
screen -r ID :还原回某屏幕
二次编译时清理,清理前,如果有需要,请备份配置文件.config
make clean
make mrproper
mkinitrd initrd文件路径 内核版本号
mkinitrd /boot/initrd-`uname -r`.img `uname -r`
制作一个精简系统:
步骤:
1、mkdir 创建一个boot分区 一个根分区,并格式化分区
2、dev/sda1 挂载到 /test/boot/ dev/sda2 挂载到/test/sysroot
3、创建内核文件
cp /boot/vmlinuz-2.6.32-573.el6.x86_64 /test/boot/vmlinuxz
4、创建initrd文件
①cd /tmp/test
②zcat /boot/initramfs-2.6.32-573.el6.x86_64.img | cpio -id 展开归档
③vim init 自定义修改
④find . | cpio -H newc --quiet -o | gzip -9 > /test/boot/initrd.gz 归档压缩
5、安装grub
①grub-install --root-directory=/test /dev/sda
②vim /test/boot/grub/grub.conf
default=0
timeout=5
title My Linux (2.6.32-573.el6.x86_64)
root (hd0,0)
kernel /vmlinuz
initrd /initramfs.gz
6、创建必要目录
mkdir -pv etc/rc.d/init.d bin sbin proc sys dev lib root mnt media /var/{log,run,lock/subsys,tmp} usr/{bin,shbin,local} tmp home opt boot
7、创建etc/inittab
vim /test/myroot/etc/inittab
id:3:initdefault:
8、创建etc/rc.d/rc.sysinit
vim /test/myroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "Welcome to \033[32m TangCongJiang\033[0m Linux"
/bin/bash9、复制/sbin/init 和/bin/bash 到新根目录
cp /sbin/init /test/myroot/sbin/
cp /bin/bash /test/myroot/bin/
10、利用脚本copy命令以及命令依赖的库文件到新的根目录
#!/bin/bash
MYROOT=/www/myroot
cplib(){
libdir=${1%/*}
newlib=$MYROOT$libdir
[ ! -d $newlib ] && mkdir -p $newlib
[ ! -e $MYROOT$1 ] && cp $1 $newlib && echo -e "\033[35m$1 copy finished!\033[0m"
}
cpcmd(){
cmddir=${1%/*}
newcmd=$MYROOT$cmddir
[ ! -d $newcmd ] && mkdir -p $newcmd
[ ! -e $MYROOT$1 ] && cp $1 $newcmd
for i in `ldd $1 | grep -o "/.*lib\(64\)\?/[^[:space:]]\+"`;do
cplib $i
done
}
echo -ne "\033[34mPlease input Command:\033[0m"
read CMD
until [ $CMD == 'q' ];do
! which $CMD &>/dev/null && echo -ne "\033[31mCommand not exist,Please again input:\033[0m" && read CMD && continue
COMMAND=`which $CMD | grep -v "alias" | grep -o "[^[:space:]]\+"`
cpcmd $COMMAND
echo -e "\033[32m$COMMAND copy finished!\033[0m"
echo -ne "\033[33mPlease input Command:\033[0m"
read CMD
done
精简系统功能完善
#/etc/rc.d/init.d/functions
SCREEN=`stty -F /dev/console size 2>/dev/null`
COLUMNS=${SCREEN#* }
[ -z $COLUMNS ]&& COLUMNS=80
SPA_COL=$[$COLUMNS-14]
RED='\033[1;31m'
GREEN='\033[1;32m'
BLUE='\033[1;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} ]"
}
failde(){
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} ]"
}
1、关机重启;
#!/bin/bash
case $0 in
*reboot)
COMMAND='/sbin/halt -p';;
*halt)
COMMAND='/sbin/reboot';;
*)
echo "Only call this script by *reboot OR *halt";;
esac
exec $COMMAND/etc/rc.d/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
2、主机名
/etc/rc.d/rc.sysinit
#!/bin/bash
echo "Welcome to linux"
echo "Remount rootfs"
mount -n -o remount,rw /
mount -a
[ $? -eq 0 ] && success "Mount others filesystem"
echo "Set the hostname"
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o $HOSTNAME == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
3、运行对应服务脚本
(服务样例脚本)
/etc/rc.d/init.d/myservice
#!/bin/bash
#
# chkconfig:2345 45 55
# description:This is my services!
. /etc/rc.d/init.d/functions
NAME=myservice
FILE=/var/lock/subsys/$NAME
STATUS(){
if [ -e $FILE ];then
echo -e "\033[32m$NAME is running... \033[0m"
else
echo -e "\033[31m$NAME is stoped\033[0m"
fi
}
START(){
touch $FILE
[ $? -eq 0 ] && success "Staring $NAME" || failed "Staring $NAME"
}
STOP(){
rm -f $FILE $>/dev/null
[ $? -eq 0 ] && success "Stoping $NAME" || failed "stoping $NAME"
}
USAGE(){
echo "/etc/init.d/$NAME {start|stop|restart|status}"
}
case $1 in
start)
START;;
stop)
STOP;;
restart)
echo "restarting...";;
status)
STATUS ;;
*)
USAGE;;
esac
4、启动终端;
/etc/inittab
1:2345:respawn:/sbin/agetty -n -1 /bin/bash 38400 tty1
1:2345:respawn:/sbin/agetty -n -1 /bin/bash 38400 tty2
终端提示信息:
/etc/issue文件的内容
5、定义单用户级别
/etc/init.d/single
. /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
6、装载网卡驱动,启用网络功能
/etc/rc.d/rc.sysinit
....
echo " Initializing network device..."
/sbin/inmod /lib/modules/mii.ko
/sbin/inmod /lib/modules/pcnet32.ko
ifconfig lo 127.0.0.1/8
[ $? -eq 0 ] && success "Activating loopback network device" || failed "
Activating loopback network device"
/etc/rc.d/init.d/network
#!/bin/bash
#chkconfig: 35 10 90
#description:network services
prog=network
. /etc/rc.d/init.d/functions
C>
. $CONF
start(){
ifconfig eht0 $IPADDR/24 up
[ -z $GATEWAY ] && route add default gw $GATEWAY
}
stop(){
ifconfig eth0 down
}
status(){
ifconfig eth0
}
usage(){
echo "$prog:{start|stop|restart|status}"
}
case $1 in
start)
start
success "config network eht0";;
stop)
success "Stop network eht0";;
restart)
stop
start
success "Restart network card eht0";;
status)
status;;
*)
usge;;
exit 6
esac
7、rc.sysinit:挂载/etc/fstab 中定义的其他文件系统
grep -v -E "^$|^#" /etc/fstab | grep -E -v "\<swap|proc|sysfs\>" | awk '{print $1}' | while read LINE;do awk '{print $1}' /proc/mounts | grep "^$LINE";done
8、设定内核参数:/etc/sysctl.conf
/etc/rc.d/rc.sysinit
sysctl -p &> /dev/null
[ $? -eq 0 ] && success "Set kernel parameter" || failed "
Set kernel parameter"
9、用户
PAM :pluggable Authentication Module
/etc/pam.d/*
绕过pam
/bin/login
nsswitch:Network Service Switch
框架:/etc/passwd , /etc/shadow , /etc/group
库: libnss_file.so , libnss_nis.so ,libnsss_ldap.so
配置文件:/etc/nsswitch.conf
NIS ,LDAP ,MYSQL/etc/inittab
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
.bash_profile
PS1='[\u@\h \W]\$'
u:用户名
h:主机名
W:路径基名
export PS1
busybox :1M
kernel+initrd(busybox)-->rootfs(busybox)
查看本机硬件设备信息:
1、cat /proc/cpuinfo
2、lsusb
3、lspci
4、hal-device
Hardware Abstract Layer
如何编译busybox(busybox-1.21.1 kernel-2.6.39.3):
①www.busybox.net下载源文件解压
②进入解压目录,执行 make menuconfig编译,然后保存退出 执行make install(glibc报错需要yum install glibc-static -y;kernel版本较低,需要下载高版本的kernel,复制include/mtd/ubi-user.h 到busybox/include/mtd目录)
③cp -a _install/* /tmp/busybox mkdir -pv /tmp/busybox/{proc,sys,etc,dev,mnt/sysroot,lib/modules,tmp}
创建两个必要的设备文件:
# mknod dev/console c 5 1
# mknod dev/null c 1 3
④modinfo ext3 复制ext3库和依赖的库到 busybox/lib/modules目录
⑤在busybox目录创建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制作initrd : find . | cpio --quiet -H newc -o | gzip -9 -n > /test/boot/initrd.gz
⑥cp /boot/vmlinux /mnt/boot/vmlinuz
⑦安装grub grub-install --root-directory=/test /dev/sda 创建grub.conf
vim /test/boot/grub/grub.conf
default=0
timeout=5
title My Linux (2.6.32-573.el6.x86_64)
root (hd0,0) ro root=/dev/sda2
kernel /vmlinuz
initrd /initrd.gz
⑧cp _install/* /test/sysroot/ -a
rm linuxrc
cd /test/sysroot/
mkdir -pv proc sys etc/rc.d/init.d tmp dev/pts boot var/{log,lock,run} usr/lib root mnt media
mknod dev/console c 5 1
mknod dev/null c 1 3⑨为init进程提供配置文件:
# vim etc/inittab
添加如下内容:
::sysinit:/etc/rc.d/rc.sysinit
console::respawn:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
⑩建立系统初始化脚本文件# 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
⑪为系统准备一个“文件系统表”配置文件/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
Kernel + initrd( busybox 制作 ,不提供ext3文件系统模块) + ROOTFS (busybox制作)
make arch/
arch/x86/bootbzImage
硬件驱动:initrd
initrd:仅需要提供内核访问真正的根文件系统所在设备需要的驱动
存储设备和文件系统相关的模块
系统初始化rc.sysinit :初始其他硬件的驱动程序;
ROOTFS:bushbox ,init 不支持运行级别
/etc/inittab 格式也不尽相同
ash,bush
bash
内核设计风格:
RedHat,SUSE
核心:动态加载 内核模块
内核:/lib/modules/“内核版本号命名的目录”vmlinuz-2.6.32
/lib/modules/2.6.32/
RedHat5:ramdisk-->initrd
RedHat6:ramfs-->initramfs单内核:Linux(LWP)
核心:ko(kernel object 内核对象)
微内核:Windows ,Solaris(线程)
chroot命令:切换根目录
chroot /PATH/TO/TEMPROOT
chroot /test/virroot /bin/bash
ldd命令:查看命令支持的库文件
ldd /bin/bash ldd /bin/mv
kickstart:三部分
命令段
必备命令
keyboard
lang
timezone
rootpw --iscrpted
selinux --disabled|--permissive
authconfig --useshadow
bootloader --location
clearpart --initlabel --linux
driverdisk --source=
firewail --disabled
firstboot --disabled
test|graphical
key --skip
network --botoproto= --ip= --netmask= --geteway= --nameserver=
install|upgrade
可选命令
软件包 选择段,%packages
@package_group_name
package_name
-package_name
脚本段
%pre
%post
安装过程中,boot提示符中可以使用的命令 :
askmethod
dd
ip=
netmask=
geteway=
dns=
ks=http://
ks=cdrom:/
rescue:进入紧急救援模式ksvalidator /bash/to/anaconda-ks.cfg 检查语法错误
system-config-kickstart & 启用图形化调试
mkisofs -R -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o boot.iso iso/ 创建光盘镜像