type
status
slug
summary
tags
category
icon
password
new update day
Property
Oct 22, 2023 01:31 PM
created days
Last edited time
Oct 22, 2023 01:31 PM
程序的符号表基本上只是一个包含程序符号(函数名、全局变量等)及其对应地址的符号的列表。对于每个 OSDever,使用符号表的原因可能不同,但是在加载内核模块时尤其有用,因为模块可以在任何地方加载并且它应该知道如何调用内核(干净利落,而不是肮脏的硬代码) .

1 Extracting the Debug Symbol Table

例如,如果您想要获取内核中的所有全局符号以进行调试,只需使用 nm 实用程序,如下所示。
在这里需要注意的重要一点是,我假设您使用 ELF 作为二进制格式,并且符号表部分没有被删除。生成的文件包含三列。第一个是符号的地址,第二个是它是什么类型的符号,第三个是符号的名称。

2 The Modulation Problem

我将从底部解释它。如果您有模块化和/或微内核,如果您不想失去调制优势,则必须遵守一条规则。这个简单的规则是在运行时加载每个需要的模块(仅需要的模块)。你注意到问题了吗?好吧,我将列出它们:
  • 该运行时模块包括 PCI IDE 驱动程序,对应于根挂载文件系统的驱动程序,以及所有 ACPI 表示存在的所有驱动程序。其中一些驱动程序需要访问海量存储单元,而其他模块是... 解决方案:一个 initrd。
  • 如果模块是在动态选择的位置加载的(由于硬件更改的可能性,这是强制性的),您必须为模块提供一个符号表,否则它们将不知道如何调用内核。 (甚至不要考虑使用典型的系统调用,那会太慢和昂贵,留给应用程序吧)这将包括驱动程序应该使用的所有快速和低级 API 函数。
对于动态加载问题,请使用以下解决方案:
  • #include 所有要导出到一个地方的符号。
  • 创建一个函数指针数组。由于您有不同的函数返回类型和参数,您应该这样做:
您必须将 123 替换为您的函数数量。
  • 在设置时,像这样填充表:
  • 当加载一个模块时,你应该(使用分页)引用KRNLSYMTABLE专用页(是的,它必须是这样的)到一个固定的虚拟内存页,这样模块总是知道在哪里找到东西。
注意,这个模型为每个驱动程序使用一个单独的页面目录。这不是最好的方法,但是这样内核就不会因为模块而崩溃。
 
wiki.osdev.org 系列之 - OS theorywiki.osdev.org 系列之 - System V ABI