LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

init启动库文件找不到问题定位和解决

内核启动流程start_kernel->arch_call_rest_init->rest_init->kernel_init启动第一个用户空间进程。

init启动时提示库文件无法找到。

说明是ld.so正常执行,但是未能在目录列表中找到依赖的库文件。问题根源在于ld.so中默认库文件搜索路径和rootfs中不匹配。

1 ld.so主要作用和库搜索路径配置

ld.so(动态链接器)的主要作用包括:

  • 动态链接:在程序运行时,ld.so 负责将程序与共享库动态链接起来,而不是在编译时静态链接。
  • 库搜索:根据配置文件(如 /etc/ld.so.conf 和 /etc/ld.so.conf.d/*.conf)和环境变量(如 LD_LIBRARY_PATH),ld.so 搜索并定位所需的共享库文件。
  • 符号解析:ld.so 负责解析程序中的符号引用(例如函数调用和全局变量)到共享库中的相应定义。
  • 加载库:当程序需要某个库时,ld.so 加载该库到内存中,并确保库的初始化代码(如构造函数)被执行。
  • 依赖管理:ld.so 处理库之间的依赖关系,确保所有依赖的库都按照正确的顺序加载。
  • 版本管理:支持库的符号版本,允许库的兼容性和向后兼容性。
  • 性能优化:使用 /etc/ld.so.cache 缓存文件加速库的搜索和加载过程。
  • 运行时链接:允许程序在不重新编译的情况下使用更新的库版本,只要新版本保持了相同的接口。
  • 安全性:可以配置为限制库的搜索路径,以防止潜在的安全风险,例如库被恶意替换。
  • 环境变量:考虑 LD_LIBRARY_PATH 环境变量来搜索额外的库路径,为运行时指定库位置提供灵活性。

ld.so通过以下几种主要途径获取库搜索路径:

  • 默认搜索路径:ld.so 有一些默认的搜索路径,如 /lib 和 /usr/lib 等,这些路径是预设的,不需要额外配置。
  • 配置文件/etc/ld.so.conf:这是主配置文件,定义了额外的库搜索路径。管理员可以在该文件中添加自定义的库路径。
  • 包含的配置文件/etc/ld.so.conf.d/*.conf:/etc/ld.so.conf 文件可能包含 include 指令,用于包含 /etc/ld.so.conf.d/ 目录下的其他配置文件。这些文件可以为特定的应用程序或库定义搜索路径。
  • 环境变量LD_LIBRARY_PATH:这个环境变量可以设置额外的库搜索路径。它允许用户或应用程序指定 ld.so 应该搜索的目录,这些路径在运行时被添加到默认搜索路径中。
  • 编译时指定的路径:如果程序在编译时使用了-rpath选项,那么编译器会在程序的可执行文件中嵌入这些路径。ld.so 会根据这些记录的路径搜索库。
  • 缓存文件 /etc/ld.so.cache:ld.so 使用这个缓存文件来加速库的搜索过程。/etc/ld.so.cache 由 ldconfig 命令生成或更新,包含了 ld.so.conf 和所有包含的配置文件中定义的库路径。

2 解决方案

2.1 kernel中设置LD_LIBRARY_PATH

修改init/main.c中的envp_init:

const char *envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", "LD_LIBRARY_PATH=/lib;/usr/lib", NULL, };

2.2 根据ld.so中默认库搜索路径建立软链接

 查看编译ld.so源码,找到默认路径。没有源码可以通过vi打开库文件搜索/lib类似的字符串。

2.3 添加ld.so.conf配置

/etc/ld.so.conf是ld.so库搜索路径的入口,可以包含/etc/ld.so.conf.d/中的配置。

cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

通过ldconfig读取/etc/ld.so.conf生成缓存文件到/etc/ld.so.cache。

posted on 2024-08-18 23:59  ArnoldLu  阅读(62)  评论(0编辑  收藏  举报

导航