早期的内核启动流程。
函数 rest_init()
产生了一个新过程以运行 kernel_init()
,并调用了 do_initcalls()
。用户可以经由过程将 initcall_debug
附加到内核敕令行来监控 initcalls
,如许每运行一次 initcall
函数就会产生 一个 dmesg
条目。initcalls
会历经七个持续的级别:early、core、postcore、arch、subsys、fs、device 和 late。initcalls
最为用户可见的部分是所有处理器外围设备的探测和设置:总线、收集、存储和显示器等等,同时加载其内核模块。rest_init()
也会在引导处理器上产生第二个线程,它起首运行 cpu_idle()
,然后等待调剂器分派工作。
kernel_init()
也可以 设置对称多处收成SMP)构造。在较新的内毫闼楝如不雅 dmesg
的输出中出现 “Bringing up secondary CPUs...” 等字样,体系便应用了 SMP。SMP 经由过程“热插拔” CPU 来进行,这意味着它用状况机来治理其生命周期,这种状况机在概念上类似于热插拔的 U 盘一样。内核的电源治理体系经常会使某个核离线,然后根据须要将其唤醒,以便在不忙的机械上反复调用同一段的 CPU 热插拔代码。不雅察电源治理体系调用 CPU 热插拔代码的 BCC 对象 称为 offcputime.py
。
请留意,init/main.c
中的代码在 smp_init()
运行时几乎已履行完毕:引导处理器已经完成了大年夜部分一次性初始化操作,其它核无需反复。尽管如斯,跨 CPU 的线程仍然要在每个核上生成,以治理每个核的中断(IRQ)、工作队列、准时器和档链事宜。例如,经由过程 ps -o psr
敕令可以查看办事每个 CPU 上的线程的 softirqs 和 workqueues。
个中,PSR 字段代表“处理器”。每个核还必须拥有本身的准时器和 cpuhp
热插拔处理法度榜样。
那么竽暌姑户空间是若何启动的呢?在最后,kernel_init()
寻找可以代表它履行 init
过程的 initrd
。如不雅没有找到,内核直接履行 init
本身。那么为什么须要 initrd
呢?
早期的用户空间:谁规定要用 initrd?
除了设备树之外,在启动时可以供给给内核的另一个文件路径是 initrd
的路径。initrd
平日位于 /boot
目次中,与 x86 体系中的 bzImage 文件 vmlinuz 一样,或是与 ARM 体系中的 uImage 和设备辅弼同。用 initramfs-tools-core
软件包中的 lsinitramfs
对象可以列出 initrd
的内容。发行版的 initrd
筹划包含了最小化的 /bin
、/sbin
和 /etc
目灌音及内核模块,还有 /scripts
中的一些文件。所有这些看起来都很熟悉,因为 initrd
大年夜致上是一个简单的最小化 Linux 根文件体系。看似类似,其实不然,因为位于虚拟内存盘中的 /bin
和 /sbin
目次下的所有可履行文件几乎都是指向 BusyBox 二进制文件 的符号链接,由此导致 /bin
和 /sbin
目次比 glibc 的小 10 倍。
在 main()
函数运行之前,法度榜样须要一个履行高低文,包含客栈内存以及 stdio
、stdout
和 stderr
的文件描述符。用户空间法度榜样大年夜标准库若干好多半 Linux 体系在用 “glibc”)中获取这些资本。参照以下输出:
如不雅要做的只是加载一些模块,然后在通俗的根文件体系上启动 init
,为什么还要创建一个 initrd
呢?想想一个加密的根文件体系,解密可能依附于加载一个位于根文件体系 /lib/modules
的内核模块,当然还有 initrd
中的。加密模块可能被静态地编译到内毫闼楝而不是大年夜文件加载,但有多种原因不欲望如许做。例如,用模块静态编译内核可能会使其太大年夜而不克不及适应存储空间,或者静态编译可能会违背软件许可条目。不出所料,存储、收集和仁攀类输入设备(HID)驱动法度榜样也可能存在于 initrd
中。initrd
根本上包含了任何挂载根文件体系所必须的非内核代码。initrd
也是用户存放 自定义ACPI 表代码的处所。
救济模式的 shell 和自定义的 initrd
照样很有意思的。
最后,当 init
开端运行时,体系就启动啦!因为第二个处理器如今在运行,机械已经成为我们所熟知和爱好的异步、可抢占、弗成猜测和高机能的生物。切实其实,ps -o pid,psr,comm -p 1
很轻易显示用户空间的 init
过程已不在引导处理器上运行了。
总结
Linux 引导过程听起来或许令人生畏,即使是简单嵌入式设毕喔赡软件数量也是如斯。但换个角度来看,启动过程相当简单,因为启动中没有抢占、RCU 和竞争前提等扑朔迷离的复杂功能。只存眷内核和 PID 1 会忽视了引导程序和帮助处理器为运行内核履行的大年夜量预备工作。固然内核在 Linux 法度榜样中是环球无双的,但经由过程一些检查 ELF 文件的对象也可以懂得其构造。进修一个正常的启动过程,可以赞助运维人员处理启动的故障。
推荐阅读
沙龙晃荡 | 3月31日 京东、微博拭魅战专家与你合营商量容器技巧实践!如不雅你善于应用Pandas变换数据、创建特点以及清洗数据等,那么你就可以或许轻松地应用Dask和Numba并行加快你的工作。纯真赶紧度上>>>详细阅读
本文标题:对Linux系统启动过程分析
地址:http://www.17bianji.com/lsqh/40676.html
1/2 1