内核如何获得在linux下运行的可执行二进制文件?

Dan*_*iel 26 c linux

内核如何获得在linux下运行的可执行二进制文件?

这似乎是一个简单的问题,但任何人都可以帮助我深入挖掘?如何将文件加载到内存以及如何启动执行代码?

任何人都可以帮助我,一步一步地告诉我们发生了什么吗?

Cir*_*四事件 29

exec在Linux 4.0上系统调用的最佳时刻

找到所有这些的最好方法是使用QEMU GDB步骤调试内核:如何使用GDB和QEMU调试Linux内核?

  • fs/exec.c 定义系统调用 SYSCALL_DEFINE3(execve

    简单地转发到do_execve.

  • do_execve

    前往do_execveat_common.

  • do_execveat_common

    要查找下一个主要功能,请跟踪retval上次修改返回值的时间.

    开始构建a struct linux_binprm *bprm来描述程序,并将其传递exec_binprm给执行.

  • exec_binprm

    再次按照返回值查找下一个主要调用.

  • search_binary_handler

  • fs/binfmt_elf.c:load_binary

    实际工作是否:

    • 根据规范解析ELF文件
    • 基于解析的ELF设置进程初始程序状态(将内存转换为a struct pt_regs,注册成a start_thread)
    • 呼叫struct pt_regs,这是它真正开始安排的地方

TODO:继续进行源分析.我期望接下来会发生什么:

  • 内核解析ELF的INTERP头以找到动态加载器(通常设置为/lib64/ld-linux-x86-64.so.2).
  • 内核将动态加载程序和ELF执行到内存
  • 启动动态加载程序,在内存中指向ELF.
  • 现在在userland中,加载器以某种方式解析elf头,并对dlopen它们进行处理
  • dlopen使用可配置的搜索路径来查找这些库(ldd和朋友),将它们映射到内存,并以某种方式通知ELF在哪里找到它缺少的符号
  • 加载程序调用_startELF


Bas*_*tch 8

来自linux内核的两个系统调用是相关的.该系统调用(或许或)用于创建新的进程,类似于调用一个(每个Linux用户空间的过程,除了通过创建或朋友).所述的execve系统调用用新鲜(基本上由排序的替换进程地址空间MMAP从ELF可执行和匿名的段,然后初始化寄存器,包括堆栈指针-ing段).该X86-64 ABI补充Linux的装配HOWTO透露详情.vforkcloneinitfork

动态链接发生在文件之后execve并且涉及/lib/x86_64-linux-gnu/ld-2.13.so文件,ELF被视为"解释器".


Emp*_*ian 7

在阅读已经引用的ELF文档之后,您应该只读取实际执行它的内核代码.

如果您无法理解该代码,请构建UML Linux,并且可以在调试器中单步执行该代码.

  • 实际上,内核代码非常简单,与内核中的许多其他内容不同. (4认同)

TJD*_*TJD 2

您可以从了解可执行文件格式开始,例如 ELF。 http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

ELF 文件包含多个部分,其中的标头描述了二进制文件的各个部分应如何以及在何处加载到内存中。

然后,我建议阅读 linux 加载二进制文件和处理动态链接的部分ld-linux。这也是对 ld-linux 的一个很好的描述:http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html

  • 实际上ld-linux与内核无关,而且比内核的功能复杂得多。了解静态链接的可执行文件如何开始运行更容易,并且了解 OP 实际询问的内容。 (3认同)

归档时间:

查看次数:

12774 次

最近记录:

5 年,10 月 前