linux-系统启动流程-7
1,BIOS开机自检,检查cpu硬件及开机启动顺序,查找第一个磁盘磁头的MBR信息并加载BOOtloader,然后将控制权交与bootloader
2, GRUB
GRUB(Grand Unified Bootloader),多系统启动程序
stage1 : 查找加载stage 1.5
stage1.5: 可以识别文件系统, 即识别 /boot/ 磁盘第一个分区
stage 2: grub 识别/boot/grub/grub.conf ,根据配置文件,读取Kernel 信息,然后加载kernel 同时stage2也将initrd (Initial RAM Disk) 包含了磁盘的驱动程序,) 拷贝到内存,内核解压后,从该临时文件系统中加载驱动,识别根文件系统,根据 /etc/fstab 挂载文件系统 ,然后内核切根,随后执行第一个进程 init
内核解压后同时解压initramfs微型文件系统,通过此文件系统,内核获取磁盘的驱动程序,并驱动所有的硬件外设,读取磁盘后将文件系统根
切换到该磁盘文件系统下,通过/etc/fstab挂载所有文件系统。然后执行核心init 程序,根据/etc/inittab,执行脚本
系统进程
在内核加载完毕,并完成硬件检测与驱动程序加载后,主机硬件已经准备完毕,内核会主动呼叫第一个进程,也就是 /sbin/init
CentOS 5.x 系统相比也有较大变化。在 CentOS 5.x 系统中,主要通过 init 进程的配置文件 /etc/inittab 来设定系统,并启动 Linux。但是在 CentOS 6.x 系统中,由于用 Upstart 启动服务来替换以前的 init,所以在 /etc/inittab 配置文件中只能定义系统的默认运行级别,而其他的功能是靠 /etc/init/ 目录中的其他配置文件实现的
stage2:
开机启动的时候看到的Grub选项、信息,还有修改GRUB背景等功能都是stage2提供的,stage2会去读入/boot/grub/grub.conf或者menu.lst等配置文件
4.读取grub.conf文件
读取grub.conf文件以确定内核启动的参数,准备启动内核
5.启动内核
加载内核,核心开始解压缩,启动一些最核心的程序。
因为为了让内核足够轻小,硬件驱动并没有放在内核文件里面,我们可以看到内核很小,才4M左右,我们可以想象Windows中的驱动,安装系统时候还需要使用驱动软件下载好长时间呢
因此需要使用/initramfs-2.6.32-696.el6.x86_64.img来驱动硬件
6.加载伪文件系统(ramdisk),
内核已将启动起来了,再调用ramdisk文件,尝试驱动所有的硬件设备,到这一步,内核起来了,所有驱动也装上了,因此后面的启动就可以交给程序了
7.启动init进程
grub中默认指定init=/sbin/init程序,可以在grub.conf中kernel行自定义执行程序init=/bin/bash,此时可以绕过下面步骤直接进入bash界面。
内核源代码文件中显示996行左右,规定了init启动的顺序,/sbin/init->/etc/init->/bin/init->/bin/sh,/bin/bash没有写,应该是和/bin/sh一样吧
(1)读取/etc/inittab文件
inittab文件里面定义了系统默认运行级别,这一步做了一些工作如下:
a)初始运行级别(RUN LEVEL)
b)系统初始化脚本
c)对应运行级别的脚本目录
d)定义UPS电源终端/恢复脚本
e)在虚拟控制台生成getty,以生成终端
f)在运行级别5初始化X
(2)执行/etc/rc.d/rc.sysinit程序
系统初始化一些脚本,主要完成以下工作
a)设置主机名
b)设置欢迎信息
c)激活udev和selinux可以在grub.conf中,kernel行添加selinux=0以关闭selinux
d)挂载/etc/fstab文件中定义的文件系统
e)检测根文件系统,并以读写方式重新挂载根文件系统
f)设置系统时钟
g)激活swap设备
h)根据/etc/sysctl.conf文件设置内核参数
i)激活lvm及software raid设备
j)加载额外设备的驱动程序
k)清理操作
(3)/etc/rc#.d/文件(各种服务)
里面定义的是各种服务的启动脚本,可以ls查看,S开头代表开机启动的服务,K开头的是关机要执行的任务。#代表数字,一个数字代表一个运行级别,共7个运行级别,这里就不多说了
(4)/etc/rc.d/rc.local文件
这里面可以自定义开机启动的命令。
8.执行/bin/login
执行/bin/login程序,等待用户登录
CentOS7启动流程
CentOS7和CentOS6启动流程差不多,只不过到init程序时候,改为了systemd,因此详细解释一下systemd后的启动流程
1.uefi或BIOS初始化,开始post开机自检
2.加载mbr到内存
3.GRUB阶段
4.加载内核和inintamfs模块
5.内核开始初始化,使用systemd来代替centos6以前的init程序
(1)执行initrd.target
包括挂载/etc/fstab文件中的系统,此时挂载后,就可以切换到根目录了
(2)从initramfs根文件系统切换到磁盘根目录
(3)systemd执行默认target配置
centos7表面是有“运行级别”这个概念,实际上是为了兼容以前的系统,每个所谓的“运行级别”都有对应的软连接指向,默认的启动级别时/etc/systemd/system/default.target,根据它的指向可以找到系统要进入哪个模式
模式:
0 ==> runlevel0.target, poweroff.target
1 ==> runlevel1.target, rescue.target
2 ==> runlevel2.target, multi-user.target
3 ==> runlevel3.target, multi-user.target
4 ==> runlevel4.target, multi-user.target
5 ==> runlevel5.target, graphical.target
6 ==> runlevel6.target, reboot.target
(4)systemd执行sysinit.target
有没有很眼熟?是的,在CentOS6上是被叫做rc.sysint程序,初始化系统及basic.target准备操作系统
(5)systemd启动multi-user.target下的本机与服务器服务
(6)systemd执行multi-user.target下的/etc/rc.d/rc.local
6.Systemd执行multi-user.target下的getty.target及登录服务
getty.target我们也眼熟,它是启动终端的systemd对象。如果到此步骤,系统没有被指定启动图形桌面,到此就可以结束了,如果要启动图形界面,需要在此基础上启动桌面程序
7.systemd执行graphical需要的服务
CentOS6,7启动区别
系统启动和服务器守护进程管理器,它不同于centos5的Sysv init,centos6的Upstart(Ubuntu制作出来),systemd是由Redhat的一个员工首先提出来的,它在内核启动后,服务什么的全都被systemd接管,kernel只是用来管理硬件资源,相当于内核被架空了,因此linus很不满意Redhat这种做法。
系统启动流程实验
centos 6 grub.conf
grub/grub.conf
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-754.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-754.el6.x86_64 ro root=UUID=f2230c8f-30fb-4c8a-b7c9-a08f0e42bf7b rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-754.el6.x86_64.img
1,/boot/grub.conf 被破环的显示图
内核及initrd 后 tab出来的选项
root(hd0,0) 指boot分区,root=/dev/sda2 指根分区
进入后创建/boot/grub/grub.conf
default=0
timeout=5
title CentOS 6 (2.6.32-754.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-754.el6.x86_64 ro root=/dev/sda2
initrd /initramfs-2.6.32-754.el6.x86_64.img
没有配置 root =/dev/sda2时报错如下
进入救援模式后
chroot /mnt/sysimage
grub-install --root-directory=/ /dev/sda
创建/boot/grub/grub.conf
default=0
timeout=3
title centos6
root (hd0,0)
kernel /vmlinuz-------- root=/dev/sda2
initrd /initramfs ----
2,破环了mbr 446 字节
dd if=/dev/zero of=/dev/sda bs=1 count=446
现象
还可以看见分区表 且可以挂载到 /mnt/sysimage
chroot /mnt/sysimage
grub-install /dev/sda
sync
sync 数据写入磁盘
退出重启
3,删除掉 /boot/initramfs-·内核版本号·
现象
可以显示grub内核列表,但是回车后无法进入下一项,光标在左上角一直闪烁,不能进入centoes 6logo 界面
救援光盘进入bash
切根 chroot /mnt/sysimage
生成 initramfs.img
mkinitrd /boot/initramfs-uname -r
.img uname -r
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
/boot/vmlinuz--
可以看到grub可以识别grub.conf
但是不能正常载入内核,
无法载入内核报错
救援模式进入系统,挂载光盘
进入镜像目录,复制vmlinuz 为 vmlinuz-uname -r
与/boot/grub/grub.conf 里kernel 保持一致
或者通过挂载光盘使用rpm强制安装内核生成
rpm -ivh --force kernel-2.6.32-71.el6.x86_64.rpm
https://www.ibm.com/developerworks/cn/linux/l-cn-disa-recov/
CentOS6启动流程
1.加载BIOS的硬件信息,获取第一个启动设备
2.读取第一个启动设备MBR的引导加载程序(grub)的启动信息
3.加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备
4.核心执行init程序,并获取默认的运行信息
5.init程序执行/etc/rc.d/rc.sysinit文件
6.启动核心的外挂模块
7.init执行运行的各个批处理文件(scripts)
8.init执行/etc/rc.d/rc.local
9.执行/bin/login程序,等待用户登录
10.登录之后开始以Shell控制主机
内核
核心文件
未压缩的内核镜像 :/boot/vmlinuz-version-release
内核镜像可以挂载光盘,在iso中获取
RAMDISK 辅助的伪根系统
在stage-2阶段被读取进内存,被内核解压释放后暂时挂载,
内核读取硬件驱动文件后,识别系统磁盘,进而挂载真实文件系统,然后切换根到
真实的根上。
CentOS 5 /boot/initrd-VERSION-release.img
CentOS 6,7 /boot/initramfs-VERSION-release.img
可以使用工具生成
mkinitrd
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
CentOS 5 的inittab文件
init 初始化
init读取其初始化文件:/etc/inittab
初始运行级别(RUN LEVEL)
系统初始化脚本对应运行级别的脚本目录
捕获某个关键字顺序
定义UPS电源终端/恢复脚本
在虚拟控制台生成getty
在运行级别5初始化X
CentOS 6 的inittab文件
/etc/rc.d/rc.sysinit: 系统初始化脚本
(1) 设置主机名
(2) 设置欢迎信息
(3) 激活udev和selinux
(4) 挂载/etc/fstab文件中定义的文件系统
(5) 检测根文件系统,并以读写方式重新挂载根文件系统
(6) 设置系统时钟
(7) 激活swap设备
(8) 根据/etc/sysctl.conf文件设置内核参数
(9) 激活lvm及software raid设备
(10) 加载额外设备的驱动程序
(11) 清理操作
centos 7
CentOS 7
引导顺序UEFi或BIOS初始化,运行POST开机自检
选择启动设备
引导装载程序, centos7是grub2
加载装载程序的配置文件:
/etc/grub.d/
/etc/default/grub
/boot/grub2/grub.cfg
加载initramfs驱动模块
加载内核选项
内核初始化,centos7使用systemd代替init
执行initrd.target所有单元,包括挂载/etc/fstab
从initramfs根文件系统切换到磁盘根目录
systemd执行默认target配置,配置文件/etc/systemd/system/default.target
systemd执行sysinit.target初始化系统及basic.target准备操作系
systemd启动multi-user.target下的本机与服务器服务
systemd执行multi-user.target下的/etc/rc.d/rc.local
Systemd执行multi-user.target下的getty.target及登录服务
systemd执行graphical需要的
6破解
grub 菜单------e ------修改内核 加 1 进入单用户模式
7破解口令
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux16开始的行,添加内核参数rd.break
按ctrl-x启动
mount –o remount,rw /sysroot
chroot /sysroot
passwd root
touch /.autorelabe
lexit
reboot
方法2
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux16开始的行,改为rw init=/sysroot/bin/sh
按ctrl-x启动
chroot /sysroot
passwd root
touch /.autorelabel
exit
reboot
修复grub2
GRUB“the Grand Unified Bootloader”
引导提示时可以使用命令行界面可从文件系统引导
主要配置文件 /boot/grub2/grub.cfg
修复配置文件grub2-mkconfig -o /boot/grub2/grub.cfg
修复grub
grub2-install /dev/sda BIOS环境
grub2-install UEFI环境
调整默认启动内核
vim /etc/default/grub
GRUB_DEFAULT=0
或者
grub2-set-default "CentOS Linux (3.10.0-327.el7.x86_64) 7 (Core)"
查看是否修改成功
grub2-editenv list
自制Linux系统
添加新硬盘,扫描新增磁盘
echo "- - -" /sys/
1,创建分区文件系统
fdisk /dev/sdb分两个必要的分区
/dev/sdb1对应/boot /dev/sdb2对应根/
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
挂载boot
mkdir /mnt/boot 子目录必须为boot
mount /dev/sdb1 /mnt/boot
然后安装grub
grub-install --root-directory=/mnt /dev/sdb
####################
确定busybox 复制在/dev/sdb1 中而不是/dev/sdb2
2,恢复内核及initramfs
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot
建立grub.conf
vim /mnt/boot/grub/grub.conf
title wanglinux
root (hd0,0)kernel
/vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2 selinux=0 init=/bin/bash initrd
/initramfs-2.6.32-642.el6.x86_64.img
配置文件内核名称与目录中文件保持一致
3,创建一级目录,复制相关命令至指定目录
mkdir /mnt/sysroot
mount /dev/sdb2 /mnt/sysroot
mkdir –pv
/mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,dev,mnt,media}
复制相关命令及库文件
ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid
ldd which swapon
判断链接库文件,复制到相应目录
如果需要使用网路功能,还需要复制驱动程序e1000
cp /lib/modules/2.6.32-696.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
/mnt/sysroot/lib/
查看网卡驱动
ethtool -i eth0
modinfo e1000 查看驱动位置,复制网卡驱动
insmod e1000.ko 加载驱动模块
开机启动具有加载模块功能
############
使用脚本复制动态链接库文件至相关目录中,驱动模块一并复制进去
############
复制动态链接库脚本
如果有该命令就且存在目标目录,复制命令和动态链接库至指定目录
which --skip-alias mv 跳过别名
#!/bin/bash
bincopy(){
if which $1 &> /dev/null ;then
local bin_cmd=`which --skip-alias $1`
local dir_cmd=`dirname $bin_cmd `
[ -d ${chroot}${dir_cmd} ] || mkdir -pv ${chroot}${dir_cmd}
[ -f ${chroot}${bin_cmd} ] || { cp $bin_cmd ${chroot}${dir_cmd}; action
"cp $bin_cmd ${chroot}${dir_cmd}" ; }
return 0
else
echo "$1 is not found"
return 1
fi
}
libcopy(){
ldd $(which --skip-alias $1)|grep -Eo "/[^[:space:]]+" |while read line ;do
local lib_dir=`dirname $line`
[ -d ${chroot}${lib_dir} ] || mkdir -pv ${chroot}${lib_dir}
[ -f ${chroot}${line} ] || { cp $line ${chroot}${lib_dir}; action "cp
$line ${chroot}${lib_dir}" ; }
done
}
source /etc/init.d/functions
chroot=/mnt/sysroot
[ -d $chroot ] || mkdir -pv $chroot
while : ;do
read -p "please input a command you want to copy:" cmd
[[ $cmd =~ ^q(uit)?$ ]] && break
bincopy $cmd
if [ $? -eq 0 ]; then
libcopy $cmd
fi
done
内核模块编译
lsmod | grep xfs
显示由核心装载的模块 内容来自 /proc/modules
需要写模块路径,不能解决依赖关系
depmod
insmod 指定模块文件,不自动解决依赖模块
insmod `modinfo –n exportfs`
modprobe -r 装载模块
modinfo [ -k kernel ] [ modulename|filename... ]
-n:只显示模块文件路径
-p:显示模块参数-
a:作者
-d:描述
编译内核
前提:获取目标主机硬件设备信息,系统信息,开发环境准备
目标主机硬件设备相关信息
cpu
cat /proc/cpuinfo
x86info -a
lscpu
硬件设备
lspci
-v
-vv
lsusb
-v
-vv
lsblk
hal-device:CentOS 6
编译系统
安装开发包组
下载源码文件
.config:准备文本配置文件
make menuconfig:配置内核选项
make [-j #] (选择相应的功能)
make modules_install:安装模块
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件
部分编译内核
编译内核的一部分功能:
(a) 只编译某子目录中的相关代码
cd /usr/src/linux
make dir/
(b) 只编译一个特定的模块
cd /usr/src/linux
make dir/file.ko
示例:只为e1000编译驱动:
make drivers/net/ethernet/intel/e1000/e1000.ko
示例
tar xf linux-3.10.67.tar.xz -C /usr/src
cd /usr/src
ln -sv linux-3.10.67 linux
cd /usr/src/linux
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig
make -j 2
make modules_install
make install
reboot
busybox 编译
centos 6 没有编译成功 centos7 成功,可以在6 中使用
编译安装busybox
环境
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel libmcrypt-devel glibc-static ncurses-devel
下载源代码
wget https://busybox.net/downloads/busybox-1.30.0.tar.bz2
make menuconfig
按下面选择,把busybox编译也静态二进制、不用共享库
Busybox Settings -->Build Options -->[*] Build BusyBox as a static binary (no shared libs)
make && make install 如果出错,执行make clean后,重新执行上面命令
mkdir /mnt/sysroot/
cp -a _install/* /mnt/sysroot/
_install 目录文件中存放有软连接
面试
查看加载模块
lsmod modinfo modprobe
开机启动文件 /etc/rc.d/
引导加载程序 LILO GRUB
开机启动流程
查看BIOS版本 biosdecode
查看服务器型号: dmidecode | grep 'Product Name'
查看主板的序列号: dmidecode |grep 'Serial Number'
ethtool -i eth0
内核参数处理
sysctl -a 显示当前所有可用的内核参数
sysctl kernel.hostname 读特定的内核参数,比如kernel.hostname
sysctl -w kernel.hostname=abc 把hostname改为abc
linux 系统运行级别
0: 系统停机(关机)模式,系统默认运行级别不能设置为0,否则不能正常启动,一开机就自动关机。
1:单用户模式,root权限,用于系统维护,禁止远程登陆,就像Windows下的安全模式登录。
2:多用户模式,没有NFS网络支持。
3:完整的多用户文本模式,有NFS,登陆后进入控制台命令行模式。
4:系统未使用,保留一般不用,在一些特殊情况下可以用它来做一些事情。例如在笔记本电脑的电池用尽时,可以切换到这个模式来做一些设置。
5:图形化模式,登陆后进入图形GUI模式或GNOME、KDE图形化界面,如X Window系统。
6:重启模式,默认运行级别不能设为6,否则不能正常启动,就会一直开机重启开机重启。
/etc/rc.d/rc.local 写入此文件的命令登陆前自动执行
系统关机及重启
shutdown -h 10 自动关机
-r 10 自动重启
centos 6 设置grub密码
vim /boot/grub.conf
default=0
timeout=8
password centos
........
###############
破坏的文件是需要命令进行恢复,即切根后可以执行完整的命令
如果没有命令,需要从光盘进行安装软件
#######
1,破坏stage-1 :mbr破坏掉
切换跟使用grub-install /dev/sda
2,删除vmlinuz和initramfs文件后无法启动
切跟后
mkinitrd /boot/initramfs-`uname -r`.img `uname -r `
cp /mnt/cdrom/isolinux/vmlinuz /boot/vmlinuz-`uname -r`
sync
sync
或
rpm -ivh /mnt/cdrom/Packages/kernel-2.6.32-696.e16.x86_64.rpm --root=/mnt/sysimage/ --force
centos 7 编译安装的服务配置service 服务脚本