为什么无法将 link 共享库放入内核代码?
Why is it not possible to link shared libraries into kernel code?
有什么影响?内核是用静态库编译的还是内部实现的?
另外,根据this,内核代码不能使用任何浮点运算。这是为什么?
Why is it not possible to link shared libraries into kernel code?
是可能的。但是,它们与您在用户空间中使用的共享库不同。
自经典 System V 以来,内核可以 运行 宁作为一组可加载模块而 是 通常 运行 这种方式。几乎所有的现代系统都使用它; Linux 和 FreeBSD 就是很好的例子。而且,他们使用相同的工具来创建与用户空间相同的模块。例如:
内核模块的共享对象:
$ file /lib/modules/4.4.0-97-generic/kernel/drivers/net/vxlan.ko
'/lib/modules/4.4.0-97-generic/kernel/drivers/net/vxlan.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=561b0b69742c93a595c85be50f6916352c793e5c, not stripped
用户空间库的共享对象:
$ file /lib64/libm-2.23.so
/lib64/libm-2.23.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=cb41640d6965fac9bac4010bebac955e95e4d8c1, for GNU/Linux 2.6.32, stripped
FreeBSD 也一样:
$ file /boot/kernel/agp.ko
/boot/kernel/agp.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not stripped
$ file /lib/libm.so.5
/lib/libm.so.5: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, stripped
在这些情况下,都是 ELF“共享对象”(您命名为“共享库”的东西;术语“共享对象”不太明显,但在 ELF 规范中声明)或“可重定位”(“目标文件” ; 但内核使用它的方式几乎与共享对象相同)。您可以在 file
诊断中看到细微差别,如 ELF 品牌和目标规范;他们不是这个 linking 的主要负责人。在新加载的内核中启动的第一件事是 运行time linker,它知道选定的目标文件格式并执行初始 linking。
但是,不同的是,内核模块是针对不同的编程接口构建的,在某些情况下,针对不同的二进制接口构建。一些库函数可以停止;有些可以以完全不同的方式实施。如果你编译 link 内核模块时没有针对内核的特殊选项,它很可能不会 运行 正确(并导致内核崩溃)。这就是为什么应该使用特定的头文件集和编译选项。而且,您通常不能将用户态库加载到内核中,因为它依赖于内核中不存在的符号。
有什么影响?内核是用静态库编译的还是内部实现的?
另外,根据this,内核代码不能使用任何浮点运算。这是为什么?
Why is it not possible to link shared libraries into kernel code?
是可能的。但是,它们与您在用户空间中使用的共享库不同。
自经典 System V 以来,内核可以 运行 宁作为一组可加载模块而 是 通常 运行 这种方式。几乎所有的现代系统都使用它; Linux 和 FreeBSD 就是很好的例子。而且,他们使用相同的工具来创建与用户空间相同的模块。例如:
内核模块的共享对象:
$ file /lib/modules/4.4.0-97-generic/kernel/drivers/net/vxlan.ko
'/lib/modules/4.4.0-97-generic/kernel/drivers/net/vxlan.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=561b0b69742c93a595c85be50f6916352c793e5c, not stripped
用户空间库的共享对象:
$ file /lib64/libm-2.23.so
/lib64/libm-2.23.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=cb41640d6965fac9bac4010bebac955e95e4d8c1, for GNU/Linux 2.6.32, stripped
FreeBSD 也一样:
$ file /boot/kernel/agp.ko
/boot/kernel/agp.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not stripped
$ file /lib/libm.so.5
/lib/libm.so.5: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, stripped
在这些情况下,都是 ELF“共享对象”(您命名为“共享库”的东西;术语“共享对象”不太明显,但在 ELF 规范中声明)或“可重定位”(“目标文件” ; 但内核使用它的方式几乎与共享对象相同)。您可以在 file
诊断中看到细微差别,如 ELF 品牌和目标规范;他们不是这个 linking 的主要负责人。在新加载的内核中启动的第一件事是 运行time linker,它知道选定的目标文件格式并执行初始 linking。
但是,不同的是,内核模块是针对不同的编程接口构建的,在某些情况下,针对不同的二进制接口构建。一些库函数可以停止;有些可以以完全不同的方式实施。如果你编译 link 内核模块时没有针对内核的特殊选项,它很可能不会 运行 正确(并导致内核崩溃)。这就是为什么应该使用特定的头文件集和编译选项。而且,您通常不能将用户态库加载到内核中,因为它依赖于内核中不存在的符号。