diff options
| -rw-r--r-- | .conan/profiles/x86_64-gcc | 26 | ||||
| -rw-r--r-- | .gitignore | 7 | ||||
| -rw-r--r-- | .vscode/extensions.json | 9 | ||||
| -rw-r--r-- | .vscode/settings.json | 10 | ||||
| -rw-r--r-- | cmake/Platforms/x86_64.cmake | 23 | ||||
| -rw-r--r-- | conanfile.py | 54 | ||||
| -rw-r--r-- | requirements.txt | 1 | ||||
| -rw-r--r-- | source/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | source/boot/arch/x86_64/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | source/boot/arch/x86_64/src/boot.s | 374 | ||||
| -rw-r--r-- | source/boot/arch/x86_64/src/crti.s | 13 | ||||
| -rw-r--r-- | source/boot/arch/x86_64/src/crtn.s | 9 | ||||
| -rw-r--r-- | source/boot/arch/x86_64/src/multiboot.s | 17 | ||||
| -rw-r--r-- | source/kernel/CMakeLists.txt | 33 | ||||
| -rw-r--r-- | source/kernel/arch/x86_64/kern.ld | 139 | ||||
| -rw-r--r-- | source/kernel/src/entry.cpp | 9 |
16 files changed, 742 insertions, 1 deletions
diff --git a/.conan/profiles/x86_64-gcc b/.conan/profiles/x86_64-gcc new file mode 100644 index 0000000..1c29e8d --- /dev/null +++ b/.conan/profiles/x86_64-gcc @@ -0,0 +1,26 @@ +target_host=x86_64-none-elf +cc_compiler=gcc +cxx_compiler=g++ + +[env] +CHOST=$target_host +AR=$target_host-ar +AS=$target_host-as +CC=$target_host-$cc_compiler +CXX=$target_host-$cxx_compiler +LD=$target_host-$cxx_compiler +OBJDUMP=$target_host-objdump +RANLIB=$target_host-ranlib +STRIP=$target_host-strip + +[settings] +arch=x86_64 +build_type=Debug +compiler=gcc +compiler.version=13 +compiler.libcxx=libstdc++11 +compiler.cppstd=20 +os=baremetal + +[options] +gcc:target_arch=x86_64 @@ -1 +1,6 @@ -.venv +/.venv +/build + +# Conan Generated CMake presets +CMakeUserPresets.json +.gdb_history
\ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..8122897 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "basdp.language-gas-x86", + "ms-python.python", + "ms-vscode.cmake-tools", + "ms-vscode.cpptools", + "zixuanwang.linkerscript" + ] +}
\ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..51bcf93 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "cmake.sourceDirectory": "/home/sophia/Projects/os/teachos/kernel/source", + "cmake.useCMakePresets": "always", + + "C_Cpp.autoAddFileAssociations": false, + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + // "[python]": { + // "editor.defaultFormatter": "ms-python.black-formatter" + // }, +}
\ No newline at end of file diff --git a/cmake/Platforms/x86_64.cmake b/cmake/Platforms/x86_64.cmake new file mode 100644 index 0000000..9e727cf --- /dev/null +++ b/cmake/Platforms/x86_64.cmake @@ -0,0 +1,23 @@ +execute_process(COMMAND "x86_64-none-elf-g++" "-print-file-name=crtbegin.o" + OUTPUT_VARIABLE CRT_BEGIN + ERROR_QUIET +) +string(STRIP "${CRT_BEGIN}" CRT_BEGIN) +mark_as_advanced(CRT_BEGIN) + +string(REGEX REPLACE "/crtbegin.o" "" CMAKE_SYSROOT "${CRT_BEGIN}") +mark_as_advanced(CMAKE_SYSROOT) + +set(CMAKE_CXX_FLAGS_INIT "-m64 -mno-red-zone -mcmodel=large") +set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostartfiles") +set(CMAKE_CXX_LINK_EXECUTABLE + "<CMAKE_CXX_COMPILER> \ + <FLAGS> \ + <CMAKE_CXX_LINK_FLAGS> \ + <LINK_FLAGS> \ + ${CMAKE_SYSROOT}/crtbegin.o \ + <OBJECTS> \ + -o <TARGET> \ + <LINK_LIBRARIES> \ + ${CMAKE_SYSROOT}/crtend.o" +) diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..4712156 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,54 @@ +from conan import ConanFile +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.tools.env import VirtualBuildEnv + +class KernelConan(ConanFile): + name = "kernel" + description = "The kernel of TeachOS" + version = "0.0.1" + package_type = "application" + homepage = "https://gitlab.ost.ch/teachos/kernel" + + settings = [ + "arch", + "build_type", + "compiler", + ] + + tool_requires = [ + "cmake/[~3.27]", + "gcc/13.2.0@teachos/stable", + ] + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def generate(self): + build_environment = VirtualBuildEnv(self) + build_environment.generate() + + dependencies = CMakeDeps(self) + dependencies.generate() + + toolchain = CMakeToolchain(self) + toolchain.cache_variables["CMAKE_TRY_COMPILE_TARGET_TYPE"] = "STATIC_LIBRARY" + toolchain.variables["TEACHOS_DESCRIPTION"] = self.description + toolchain.variables["TEACHOS_HOMEPAGE_URL"] = self.homepage + toolchain.variables["TEACHOS_VERSION"] = self.version + toolchain.blocks["teachos_platform"] = PlatformIncludeBlock + toolchain.blocks["teachos_platform"].values["platform"] = self.settings.arch + toolchain.blocks.remove("cmake_flags_init") + toolchain.blocks.remove("arch_flags") + toolchain.generate() + + def layout(self): + cmake_layout(self, src_folder="source") + +class PlatformIncludeBlock: + template = "include(\"../cmake/Platforms/{{platform}}.cmake\")" + +def context(self): + return { "platform": None } + diff --git a/requirements.txt b/requirements.txt index 8dc8e73..4021434 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ +black>=23 conan~=1.61 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..80b566e --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION "3.27") + +project("kernel" + DESCRIPTION "${TEACHOS_DESCRIPTION}" + HOMEPAGE_URL "${TEACHOS_HOMEPAGE_URL}" + VERSION "${TEACHOS_VERSION}" + LANGUAGES ASM C CXX +) + +add_subdirectory("boot/arch/${CMAKE_SYSTEM_PROCESSOR}") +add_subdirectory("kernel") diff --git a/source/boot/arch/x86_64/CMakeLists.txt b/source/boot/arch/x86_64/CMakeLists.txt new file mode 100644 index 0000000..454f347 --- /dev/null +++ b/source/boot/arch/x86_64/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library("boot" STATIC + "src/boot.s" + "src/crti.s" + "src/crtn.s" + "src/multiboot.s" +) + +add_library("teachos::boot" ALIAS "boot")
\ No newline at end of file diff --git a/source/boot/arch/x86_64/src/boot.s b/source/boot/arch/x86_64/src/boot.s new file mode 100644 index 0000000..4781773 --- /dev/null +++ b/source/boot/arch/x86_64/src/boot.s @@ -0,0 +1,374 @@ +.extern _end_physical +.extern _init +.extern kernel_main + + +/** + * Uninitialized data for the bootstrapping process. + */ +.section .boot_bss, "aw", @nobits +.align 4096 + +/** + * Reserve space for the page maps we are going to used during startup. + * + * Note: We are going to use large pages to make the initial mapping code + * simpler. + * + * We need: + * - A single PML 4 (since we will only use 4-level paging) + * - 2 PML 3s (since we need to map high (-2GiB) and low (1+MiB) memory) + * - 2 PML 2s (since we need to map high (-2GiB) and low (1+MiB) memory) + */ + +.global page_map_level_4 +page_map_level_4: .skip 512 * 8 + +.global page_map_level_3_low +page_map_level_3_low: .skip 512 * 8 +.global page_map_level_3_high +page_map_level_3_high: .skip 512 * 8 + +.global page_map_level_2_low +page_map_level_2_low: .skip 512 * 8 +.global page_map_level_2_high +page_map_level_2_high: .skip 512 * 8 + +/** + * Reserve some space for the Multiboot 2 information pointer. + */ +.global multiboot_information_pointer +multiboot_information_pointer: .skip 4 + +/** + * Stack space for the bootstrapping process. + * + * Note: We are going to reserve 1 MiB for now. If/when the kernel requires + * more space to run, it will have to relocate the stack. + */ +.section .boot_stack, "aw", @nobits +.align 16 + +stack_bottom: .skip 1 << 20 +stack_top: + +/** + * Constants for the bootstrapping process. + */ +.section .boot_rodata, "a", @progbits + +/** + * A valid Global Descriptor Table is still required in long mode. However, we + * only need a single entry for the "code segment", so we will setup a single + * segment table below. + * + * Bit 43: "E" in the access byte => mark the segment as executable. + * Bit 44: "S" in the access byte => mark the segment as code or data. + * Bit 47: "P" in the access byte => mark the segment as being present. + * Bit 53: "L" in the flags byte => mark the segment as being for long mode + */ + +global_descriptor_table: .quad 0 +global_descriptor_table_code = . - global_descriptor_table +.quad (1<<43) | (1<<44) | (1<<47) | (1<<53) + +/** + * We also need a pointer that we can load into the GDTR. + * + * The pointer consists of a word describing the size of the table minus 1 and + * the pointer to the actual table. + */ +global_descriptor_table_pointer: +.word . - global_descriptor_table - 1 +.quad global_descriptor_table + +/** + * We are going to print some messages in case we panic during boot, so we are + * going to store them here as well + */ +message_prefix_panic: +.string "TeachOS Panic: " +message_not_loaded_by_multiboot2: +.string "The operating system was not loaded by a Multiboot 2 loader." +message_cpuid_instruction_no_supported: +.string "The 'cpuid' instruction is not supported on this platform." +mesage_long_mode_not_supported: +.string "Long mode is not supported by this platform." + +/** + * Mutable data for the bootstrapping process. + */ +.section .boot_data, "aw", @progbits + +/** + * We need a pointer to our current position in the VGA text buffer. + */ +vga_buffer_pointer: .long 0xb8000 + +/** + * Code for the bootstrapping process. + */ +.section .boot_text, "ax", @progbits +.align 16 +.code32 + +/** + * Print a given panic message and then halt the machine. + * + * Parameters: + * - [stack - 0] message: the message to print + */ +_panic: + push %ebp + mov %esp, %ebp + + push message_prefix_panic + push $0x4f + call _print + add $8, %esp + + push 8(%ebp) + push 0x4f + call _print + add $8, %esp + + hlt + +/** + * Print a message via the VGA buffer. + * + * Parameters: + * - [stack - 4] message: the message to print + * - [stack - 0] color: the color of the message + */ +_print: + push %ebp + mov %esp, %ebp + + push %ebx + push %esi + mov 8(%ebp), %eax + mov 12(%ebp), %ebx + mov $0, %ecx + mov (vga_buffer_pointer), %esi + +.Lprint_loop: + mov (%ebx, %ecx), %dl + test %dl, %dl + je .Lupdate_vga_buffer_address + mov %dl, (%esi, %ecx, 2) + mov %al, 1(%esi, %ecx, 2) + inc %ecx + jmp .Lprint_loop + +.Lupdate_vga_buffer_address: + shl $1, %ecx + add %ecx, (vga_buffer_pointer) + +.Lprint_end: + pop %esi + pop %ebx + mov %ebp, %esp + pop %ebp + ret + +/** + * This is our entry point after being loaded by the bootloader. + * + * Having this in assembly makes it easier for us to keep things together. + */ +.global _start +_start: + mov $stack_top, %esp + mov %esp, %ebp + + call assert_loaded_by_multiboot2_loader + call assert_cpuid_instruction_is_supported + call assert_cpu_supports_long_mode + call prepare_page_maps + call enable_paging + call enable_sse + + lgdt (global_descriptor_table_pointer) + jmp $global_descriptor_table_code,$_transition_to_long_mode + + hlt + +/** + * Assert that the CPU supports going into long mode. + */ +assert_cpu_supports_long_mode: + mov $0x80000000, %eax + cpuid + cmp $0x80000001, %eax + jb .Llong_mode_assertion_failed + + mov $0x80000001, %eax + cpuid + test $(1 << 29), %edx + jz .Llong_mode_assertion_failed + ret +.Llong_mode_assertion_failed: + push $mesage_long_mode_not_supported + call _panic + +/** + * Assert that the CPU supports the CPUID instruction. + * + * The primary way to check for support of the instruction is to flip the ID + * bin in EFLAGS and then check if this changed was accepted. If so, the CPU + * supports the CPUID instruction, otherwise it most-likely doesn't. + */ +assert_cpuid_instruction_is_supported: + pushfl + pop %eax + mov %eax, %ecx + + xor $(1 << 21), %eax /* Flip the ID bit */ + push %eax /* Move the new bitset on the stack for loading */ + popfl /* Load the flags with ID set back into EFLAGS */ + pushfl /* Copy the flags back onto the stack */ + pop %eax /* Load the flags for further checking */ + + push %ecx + popfl + + cmp %ecx, %eax + je .Lcpuid_assertion_fail + ret +.Lcpuid_assertion_fail: + push $message_cpuid_instruction_no_supported + call _panic + +/** + * Assert that we were loaded by a Multiboot 2 compliant bootloader. + * + * This assertion will panic the system if the magic signature was not found. + * If we were loaded my an appropriate bootloader, this function also saves + * the provided MBI pointer to `multiboot_information_pointer`. + */ +assert_loaded_by_multiboot2_loader: + cmp $0x36d76289, %eax /* Check if we received the + expected magic */ + jne .Lmultiboot2_assertion_fail /* Panic otherwise */ + mov %ebx, multiboot_information_pointer /* Store the MBI pointer */ + ret +.Lmultiboot2_assertion_fail: + push $message_not_loaded_by_multiboot2 + call _panic + +/** + * Enable paging. + * + * Note: This routine expects for there to be a valid set of page maps already + * set up for use. + */ +enable_paging: + mov $page_map_level_4, %eax + mov %eax, %cr3 + + /* Enable Physical Address Extension */ + mov %cr4, %eax + or $(1 << 5), %eax + mov %eax, %cr4 + + /* Enable long mode support */ + mov $0xC0000080, %ecx + rdmsr + or $(1 << 8), %eax + wrmsr + + /* Enable paging */ + mov %cr0, %eax + or $(1 << 31), %eax + mov %eax, %cr0 + + ret + +/** + * Enable use of SSE instructions. + */ +enable_sse: + mov %cr0, %eax + and $0xfffffffb, %eax + or $0x00000002, %eax + mov %eax, %cr0 + + mov %cr4, %eax + or $(3 << 9), %eax + mov %eax, %cr4 + + ret + +/** + * Prepare the page maps. + * + * 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. Note that we also map memory both in the low and high + * virtual address ranges, giving us two ways of accessing it. We need to do + * this, because the bootstrapping code lives in low memory, while the rest of + * the kernel will reside on the high end. + */ +prepare_page_maps: + /* Add an entry to the PML4, pointing to the low PML3 */ + mov $page_map_level_3_low, %eax + or $0x3, %eax + mov %eax, (page_map_level_4 + ((0x0000000000100000 >> 39) & 0x1ff) * 8) + + /* Add an entry to the PML4, pointing to the high PML3 */ + mov $page_map_level_3_high, %eax + or $0x3, %eax + mov %eax, (page_map_level_4 + ((0xffffffff80100000 >> 39) & 0x1ff) * 8) + + /* Add an entry to the low PML3, pointing to the low PML2 */ + mov $page_map_level_2_low, %eax + or $0x3, %eax + mov %eax, (page_map_level_3_low + ((0x0000000000100000 >> 30) & 0x1ff) * 8) + + /* Add an entry to the high PML3, pointing to the high PML2 */ + mov $page_map_level_2_high, %eax + or $0x3, %eax + mov %eax, (page_map_level_3_high + ((0xffffffff80100000 >> 30) & 0x1ff) * 8) + + xor %ecx, %ecx + + mov $_end_linear, %esi + shr $21, %esi + add $2, %esi + +.Lmap_pages: + mov $(1 << 21), %eax + mul %ecx + or $((1 << 0) | (1 << 1) | (1 << 7)), %eax + mov %eax, page_map_level_2_low(,%ecx,8) + mov %eax, page_map_level_2_high(,%ecx,8) + + inc %ecx + cmp %esi, %ecx + jne .Lmap_pages + + ret + +.section .boot_text, "ax", @progbits +.code64 + +_transition_to_long_mode: + xor %rax, %rax + mov %rax, %ss + mov %rax, %ds + mov %rax, %es + mov %rax, %fs + mov %rax, %gs + + /* Clear the screen */ + mov $0x0f200f200f200f20, %rax + mov $0x0b8000, %rdi + mov $500, %rcx + rep stosq + + call _init + + mov multiboot_information_pointer, %rdi + call kernel_main + hlt diff --git a/source/boot/arch/x86_64/src/crti.s b/source/boot/arch/x86_64/src/crti.s new file mode 100644 index 0000000..26878fe --- /dev/null +++ b/source/boot/arch/x86_64/src/crti.s @@ -0,0 +1,13 @@ +.code64 + +.section .init +.global _init +_init: + push %rbp + movq %rsp, %rbp + +.section .fini +.global _fini +_fini: + push %rbp + movq %rsp, %rbp diff --git a/source/boot/arch/x86_64/src/crtn.s b/source/boot/arch/x86_64/src/crtn.s new file mode 100644 index 0000000..06fb7ce --- /dev/null +++ b/source/boot/arch/x86_64/src/crtn.s @@ -0,0 +1,9 @@ +.code64 + +.section .init + popq %rbp + ret + +.section .fini + popq %rbp + ret diff --git a/source/boot/arch/x86_64/src/multiboot.s b/source/boot/arch/x86_64/src/multiboot.s new file mode 100644 index 0000000..207a639 --- /dev/null +++ b/source/boot/arch/x86_64/src/multiboot.s @@ -0,0 +1,17 @@ +.section .boot_mbh, "a" +.align 64 + +multiboot_header_start: +.Lmagic: + .long 0xe85250d6 +.Larch: + .long 0 +.Llength: + .long multiboot_header_end - multiboot_header_start +.Lchecksum: + .long 0x100000000 - (0xe85250d6 + 0 + (multiboot_header_end - multiboot_header_start)) +.Lend: + .int 0 + .int 0 + .long 8 +multiboot_header_end: diff --git a/source/kernel/CMakeLists.txt b/source/kernel/CMakeLists.txt new file mode 100644 index 0000000..c8e0c4a --- /dev/null +++ b/source/kernel/CMakeLists.txt @@ -0,0 +1,33 @@ +set(TEACHOS_KERNEL_LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/arch/${CMAKE_SYSTEM_PROCESSOR}/kern.ld") +mark_as_advanced(TEACHOS_KERNEL_LINKER_SCRIPT) + +add_executable("kernel" + "src/entry.cpp" +) + +target_compile_features("kernel" PRIVATE + "cxx_std_20" +) + +target_compile_options("kernel" PRIVATE + "$<$<CXX_COMPILER_ID:GNU>:-Wall>" + "$<$<CXX_COMPILER_ID:GNU>:-Wextra>" + "$<$<CXX_COMPILER_ID:GNU>:-Werror>" + "$<$<CXX_COMPILER_ID:GNU>:-pedantic-errors>" +) + +target_link_options("kernel" PRIVATE + "-T${TEACHOS_KERNEL_LINKER_SCRIPT}" +) + +target_link_libraries("kernel" PRIVATE + "-Wl,--whole-archive" + "teachos::boot" + "-Wl,--no-whole-archive" +) + +set_target_properties("kernel" PROPERTIES + CXX_EXTENSIONS OFF + CXX_STANDARD_REQUIRED YES + LINK_DEPENDS "${TEACHOS_KERNEL_LINKER_SCRIPT}" +) diff --git a/source/kernel/arch/x86_64/kern.ld b/source/kernel/arch/x86_64/kern.ld new file mode 100644 index 0000000..4e44cfa --- /dev/null +++ b/source/kernel/arch/x86_64/kern.ld @@ -0,0 +1,139 @@ +ENTRY(_start) + +/***************************************************************************** + * Virtual and linear start addresses of the TeachOS kernel + *****************************************************************************/ +TEACHOS_HIGH = -2048M; +TEACHOS_LOW = 1M; + +PHDRS { + boot_rodata PT_LOAD FLAGS(4); + boot_text PT_LOAD FLAGS(5); + boot_data PT_LOAD FLAGS(6); + + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); + rodata PT_LOAD FLAGS(4); +} + +SECTIONS +{ + /*************************************************************************** + * Load the bootstrap code into low memory. We need to be accessible in + * 32-Bit mode, so we want to live down low, but we need to leave the 1MiB + * hole open since some BIOS functionality resides below it. + ***************************************************************************/ + . = TEACHOS_LOW; + + /*************************************************************************** + * We want to be able to be able to access all memory (linear and virtual) + * during bootstrapping and operation. To achieve this, we define some + * symbols at the beginning. + ***************************************************************************/ + _start_linear = .; + _start_virtual = . + TEACHOS_HIGH; + + /*************************************************************************** + * The bootstrapping infratructure goes first. We first place the read-only + * data, followed by our code, initialized mutable data, and finally our + * uninitialized mutable data. + ***************************************************************************/ + .boot_rodata : + { + KEEP(*(.boot_mbh)) + *(.boot_rodata) + } :boot_rodata + + .boot_text : + { + *(.boot_text) + } :boot_text + + .boot_data : + { + *(.boot_data) + } :boot_data + + .boot_bss : + { + *(.boot_bss) + *(.boot_stack) + } + + /*************************************************************************** + * Now it is time to load the 64-bit kernel code. We virtually load it into + * the upper 2GiB, while adjusting the linear load address appropriately. We + * also make sure to align the loaded data onto a page boundary. + ***************************************************************************/ + . = ALIGN(4K); + . += TEACHOS_HIGH; + + .init ALIGN(4K) : AT(ADDR (.init) - TEACHOS_HIGH) + { + /* + * Make sure that the crt code is wrapped around the compiler generated + * initialization code. + */ + KEEP(*:crti.s.obj(.init)) + KEEP(*(EXCLUDE_FILE (*crti.s.obj crtn.s.obj) .init)) + KEEP(*:crtn.s.obj(.init)) + } :text + + .fini ALIGN(4K) : AT(ADDR (.fini) - TEACHOS_HIGH) + { + /* + * Make sure that the crt code is wrapped around the compiler generated + * finalizer code. + */ + KEEP(*:crti.s.obj(.fini)) + KEEP(*(EXCLUDE_FILE (*crti.s.obj crtn.s.obj).fini)) + KEEP(*:crtn.s.obj(.fini)) + } + + .text ALIGN(4K) : AT(ADDR (.text) - TEACHOS_HIGH) + { + *(.text*) + } + + .rodata ALIGN(4K) : AT (ADDR (.rodata) - TEACHOS_HIGH) + { + *(.rodata) + *(.rodata.*) + } :rodata + + .ctors ALIGN(4K) : AT (ADDR (.ctors) - TEACHOS_HIGH) + { + KEEP(*crtbegin.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*crtend.o(.ctors)) + } :data + + .dtors ALIGN(4K) : AT (ADDR (.dtors) - TEACHOS_HIGH) + { + KEEP(*crtbegin.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*crtend.o(.dtors)) + } + + .data ALIGN(4K) : AT (ADDR (.data) - TEACHOS_HIGH) + { + *(.data) + } + + .bss ALIGN(4K) : AT (ADDR (.bss) - TEACHOS_HIGH) + { + *(COMMON) + *(.bss*) + } + + /*************************************************************************** + * 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_linear = _end_virtual - TEACHOS_HIGH; + + /DISCARD/ : { *(.comment) } +} diff --git a/source/kernel/src/entry.cpp b/source/kernel/src/entry.cpp new file mode 100644 index 0000000..0daf227 --- /dev/null +++ b/source/kernel/src/entry.cpp @@ -0,0 +1,9 @@ +namespace teachos +{ + extern "C" auto kernel_main() -> void + { + while(true) { + asm volatile ("nop"); + } + } +} |
