6

在初始化我的内核时,我有一些事情需要发生:1)需要启用分页,2)物理内存管理器需要从 grub 解析内存映射,3)各种启动代码需要访问需要的数据留在那里供以后使用(例如 GDT、IDT、内存管理结构)。

这些步骤之间的依赖关系让我发疯。对于高半部分,内核链接在其虚拟地址处,因此我提出的选项是 1)在程序集中启用分页,这将涉及跟踪所有多引导指针(在程序集中),因此它们仍然可以访问到物理内存管理器,然后将它们全部取消映射,2)将启动代码链接到其物理地址,然后进行一些指针操作以访问其物理地址处的内核结构,或者 3)不使用高半部分核心。

还涉及在编译时不知道物理内存量的情况下引导物理内存管理器。我很确定我必须在分配第一个结构时小心避免所有多重引导结构,或者先使用它们然后不要担心覆盖它们(尽管我仍然必须处理模块并且这种方法可能涉及在设置物理内存管理器时将多重引导表复制到我需要的已知位置)。

这些问题是我到目前为止避免使用更高半内核的原因。有没有人有一个很好的系统来解决这些依赖关系?也许这个 GDT 技巧的一些变化是在其链接/虚拟地址访问内核和在其物理地址访问多引导表,或者使用某种预定义的页表来避免上述问题,可能涉及 PSE?

4

1 回答 1

6

This is how I tackled this problem:

My kernel image is loaded by GRUB at (physical) address 0x01000000 (16MB, just above the ISA DMA region). This image basically consists of two parts:

  1. An "early init" section. This section contains code that is executed to prepare to jump to the higher half kernel. I also reserve some space in this section for a stack and a heap used during this preparation. All code in this section is linked at (virtual) address 0x01000000.
  2. The rest of the image contains code and data that is part of the higher half kernel. All code in this part is linked at (virtual) address 0xc0000000 (3GB).

Since the code in the early init section is linked at the same address as where it is loaded, GRUB can jump into this code without any problems. This early init code performs the following steps:

  1. Relocate the MBI structure that GRUB passes to the kernel. The heap inside the early init section is used for this.
  2. Identity map all pages starting at physical address 0x0 up to the physical address of the last page used by the early init section. Identity mapping means that the virtual addresses are the same as the physical addresses. This makes sure that the code in the early init section can still be executed after paging is enabled.
  3. Map the higher half kernel at virtual address 0xc0000000.
  4. Enable paging.
  5. Jump into the higher half kernel.

At this point the rest of the initialization is done from higher half code. This includes setting up the GDT, IDT, memory management,... Note that the MBI is relocated to a well-known location so you shouldn't have to worry about overwriting it with your own data structures.

A small word about the physical memory manager: What I do is calculate the amount of pages needed for my data structures, allocate these structures starting at the first page after the kernel image and start dealing pages starting after these data structures.

I hope this explanation is clear. If it's not, please let me know. I could also provide you with a copy of my kernel if you'd like that.

于 2011-06-03T08:39:34.127 回答