CentOS启动流程
1. 加电自检
通电后主板CMOS中的BIOS(基本输入输出系统)将进行硬件自检并简单设置,根据硬盘等相关设备情况进入下一步
2. 引导加载次序:BOOT Sequence
按次序查找各引导设备,第一个有引导程序的设备即为本次启动用到设备
3. bootloader:
引导加载器,用来引导系统加载的程序
-
windows: ntloader
-
Linux:
-
LILO:LInux LOader
-
GRUB: GRand Uniform Bootloader
-
GRUB 0.X: GRUB Legacy
-
GRUB 1.x: GRUB2
功能:提供一个菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核。
4. GRUB引导加载器
GRUB 是bootloader阶段的引导程序,CentOS主要通过GRUB(GRand Unified Bootloader)引导。
GRUB引导步骤:grub legacy
-
stage1: mbr(磁盘分区表)
-
stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;
-
stage2:磁盘分区(/boot/grub/)
配置文件:/boot/grub/grub.conf <– /etc/grub.conf
stage2及内核等通常放置于一个基本磁盘分区;
GRUB的功用
1. 提供菜单、并提供交互式接口 e: 编辑模式,用于编辑菜单; c: 命令模式,交互式接口; 2. 加载用户选择的内核或操作系统 允许传递参数给内核 可隐藏此菜单 3. 为菜单提供了保护机制 为编辑菜单进行认证 为启用内核或操作系统进行认证
常用命令:
#help: 获取帮助列表 #help KEYWORD: 详细帮助信息 #find (hd#,#)/PATH/TO/SOMEFILE: #root (hd#,#)设定grub的根设备 #kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数; #例如:init=/path/to/init, selinux=0 #initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk; #boot: 引导启动选定的内核;
配置文件:
[root@node1 ~]# cat /boot/grub/grub.conf # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/mapper/vg_node1-lv_root # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.32-642.1.1.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-642.1.1.el6.x86_64 ro root=/dev/mapper/vg_node1-lv_root rd_NO_LUKS rd_LVM_LV=vg_node1/lv_swap rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=vg_node1/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-642.1.1.el6.x86_64.img
常用配置项
default=?: 设定默认启动的菜单项;落单项(title)编号从0开始; timeout=?:指定菜单项等待选项选择的时长; splashimage=(hd?,?)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径; hiddenmenu:隐藏菜单; password [--md5] STRING: 菜单编辑认证; title TITLE:定义菜单项“标题”, 可出现多次; root (hd?,?):grub查找stage2及kernel文件所在设备分区;为grub的“根”; kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核 initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件; password [--md5] STRING: 启动选定的内核或操作系统时进行认证;
5. 进入Kernel
在GRUB中选择对应的kernel后,kernel会对自身进行初始化
自身初始化
-
探测可识别到的所有硬件设备;
-
加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
ramdisk:内核中的特性之一:使用缓冲和缓存来实现对磁盘上的文件访问
-
以只读方式挂载根文件系统;
-
运行用户空间的第一个应用程序:/sbin/init
init程序的类型:
-
SysV: init, CentOS 5
配置文件:/etc/inittab -
Upstart: init, CentOS 6
配置文件:/etc/inittab, /etc/init/*.conf -
Systemd:systemd, CentOS 7
配置文件:/usr/lib/systemd/system, /etc/systemd/system
至此,可以总结为:
POST --> BootSequence (BIOS) --> Bootloader(MBR) --> kernel(ramdisk) --> rootfs(只读) --> init
6. 运行init
CentOS6的init位置为/sbin/init,共分7个级别
运行级别:为了系统的运行或维护等应用目的而设定
0:关机 1:单用户模式(root, 无须登录), single, 维护模式; 2: 多用户模式,会启动网络功能,但不会启动NFS;维护模式; 3:多用户模式,正常模式;文本界面; 4:预留级别;可同3级别; 5:多用户模式,正常模式;图形界面; 6:重启
默认级别:3, 5
切换级别:init ?
例如 init 0 表示关机
[root@node1 ~]# init 0
查看级别:
runlevel
who -r
[root@node1 ~]# runlevel N 3 [root@node1 ~]# who -r 运行级别 3 2016-06-20 13:12
配置文件:/etc/inittab,CenOS 6的upstart程序配置文件还包括/etc/init/*.conf
配置文件格式为:id:runlevel:action:process
每行定义一个级别
id:指入口标识符,它是一个字符串,对于getty或mingetty等其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。 runlevel:init的系统运行级别 action:是用来定义后面process的运行方式,常用的有下面几种 wait: 切换至此级别运行一次; respawn:此process终止,就重新启动之; initdefault:设定默认运行级别;process省略; sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit process:为具体的执行程序
下例中,我的配置文件显示为id:3:initdefault:
,表示默认运行级别3,即多用户模式的文本界面
[root@node1 ~]# cat /etc/inittab # Default runlevel. The runlevels used 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:
设定系统初始化方式时,例如 l3:3:wait:/etc/rc.d/rc 3
表示读取 意味着读取/etc/rc.d/rc3.d/下的配置文件
ls /etc/rc.d/rc3.d/ K10saslauthd S02lvm2-monitor S12rsyslog S26udev-post S99local K15svnserve S08ip6tables S22messagebus S55sshd K50netconsole S08iptables S25blk-availability S80postfix K87restorecond S10network S25netfs S90crond K89rdisc S11auditd S26haldaemon S99libvirt-guests
说明:
K开头的文件,##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务; S开头的文件,##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务;
7. 运行初始化脚本
系统初始化脚本对应的文件是/etc/rc.d/rc.sysinit,会在系统启动时运行一次
[root@node1 ~]# cat /etc/rc.d/rc.sysinit #!/bin/bash # # /etc/rc.d/rc.sysinit - run once at boot time # # Taken in part from Miquel van Smoorenburg's bcheckrc. # HOSTNAME=$(/bin/hostname) set -m if [ -f /etc/sysconfig/network ]; then . /etc/sysconfig/network fi if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then HOSTNAME=localhost fi #后面省略
主要作用
-
设置主机名;
-
设置欢迎信息;
-
激活udev和selinux;
-
挂载/etc/fstab文件中定义的文件系统;
-
检测根文件系统,并以读写方式重新挂载根文件系统;
-
设置系统时钟;
-
激活swap设备;
-
根据/etc/sysctl.conf文件设置内核参数;
-
激活lvm及software raid设备;
-
加载额外设备的驱动程序;
-
清理操作;
8.启动系统服务
centos6下的系统服务脚本都放在/etc/rc.d/init.d或者/etc/init.d中,因为建立了链接,所以内容是一样的
[root@node1 ~]ll /etc/init.d lrwxrwxrwx 1 root root 11 6月 11 22:34 /etc/init.d -> rc.d/init.d [root@node1 ~]# ls /etc/init.d/ auditd halt lvm2-lvmetad network sandbox udev-post blk-availability ip6tables lvm2-monitor postfix saslauthd crond iptables messagebus rdisc single functions killall netconsole restorecond sshd haldaemon libvirt-guests netfs rsyslog svnserve
chkconfig命令可以用来查看服务在所有级别的启动或关闭设定情形:chkconfig [--list] [name]
查看chkconfig –list
[root@node1 ~]# chkconfig --list auditd 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭 blk-availability 0:关闭 1:启用 2:启用 3:启用 4:启用 5:启用 6:关闭 crond 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭 haldaemon 0:关闭 1:关闭 2:关闭 3:启用 4:启用 5:启用 6:关闭 ip6tables 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭 iptables 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
9. 设置登陆终端
根据终端配置打印登陆提示符
初始化阶段总结为:
/sbin/init --> (/etc/inittab) --> 设置默认运行级别 --> 运行系统初始脚本、完成系统初始化 --> 关闭对应下需要关闭的服务,启动需要启动服务 --> 设置登录终端
整体总结
POST --> Boot Sequence(BIOS) --> Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 系统初始化脚本 --> 关闭或启动对应级别下的服务 --> 启动终端
习题
习题1
为运行于虚拟机上的CentOS 6添加一块新硬件,提供两个主分区;
(1) 为硬盘新建两个主分区;并为其安装grub;
(2) 为硬盘的第一个主分区提供内核和ramdisk文件; 为第二个分区提供rootfs;
(3) 为rootfs提供bash、ls、cat程序及所依赖的库文件;
(4) 为grub提供配置文件;
(5) 将新的硬盘设置为第一启动项并能够正常启动目标主机;
查询磁盘情况
[root@node1 ~]# fdisk -l /dev/sd[a-z] Disk /dev/sdb: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000
磁盘分区并格式化
[root@node1 ~]# fdisk /dev/sdb [root@node1 ~]# partx -a /dev/sdb BLKPG: Device or resource busy error adding partition 1 BLKPG: Device or resource busy error adding partition 2 [root@node1 ~]# cat /proc/partitions major minor #blocks name 8 0 20971520 sda 8 1 512000 sda1 8 2 20458496 sda2 8 16 20971520 sdb 8 17 112423 sdb1 8 18 5253255 sdb2 253 0 6144000 dm-0 253 1 2031616 dm-1 253 2 4087808 dm-2 253 3 8192000 dm-3 [root@node1 ~]# mke2fs -t ext4 /dev/sdb1 [root@node1 ~]# mke2fs -t ext4 /dev/sdb2
创建目录并挂载分区
[root@node1 ~]# mkdir /mnt/boot /mnt/sysroot [root@node1 ~]# ls /mnt boot sysroot [root@node1 ~]# mount /dev/sdb1 /mnt/boot/ [root@node1 ~]# mount /dev/sdb2 /mnt/sysroot/ [root@node1 ~]# ls /mnt/boot lost+found [root@node1 ~]# ls /mnt/sysroot/ lost+found
拷贝kernel和ramfs文件
[root@node1 ~]# cp /boot/initramfs-2.6.32-642.1.1.el6.x86_64.img /mnt/boot/initramfs.img [root@node1 ~]# cp /boot/vmlinuz-2.6.32-642.1.1.el6.x86_64 /mnt/boot/vmlinuz [root@node1 ~]# ls /mnt/boot/ initramfs.img lost+found vmlinuz
安装grub
[root@node1 boot]# grub-install --root-directory=/mnt /dev/sdb 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/sda (hd1) /dev/sdb
创建根目录并拷贝指定程序
[root@node1 ~]# cd /mnt/sysroot/ [root@node1 sysroot]# mkdir -pv bin sbin boot root home usr etc var tmp lib lib64 proc dev mnt media [root@node1 sysroot]# ls bin dev home lib64 media proc sbin usr boot etc lib lost+found mnt root tmp var [root@node1 sysroot]# cp /bin/bash /bin/ls /bin/cat /mnt/sysroot/bin/
拷贝库文件
[root@node1 bin]# ldd /bin/bash [root@node1 bin]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libc.so.6 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/ [root@node1 bin]# ldd /bin/ls [root@node1 bin]# cp /lib64/libselinux.so.1 /mnt/sysroot/lib64/ [root@node1 ~]# cp /lib64/librt.so.1 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libcap.so.2 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libacl.so.1 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libpthread.so.0 /mnt/sysroot/lib64/ [root@node1 bin]# cp /lib64/libattr.so.1 /mnt/sysroot/lib64/ [root@node1 bin]# ldd /bin/cat
修改grub配置文件
[root@node1 ~]# vim /mnt/boot/grub/grub.conf default=0 timeout=5 title CentOS (Express) root (hd0,0) kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash initrd /initramfs.img
关闭用来设置的虚拟机,将硬盘加载到新虚拟机后,正常启动bash,并能执行ls和cat命令
习题2
制作一个kickstart文件以及一个引导镜像。描述其过程。
anaconda的配置方式:
(1) 交互式配置方式;
(2) 通过读取事先给定的配置文件自动完成配置;
按特定语法给出的配置选项;
kickstart文件;
安装引导选项:
text: 文本安装方式
method: 手动指定使用的安装方法
与网络相关的引导选项:
ip=IPADDR netmask=MASK gateway=GW dns=DNS_SERVER_IP ifname=NAME:MAC_ADDR
与远程访问功能相关的引导选项:
vnc vncpassword='PASSWORD'
指明kickstart文件的位置
ks= DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE Hard drive: ks=hd:/device/drectory/KICKSTART_FILE HTTP server: ks=http://host:port/path/to/KICKSTART_FILE FTP server: ks=ftp://host:port/path/to/KICKSTART_FILE HTTPS server: ks=https://host:port/path/to/KICKSTART_FILE
启动紧急救援模式:
rescue
kickstart文件的格式:
命令段:指明各种安装前配置,如键盘类型等;
程序包段:指明要安装的程序包组或程序包,不安装的程序包等;
%packages @group_name package -package %end
脚本段:
%pre: 安装前脚本 运行环境:运行于安装介质上的微型Linux环境 %post: 安装后脚本 运行环境:安装完成的系统;
命令段中的命令:
必备命令
authconfig: 认证方式配置 authconfig --useshadow --passalgo=sha512 bootloader:bootloader的安装位置及相关配置 bootloader --location=mbr --driveorder=sda --append="crashkernel=auto crashkernel=auto rhgb rhgb quiet quiet" keyboard: 设定键盘类型 lang: 语言类型 part: 创建分区 rootpw: 指明root的密码 timezone: 时区
可选命令
install OR upgrade text: 文本安装界面 network firewall selinux halt poweroff reboot repo user:安装完成后为系统创建新用户 url: 指明安装源
创建kickstart文件的方式:
(1) 直接手动编辑;
依据某模板修改;
(2) 可使用创建工具:system-config-kickstart (CentOS 6)
依据某模板修改并生成新配置;
检查ks文件的语法错误:ksvalidator
# ksvalidator /PATH/TO/KICKSTART_FILE
创建引导光盘:
# mkisofs -R -J -T -v –no-emul-boot –boot-load-size 4 –boot-info-table -V “CentOS 6.8 x86_64 boot” -b isolinux/isolinux.bin -c isolinux/boot.cat -o /root/boot.iso myiso/
习题3
写一个脚本
(1) 能接受四个参数:start, stop, restart, status
start: 输出“starting 脚本名 finished.”
…
(2) 其它任意参数,均报错退出;
#!/bin/bash # # chkconfig: - 88 12 # description: test service script # prog=$(basename $0) lockfile=/var/lock/subsys/$prog start() { if [ -e $lockfile ]; then echo "$prog is aleady running." return 0 else touch $lockfile [ $? -eq 0 ] && echo "Starting $prog finished." fi } stop() { if [ -e $lockfile ]; then rm -f $lockfile && echo "Stop $prog ok." else echo "$prog is stopped yet." fi } status() { if [ -e $lockfile ]; then echo "$prog is running." else echo "$prog is stopped." fi } usage() { echo "Usage: $prog {start|stop|restart|status}" } if [ $# -lt 1 ]; then usage exit 1 fi if [ $1 != 'start' -a $1 !='stop' -a $1 != 'restart' -a $1 != 'status' ];then usage exit 2 fi case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) usage esac
习题4
写一个脚本,判断给定的用户是否登录了当前系统;
(1) 如果登录了,则显示用户登录,脚本终止;
(2) 每3秒钟,查看一次用户是否登录;
#!/bin/bash # read -p "Enter a user name: " username while true; do if who | grep "^$username" &> /dev/null; then break fi sleep 3 done echo "$username logged on."
习题5
写一个脚本,显示用户选定要查看的信息;
cpu) display cpu info
mem) display memory info
disk) display disk info
quit) quit
非此四项选择,则提示错误,并要求用户重新选择,只到其给出正确的选择为止;
#!/bin/bash # cat << EOF cpu) show cpu information; mem) show memory information; disk) show disk information; quit) quit ============================ EOF read -p "Enter a option: " option while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do read -p "Wrong option, Enter again: " option done case "$option" in cpu) lscpu ;; mem) cat /proc/meminfo ;; disk) fdisk -l ;; *) echo "Quit..." exit 0 ;; esac
习题6
写一个脚本
(1) 用函数实现返回一个用户的UID和SHELL;用户名通过参数传递而来;
(2) 提示用户输入一个用户名或输入“quit”退出;
当输入的是用户名,则调用函数显示用户信息;
当用户输入quit,则退出脚本;进一步地:显示键入的用户相关信息后,再次提醒输出用户名或quit:
#!/bin/bash # function getinfo { if id $op &> /dev/null;then grep -E '^('$op')\>' /etc/passwd | cut -d: -f1,3,7;read -p "Enter a username or quit:" op else read -p "wrong argument,plsease enter a username or quit:" op fi } read -p "Enter a username or quit:" op while [[ $op != "quit" ]];do getinfo $op done
练习7
写一个脚本,完成如下功能(使用函数)
(1) 提示用户输入一个可执行命令的名字;获取此命令依赖的所有库文件;
(2) 复制命令文件至/mnt/sysroot目录下的对应的rootfs的路径上,例如,如果复制的文件原路径是/usr/bin/useradd,则复制到/mnt/sysroot/usr/bin/目录中;
(3) 复制此命令依赖的各库文件至/mnt/sysroot目录下的对应的rootfs的路径上;规则同上面命令相关的要求;
#!/bin/bash read -p "Enter a exeable commond:" cmd path() { whereis $cmd | cut -d' ' -f2 } ldd $(path $1)| sed '1d'| grep -Eo "/.*[0-9] " > path.txt cp $(path $1) /mnt/sysroot$(path $1) while read line;do cp $line /mnt/sysroot$line done < ./path.txt
原创文章,作者:sthwrong,如若转载,请注明出处:http://www.178linux.com/19012
评论列表(1条)
写的很棒,但是有的脚本应该有点小瑕疵,有的还可以在完善一下