在初始化我的内核时,我有几件事需要发生:1)需要启用分页,2)物理内存管理器需要从 grub 解析内存映射,以及 3)各种启动代码需要访问需要的数据留在那里供以后使用(例如 GDT、IDT、内存管理结构)。
这些步骤之间的依赖关系让我发疯。对于高半部分,内核链接在其虚拟地址处,因此我提出的选项是 1)在程序集中启用分页,这将涉及跟踪所有多引导指针(在程序集中),因此它们仍然可以访问到物理内存管理器,然后将它们全部取消映射,2)将启动代码链接到其物理地址,然后进行一些指针操作以访问其物理地址的内核结构,或者 3)不使用高半部分核心。
还涉及在编译时不知道物理内存量的情况下引导物理内存管理器。我很确定我必须在分配第一个结构时小心地避免所有多重引导结构,或者首先使用它们然后不要担心覆盖它们(尽管我仍然必须处理模块并且这种方法可能涉及在设置物理内存管理器时将多重引导表复制到我需要的已知位置)。
这些问题是我到目前为止避免使用更高半内核的原因。有没有人有一个很好的系统来解决这些依赖关系? this GDT trick 上可能有一些变化在其链接/虚拟地址处访问内核和在其物理地址处访问多引导表,或者使用某种预定义的页表来避免上述问题,可能涉及 PSE?
最佳答案
这就是我解决这个问题的方法:
我的内核镜像由 GRUB 在(物理)地址 0x01000000(16MB,就在 ISA DMA 区域上方)加载。这张图基本上由两部分组成:
由于早期 init 部分中的代码与加载它的地址链接在同一地址,因此 GRUB 可以毫无问题地跳转到该代码。此早期初始化代码执行以下步骤:
在这一点上,其余的初始化是从高半代码完成的。这包括设置 GDT、IDT、内存管理……请注意,MBI 已重新定位到众所周知的位置,因此您不必担心用自己的数据结构覆盖它。
关于物理内存管理器的小话:我所做的是计算我的数据结构所需的页面数量,从内核镜像之后的第一页开始分配这些结构,并从这些数据结构之后开始处理页面。
我希望这个解释是清楚的。如果不是,请告诉我。如果您愿意,我还可以为您提供我的内核的副本。
关于kernel - 高半内核初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6222411/