为什么不能将共享库链接到内核代码?

时间:2017-10-21 06:45:31

标签: assembly linux-kernel x86 osdev

有什么影响?内核是用静态库编译的还是内在实现的?

另外,根据this,内核代码不能使用任何浮点运算。那是为什么?

1 个答案:

答案 0 :(得分:4)

  

为什么不能将共享库链接到内核代码?

是可能的。但是,它们您在userland中使用的相同共享库。

从经典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

userland库的共享对象:

$ 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品牌和目标规范;他们不是这种联系的主要内容。在新加载的内核中开始的第一件事是运行时链接程序,它知道所选的目标文件格式并执行初始链接。

但是, 的不同之处在于,内核模块是针对不同的编程接口构建的,在某些情况下,针对不同的二进制接口。一些库函数可以停止;有些可以以相当不同的方式实施。如果编译并链接内核模块而没有针对内核的特殊选项,则很有可能它无法正常运行(并导致内核崩溃)。这就是为什么应该使用特定的标头集和编译选项。并且,您通常无法将userland库加载到内核中,因为它依赖于内核中不存在的符号。