c - 原型(prototype)内核和模块

标签 c module kernel osdev

最近我选择了一个旧项目并重新启动它,几乎是从头开始。 我已经病了一段时间了,所以我有时间努力打击并实现大量功能。但是,我认为实现一个好主意的一件事是模块加载。我想对模块进行内核模式动态加载。

模块这个词有点模棱两可,正确的说法应该是加载库,例如内核模式的C库的微型实现 驱动程序或标准的东西,例如 PITkeyboard,它们位于 IRQ 0 和 1 上。我试图实现的方法有点 self 维持;在我的内核将加载的模块方面,将在内核本身中使用以进入用户模式

例如,我的内核使用了我自己实现的 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 中的引导 stub 执行动态链接。稍后,同样的动态链接器也可用于加载其他驱动程序。

关于c - 原型(prototype)内核和模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6541795/

相关文章:

java - 自动包含数字的模块名称

python - 当一个模块被导入两次时会发生什么?

android - 试图修改内核

c - 重复的结构定义(一个定义在头文件中,另一个在 C 源代码中)

c++ - 关于 main 函数的命令行参数

c - 复制到 malloced 内存时出现段错误

c - 使用 vga 将消息打印到屏幕上

c - 为什么以下代码的输出为零?

module - 在 typescript 中封装子命名空间

linux - 查看内核 printk 调试消息