Linux系统启动流程、grub修复、模块管理及内核参数设定
runlevel, who -r , chkconfig ,grub ,grub-install , mkinitrd , dracut ,sysctl ,lsmod ,modinfo , modprobe , depmod , insmod ,rmmod
Linux系统的组成部分
-
kernel
- /boot/vmlinuz-VERSION-RELEASE
-
initrd
- Centos 5 : /boot/initrd-VERSION-RELEASE.img
- Centos 6/7 : /boot/initramfs-VERSION-RELEASE.img
-
filesystem
-
模块文件
- 一般存放于/lib/modules/$(uname -r)/目录下
内核的设计流派
- 单内核设计
- 把所有功能集成于同一个程序中,其中linux就是以单内核设计
- 微内核设计
- 每个功能使用一个单独的子系统实现,每个子系统通信需有特殊的机制来实现,其中winodows、solaris的内核设计方式就为微内核。
Linux内核的特点
- 单内核设计
- 支持模块化(.ko的文件,[]kernel object])
- 支持模块运行时动态装载或卸载
- 内核可以将驱动模块或者功能模块编译进内核,由内核初始化直接加载完成
linux启动流程示意(内核空间---用户空间)
-
内核空间
- POST—>BootSequence(BIOS)—>bootloader(MBR)—>kernel(ramdisk) —>rootfs(只读方式挂载)—> /sbin/init
-
用户空间:
- /sbin/init(/etc/inittab) --> { id:#:initdefault: --> si::sysinit:/etc/rc.d/rc.sysinit --> l#:#:wait:/etc/rc.d/rc # --> /etc/rc.d/rc#.d/[1、开始S开头的服务;2、结束K开头的服务]}-->/etc/rc.d/rc.local
- 注意:以上{}中,表示在/etc/inittab文件中完成的步骤。
- /sbin/init(/etc/inittab) --> { id:#:initdefault: --> si::sysinit:/etc/rc.d/rc.sysinit --> l#:#:wait:/etc/rc.d/rc # --> /etc/rc.d/rc#.d/[1、开始S开头的服务;2、结束K开头的服务]}-->/etc/rc.d/rc.local
内核空间启动步骤
1、POST加电自检
- 当按主机电源键,计算机主板通电,并完成已下操作:
- 加载Bios中的ROM中的程序,来检测各种硬件设备
Bios : Baisc input and output system
2、BootSequence
- 按bootsequence的启动列表,查找MBR或UEFI的活动设备。
3、Bootloader
- 找到MBR后查找引导加载器(bootloader程序),读取mbr中的bootloader,加载boootloader中的grub程序
Grub的工作原理
- stage1: 加载mbr中的所有分区信息
- stage1.5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的文件分区上的文件系统
- stage2: 磁盘分区之上(/boot/grub/)
注意:MBR能识别基本的硬盘设备,但不能识别高级的文件系统,如lvm , raid等
Bootloader的类型及使用场景
- ntloader
- windows
- LILO(linux loader)
- 早期的Linux系统
- 安卓手机设备
- grub(Grand Uniform bootloader)
- Centos 5/6 (grub 0.X)
- Centos 7 (grub 1.X)
4、加载虚根文件系统(ramfs)
- 完成虚根ramfs的初始化,以此来识别硬盘上的文件系统。
5、挂载rootfs
- 以只读方式挂载根文件系统
6、初始化init进程
- 运行进程ID为1的Init进程,利用init启动流程完成用户空间的启动步骤
用户空间启动步骤
SysVinit进程的初始化
-
读取/etc/inittab,需完成如下加载步骤:
- 系统运行级别加载:id:#initdefault:
- si::sysinit:/etc/rc.d/rc.sysinit : 加载运行/etc/rc.d/rc.sysinit文件,完成如下动作:
- 激动Udev和selinux
- 根据/etc/sysctl.conf文件,来设置内核参数
- 设定系统时钟
- 装载键映射
- 启用交换分区
- 设置主机名
- 要文件系统检测,并以读写方式重新挂载
- 激活raid和lvm设备
- 启用磁盘配额
- 根据/etc/fstab检测并挂载所有文件系统
- 清理过期的锁和PID文件
- l0:0:wait:/etc/rc.d/rc 0 ---> /etc/rc.d/rcX.d/* 对应系统运行级别,开启或关闭系统各服务,如下:
- 停止K*的服务
- 启动S*开头的服务
- 以上服务都由chkconfig命令管理,并由service命令调用执行停止或关闭操作。
- tty6:2345:respawn:/usr/sbin/mingetty tty6,启动登录窗口,并打印欢迎界面
- 其是mingetty调用login程序,完成密码验证过程
- 加载/etc/rc.d/rc.local文件
- 此文件是系统最后启动的一个文件,可以将不需要写在服务维护脚本的命令放置在这里,它将会随系统一起启动完成。
注意:
- Centos7的init程序为systemd,其配置文件存放于:/usr/lib/systemd/system/* ; /etc/systemd/system/*
- Centos6的init为upstart,但为了兼容SysV风格,名称也为Init,其配置文件放置于/etc/init/*.conf
upstart的初始化流程
/etc/inittab
(定义了默认的运行级别)-->/etc/init/rc.conf
(其中定义了相应的运行级别所要执行对应级别下的服务/etc/rc.d/rcX.d/* ,根据命令exec /etc/rc.d/rc $RUNLEVEL
来调用/etc/rc.d/rcX.d/*
)-->/etc/rc.d/rc.local
================
/etc/inittab文件格式说明
- id:runlevel:action:process
- id: 一个任务的标识
- runlevel: 在哪些级别下启动此任务,可以为空,即表示所有级别
- action:在什么条件下启动此任务
- wait : 等待切换至此任务所在的级别时执行一次
- respawn : 设定默认运行给别,此时process省略
- sysinit: 设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit脚本
- process:任务
示例
0:0:wait:/etc/rc.d/rc 0 : 意味着去启动或者关闭/etc/rc.d/rc3.d/目录下的服务脚本所控制的服务,所有K开头的要停止的服务,所有S开头的启动。 其中表示优先级,K中数值越小,表示越先关闭,S中数据越小表示越先开启。一般依赖的服务先关闭,然后再关闭被依赖的。或者一般被依赖的服务先启动,依赖的服务后启动
============
运行级别:
- 0:关机,shutdown
- 1: 单用户模式,(single user) root用户,无须认证登陆
- 2:多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式
- 3:多用户模式(multi user),完全功能模式,文本界面
- 4:预留级别:目前无特别使用目的。但习惯与同3级别功能使用
- 5: 多用户模式:(multi user),完全功能模式,图形界面。
- 6: 重启,reboot
查看系统运行级别
- runlevel
- who -r
- systemctl get-default(Centos 7)
=========
系统服务类脚本的添加和管理
添加一个脚本格式
#!/bin/bash
#
#chkconfig: 2345 50 60 #表示2345开启,其他关闭
#description XXXXX
下面是脚本正文,需要接受至少如下四个参数:
{start|stop|restart|status}
使用chkconfig命令添加服务及管理
- 首先需要将脚本复制至/etc/init.d/中。
- 再使用chkocnfig --add 脚本名称(服务名称)
- 再使用service 脚本服务 start
=============
chkconfig命令
- chkconfig --add service_name
- 添加一个服务脚本
- chkconfig --del service_name
- 删除一个服务脚本
- chkconfig --list
- 查看所有服务的启动状态
- chkconfig 2345 service_name on
- 在2345运行级别启用此服务
- chkconfig 2345 service_name off
- 在2345运行级别下关闭此服务
grub如何识别设备
- 1、Boot需单独分区
- grub的位置应该为/grub/vmlinz
- 2、识别磁盘都为hd
- (hd#,#) : 第一个表示磁盘分区,第二个#表示分区,都用数字表示,从零开始编号
grub的命令行接口
help:获取帮助列表
help KEYWORD : 详细帮助信息
find (hd#,#)/PATH/TOSOMFILE
find (hd0,0)/vmlinuz-2.6.32
root(hd0,0) :把那个设备设置为根设备
-
kernel /path/to/kernel_file: 设定本次启动时用到的内核文件,额外还可以添加许多内核使用的command参数
例如:init=/path/to/init, selinux=0,quiet
initrd /path/to/initramfs_file | initrd_file : 设定为选定的内核提供额外文件的ramfs(必须与内核版本号完全匹配)
boot:引导启动选定的内核
手动在grub命令行接口启动系统:
grub> root(hd0,0)
grub> kernel /vmlinuz-version-release ro root=/dev/DEVICE
grub> initrd /initramfs-version-release.img
grub> boot
注意:ro : 表示以只读方式挂载根文件系统
root=/dev/DEVICE : 应该写根文件系统所在的磁盘分区
grub的文件的配置格式
/etc/grub/grub.conf
default=0 # 设置默认启动的tile,0表示第一个tile
timeout=5 # 在启动时选择tile时的超时时间
hiddenmenu #是否隐藏启动界面
password --md5 密码串(使用grub-md5-crypt工具加密的密码串)#如果加密,编辑grub时会要求输入密码
title (Centos 6.6) #启动时的菜单名称
root (hd0,0) # 表示kernel的存放位置,hd统一表示为所有硬盘,第一个0表示第一块硬盘,第二个0表示一个分区
kernel /vmlinuz.VERSION.release #kerenl文件的存放路径
initrd /initramfs.VERSION.release.img #initramfs的存放路径
password --md5 密码串 #这个密码加密后,启动相应的内核时,会要求输入密码
#注意:title中的每一行都必须要缩进一个空白字符,当grub损坏时,可以使用"find (h0,0)/"查找目录下的文件,使用TAB键补全,如果有就会列出所有的文件,如果没有,表示(hd0,0)指定有错误,需再查找其他的分区中是否有。
进入单用户模式:
- 1、编辑grub菜单(选定要编辑的title ,e命令)
- 2、在选定的kernel后附加1,S,s 或者single都可以
- 3、在kernel所在行,键入b命令
手动安装grub的方法
-
1、grub-install --root-directory=/mnt /dev/sdb
注意:--root-directory=/mnt : 这个位置必须指定为boot目录所在的父目录,grub会自行在父目录中找到boot目录,然后把grub程序安装到对应的目录中,一般情况在挂载新预备安装gurb的硬盘时,需要在文件系统上建立一个boot目录,再把对应的磁盘挂到boot目录中,这样grub才会找到boot目录,在下面建立所需的文件,如果挂载时不创建boot目录,那和以grub会在目录下创建boot目录,启动时需要将kernel和initrd的位置就应该为/boot/vmliunz格式
-
2、分步骤安装
grub grub> root (hd0,0) grub> setup (h0,0)
手动修复grub引导程序
模拟损坏mbr
- dd if=/dev/zero of=/dev/sda bs=200 count=1
- 需要先备份好mbr,使用
dd if=/dev/sda of=/root/sda bs=512 count=1
- 需要先备份好mbr,使用
修复过程
- 1、挂载安装光盘,执行
linux rescue
进行急救模式 - 2、chroot /mnt/sysimage
- 3、执行
grub-install --root-directory=/ /dev/sda
/dev/sda : 这是对磁盘的mbr修复指定位置,必须是磁盘,不能是分区,就是mbr所存放的位置
新加硬盘,提供直接单独运行bash系统
####创建文件系统并挂载
mke2fs -t ext4 /dev/sdb1
mke2fs -t ext4 /dev/sdb2
mkdir /media/boot
mount /dev/sdb1 /media/boot/
grub-install --root-directory=/media /dev/sdb
cp /boot/vmlinuz-2.6.32-573.el6.x86_64 /media/boot/vmlinuz
cp /boot/initramfs-2.6.32-573.el6.x86_64.img /media/boot/initramfs.img
####grub配置文件信息
vim /media/boot/grub/grub.conf
default=0
timeout=5
hiddenmenu
title (Centos6.6)
root (hd0,0)
kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash
initrd /initramfs.img
####给根文件系统提供bash和相应的库文件
mount /dev/sdb2 /mnt/
cd /mnt/
mkdir $(ls /) -pv
cp /bin/bash /mnt/bin/bash
ldd /bin/bash
cp /lib64/libtinfo.so.5 /mnt/lib64/
cp /lib64/libdl.so.2 /mnt/lib64/
cp /lib64/libc.so.6 /mnt/lib64/
cp /lib64/ld-linux-x86-64.so.2 /mnt/lib64/
chroot /mnt/
ramfs文件的管理
1、mkinitfs 命令(Centos5)
- synopsis: mkinitrd [OPTION...] [<initrd-image>] <kernel-version>
示例:
- mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
2、dracut 命令(Centos 6\7)
示例:
- dracut /boot/initramfs-$(uname -r).img $(uname -r)
内核信息输出的伪文件系统:
-
1、/proc目录
内核状态及统计信息的输出接口,同时还提供了一个配置接口:
/proc/sys
,可以使用sysctl
命令修改其内核参数,其此目录下的大部分文件都可接受用户指定的一个"新值
",来实现对内核某功能或特性的配置-
2、/sys目录
输出内核识别出的各种配置设备的相关信息,也有内核对硬件特性的可设置参数,可定制硬件的特性
udev功能
通过读取sys目录下的硬件设备信息,按需为各硬件设备创建设备文件。当系统初始化的过程中,会探测计算机各种硬件设备信息,此记录会保存至/sys目录下,当系统启动完成后,udev会按照/sys目录下的各设备文件,创建相应的硬件信息。udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在其工作目录下。
-
udev的工作目录
- /etc/udev/rules.d : 自定义的规则目录
- /lib/udev/rules.d/ : 默认的规则目录
- /dev/.udev/rules.d : 临时规则目录存放位置(Centos 7才有)
-
udev目录下的文件
root@zhenping rules.d]# ls /lib/udev/rules.d/ 01-log-block.rules 60-persistent-storage-tape.rules 75-cd-aliases-generator.rules 81-kvm-rhel.rules 10-console.rules 60-persistent-v4l.rules 75-net-description.rules 88-clock.rules 10-dm.rules 60-wacom.rules 75-persistent-net-generator.rules 90-pulseaudio.rules 11-dm-lvm.rules 61-mobile-action.rules 75-tty-description.rules 91-drm-modeset.rules 13-dm-disk.rules 61-option-modem-modeswitch.rules 77-mm-ericsson-mbm.rules 95-devkit-power-battery-recall-dell.rules
内核参数调整方法
1、配置文件修改(永久有效,但需重新启动后)
-
修改
/etc/sysctl.conf
或者/etc/sysctl.d/*.conf
net.ipv4.ip_forward = 0
注意:如果需要修改后的参数立即有效,需使用sysctl -p
命令重读其配置信息加载到内核中。
2、使用命令进行修改(临时有效,下次重启后丢失)
sysctl命令
sysctl -sysctl - configure kernel parameters at runtime
synopsis : sysctl [options] [variable[=value]] [...]
-
[options]
-
-a
: 显示当前可配置的所有参数 -
-w VAR=VLUE
: 更改参数值 -
-p
: 从/etc/sysctl.conf文件中重新加载内核设定值
-
示例
- sysctl net.ipv4.ip_forward : 查看其值
- sysctl -w kernel.hostname=zhenping.mac : 设置其计算机名为zhenping.mac
- sysctl -a : 查看所有可配置的内核参数
使用文件系统命令cat
和echo
设置和查看
- cat /proc/sys/kernetl/hostname
- echo "VALUE" > /proc/sys/kernel/hostname
常见内核参数
- net.ipv4.ip_forward : 核心转发功能
- vm.drop_caches : 释放buff/cache空间,值有0\1\2
- kernel.hostname : 主机名
- net.ipv4.icmp_echo_ignore_all : 忽略所有发往自己的ping操作
模块管理
lsmod命令
lsmod
- 查看所有系统被装载的模块
-
lsmod
- 显示系统被装载的所有模块
注意:其是提取/proc/modules文件信息
=========
modinfo命令
modinfo
- Show information about a Linux Kernel module
其通过/lib/modules/[KERNEL-VERSION]/modules/下的所有文件进行分析并显示的,默认情况下在内核modules编译安装的时候,会在其目录下生成所有modules的依赖关系等,建立对应的索引信息
synopsis : modinfo [-0] [-F field] [-k kernel] [modulename|filename...]
-
[options]
-
-k MODULE
: 查看指定的模块信息 -
-F FIELD
: 只显示指定字段的信息 -
-n MODULE
显示指定模块的存放路径
-
=====
modprobe命令:
modprobe
- Add and remove modules from the Linux Kernel
- synopsis: modprobe [-r] module_name
示例:
- modprobe MODULE : 装载指定的模块文件
- modprobe -r MODULE : 卸载指定的模块文件
modprobe可以自行解决模块与模块的依赖关系,并将依赖的模块也一并启用
====
depmod命令
内核模块依赖关系文件的生成工具,系统模块的生成文件路径为:/lib/modules/KERNEL-VERSION/
下
======
模块装载和卸载的另一组命令:
insmod命令
- insmod /lib/modules/3.10.0-229.el7.x86_64/kernel/fs/btrfs/btrfs.ko (模块一定要为完整路径)
rmmod命令
- rmmod MODULE : 卸载指定的模块