本文作者:凯少技术网

凯少跟你浅谈Deepin操作系统的启动流程,很详细哦

凯少技术网 1个月前 ( 08-12 ) 62 抢沙发
摘要: 概览:deepin系统启动,从整体上看主要分为了硬件上电、内核引导、内核启动、系统初始化、图形界面等几个阶段。如果将这几个阶段分为两个部分,那么第一部分的硬件上电、内核引导、内核启...

概览:deepin系统启动,从整体上看主要分为了硬件上电、内核引导、内核启动、系统初始化、图形界面等几个阶段。如果将这几个阶段分为两个部分,那么第一部分的硬件上电、内核引导、内核启动主要是“引导(boot)”,更偏向让内核可以启动;而第二部分的系统初始化、图形界面两个阶段主要的任务则是“初始化(initialize)”了,因为对于一个系统来说仅仅有内核跑起来是不行的,还要有各种各样的服务对系统的软硬件进行管理,这也是平常大家说发行版跟纯粹的GNU/Linux内核不是一个概念的原因之一。


下面我从一个软件开发者的角度说一下我对每个阶段的理解以及一些调试的方法。

硬件上电

既然说了是软件开发者的角度,这个部分对我来说基本上相当于黑盒子了。但是大体上我们仍然知道这个部分主要是:


硬件上电

BIOS/UEFI

bootloader


当你按下电源的那一刻起,电流就会“滋滋滋”的流向主板,启动BIOS(Basic Input Output System)系统。


BIOS系统,顾名思义就是最直接跟硬件打交道的系统,因为有标准规定,所以输入输出设备的基本功能都是可以使用的,一些硬件的开关配置也可以在BIOS中进行操作。


除此之外,BIOS还有两个重要的功能,一个是硬件自检;另外一个是加载引导。硬件自检这个跟作为一个”半吊子系统工程师“没什么关系,自不多说。加载引导的过程其实就是大家耳熟能详的MBR、小蝌蚪找妈…哦不…MBR中找bootloader了。跟BIOS对应的UEFI,要说它们之间的区别,除了加载引导的方式不大一样以外。对我来说可能就是界面能够用鼠标点点点了吧,嗯……哈哈哈。


这里讲个段子,之前15.7搞启动时间优化的时候,测试的同学测试系统启动时间的优化情况,老是说效果不理想,我去看看吧,原来是他们测试系统启动是从硬件启动算起的,我说你们直接从内核引导开始计算,他还问我为什么。优化时间/(BIOS时间+GRUB时间+内核时间+图形时间) 跟 优化时间/(内核时间+图形时间)哪个大哪个小?我只能说这个测试同学的数学不大好……


内核引导

BIOS在MBR中(或者UEFI在主板专有的存储设备中)找到bootloader并加载后,bootloader就会开始加载Linux内核并启动了。


GRUB引导

deepin系统默认的bootloader是GRUB(GRand Unified Bootloader)。其实我一直觉得这个名字挺恶心的,大神们果然都是重口味……GRUB并不需要按照什么规则去硬盘中找系统,而是根据/boot/grub/grub.cfg中的启动项加载内核、启动系统,而这个配置文件则是在系统安装或者手动执行update-grub这个命令的时候生成和更新。


update-grub这个命令其实是对grub-mkconfig的一个包装,在非Debian系的发行版上是没有的。grub-mkconfig会执行的动作主要是:


1.加载/etc/default/grub中的一些配置项。比如GRUB_CMDLINE_LINUX_DEFAULT配置项会控制Linux的boot param。

2.挨个执行/etc/grub.d/目录中的脚本,用来生成最终的grub.cfg文件。比如我们平常看到update-grub命令执行时输出的哪些启动项,其实就是/etc/grub.d/03_os-prober这个脚本里面执行os-prober这个工具产生的。


在GRUB界面选择启动项,按e编辑启动项。除了普通的上下左右键移动光标,还可以使用基本的Emacs快捷键:


Ctrl+N 下一行

Ctrl+P 上一行

Ctrl+B 左移一个字符

Ctrl+F 右移一个字符

Ctrl+A 移动光标到行首

Ctrl+E 移动光标到行尾


编辑完成后按Ctrl+X按照编辑后的结果启动系统,但是编辑的结果不会保存,也就是说如果需要永久修改某个启动项,就要修改grub.cfg文件或者会影响grub.cfg生成的/etc/default/grub以及/etc/grub.d/中的脚本文件了。


对于GRUB,我们一般需要知道的就这么多。


UEFI直接引导

在UEFI模式下,除了使用GRUB来引导内核以外,还可以通过UEFI直接引导内核(需要内核开启了EFI Stub支持),具体的配置方式见Debian Wiki EFI Stub。需要注意的一点是在使用efibootmgr创建启动项的时候,可能需要-d参数指定设备,否则可能会导致创建启动项失败。


内核启动

内核启动部分其实主要是想说initrd。initrd是一个小型的rootfs,这个rootfs保证了内核启动过程中所需要的内核模块和用户态工具。同时,它还需要为下一个阶段“系统初始化”做准备,也就是为init程序准备好真正的文件系统,并且启动init程序。内核使用initrd启动的过程主要是:


1.执行init脚本(这个不是上面说得init程序,而是生成好的initramfs中的/init这个文件。后面的步骤其实都发生在这个脚本的执行过程中);

2.解析内核启动参数,识别关键的如debug、boot、break等;

3.执行/scripts/init-top/中的脚本;

4.加载内核模块;

5.执行/scripts/init-premount/中的脚本;

6.执行/scripts/$BOOT脚本中的mountroot函数,其中的$BOOT参数就是第2步中识别到的boot参数指定的,自带的可选项有local(本地启动,默认)、nfs(比如PXE启动);

7.执行/scripts/init-bottom/中的脚本;

8.执行init程序。


live系统

上面第6步提到initramfs-tools包自带有两种boot类型:local和nfs,我们使用live系统的时候的boot类型其实live。这个boot类型主要是live-boot这个包支撑起来的。


在启动live系统的时候,/scripts/live中的mountroot会调用/lib/live/boot/目录中的脚本设置根文件系统,包括挂在ISO和设置overlay等。调试initrd启动阶段支持几个特殊的启动参数辅助调试:


1.debug 会开启initrd启动脚本中的调试模式;

2.break 可以讲启动停止在某个阶段,例如break=premount就会在真正的根文件系统挂载前停掉启动流程,并给你一个busybox环境;可选break的阶段可以在/scripts/init脚本中看到,就是哪些使用maybe_break的行。


系统初始化

从这个阶段开始,启动流程就算是进入我们真实的的系统中了,init程序会启动各种服务对系统进行配置,保证软硬件环境可以正常使用。deepin系统下默认的init程序是systemd,这个庞然大物太过复杂,或许将来开个坑写一个系列才能说好……这里只简单说明一下跟系统启动流程相关的内容。


一个是 man bootup中的一个图:

(图片字体过小,请自行放大查看)

基本涵盖了由systemd接管系统以后,systemd所管理的服务之间的一个依赖和基本先后顺序。


另外一个是systemd-analyze命令,通过systemd-analyze plog > bootup.svg可以更加直观的看到systemd各个服务在启动过程中启动的时间和所存在的时间。


图形界面

图形界面阶段是系统到达图形环境后的过程,这个部分主要包括:


display-manager.service 启动lightdm;


lightdm启动lightdm-deepin-greeter;


用户输入密码后进入图形会话;


lightdm执行/usr/sbin/deepin-session;


/usr/sbin/deepin-session


执行/etc/X11/Xsession.d中的脚本,并最终启动/usr/bin/startdde;


startdde启动桌面环境的组件,系统启动完成。


凯少技术网官方公众号

文章版权及转载声明:

作者:凯少技术网本文地址:https://www.skyko.cn/?id=490发布于 1个月前 ( 08-12 )
文章转载或复制请以超链接形式并注明出处凯少技术网

赞(0

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

发表评论

快捷回复:

评论列表 (暂无评论,62人围观)参与讨论

还没有评论,来说两句吧...