浏览代码

Kernel: Make the kernel independent from specific physical addresses

Previously the kernel relied on a fixed offset between virtual and
physical addresses based on the kernel's load address. This allows us
to specify an independent offset.
Gunnar Beutner 4 年之前
父节点
当前提交
3c616ae00f
共有 5 个文件被更改,包括 7 次插入2 次删除
  1. 1 0
      Kernel/BootInfo.h
  2. 1 0
      Kernel/Prekernel/Prekernel.h
  3. 1 0
      Kernel/Prekernel/init.cpp
  4. 2 2
      Kernel/VM/MemoryManager.h
  5. 2 0
      Kernel/init.cpp

+ 1 - 0
Kernel/BootInfo.h

@@ -12,6 +12,7 @@
 
 extern "C" PhysicalAddress start_of_prekernel_image;
 extern "C" PhysicalAddress end_of_prekernel_image;
+extern "C" size_t physical_to_virtual_offset;
 extern "C" FlatPtr kernel_base;
 #if ARCH(X86_64)
 extern "C" u32 gdt64ptr;

+ 1 - 0
Kernel/Prekernel/Prekernel.h

@@ -20,6 +20,7 @@ namespace Kernel {
 struct [[gnu::packed]] BootInfo {
     u32 start_of_prekernel_image;
     u32 end_of_prekernel_image;
+    u64 physical_to_virtual_offset;
     u64 kernel_base;
     u64 multiboot_info_ptr;
 #    if ARCH(X86_64)

+ 1 - 0
Kernel/Prekernel/init.cpp

@@ -150,6 +150,7 @@ extern "C" [[noreturn]] void init()
     BootInfo info;
     info.start_of_prekernel_image = (PhysicalPtr)start_of_prekernel_image;
     info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image;
+    info.physical_to_virtual_offset = kernel_load_base;
     info.kernel_base = kernel_load_base;
     info.multiboot_info_ptr = (FlatPtr)adjust_by_load_base(multiboot_info_ptr);
 #if ARCH(X86_64)

+ 2 - 2
Kernel/VM/MemoryManager.h

@@ -43,12 +43,12 @@ constexpr FlatPtr page_round_down(FlatPtr x)
 
 inline FlatPtr low_physical_to_virtual(FlatPtr physical)
 {
-    return physical + kernel_base;
+    return physical + physical_to_virtual_offset;
 }
 
 inline FlatPtr virtual_to_low_physical(FlatPtr virtual_)
 {
-    return virtual_ - kernel_base;
+    return virtual_ - physical_to_virtual_offset;
 }
 
 enum class UsedMemoryRangeType {

+ 2 - 0
Kernel/init.cpp

@@ -111,6 +111,7 @@ extern "C" {
 READONLY_AFTER_INIT PhysicalAddress start_of_prekernel_image;
 READONLY_AFTER_INIT PhysicalAddress end_of_prekernel_image;
 READONLY_AFTER_INIT FlatPtr kernel_base;
+READONLY_AFTER_INIT size_t physical_to_virtual_offset;
 #if ARCH(X86_64)
 READONLY_AFTER_INIT PhysicalAddress boot_pml4t;
 #endif
@@ -128,6 +129,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     multiboot_info_ptr = (multiboot_info_t*)boot_info.multiboot_info_ptr;
     start_of_prekernel_image = PhysicalAddress { boot_info.start_of_prekernel_image };
     end_of_prekernel_image = PhysicalAddress { boot_info.end_of_prekernel_image };
+    physical_to_virtual_offset = boot_info.physical_to_virtual_offset;
     kernel_base = boot_info.kernel_base;
 #if ARCH(X86_64)
     gdt64ptr = boot_info.gdt64ptr;