别人的Linux私房菜(20)启动流程、模块管理与Loader

系统启动时,首先加载BIOS,通过BOIS读取COMS的硬件信息,进行自我检测,取得第一个可启动的设备(多个根据设置有关)。

读取并执行设备内的MBR启动引导程序,引导程序调用boot sector中的boot loader,通过boot loader加载Kernel调用systemd程序,并以default.target流程启动。

BOIS通过INT13中断功能读取MBR记录的引导程序,BootLoader可以让用户选择不同的启动选项,指向内核,或转交其它的loader。

在Windows安装完毕后安装的Linux使用Linux的MBR引导程序(grub2)。之后通过grub2引导到不同的BootLoader。

通过boot loader加载Kernel后,将内核文件解压到内存中,重新检测硬件设备信息。

内核文件在/boot/vmlinuz中,可以通过动态加载内核模块。内核模块存放在/lib/modules/目录下。启动过程中跟目录为只读方式挂载。

虚拟文件系统(Initial RAM Disk)一般使用的文件名为:/boot/initrd或/boot/initramfs。它加载到内存中,解压模拟成根目录,内核借此加载适当的驱动程序,最终释放虚拟文件系统。

通过lsinitrd命令显示initramfs的内容。initramfs这个小型的根目录,内核检测到后,使用initrd.target来启动,最后读入一批*.target,让系统顺利运行。

最终,卸载initramfs文件系统,挂载实际根目录,完成内核的完整加载,主机开始正确运行,之后内核调用程序systemd(PID:1)。

systemd默认启动的服务集合为default.target。可以作为default.target的项目有图形.target,命令行.target等,和SystemV对应。

取得了/etc/systemd/system/default.target后,链接到/usr/lib/systemd/system下的multi-user.targetgraphical.target之一,然后在

/etc/systemd/system/对应的.target.wants/加载用户设置的unit(service),在/usr/lib/systemd/system/对应的.target.wants/加载系统默认的unit。

systemctl list-dependencies sysinit.target,可以看到sysinit.target阶段的工作让系统可以读写,并可加载用户自定义模块,而basic.target让系统成为操作系统的基础。

之后的multi-user.target可以提供主机服务,网络服务等,在相应的两个文件夹的want中存在对应的unit功能。

新版的Linux执行自定义的额外程序写入到/etc/systemd/system下面,但保留了旧版/etc/rc.d/rc.local写入到该文件的自定义功能。

但需要启动该服务,并加入执行权限,可以在defaul.target下找到对应的依赖关系。

通过ll /usr/lib/systemd/system/runlevel*.target,可以找到运行级别的对应关系,调用过程使用init命令或systemctl isolate命令。

通过cat multi-user.target类命令查看相应的依赖项等。通过systemctl list-dependencies graphical.target查看对应的依赖关系。

根据sysinit.target的自定义模块,有两处:

 /etc/modules-load.d/*.conf单纯要内核加载的模块位置

/etc/modprobe.d/*.conf可以加上模块参数的位置

如在第一个位置建立文件,加入防火墙模块。在第二个位置加入五年级,建立合适的防火墙端口号。通过lsmod查看模块状态。

Systemd兼容SystemV,所以会读取/etc/sysconfig/*下的其他文件,如authconfig鉴权,cpupower操作cpu,firewalld防火墙等。

内核和内核模块的位置:

/lib/modules/$(uname -r)/modules.dep记录了内核支持模块的各项依赖性。

 做好一个驱动程序.ko后放入位置,通过depmod命令,重新建立依赖性。lsmod查看模块,modinfo列出模块的相关信息。

 insmod加载模块,rmmod删除模块。但二者无法解决模块依赖属性的问题。

通过modprobe加载模块,通过modprobe -v删除模块可以解决。

 boot loader执行分两个步骤,执行主程序(在MBR启动扇区(GPT兼容)),执行加载配置文件(在/boot下)。

 配置文件中/boot/grub2/grub.cfg为主配置文件。

 grub2的主程序直接在文件系统中查找内核文件,自行编辑和修改启动设置,动态配置文件,修改grub.cfg后下次在步骤二中生效。

 grub2的标识硬盘方式为:用(),硬盘hd以查找顺序标记,0开始。区号标记以1开始,区分硬盘格式加入说明。如:(hd0,msdos1)

 msdos为MBR,gpt为GPT分区形式。

grub.cfg文件强烈不建议修改。文件中,有设置启动选项(set default),预设的秒数(set timeout),

每一个选项的设置menuentry,设置了一些选项,和加载模块。set root设置grub2的配置文件根目录

在挂载过程中/先,/boot后,所以挂载设置为:set root='hd0,gpt2',为boot。

 linux16 /vmlinuz-... root=/dev/mapper/centos-root ...为内核文件与执行内核所带的参数。

 grub2配置文件/etc/default/grub与/etc/grub.d目录的修改,来更新grub.cfg。

其中/etc/default/grub倒数时间参数: GRUB_TIMEOUT,是否隐藏选项:GRUB_TIMEOUT_STYLE(menu, countdown, hidden)

信息终端输出模式:GRUB_TERMINAL_OUTPUT(console, serial,gfxterm, vga_text等),

默认启动选项:GRUB_DEFAULT(可使用menuentry顺序号,ID,saved等),

核心的外加参数功能:GRUB_CMDLINE_LINUX,如GRUB_CMDLINE_LINUX="..... crashkernel=auto rhgb quiet elevator=deadline"

 创建完毕后,使用grub2-mkconfig命令来重建grub.cfg。(grub2-mkconfig -o /boot/grub2/grub.cfg)

 选项创建的脚本。/etc/grub.d/*

有00_header,创建初始项目,10_linux找到内核并读取模块,参数。

30_os-prober找到其他分区可能含有的操作系统。40_custom其它自定义要的选项。

通过chainloader 的方式移交loader 控制权交给下一个boot sector 或MBR 内的boot loader 而已

 initramfs将/lib/modules内的必要模块打包成文件,在主机调用INT13硬件中断时,将文件解压缩。

 重制作该文件可以通过dracut命令和mkinitrd完成。如dracut -v initramfs-test.img $(uname -r)

 ;dracut -v --add-drivers "e1000e" --filesystems "ext4 nfs"  initramfs-new.img $(uname -r)

 测试安装grub2。使用grub2-install

 如:grub2-install --force --recheck --skip-fs-probe /dev/vda4

 将主程序写到启动扇区vda4上(一般只支持写入到整个文件系统vda)

关于启动项默认的问题,翻书或自行解决.....偷个懒,这个..等用到再说吧!

 在启动界面e,编辑进入恢复模式,在内核信息参数后加入systemd.unit=rescue.target,ctrl x进入。

为个别grub2的启动选项设置密码。设立管理员账号和普通账号。

如下示例:

在/etc/grub.d/*下建立01_users的文件,然后写入账户数据:

 1 set superusers="vbird" # 这里是设定系统管理员的账号名称为啥的意思!
 2 password vbird abcd1234 # 当然要给予这个账号密码啊!
 3 password dmtsai dcba4321 # 没有输入 superuses 的其他账号,当然就是判定为一般账号
 4 #有必要使用密文,采用cat echo方式显示出来等。这里只是思路举例
 5 
 6 
 7 
 8 set superusers="vbird" # 这里是设定系统管理员的账号名称为啥的意思!
 9 password vbird abcd1234 # 当然要给予这个账号密码啊!
10 password dmtsai dcba4321 # 没有输入 superuses 的其他账号,当然就是判定为一般账号
11 
12 menuentry "大家都可以选择我来开机喔!" --unrestricted {
13 set root=(hd0,1)
14 chainloader +1
15 }
16 menuentry "只有管理员的密码才有办法使用" --users "" {
17 set root=(hd0,2)
18 chainloader +1
19 }
20 menuentry "只有管理员与 dmtsai 才有办法使用喔!" --users dmtsai {
21 set root=(hd0,3)
22 chainloader +1
23 }
View Code

/etc/grub.d/10_linux检测两个启动选项,/etc/grub.d/40_custom启动自定义的选项(上面代码后部分)

 忘记root密码时的恢复:使用rd.break。

在开机界面使用e,在linux16后加入rd.break启动。ctrl x。

 进入后重新挂载,使能读写root。mount -o remount,rw /sysroot

 切换挂载原先的根目录,取回环境:chroot /sysroot

 修改密码:echo "your_root_new_pw" | passwd --stdin root

建立新文件:touch /.autorelabel #修复被取消的SELinux 安全本文的特性,否则无法启动

 退出:exit,重启reboot

另一种修复被取消的SELinux 安全本文的特性的方案,先调整为宽容模式,然后再启动后恢复。

 

因文件系统错误无法启动,那么,按照提示输入,使用:mount -o remount,rw /。继续处理吧。修正/etc/fstab

xfs_repair等命令处理吧...

原文地址:https://www.cnblogs.com/bai2018/p/10780904.html