作家
登录

对Linux系统启动过程分析

作者: 来源: 2018-03-13 14:04:18 阅读 我要评论

/lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,
  • BuildID[sha1]=14e8563676febeb06d701dbee35d225c5a8e565a,
  • stripped
  • ELF 二进制文件有一个说冥器,就像 Bash 和 Python 脚本一样,然则说冥器不须要像脚本那样用 #! 指定,因为 ELF 是 Linux 的原生格局。ELF 说冥器经由过程调用 _start() 函数来竽暌姑所需资本 设备一个二进制文件,这个函数可以大年夜 glibc 源代码包中找到,可以 用 GDB 查看。内核显然没有说冥器,必须自我设备,这是怎么做到的呢?

    用 GDB 检查内核的启动给出了谜底。起首安装内核的调试软件包,内核中包含一个未剥离的unstripped vmlinux,例如 apt-get install linux-image-amd64-dbg,或者大年夜源代码编译和安装你本身的内核,可以参照 Debian Kernel Handbook 中的指令。gdb vmlinux 后加 info files 可显示 ELF 段 init.text。在 init.text 顶用 l *(address) 列出法度榜样履行的开首,个中 addressinit.text 的十六进制开首。用 GDB 可以看到 x86_64 内核大年夜内核文件 arch/x86/kernel/head_64.S 开端启动,在这个文件中我们找到了汇编函数 start_cpu0(),以及一段明白的代码显示在调用 x86_64 start_kernel() 函数之前创建了客栈并解压了 zImage。ARM 32 位内核也有类似的文件 arch/arm/kernel/head.S。start_kernel() 不针对特定的体系构造,所以这个函数驻留在内核的 init/main.c 中。start_kernel() 可以说是 Linux 真正的 main() 函数。

    大年夜 start_kernel() 到 PID 1 

    内核的硬件清单:设备树和 ACPI 表

    在引导时,内核须要硬件信息,不仅仅是已编译过的处理器类型。代码中的指令经由过程零丁存储的设备数据进行扩充。有两种重要的数据存储办法:设备树device-tree 和 高等设备和档链接口(ACPI)表。内核经由过程攫取这些文件懂得每次启动时须要运行的硬件。

    对于嵌入式设备,设备树是已安装硬件的清单。设备树只是一个与内核源代码同时编译的文件,平日与 vmlinux 一样位于 /boot 目次中。要查看 ARM 设毕喔赡设备树的内容,只需对名称与 /boot/*.dtb 匹配的文件履行 binutils 包中的 strings 敕令即可,这里 dtb 是指设备树二进制文件device-tree binary。显然,只需编辑构成它的类 JSON 的文件并从新运行随内核源代码供给的特别 dtc 编译器即可修改设备树。固然设备树是一个静态文件,其文件路径平日由敕令行引导法度榜样传递给内核,但近年来增长了一个 设备树覆盖 的功能,内核在启动后可以动态加载热插拔的附加设备。

    x86 系列和很多企业级的 ARM64 设备应用 ACPI 机制。与设备树不合的是,ACPI 信息存储在内核在启动时经由过程拜访板载 ROM 而创建的 /sys/firmware/acpi/tables 虚拟文件体系中。攫取 ACPI 表的简单办法是应用 acpica-tools 包中的 acpidump 敕令。例如:

    联想标记本电脑的 ACPI 表都是为 Windows 2001 设置的。

    联想标记本电脑的 ACPI 表都是为 Windows 2001 设置的。

    init/main.c 中的代码竟然是可读的,并且有趣的是,它仍然在应用 1991 - 1992 年的 Linus Torvalds 的原始版权。在一个刚启动的体系上运行 dmesg | head,其输出重要来源竽暌冠此文件。第一个 CPU 注册到体系中,全局数据构造被初始化,并且调剂法度榜样、中断处理法度榜样(IRQ)、准时器和控制台按照严格的次序一一启动。在 timekeeping_init() 函数运行之前,所有的时即噶都是零。内核初始化的┞封部分是同步的,也就是说履行只产生在一个线程中,在最后一个完成并返回之前,没有任何函数会被履行。是以,即使在两个体系之间,dmesg 的输出也是完全可反复的,只要它们具有雷同的设备树或 ACPI 表。Linux 的行动就像在 MCU 上运行的 RTOS(及时操作体系)一样,如 QNX 或 VxWorks。这种情况持续存在于函数 rest_init() 中,该函数在终止时由 start_kernel() 调用。

    initrd 对测试文件体系和数据存储设备也很有效。将这些测试对象存放在 initrd 中,并大年夜内存中运行测试,而不是大年夜被测对象中运行。


      推荐阅读

      Python数据预处理:使用Dask和Numba并行化加速

    沙龙晃荡 | 3月31日 京东、微博拭魅战专家与你合营商量容器技巧实践!如不雅你善于应用Pandas变换数据、创建特点以及清洗数据等,那么你就可以或许轻松地应用Dask和Numba并行加快你的工作。纯真赶紧度上>>>详细阅读


    本文标题:对Linux系统启动过程分析

    地址:http://www.17bianji.com/lsqh/40676.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)