原型内核和模块
最近我选择了一个旧项目并重新启动它,几乎从零开始。 我已经病了一段时间,所以我有时间严厉打击并实施大量功能。 然而,我认为有一件事是实现模块加载的好主意。 我想做内核模式动态加载模块。
单词模块有点模棱两可,正确的术语只是加载库,例如内核模式驱动程序的C库的最小实现或IRQ 0和1上的PIT和键盘等标准事物。 我试图实现的方法有点自持, 在内核将加载的模块方面,内核本身将使用它来进入用户模式 。
举个例子,我的内核使用了我自己实现的C库中的很少的函数。 这些函数本身用于设置我的GDT,IDT,IRQ,ISR等等。我想将这些函数抽象为内核可以加载和使用的库。 这意味着内核本身在第一阶段需要模块加载,在任何设置之前。
现在,我已经想到了一些自己做这件事的方法,比如在这个库中添加一个结构体,该结构体包含一个函数指针表,这些函数指针指定了库本身中函数的地址。 将库编译为aout-kludge文件,将库作为void * (这是可以的,因为我有一个工作分配器)加载到内核中,然后计算结构的偏移量,进入void指针,并在内核中重新创建结构。 这听起来不像是可行的,因为函数指针表需要分配,这意味着库中需要有一个初始化函数。 即使我知道这个地址,怎么会这样呢?
我对于如何实现这样一个装载机毫无头绪,它甚至值得吗? 我想尽可能地抽象,我的内核有一个模块化设计。 我也希望用这种方法加载驱动程序和其他东西,我只是不确定如何实现它。 我已经尝试了各种方法,但都失败了。 我该怎么办?
我建议你先在用户空间中编写一个动态加载器。 所需的技术非常相似,您可能稍后将大部分代码调整到内核空间。 另外,不要使用a.out,也不要编写自己的'函数指针表' - 使用更现代的格式,比如ELF。 编译时工具已经存在,所以这会节省你很多的工作量; 你可以写一个适当的链接器脚本,并直接从Linux GCC构建。
正如它发生的那样,Windows内核的操作与您所说的非常相似--Windows内核(ntoskrnl.exe)是一个PE可执行文件,它链接来自各种DLL(PSHED.dll,HAL.dll,KDCOM.dll,CLFS)的例程。 sys和Cl.dll在我的系统上)。 在这种情况下,NTLDR程序会将ntoskrnl.exe所需的所有文件加载到内存中,然后ntoskrnl.exe中的启动存根执行动态链接。 稍后可以使用相同的动态链接器来加载其他驱动程序。
实现内核模块并不是一件简单的工作。 这有点复杂,你需要阅读ELF文档进行编码。 我会尽力为您提供一些见解 -
在用户空间中,可执行文件需要共享库来实现其某些功能或代码。 因此,可执行文件中的代码将引用共享库中的代码。 这导致了符号的发展。 符号表示指向数据/函数/其他并具有名称的指针。
CHAR VariableName[20];
例如,在上面的代码中,将使用名称'VariableName'创建一个数据符号。 在动态/共享库的“发明”之后,必须加载符号表(二进制符号集)以解析来自库中可执行文件的引用。 但符号表中存在大量调试符号和无用符号。
Symbol: Main.c
例如,在符号表中,即使是用于调试的C源文件的符号也会出现。 但这在运行时解析引用不是必需的。 在这里,动态符号的概念来了。
动态链接是指解析二进制文件之间的引用。 动态链接器将使用动态符号表(必须加载&'正常'符号表不需要)来解析可执行文件在库中所做的引用。
现在,在作为可执行文件的内核核心中,共享库(内核模块)中没有引用。 但共享库在可执行文件中引用。 因此,可执行文件必须包含用于解析内核模块中引用的动态符号。 这与用户空间中的情况相反。 因此,如果你使用ld,
-pie -T LinkerScript.ld
选项应该用于在内核可执行文件中创建一个动态符号表。
你应该创建一个LinkerScript.ld文件 -
/* File: LinkerScript.ld */
PHDRS {
kernel PT_LOAD FILEHDR;/* This declares a segment in which your code/data is.*/
dynamic PT_DYNAMIC;/* Segment containing the dynamic table (not DST). */
}
SECTIONS {
/* text, data, bss sections must be implemented already */
.dynamic ALIGN(0x1000) : AT(ADDR(.dynamic) - KERNEL_OFFSET)
{
*(.dynamic)
} :dynamic/* add :kernel to text, data, bss*/
}
具有上述结构。 确保你的.text,.data和.bss部分已经存在&:kernel被添加到部分描述符的末尾。
有关更多信息,请阅读ELF文档和LD手册(链接器脚本见解)。
链接地址: http://www.djcxy.com/p/70313.html上一篇: Prototype Kernel and modules
下一篇: How do websites play audio in the header continuously on url changes