【问题标题】:What and where exactly is the loader?装载机到底是什么以及在哪里?
【发布时间】:2016-02-06 08:36:05
【问题描述】:

我了解 C 编译过程的每一点(如何链接目标文件以创建可执行文件)。但是关于加载程序本身(启动程序运行)我有一些疑问。

  1. 加载器是内核的一部分吗?

  2. ./firefox 或类似的命令究竟是如何加载的?我的意思是你通常在终端中输入这样的命令来加载我认为的可执行文件。那么loader是shell的一个组件吗?

我想我也对终端/shell 适合所有这些以及它的作用感到困惑。

【问题讨论】:

  • Q1:否;加载器通常是一个名为ld 的常规程序;它不是内核的一部分。它也被称为链接器(但名称仍然是ld)。它收集目标文件和库并从中创建一个可执行文件——或者如果您使用正确的选项调用它,则创建一个共享库,如果您有足够的知识,您还可以生成一两个其他东西。 Q2:您的意思是 Firefox 是如何运行的,或者它是如何链接的?运行程序不是编译过程的一部分,但有时称为“加载程序”。该代码在内核中。
  • Q2(续):嗯,有些代码在内核中;另一个主要块是动态加载器,它通常具有诸如ld.so.1 之类的名称。对于您想要了解的内容,我们确实需要更多背景信息。不过,对于 SO,这个问题可能过于宽泛。
  • 我认为 OP 正在讨论加载未链接的过程映像。但他可能会提出他的问题……
  • +Jonathan Leffler 谢谢。我相当了解链接过程。我只是想了解从创建可执行文件到实际执行可执行文件的过程。如果确实如此,那么 shell 适合所有这些吗?
  • 在被链接的可执行文件的结尾和它被执行之间没有任何事情发生——除非它被复制(安装)到新的地方。当您运行可执行文件时,无论是通过 shell 命令行还是其他机制(例如单击图标),内核都会参与其中(通过 exec() 系列系统调用 - 通常也是 fork()),启动程序。然后动态加载器整理出共享库,程序开始运行。这是一个很大的话题;您应该找到一本教科书并详细阅读其中的内容。

标签: c linux linker system-calls loader


【解决方案1】:

可执行文件的格式决定了它的加载方式。例如带有“#!”的可执行文件因为前两个字符由内核通过执行命名解释器并将文件作为第一个参数提供给它来加载。如果可执行文件被格式化为 PE、ELF 或 MachO 二进制文件,则内核使用内核内置的该格式的解释器来查找可执行代码和数据,然后选择下一步。

在动态链接 ELF 的情况下,下一步是执行动态加载程序(通常是 ld.so)以查找库、加载它们、解析符号。这一切都发生在用户空间。内核或多或少不知道动态链接,因为这一切都发生在内核将控制权交给 ELF 文件中指定的解释器之后的用户空间。

【讨论】:

    【解决方案2】:

    对应的系统调用是exec。它是内核的一部分,负责清理进行调用的旧地址空间,并使用所有材料获取新的地址空间以运行新代码。这是内核的一部分,因为地址空间是一种沙箱,可以保护进程免受其他进程的影响,而且由于它至关重要,因此它负责内核。

    shell 只负责解释您键入的内容并将其转换为适当的结构(C 字符串的列表或数组)以传递给一些 exec 调用(在大多数情况下产生了一个新进程fork)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2019-01-30
      • 2014-03-29
      • 1970-01-01
      • 2016-04-25
      相关资源
      最近更新 更多