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

Tre*_*rey 1 x86 assembly osdev linux-kernel

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

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

Net*_*tch 5

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

可能的。但是,他们是不是你在用户空间使用相同的共享库。

由于经典的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
Run Code Online (Sandbox Code Playgroud)

用户空间库的共享对象:

$ 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在这些情况下,所有都是 ELF“共享对象”(您命名为“共享库”的东西;术语“共享对象”不太明显但在 ELF 规范中声明)或“可重定位”(“对象文件”;但是内核的方式使用它几乎与共享对象相同)。您可以看到file诊断的细微差别,如 ELF 品牌和目标规范;它们不是这种链接的主体。在新加载的内核中启动的第一件事是运行时链接器,它知道选定的目标文件格式并执行初始链接。

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