loader和C运行时初始化角色之间的差异
我从以下链接了解了C运行时初始化的角色: 它说运行时初始化完成了设置堆栈之类的任务,在后面的页面中,它还详细说明了它用零初始化bss段。在其他一些地方,我也读到它初始化数据和其他一些段 这在我的脑海中产生了一个疑问,装载机会做什么?因为其中一些任务也是装载机的责任 所以,我的问题是:loader和C运行时初始化角色之间的差异,c,runtime,loader,C,Runtime,Loader,我从以下链接了解了C运行时初始化的角色: 它说运行时初始化完成了设置堆栈之类的任务,在后面的页面中,它还详细说明了它用零初始化bss段。在其他一些地方,我也读到它初始化数据和其他一些段 这在我的脑海中产生了一个疑问,装载机会做什么?因为其中一些任务也是装载机的责任 所以,我的问题是: 运行时初始化或c运行时实际上做什么 加载器实际上做什么 编辑 好的,如果这个链接专门描述了嵌入式系统的运行时初始化的角色,那么它在普通系统上有什么角色呢。 在我看来,运行时初始化将只调用main,没有其他工作留给它
main
基本上将控制权交给用户
根据问题注释中的回答,您可能已经了解到,程序为其环境引导的过程随目标环境的数量而变化。考虑到C现在和过去所支持的平台和操作系统的数量,没有可能列举C运行时已经或当前工作的所有方式
每个C库都有自己的C运行时,每个支持C的环境都可能有不同的引导问题和要求。这些需求在很大程度上取决于操作系统或硬件的特性以及C实现的完整性。然而,我可以回答C运行时在您可能熟悉的环境中通常会做的一些事情
- 由于C运行时负责调用
,因此调用通过main
注册的函数将由C运行时负责atexit(3)
- 解析并调用任何构造函数/析构函数接口(
,\u init
等)\u fini
- 初始化并调用实时加载程序(负责解析和加载在链接时注册并在运行时加载的动态共享对象)
- 优雅地处理分离线程的退出
- 初始化并将
和argc
传递到程序的argv
main
- 定义和初始化各种C库全局符号。例如,它为环境正确地设置了
(现代系统将errno
定义为线程安全,因此它需要生活在TLS中)errno
是另一个全局符号,在调用environ
之前需要初始化main
- 因此,C运行时需要设置TLS
- 还有很多
- 您的shell尝试在您配置的
路径中的某个位置查找二进制文件。这是通过对内核发出大量系统调用来解决不同路径序列下的文件名问题的李>
- 假设找到了文件,shell通常会
和fork(2)
。execve(2)
调用导致内核创建一个新进程;fork(2)
调用将克隆的二进制文件替换为新的二进制文件execve(2)
- 内核从其存储介质(磁盘、网络、内存等)读取文件的第一页,并尝试找出如何执行它。
- 如果它是一个ELF二进制文件,它可以通过二进制文件的头来确定。然后,内核根据ELF节h中指定的偏移量,将二进制文件的部分加载到内存中的某个位置
- 假设找到了文件,shell通常会