aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-07-24 10:17:53 +0000
committerFelix Morgner <felix.morgner@ost.ch>2025-07-24 10:17:53 +0000
commit2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985 (patch)
treed311baa0e25e56bd1d7789fa3260ac5076fd6187
parentbb685cca3a537f0df4205050a9c52b411dee95c6 (diff)
downloadteachos-2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985.tar.xz
teachos-2ebf8d525e6a030efc8ca23bcbdf92c2d0cb8985.zip
x86_64: implement high/low split
-rw-r--r--.devcontainer/x86-64/devcontainer.json2
-rw-r--r--CMakeLists.txt1
-rw-r--r--arch/CMakeLists.txt4
-rw-r--r--arch/x86_64/scripts/kernel.ld35
-rw-r--r--arch/x86_64/src/boot/boot32.S102
-rw-r--r--cmake/Platforms/x86_64.cmake24
6 files changed, 96 insertions, 72 deletions
diff --git a/.devcontainer/x86-64/devcontainer.json b/.devcontainer/x86-64/devcontainer.json
index c23e655..3e3b934 100644
--- a/.devcontainer/x86-64/devcontainer.json
+++ b/.devcontainer/x86-64/devcontainer.json
@@ -1,6 +1,6 @@
{
"name": "TeachOS on x86-64",
- "image": "registry.gitlab.ost.ch:45023/teachos/devcontainers/x86-64:15.1.0-2",
+ "image": "registry.gitlab.ost.ch:45023/teachos/devcontainers/x86-64:15.1.0-3",
"customizations": {
"vscode": {
"extensions": [
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 821640c..7c7cc22 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,7 @@ target_link_libraries("kernel" PRIVATE
target_link_options("kernel" PRIVATE
"-no-pie"
+ "-nostdlib"
)
target_disassemble("kernel")
diff --git a/arch/CMakeLists.txt b/arch/CMakeLists.txt
index eded57e..661de26 100644
--- a/arch/CMakeLists.txt
+++ b/arch/CMakeLists.txt
@@ -16,6 +16,10 @@ target_include_directories("arch-any" INTERFACE
target_link_libraries("arch-any" INTERFACE
"libs::kstd"
+
+ "c"
+ "gcc"
+ "stdc++"
)
add_subdirectory("${CMAKE_SYSTEM_PROCESSOR}")
diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld
index 8af242f..6ba8b80 100644
--- a/arch/x86_64/scripts/kernel.ld
+++ b/arch/x86_64/scripts/kernel.ld
@@ -4,6 +4,7 @@ ENTRY(_start)
* Virtual and linear start addresses of the TeachOS kernel
*****************************************************************************/
TEACHOS_PMA = 1M;
+TEACHOS_VMA = 0xFFFFFFFF80000000;
PHDRS {
boot_rodata PT_LOAD FLAGS(4);
@@ -25,12 +26,13 @@ SECTIONS
. = TEACHOS_PMA;
/***************************************************************************
- * We want to be able to be able to access all memory (linear and virtual)
+ * We want to be able to be able to access all memory (physical and virtual)
* during bootstrapping and operation. To achieve this, we define some
* symbols at the beginning.
***************************************************************************/
_start_physical = .;
- _start_virtual = .;
+ _start_virtual = . + TEACHOS_VMA;
+
/***************************************************************************
* The bootstrapping infratructure goes first. We first place the read-only
@@ -63,7 +65,10 @@ SECTIONS
* Now it is time to load the 64-bit kernel code. We
* make sure to align the loaded data onto a page boundary.
***************************************************************************/
- .init ALIGN(4K) : AT(ADDR (.init))
+ . = ALIGN(4K);
+ . += TEACHOS_VMA;
+
+ .init ALIGN(4K) : AT(ADDR(.init) - TEACHOS_VMA)
{
/*
* Make sure that the crt code is wrapped around the compiler generated
@@ -74,7 +79,7 @@ SECTIONS
KEEP(*crtn.s.o*(.init))
} :text
- .fini ALIGN(4K) : AT(ADDR (.fini))
+ .fini ALIGN(4K) : AT(ADDR (.fini) - TEACHOS_VMA)
{
/*
* Make sure that the crt code is wrapped around the compiler generated
@@ -85,29 +90,29 @@ SECTIONS
KEEP(*crtn.s.o*(.fini))
}
- .stl_text ALIGN(4K) : AT(ADDR (.stl_text))
+ .stl_text ALIGN(4K) : AT(ADDR (.stl_text) - TEACHOS_VMA)
{
*(.stl_text .stl_text*)
KEEP(*libstdc++.a:*(.text .text.*))
}
- .text ALIGN(4K) : AT(ADDR (.text))
+ .text ALIGN(4K) : AT(ADDR (.text) - TEACHOS_VMA)
{
*(.text .text.*)
}
- .user_text ALIGN(4K) : AT(ADDR (.user_text))
+ .user_text ALIGN(4K) : AT(ADDR (.user_text) - TEACHOS_VMA)
{
*(.user_text .user_text.*)
}
- .rodata ALIGN(4K) : AT (ADDR (.rodata))
+ .rodata ALIGN(4K) : AT (ADDR (.rodata) - TEACHOS_VMA)
{
*(.rodata)
*(.rodata.*)
} :rodata
- .ctors ALIGN(4K) : AT (ADDR (.ctors))
+ .ctors ALIGN(4K) : AT (ADDR (.ctors) - TEACHOS_VMA)
{
KEEP(*crtbegin.o(.ctors))
KEEP(*(EXCLUDE_FILE (*crtend.o) .ctors))
@@ -115,7 +120,7 @@ SECTIONS
KEEP(*crtend.o(.ctors))
} :data
- .dtors ALIGN(4K) : AT (ADDR (.dtors))
+ .dtors ALIGN(4K) : AT (ADDR (.dtors) - TEACHOS_VMA)
{
KEEP(*crtbegin.o(.dtors))
KEEP(*(EXCLUDE_FILE (*crtend.o) .dtors))
@@ -123,18 +128,18 @@ SECTIONS
KEEP(*crtend.o(.dtors))
}
- .bss ALIGN(4K) : AT (ADDR (.bss))
+ .bss ALIGN(4K) : AT (ADDR (.bss) - TEACHOS_VMA)
{
*(COMMON)
*(.bss*)
}
- .data ALIGN(4K) : AT (ADDR (.data))
+ .data ALIGN(4K) : AT (ADDR (.data) - TEACHOS_VMA)
{
*(.data*)
}
- .user_data ALIGN(4K) : AT (ADDR (.user_data))
+ .user_data ALIGN(4K) : AT (ADDR (.user_data) - TEACHOS_VMA)
{
*(.user_data .user_data.*)
}
@@ -143,8 +148,8 @@ SECTIONS
* In accordance with the symbol definitions at the start, we generate some
* symbols to mark the end of our loaded image.
***************************************************************************/
- _end_virtual = ADDR(.bss) + SIZEOF(.bss);
- _end_physical = _end_virtual;
+ _end_virtual = .;
+ _end_physical = _end_virtual - TEACHOS_VMA;
/DISCARD/ : { *(.comment) }
}
diff --git a/arch/x86_64/src/boot/boot32.S b/arch/x86_64/src/boot/boot32.S
index 7e6c2ae..3039f38 100644
--- a/arch/x86_64/src/boot/boot32.S
+++ b/arch/x86_64/src/boot/boot32.S
@@ -13,9 +13,13 @@ multiboot_information_pointer: .skip 8
.align 4096
-page_map_level_4: .skip 512 * 8
-page_map_level_3: .skip 512 * 8
-page_map_level_2: .skip 512 * 8
+page_maps_start:
+page_map_level_4: .skip 512 * 8
+page_map_level_3_high: .skip 512 * 8
+page_map_level_3_low: .skip 512 * 8
+page_map_level_2: .skip 512 * 8
+page_maps_end = .
+page_maps_size = page_maps_end - page_maps_start
/**
* @brief Storage for the bootstrap stack.
@@ -40,9 +44,9 @@ global_descriptor_table:
global_descriptor_table_null = . - global_descriptor_table
.quad 0
global_descriptor_table_code = . - global_descriptor_table
-.quad GDT_ACCESSED | GDT_READ_WRITE | GDT_EXECUTABLE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | GDT_LONG_MODE
+.quad GDT_READ_WRITE | GDT_EXECUTABLE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | GDT_LONG_MODE | (1 << 55)
global_descriptor_table_data = . - global_descriptor_table
-.quad GDT_ACCESSED | GDT_READ_WRITE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT
+.quad GDT_READ_WRITE | GDT_DESCRIPTOR_TYPE | GDT_PRESENT | (1 << 54) | (1 << 55)
global_descriptor_table_end:
message_prefix_panic: .string "Panic: "
@@ -125,7 +129,10 @@ _start:
call _assert_cpuid_instruction_is_supported
call _assert_cpu_supports_long_mode
+ push $HUGE_PAGES_TO_MAP
call _prepare_page_maps
+ add $4, %esp
+
call _enable_paging
call _enable_sse
call _reload_gdt
@@ -302,51 +309,74 @@ _assert_cpu_supports_long_mode:
/**
* @brief Prepare a recursive page map hierarchy
*
- * We map all physical memory we were loaded in plus one additional page. The
- * mapping is done in terms of huge pages (2 MiB per page) to save on required
- * page map entries.
- *
+ * @param ebp+8 The number of huge pages to map
* @return void
*/
_prepare_page_maps:
pie_function_start
- push %ebx
- /* Map the P4 table recursively */
- lea (page_map_level_4 - 0b)(%esi), %eax
- mov %eax, %ebx
- or $0b11, %ebx
- mov %ebx, (511 * 8)(%eax)
-
- /* Add an entry to the PML4, pointing to the PML3 */
- lea (page_map_level_3 - 0b)(%esi), %ebx
- or $0b11, %ebx
- mov %ebx, (((0x0000000000100000 >> 39) & 0x1ff) * 8)(%eax)
-
- /* Add an entry to the PML3, pointing to the PML2 */
- lea (page_map_level_3 - 0b)(%esi), %eax
- lea (page_map_level_2 - 0b)(%esi), %ebx
- or $0b11, %ebx
- mov %ebx, (((0x0000000000100000 >> 30) & 0x1ff) * 8)(%eax)
-
- /* Add entries for huge pages to the PML2 */
push %edi
- lea (page_map_level_2 - 0b)(%esi), %ebx
- mov $HUGE_PAGES_TO_MAP, %edi
- xor %ecx, %ecx
+
+ call _clear_page_map_memory
+
+ lea (page_map_level_4 - 0b)(%esi), %edi
+ mov %edi, %eax
+ or $0b11, %eax
+ mov %eax, (510 * 8)(%edi)
+
+ lea (page_map_level_3_low - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (%edi)
+
+ lea (page_map_level_3_high - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (511 * 8)(%edi)
+
+ lea (page_map_level_3_low - 0b)(%esi), %edi
+ lea (page_map_level_2 - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (%edi)
+
+ lea (page_map_level_3_high - 0b)(%esi), %edi
+ lea (page_map_level_2 - 0b)(%esi), %eax
+ or $0b11, %eax
+ mov %eax, (510 * 8)(%edi)
+
+ lea (page_map_level_2 - 0b)(%esi), %edi
+ mov 8(%ebp), %ecx
1:
+ dec %ecx
mov $(1 << 21), %eax
mul %ecx
or $0b10000011, %eax
- mov %eax, (%ebx, %ecx, 8)
+ mov %eax, (%edi, %ecx, 8)
- inc %ecx
- cmp %edi, %ecx
- jne 1b
+ test %ecx, %ecx
+ jnz 1b
pop %edi
- pop %ebx
+
+ pie_function_end
+
+/**
+ * @brief Clear all page map memory by filling it with 0s.
+ *
+ * @return void
+ */
+_clear_page_map_memory:
+ pie_function_start
+
+ push %edi
+
+ xor %eax, %eax
+ mov $page_maps_size, %ecx
+ shr $2, %ecx
+ lea (page_maps_start - 0b)(%esi), %edi
+ rep stosl
+
+ pop %edi
+
pie_function_end
/**
diff --git a/cmake/Platforms/x86_64.cmake b/cmake/Platforms/x86_64.cmake
index c84d9ba..8db6142 100644
--- a/cmake/Platforms/x86_64.cmake
+++ b/cmake/Platforms/x86_64.cmake
@@ -1,17 +1,5 @@
include_guard(GLOBAL)
-macro(find_compiler_file NAME OUTPUT_VARIABLE)
- execute_process(COMMAND
- "${CMAKE_CXX_COMPILER}"
- "-mno-red-zone"
- "-print-file-name=${NAME}"
- OUTPUT_STRIP_TRAILING_WHITESPACE
- OUTPUT_VARIABLE "${OUTPUT_VARIABLE}"
- ERROR_QUIET
- )
- mark_as_advanced("${OUTPUT_VARIABLE}")
-endmacro()
-
set(PLATFORM_TARGET "x86_64-pc-elf")
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
@@ -27,7 +15,8 @@ find_program(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER_TARGET}-g++" REQUIRED)
set(CMAKE_CXX_FLAGS_INIT
"-mno-red-zone \
--mcmodel=large \
+-mcmodel=kernel \
+-fno-pie \
-fno-rtti \
-fno-exceptions \
-ffunction-sections \
@@ -46,19 +35,14 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -ggdb3")
set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -ggdb3")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -ggdb3")
-set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostartfiles -Wl,--gc-sections")
-
-find_compiler_file("crtbegin.o" CRT_BEGIN_PATH)
-find_compiler_file("crtend.o" CRT_END_PATH)
+set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--gc-sections")
set(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> \
<FLAGS> \
<CMAKE_CXX_LINK_FLAGS> \
<LINK_FLAGS> \
-${CRT_BEGIN_PATH} \
<OBJECTS> \
-o <TARGET> \
-<LINK_LIBRARIES> \
-${CRT_END_PATH}"
+<LINK_LIBRARIES>"
)