type
Post
status
Published
slug
2022/12/11/wiki-osdev-org-symbol-table
summary
tags
osdev
category
osdev
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 实用程序,如下所示。
$ nm mykernel.bin > mykernel.map
在这里需要注意的重要一点是,我假设您使用 ELF 作为二进制格式,并且符号表部分没有被删除。生成的文件包含三列。第一个是符号的地址,第二个是它是什么类型的符号,第三个是符号的名称。
2 The Modulation Problem
我将从底部解释它。如果您有模块化和/或微内核,如果您不想失去调制优势,则必须遵守一条规则。这个简单的规则是在运行时加载每个需要的模块(仅需要的模块)。你注意到问题了吗?好吧,我将列出它们:
- 该运行时模块包括 PCI IDE 驱动程序,对应于根挂载文件系统的驱动程序,以及所有 ACPI 表示存在的所有驱动程序。其中一些驱动程序需要访问海量存储单元,而其他模块是... 解决方案:一个 initrd。
- 如果模块是在动态选择的位置加载的(由于硬件更改的可能性,这是强制性的),您必须为模块提供一个符号表,否则它们将不知道如何调用内核。 (甚至不要考虑使用典型的系统调用,那会太慢和昂贵,留给应用程序吧)这将包括驱动程序应该使用的所有快速和低级 API 函数。
对于动态加载问题,请使用以下解决方案:
#include
所有要导出到一个地方的符号。
- 创建一个函数指针数组。由于您有不同的函数返回类型和参数,您应该这样做:
uint32_t KRNLSYMTABLE[123];
您必须将 123 替换为您的函数数量。
- 在设置时,像这样填充表:
KRNLSYMTABLE[321] = (uint32_t)&myFunction;
- 当加载一个模块时,你应该(使用分页)引用KRNLSYMTABLE专用页(是的,它必须是这样的)到一个固定的虚拟内存页,这样模块总是知道在哪里找到东西。
注意,这个模型为每个驱动程序使用一个单独的页面目录。这不是最好的方法,但是这样内核就不会因为模块而崩溃。
欢迎加入“喵星计算机技术研究院”,原创技术文章第一时间推送。
- 作者:tangcuyu
- 链接:https://expoli.tech/articles/2022/12/11/wiki-osdev-org-symbol-table
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章
2022-12-11
wiki.osdev.org 系列之 - Category:Bare Bones (类别:基本教程)
2022-12-11
wiki.osdev.org 系列之 - Linux Kernel Primer(Linux 内核入门)
2022-12-11
wiki.osdev.org 系列之 - OS theory
2022-12-11
wiki.osdev.org 系列之 - System V ABI
2022-12-10
wiki.osdev.org 系列之 - Category:Object Files (类别:目标文件)
2022-12-10
wiki.osdev.org 系列之 - ELF