1、请详细描述CentOS系统的启动流程(详细到每个过程系统做了哪些事情)
启动过程 (PC架构)
POST –> Boot Sequence(BIOS) –> Boot Loader (MBR)–>GRUB—> Kernel(ramdisk) –> rootfs –> switchroot –> /sbin/init–>(/etc/inittab, /etc/init/*.conf) –> 设定默认运行级别> 系统初始化脚本 –> 关闭或启动对应级别下的服务 –> 启动终端
系统启动过程简介:
1、加载BIOS的硬件信息与进行自我检测,并依据设置取得第一个可启动的设备;
2、读取并执行第一个启动设备内的MBR的 boot loader (既是grub,spfdisk等程序);
3、依据boot loader的设置加载Kernel, kernel会开始重新检测硬件,加载驱动程序;
4、在硬件驱动成功后,Kernel会主动调动init进程,而init会取得run-level信息;
5、init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境(如网络、时区等);
6、init执行run-level的各个服务的启动(script方式);
7、init执行/etc/rc.d/rc.local文件;
8、init执行终端机模拟程序mingetty来启动login程序,最后等待用户登录。
第一步:加电自检(POST)
系统加电之后,首先进行的硬件自检,一但通电后主板会自动读取ROM(只读)中的程序,进行加载,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。检查各种硬件设备是否完整存在,如内存,硬盘,显示,IO设备等。如果有硬件故障的话将按两种情况理:对于严重故障(致命性故障)则停机,此时由于各种初始化操作还没完成,不能给出任何提示或信号;对于非严重故障则给出提示或声音报警信号,等待用户处理),如果没有故障,POST完成自己
的接力任务,将尾部工作交接给BIOS处理。
第二步:系统引导过程Boot Sequence(BIOS)
POST 过程结束后,系统的控制权从 BIOS 转交到 boot loader。Boot loader 一般存储在系统的硬盘上(传统的 BIOS/MBR 系统),这个时候机器不能获取外部的存储或者网络信息,一些重要的值(日期、时间、其他外部值)都是从CMOS里读取.
POST(POST-power on self test)—>ROM->CMOS(互补金属氧化物)->BIOS (Basic Input Output System,基础输入输出系统)
BIOS(Basic Input/Output System)启动初始化硬件的工作,包括屏幕和键盘,内存检测,这个过程也被成为 POST(Power On Self Test),通过ROM加载自检程序,然后按照 CMOS RAM 中设置的启动设备查找顺序,来寻找可启动设备 。注:BIOS 程序嵌在主板的 ROM 芯片上的。
第三步:启动加载器阶段Master Boot Loader(MBR)
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,决定启动介质按照BIOS所设定的系统启动流程,根据引导次序(Boot Sequence)自上而下的寻找对应存储设备上操作系统的MBR。它的大小仅有512字节,但里面却存放了预启动信息、分区表信息。可分为两部分:
第一部分为引导(PRE-BOOT)区,占了 446个字节;
第二部分为分区表(PARTITION TABLE),共有64个字节,每个主分区占用16字节,记录硬盘的分区信息。(这就是为什么一块硬盘只能有4个主分区)分区表有效性标记会占用2字节。
预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。剩余两个字节为结束标记。寻找 grub,读取配置文件/etc/grub.conf,决定默认启动项根据MBR所指引的活动分区上寻找系统分区中的 bootloader.在bootloader当中配置了所要引导操作系统的内核所在的位置,因此BIOS被载入内存以后,当它实现将控制权限转交给bootloader以后,bootloader接收整个系统的控制权限,而后根据用户的选择去读取相应操作系统中的内核,并将内核装载入内存的某个空间位置,解压缩,这时kernel就可以在内存中活动,并根据kernel本身功能在内存当中探索硬件并加载硬件驱动程序并完成内核初始化,bootloader会将控制权限转交给内核。
第四步:引导加载器阶段(GRUB加载器)
对于GRUB来说,一个比较好的方面就是它包含了linux文件系统的知识。GRUB能够从ext2或者ext3文件系统中加载linux内核。一旦Bootloader的第一阶段已完成MBR(启动加载器阶段),并能找到实际的引导加载程序位置,第1阶段启动加载器加载引导程序到内存中开始第二阶段。GRUB引导加载器阶段它是通过将本来两阶段的boot loader转换成三个阶段的boot loader。
stage1个阶段 :BIOS加载MBR里面的GRUB(属于第1阶段的文件),由于只有GRUB只占用446字节所以不能实现太多的功能,所以就有此阶段里面的文件来加载第1.5阶段的文件(/boot/grub下的文件)
stage1.5个阶段:这个阶段里面的就是加载识别文件系统的程序,来识别文件系统,不加载就无法识别文件系统,进而就找不到boot目录,由于GRUB是无法识别LVM,所以你不能把/boot分区设置为LVM,所以必须要把/boot单独分区
stage2个阶段:这里面才是正在的开始寻找内核的过程,然后是启动内核
(当stage1.5的boot loader被加载并运行时,stage2 的boot loader才能被加载。)
当stage2被加载时,GRUB能根据请求的情况显示一个可选内核的清单(在 /etc/grub.conf 中进行定义,同时还有几个软符号链接 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以选择一个内核,修改其附加的内核参数。同时,你可以选择使用命令行的shell来对启动过程进行更深层次的手工控制。
GRUB的配置文件中的配置哪些信息
在第二阶段boot loader加载到内存中后,就可以对文件系统进行查询了,同时,默认的内核镜像以及初始化内存盘镜像也被加载到内存中。
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux(解压内核中)”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel(正在启动内核)”。
第五步:加载kernel
GRUB把内核加载到内存后展开并运行,此时GRUB的任务已经完成,接下来内核将会接管并完成:
探测硬件—>加载驱动—>挂载根文件系统—>切换至根文件系统(rootfs)—>运行/sbin/init完成系统初始化
内核一般都是压缩的,所以它的首要任务是解压缩,然后检查和分析系统的硬件并初始化内核里的硬件驱动程序。内核刚加载到内存的时候,文件系统还不能使用,它使用的是 Boot Loader 加载进内存的 initramfs。系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
第六步:初始化initrd /etc/inittab
在核心加载完毕,进行完硬件侦测与驱动程序加载后,内核会启动第一个进程/sbin/init, init进程将会读取/etc/inittab,init进程是系统所有进程的起点,你可以把它比拟成系统所有进程的老祖宗,没有这个进程,系统中任何进程都不会启动。
/etc/inittab最主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等,而所有的动作都根据在/etc/inittab中的配置.将会执行/etc/inittab来设定系统运行的默认级别,
init进程首先会读取/etc/inittab文件,根据inittab文件中的内容依次执行
设定系统运行的默认级别(id:3:initdefault:)
执行系统初始化脚本文件(si::sysinit:/etc/rc.d/rc.sysinit)
执行在该运行级别下所启动或关闭对应的服务(l3:3:wait:/etc/rc.d/rc 3)
启动6个虚拟终端
0-6:7个级别的定义
0:关机, shutdown
1:单用户模式(singleuser),root用户,无须认证;维护模式;
2:多用户模式(multiuser),会启动网络功能,但不会启动NFS;维护模式;
3:多用户模式(mutliuser),完全功能模式;文本界面;
4:预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
5:多用户模式(multi user),完全功能模式,图形界面;
6:重启,reboot
许多程序需要开机启动。它们在Windows叫做”服务”(service),在Linux就叫做”守护进程”(daemon)。init进程的一大任务,就是去运行这些开机启动的程序。但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。
Linux允许为不同的场合,分配不同的开机启动程序,这就叫做”运行级别”(runlevel)。也就是说,启动时根据”运行级别”,确定要运行哪些程序。
要访问根文件系统必须要加载根文件系统所在的设备,而这时根文件系统又没有挂载,要挂载根文件系统有需要根文件系统的驱动程序,这是一个典型的先有鸡先有蛋的问题!为解决这个问题,GRUB在加载内核同时,也把initrd加载到内存中并运行.那么initrd又起到了什么作用哪?
initrd展开后的文件
linux中/下的文件
我们可以看到,其实initrd文件其实是一个虚拟的根文件系统,里面有bin、lib、lib64、sys、var、etc、sysroot、dev、proc、tmp等根目录,它的功能就是讲内核与真正的根建立联系,内核通过它加载根文件系统的驱动程序,然后以读写方式挂载根文件系统,至此,内核加载完成。
第七步:运行/sbin/init,进行系统初始化
/sbin/init 最主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等,而所有的动作都根据在/etc/inittab中的配置.init首先运行/etc/init/rcS.conf脚本,如下图
第八步:启动系统服务/etc/rc.d/rc.sysinit
可以看到,init进程通过执行/etc/rc.d/rcS.conf首先调用了/etc/rc.d/rc.sysinit,对系统做初始化设置,设置好整个系统环境。我们来看看这个脚本都是做了些什么哪? 事实上init执行/etc/rc.d/rc.sysinit的初始化将会做很多设置:
1、获得网络环境
2、挂载设备
3、开机启动画面Plymouth(取替了过往的 RHGB)
4、判断是否启用SELinux
5、显示于开机过程中的欢迎画面
6、初始化硬件
7、用户自定义模块的加载
8、配置内核的参数
9、设置主机名
10、同步存储器
11、设备映射器及相关的初始化
12、初始化软件磁盘阵列(RAID)
13、初始化 LVM 的文件系统功能
14、检验磁盘文件系统(fsck)
15、设置磁盘配额(quota)
16、重新以可读写模式挂载系统磁盘
17、更新quota(非必要)
18、启动系统虚拟随机数生成器
19、配置机器(非必要)
20、清除开机过程当中的临时文件
21、创建ICE目录
22、启动交换分区(swap)
23、将开机信息写入/var/log/dmesg文件中
第九步:启动配置文件/etc/rc.d/rc.n
设定玩系统默认运行级别以后,接着调用/etc/rc.d/rc脚本,/etc/rc.d, 里面存放了rc.local, rc.sysinit, init.d, rcX.d (X包括0-6对应相对runlevel).这个脚本接收默认运行级别参数后,依脚本设置启用或停止/etc/rc.d/rc[0-6].d/中相应的程序,如下图,看一下我系统运行默认级别(级别)3下的内容吧
如图示,/etc/rc.d/rc3].d/下的脚本文件在系统初始化阶段,脚本名字以K开头的,表示STOP动作(关闭),名字以S开头,表示Start动作(启动),文件名K/S 后面的的数字代表优先级,名称中的数字表示执行次序(优先级),数字越小表示越先执行,优先级越高
第十步:用户自定义开机启动程序 (/etc/rc.d/rc.local)
系统根据runlevel启动完rcX.d中的脚本之后,会调用rc.local脚本,如果你有一个脚本命令不论在3和5都想开机启动,那么就添加于此,免去rc3.d和rc5.d分别增加启动脚本工作量.最后,将执行/etc/rc.d/rc.local脚本,可以根据自己的需求将一些执行命令或者脚本写到其中,当开机时就可以加载。
第十一步:打印登录提示符
系统初始化完成后,init给出用户登录提示符(login)或者图形化登录界面,用户输入用户和密码登陆后,系统会为用户分配一个用户ID(uid)和组ID(gid),这两个ID是用户的身份标识,用于检测用户运行程序时的身份验证。登录成功后,整个系统启动流程运行完毕!
2、为运行于虚拟机上的CentOS 6添加一块新硬件,提供两个主分区;
(1) 为硬盘新建两个主分区;并为其安装grub;
(2) 为硬盘的第一个主分区提供内核和ramdisk文件; 为第二个分区提供rootfs;
(3) 为rootfs提供bash、ls、cat程序及所依赖的库文件;
(4) 为grub提供配置文件;
(5) 将新的硬盘设置为第一启动项并能够正常启动目标主机;
新建两个主分区
Disk identifier: 0x474f70eb
Device Boot Start End Blocks Id System
/dev/sdb1 1 66 530113+ 83 Linux
/dev/sdb2 67 1372 10490445 83 Linux
挂载
mount /dev/sdb1 /mnt
安装grub到分区
# 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
复制虚拟文件系统,内核文件
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/initramfs
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/vmlinuz
创建grub.conf文件
~]# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title CentOS6(test)
root (hd0,0)
kernel /vmlinuz ro root=/dev/sdb2 selinux=0 init=/bin/bash
initrd /initramfs
挂载sdb2,并创建rootfs相关目录
~]# umount /dev/sdb1
~]# mount /dev/sdb2 /mnt
~]# mkdir -p /mnt/{bin,sbin,lib,lib64,etc,home,root,media,mnt,dev,tmp}
~]# mkdir -p /mnt/{usr/{bin,sbin,lib,lib64},var/{lib,lib64,log,local,cache},proc,sys,selinux}
~]# which ls
alias ls=’ls –color=auto’
/bin/ls
~]# which bash
/bin/bash
~]# which cat
/bin/cat
~]# cp /bin/{bash,ls,cat} /mnt/bin
ldd命令:
– print shared library dependencies
ldd [OPTION]… FILE…
~]# ldd /bin/{bash,ls,cat}|grep -Eo “/lib.*[[:space:]]”| sort -u
/lib64/ld-linux-x86-64.so.2
/lib64/libacl.so.1
/lib64/libattr.so.1
/lib64/libcap.so.2
/lib64/libc.so.6
/lib64/libdl.so.2
/lib64/libpthread.so.0
/lib64/librt.so.1
/lib64/libselinux.so.1
/lib64/libtinfo.so.5
~]# cp `ldd /bin/{bash,ls,cat}|grep -Eo “/lib.*[[:space:]]”| sort -u` /mnt/lib64
~]# sync 同步sync – flush file system buffers
~]#init 6
重启后进入bios设置 调整硬盘启动顺序后保存退出。
3、制作一个kickstart文件以及一个引导镜像。描述其过程。
1、centos系统安装完成后,anaconda会根据本次系统安装的配置,生成一个与本次安装设置相同的kickstart文件,文件位于/root/anaconda-ks.cfg,可以使用vim对这个文件进行修改来使用。
2、图形化配置 kickstart 文件的工具: system-config-kickstart,能够在图形界面下选择安装选项并将结果保存为 kickstart 文件。yum install system-config-kickstart
可以直接手动编辑或使用工具在桌面模式下用system-config-kickstart(centos6.x)来创建ks.cfg #命令段 firewall --disabled//禁用防火墙 install//执行新安装 cdrom//用光盘安装 lang en_US.UTF-8//默认安装语言 keyboard us//选择键盘 rootpw --iscrypted $6$AF1u4TWzFxa/SzHI$yJvJdbhyw/2rG8dtr.PY6c15sZ.qNc6US/z7PMQ4lADdlIis/qIMO738b9czXK/rX1YDiL7Uv/C6Bi99ig8ov0//管理员加密密码 authconfig --enableshadow --passalgo=sha512 selinux --enforcing//激活selinux logging --level=info//信息等级 timezone --utc Asia/Shanghai//系统时区 bootloader --location=mbr --driveorder=sdb --append="crashkernel=auto rhgb quiet" clearpart --all//删除所有现在分区 part /boot --fstype=ext4 --size=200//分区挂载 part / --fstype=ext4 --size=40960 part swap --size=4096 #脚本段 %pre//安装前脚本 echo "start install" %end %post//安装后脚本 echo "install end" #程序包段 %packages @chinese-support//中文支持 @development//开发工具 @graphical-desktop-clients//图形化工具 @remote-desktop-clients//远程桌面客户端 %end 简单引导镜像光盘制作: 1、复制安装系统光盘引导文件和配置好的ks.cfg文件到一自制目录(/centos6.6) mkdir myboot cd /myboot cp -r /media/cdrom/isolinux/./ cp /root/ks.cfg ks.cfg 2、在isolinux.cfg中指明kickstart文件位置,可以实现完全自动化安装。也可以在“boot:”提示符下手动指定 append initrd=initrd.img ks=cdrom:/ks.cfg 3、创建ISO启动镜像 mkisofs -R -J -T -v --no-emul-boot --boot-load-size 4 --boot-info-table -V "CentOS 6.6 x86_64 boot" -c isolinux/boot.cat -b isolinux/isolinux.bin -o isolinux/boot.iso
4、写一个脚本
(1) 能接受四个参数:start, stop, restart, status start: 输出“starting 脚本名 finished.” …
(2) 其它任意参数,均报错退出;
#!/bin/bash # case $1 in start) echo "start $0 finished." ;; stop) echo "stop $0 finished." ;; restart) echo "restart $0 finished." ;; status) echo "status $0 ok." ;; *) echo "error" exit 1 ;; esac
5、写一个脚本,判断给定的用户是否登录了当前系统;
(1) 如果登录了,则显示用户登录,脚本终止;
(2) 每3秒钟,查看一次用户是否登录;
#!/bin/bash if [ $# -lt 1 ];then echo "at least one arg" exit 1 fi while true;do if w | grep $1 &>/dev/null;then echo "the user $1 is login" break else echo "waiting" sleep 3 fi done
6、写一个脚本,显示用户选定要查看的信息;
cpu) display cpu info
mem) display memory info
disk) display disk info
quit) quit
非此四项选择,则提示错误,并要求用户重新选择,只到其给出正确的选择为止;
#!/bin/bash # cat << EOF cpu) display cpu information mem) display memory infomation disk) display disks information quit) quit EOF read -p "Enter your option: " option while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]; do echo "cpu, mem, disk, quit" read -p "Enter your option again: " option done if [ "$option" == "cpu" ]; then lscpu elif [ "$option" == "mem" ]; then free -m elif [ "$option" == "disk" ]; then fdisk -l /dev/[hs]d[a-z] else echo "quit" exit 0 fi
7、写一个脚本
(1) 用函数实现返回一个用户的UID和SHELL;用户名通过参数传递而来;
(2) 提示用户输入一个用户名或输入“quit”退出;
当输入的是用户名,则调用函数显示用户信息;
当用户输入quit,则退出脚本;进一步地:显示键入的用户相关信息后,再次提醒输出用户名或quit: ”
#!/bin/bash function user_id( ) { if id $username &> /dev/null; then grep "^$username" /etc/passwd | awk -F: '{print "UID is:"$3, " Shell is:"$7}' else echo "none user" fi } while true;do read -p "please enter username or quit:" username if [ $username == "quit" ];then exit 0 else user_id $username fi done
原创文章,作者:victorli88,如若转载,请注明出处:http://www.178linux.com/67100
评论列表(1条)
总结的很好,图文并茂,Linux的启动流程可以画一张图,加油!!!