浏览代码

Kernel: Invoke heap constructors separately early on

By having a separate list of constructors for the kernel heap
code, we can properly use constructors without re-running them
after the heap was already initialized. This solves some problems
where values were wiped out because they were overwritten by
running their constructors later in the initialization process.
Tom 5 年之前
父节点
当前提交
08ff25f4ef
共有 4 个文件被更改,包括 20 次插入8 次删除
  1. 8 4
      Kernel/CMakeLists.txt
  2. 3 4
      Kernel/Heap/SlabAllocator.cpp
  3. 5 0
      Kernel/init.cpp
  4. 4 0
      Kernel/linker.ld

+ 8 - 4
Kernel/CMakeLists.txt

@@ -1,3 +1,8 @@
+set(KERNEL_HEAP_SOURCES
+    Heap/SlabAllocator.cpp
+    Heap/kmalloc.cpp
+)
+
 set(KERNEL_SOURCES
 set(KERNEL_SOURCES
     ACPI/DynamicParser.cpp
     ACPI/DynamicParser.cpp
     ACPI/Initialize.cpp
     ACPI/Initialize.cpp
@@ -47,8 +52,6 @@ set(KERNEL_SOURCES
     FileSystem/ProcFS.cpp
     FileSystem/ProcFS.cpp
     FileSystem/TmpFS.cpp
     FileSystem/TmpFS.cpp
     FileSystem/VirtualFileSystem.cpp
     FileSystem/VirtualFileSystem.cpp
-    Heap/SlabAllocator.cpp
-    Heap/kmalloc.cpp
     Interrupts/APIC.cpp
     Interrupts/APIC.cpp
     Interrupts/GenericInterruptHandler.cpp
     Interrupts/GenericInterruptHandler.cpp
     Interrupts/IOAPIC.cpp
     Interrupts/IOAPIC.cpp
@@ -244,6 +247,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -nostdinc -nostdinc++")
 add_link_options(LINKER:-T ${CMAKE_CURRENT_BINARY_DIR}/linker.ld -nostdlib)
 add_link_options(LINKER:-T ${CMAKE_CURRENT_BINARY_DIR}/linker.ld -nostdlib)
 
 
 add_library(boot OBJECT Arch/i386/Boot/boot.S)
 add_library(boot OBJECT Arch/i386/Boot/boot.S)
+add_library(kernel_heap STATIC ${KERNEL_HEAP_SOURCES})
 file(GENERATE OUTPUT linker.ld INPUT linker.ld)
 file(GENERATE OUTPUT linker.ld INPUT linker.ld)
 
 
 if (${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS)
 if (${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS)
@@ -255,8 +259,8 @@ else()
 endif()
 endif()
 
 
 add_executable(Kernel ${SOURCES})
 add_executable(Kernel ${SOURCES})
-target_link_libraries(Kernel gcc stdc++)
-add_dependencies(Kernel boot)
+target_link_libraries(Kernel kernel_heap gcc stdc++)
+add_dependencies(Kernel boot kernel_heap)
 install(TARGETS Kernel RUNTIME DESTINATION boot)
 install(TARGETS Kernel RUNTIME DESTINATION boot)
 
 
 add_custom_command(
 add_custom_command(

+ 3 - 4
Kernel/Heap/SlabAllocator.cpp

@@ -100,12 +100,11 @@ private:
         char padding[templated_slab_size - sizeof(FreeSlab*)];
         char padding[templated_slab_size - sizeof(FreeSlab*)];
     };
     };
 
 
-    // NOTE: These are not default-initialized to prevent an init-time constructor from overwriting them
-    FreeSlab* m_freelist;
+    FreeSlab* m_freelist { nullptr };
     Atomic<size_t> m_num_allocated;
     Atomic<size_t> m_num_allocated;
     Atomic<size_t> m_num_free;
     Atomic<size_t> m_num_free;
-    void* m_base;
-    void* m_end;
+    void* m_base { nullptr };
+    void* m_end { nullptr };
     SpinLock<u32> m_lock;
     SpinLock<u32> m_lock;
 
 
     static_assert(sizeof(FreeSlab) == templated_slab_size);
     static_assert(sizeof(FreeSlab) == templated_slab_size);

+ 5 - 0
Kernel/init.cpp

@@ -76,6 +76,8 @@
 
 
 // Defined in the linker script
 // Defined in the linker script
 typedef void (*ctor_func_t)();
 typedef void (*ctor_func_t)();
+extern ctor_func_t start_heap_ctors;
+extern ctor_func_t end_heap_ctors;
 extern ctor_func_t start_ctors;
 extern ctor_func_t start_ctors;
 extern ctor_func_t end_ctors;
 extern ctor_func_t end_ctors;
 
 
@@ -107,6 +109,9 @@ extern "C" [[noreturn]] void init()
 
 
     s_bsp_processor.early_initialize(0);
     s_bsp_processor.early_initialize(0);
 
 
+    // Invoke the constructors needed for the kernel heap
+    for (ctor_func_t* ctor = &start_heap_ctors; ctor < &end_heap_ctors; ctor++)
+        (*ctor)();
     kmalloc_init();
     kmalloc_init();
     slab_alloc_init();
     slab_alloc_init();
 
 

+ 4 - 0
Kernel/linker.ld

@@ -18,6 +18,10 @@ SECTIONS
 
 
     .rodata ALIGN(4K) : AT (ADDR(.rodata) - 0xc0000000)
     .rodata ALIGN(4K) : AT (ADDR(.rodata) - 0xc0000000)
     {
     {
+        start_heap_ctors = .;
+        *libkernel_heap.a:*(.ctors)
+        end_heap_ctors = .;
+
         start_ctors = .;
         start_ctors = .;
         *(.ctors)
         *(.ctors)
         end_ctors = .;
         end_ctors = .;