diff --git a/SConstruct b/SConstruct index abfc4b1..a29173a 100644 --- a/SConstruct +++ b/SConstruct @@ -1,52 +1,36 @@ import subprocess +AddOption( + '--target', + dest = 'target', + type = 'choice', + choices = ('i686', 'x86_64'), + nargs = 1, + action = 'store', + default = 'i686' +) + +target = GetOption('target') + env = Environment(tools = ['default', 'compilation_db']) -env['AS'] = 'i686-elf-as' -env['CC'] = 'i686-elf-gcc' -env['CXX'] = 'i686-elf-g++' -env['LD'] = 'i686-elf-g++' env.Append(CXXFLAGS = ['-ffreestanding', '-fno-exceptions', '-fno-rtti', '-std=c++20']) env.Append(LINKFLAGS = ['-T', 'linker.ld', '-ffreestanding', '-nostdlib']) -env.Append(CPPPATH = ['#include', '#bastl/include']) +env.Append(CPPPATH = ['#targets/_any/include', '#bastl/include']) env.Append(CCFLAGS = ['-g', '-O0']) -def get_crt_object(name: str) -> str: - cmd = [env['CXX']] - cmd.extend(env['CXXFLAGS']) - cmd.append(f'-print-file-name={name}') - result = subprocess.run(cmd, stdout=subprocess.PIPE) - return result.stdout.decode('utf-8').strip() -crtbegin_o = get_crt_object('crtbegin.o') -crtend_o = get_crt_object('crtend.o') -crti_o = env.Object('src/crt/crti.s') -crtn_o = env.Object('src/crt/crtn.s') - -os_sources = Split(''' - src/app/main.cpp - - src/kernel/boot.s - src/kernel/startup.cpp - - src/os/panic.cpp - src/os/tty.cpp - - src/cstdlib/assert.cpp - src/cstdlib/stdio.cpp - src/cstdlib/stdlib.cpp - src/cstdlib/string.cpp - - bastl/src/exception.cpp - bastl/src/new.cpp -''') -env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0]} {crtbegin_o} $_LIBFLAGS {crtend_o} {crtn_o[0]}') +env['KERNEL_SOURCES'] = [] +env['KERNEL_DEPENDENCIES'] = [] +env = SConscript('bastl/SConscript', exports = 'env') +env = SConscript('targets/_any/SConscript', exports = 'env') +env = SConscript(f'targets/{target}/SConscript', exports = 'env') prog_os = env.Program( target = 'os.bin', - source = os_sources, + source = env['KERNEL_SOURCES'], LIBS = ['gcc'] ) -env.Depends(prog_os, [crti_o, crtn_o]) +env.Depends(prog_os, env['KERNEL_DEPENDENCIES']) env.Default(prog_os) comp_db = env.CompilationDatabase(target = '#compile_commands.json') env.Default(comp_db) diff --git a/bastl/SConscript b/bastl/SConscript new file mode 100644 index 0000000..590b854 --- /dev/null +++ b/bastl/SConscript @@ -0,0 +1,10 @@ +Import('env') + +bastl_sources = Split(''' + src/exception.cpp + src/new.cpp +''') + +env.Append(KERNEL_SOURCES = [env.File(f) for f in bastl_sources]) + +Return('env') \ No newline at end of file diff --git a/targets/_any/SConscript b/targets/_any/SConscript new file mode 100644 index 0000000..162da52 --- /dev/null +++ b/targets/_any/SConscript @@ -0,0 +1,17 @@ +Import('env') + +any_target_sources = Split(''' + src/app/main.cpp + + src/os/panic.cpp + src/os/tty.cpp + + src/cstdlib/assert.cpp + src/cstdlib/stdio.cpp + src/cstdlib/stdlib.cpp + src/cstdlib/string.cpp +''') + +env.Append(KERNEL_SOURCES = [env.File(f) for f in any_target_sources]) + +Return('env') \ No newline at end of file diff --git a/include/assert.h b/targets/_any/include/assert.h similarity index 100% rename from include/assert.h rename to targets/_any/include/assert.h diff --git a/include/detail/common.h b/targets/_any/include/detail/common.h similarity index 100% rename from include/detail/common.h rename to targets/_any/include/detail/common.h diff --git a/include/os/panic.hpp b/targets/_any/include/os/panic.hpp similarity index 100% rename from include/os/panic.hpp rename to targets/_any/include/os/panic.hpp diff --git a/include/os/tty.hpp b/targets/_any/include/os/tty.hpp similarity index 100% rename from include/os/tty.hpp rename to targets/_any/include/os/tty.hpp diff --git a/include/stdio.h b/targets/_any/include/stdio.h similarity index 100% rename from include/stdio.h rename to targets/_any/include/stdio.h diff --git a/include/stdlib.h b/targets/_any/include/stdlib.h similarity index 100% rename from include/stdlib.h rename to targets/_any/include/stdlib.h diff --git a/include/string.h b/targets/_any/include/string.h similarity index 100% rename from include/string.h rename to targets/_any/include/string.h diff --git a/src/app/main.cpp b/targets/_any/src/app/main.cpp similarity index 100% rename from src/app/main.cpp rename to targets/_any/src/app/main.cpp diff --git a/src/cstdlib/assert.cpp b/targets/_any/src/cstdlib/assert.cpp similarity index 100% rename from src/cstdlib/assert.cpp rename to targets/_any/src/cstdlib/assert.cpp diff --git a/src/cstdlib/stdio.cpp b/targets/_any/src/cstdlib/stdio.cpp similarity index 100% rename from src/cstdlib/stdio.cpp rename to targets/_any/src/cstdlib/stdio.cpp diff --git a/src/cstdlib/stdlib.cpp b/targets/_any/src/cstdlib/stdlib.cpp similarity index 100% rename from src/cstdlib/stdlib.cpp rename to targets/_any/src/cstdlib/stdlib.cpp diff --git a/src/cstdlib/string.cpp b/targets/_any/src/cstdlib/string.cpp similarity index 100% rename from src/cstdlib/string.cpp rename to targets/_any/src/cstdlib/string.cpp diff --git a/src/os/panic.cpp b/targets/_any/src/os/panic.cpp similarity index 100% rename from src/os/panic.cpp rename to targets/_any/src/os/panic.cpp diff --git a/src/os/tty.cpp b/targets/_any/src/os/tty.cpp similarity index 100% rename from src/os/tty.cpp rename to targets/_any/src/os/tty.cpp diff --git a/targets/i686/SConscript b/targets/i686/SConscript new file mode 100644 index 0000000..32de224 --- /dev/null +++ b/targets/i686/SConscript @@ -0,0 +1,31 @@ +Import('env') + +env['AS'] = 'i686-elf-as' +env['CC'] = 'i686-elf-gcc' +env['CXX'] = 'i686-elf-g++' +env['LD'] = 'i686-elf-g++' + +def get_crt_object(name: str) -> str: + import subprocess + + cmd = [env['CXX']] + cmd.extend(env['CXXFLAGS']) + cmd.append(f'-print-file-name={name}') + result = subprocess.run(cmd, stdout=subprocess.PIPE) + return result.stdout.decode('utf-8').strip() +crtbegin_o = get_crt_object('crtbegin.o') +crtend_o = get_crt_object('crtend.o') +crti_o = env.Object('src/crt/crti.s') +crtn_o = env.Object('src/crt/crtn.s') + +i686_sources = Split(''' + src/kernel/boot.s + src/kernel/startup.cpp +''') + +env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0].abspath} {crtbegin_o} $_LIBFLAGS {crtend_o} {crtn_o[0].abspath}') + +env.Append(KERNEL_SOURCES = [env.File(f) for f in i686_sources]) +env.Append(KERNEL_DEPENDENCIES = [crti_o, crtn_o]) + +Return('env') \ No newline at end of file diff --git a/src/crt/crti.s b/targets/i686/src/crt/crti.s similarity index 100% rename from src/crt/crti.s rename to targets/i686/src/crt/crti.s diff --git a/src/crt/crtn.s b/targets/i686/src/crt/crtn.s similarity index 100% rename from src/crt/crtn.s rename to targets/i686/src/crt/crtn.s diff --git a/src/kernel/boot.s b/targets/i686/src/kernel/boot.s similarity index 100% rename from src/kernel/boot.s rename to targets/i686/src/kernel/boot.s diff --git a/src/kernel/multiboot.h b/targets/i686/src/kernel/multiboot.h similarity index 100% rename from src/kernel/multiboot.h rename to targets/i686/src/kernel/multiboot.h diff --git a/src/kernel/startup.cpp b/targets/i686/src/kernel/startup.cpp similarity index 100% rename from src/kernel/startup.cpp rename to targets/i686/src/kernel/startup.cpp diff --git a/targets/x86_64/SConscript b/targets/x86_64/SConscript new file mode 100644 index 0000000..76e5968 --- /dev/null +++ b/targets/x86_64/SConscript @@ -0,0 +1,32 @@ +Import('env') + +env['AS'] = 'x86_64-elf-as' +env['CC'] = 'x86_64-elf-gcc' +env['CXX'] = 'x86_64-elf-g++' +env['LD'] = 'x86_64-elf-g++' + +def get_crt_object(name: str) -> str: + import subprocess + + cmd = [env['CXX']] + cmd.extend(env['CXXFLAGS']) + cmd.append(f'-print-file-name={name}') + result = subprocess.run(cmd, stdout=subprocess.PIPE) + return result.stdout.decode('utf-8').strip() +crtbegin_o = get_crt_object('crtbegin.o') +crtend_o = get_crt_object('crtend.o') +crti_o = env.Object('src/crt/crti.s') +crtn_o = env.Object('src/crt/crtn.s') + +i686_sources = Split(''' + src/kernel/boot.s + src/kernel/startup.cpp +''') + +env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0].abspath} {crtbegin_o} $_LIBFLAGS {crtend_o} {crtn_o[0].abspath}') + +env.Append(KERNEL_SOURCES = [env.File(f) for f in i686_sources]) +env.Append(KERNEL_DEPENDENCIES = [crti_o, crtn_o]) +env.Append(LINKFLAGS = ['-mcmodel=large', '-mno-red-zone', '-mno-mmx', '-mno-sse', '-mno-sse2']) + +Return('env') diff --git a/targets/x86_64/src/crt/crti.s b/targets/x86_64/src/crt/crti.s new file mode 100644 index 0000000..3b9195b --- /dev/null +++ b/targets/x86_64/src/crt/crti.s @@ -0,0 +1,16 @@ +/* x86 crti.s */ +.section .init +.global _init +.type _init, @function +_init: + push %rbp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .init section here. */ + +.section .fini +.global _fini +.type _fini, @function +_fini: + push %rbp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/targets/x86_64/src/crt/crtn.s b/targets/x86_64/src/crt/crtn.s new file mode 100644 index 0000000..6b674ba --- /dev/null +++ b/targets/x86_64/src/crt/crtn.s @@ -0,0 +1,10 @@ +/* x86 crtn.s */ +.section .init + /* gcc will nicely put the contents of crtend.o's .init section here. */ + pop %rbp + ret + +.section .fini + /* gcc will nicely put the contents of crtend.o's .fini section here. */ + pop %rbp + ret diff --git a/targets/x86_64/src/kernel/boot.s b/targets/x86_64/src/kernel/boot.s new file mode 100644 index 0000000..f502c78 --- /dev/null +++ b/targets/x86_64/src/kernel/boot.s @@ -0,0 +1,79 @@ +// constants for the multiboot header +.set ALIGN, 1<<0 /* align loaded modules on page boundaries */ +.set MEMINFO, 1<<1 /* provide memory map */ +.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */ +.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ +.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ + +// the actual multiboot header +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +// stack section +.section .bss +.align 16 +stack_bottom: +.skip 16384 # 16 KiB +stack_top: + +// kernel entry point +.section .text +.global _start +.type _start, @function +_start: + /* + The bootloader has loaded us into 32-bit protected mode on a x86 + machine. Interrupts are disabled. Paging is disabled. The processor + state is as defined in the multiboot standard. The kernel has full + control of the CPU. The kernel can only make use of hardware features + and any code it provides as part of itself. There's no printf + function, unless the kernel provides its own header and a + printf implementation. There are no security restrictions, no + safeguards, no debugging mechanisms, only what the kernel provides + itself. It has absolute and complete power over the + machine. + */ + + // store the multiboot info + mov %ebx, (gMultibootHeader) + + // setup stack + mov $stack_top, %esp + + // call the constructors + mov $start_ctors, %ebx + jmp .ctors_loop_end +.ctors_loop_start: + call *(%ebx) + add 4, %ebx +.ctors_loop_end: + cmp $end_ctors, %ebx + jb .ctors_loop_start + + // enter high-level kernel + call kernel_main + +// // call the destructors +// mov $start_dtors, %ebx +// jmp .dtors_loop_end +//.dtors_loop_start: +// call *(%ebx) +// add 4, %ebx +//.dtors_loop_end: +// cmp $end_dtors, %ebx +// jb .dtors_loop_start + + // We are done. Clear interrupts and halt. + cli +.kernel_end: + hlt + jmp .kernel_end + +/* +Set the size of the _start symbol to the current location '.' minus its start. +This is useful when debugging or when you implement call tracing. +*/ +.size _start, . - _start diff --git a/targets/x86_64/src/kernel/multiboot.h b/targets/x86_64/src/kernel/multiboot.h new file mode 100644 index 0000000..f6302ea --- /dev/null +++ b/targets/x86_64/src/kernel/multiboot.h @@ -0,0 +1,274 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info +{ + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/targets/x86_64/src/kernel/startup.cpp b/targets/x86_64/src/kernel/startup.cpp new file mode 100644 index 0000000..e51c816 --- /dev/null +++ b/targets/x86_64/src/kernel/startup.cpp @@ -0,0 +1,70 @@ + +#include "os/tty.hpp" + +#include +#include +#include +#include "./multiboot.h" + +extern "C" int gKernelEnd; + +namespace +{ +void initHeapFromMultibootHeader(const uint32_t firstEntryAddr, const size_t bufferLength) noexcept +{ + const uint64_t minAddr = reinterpret_cast(&gKernelEnd); + for (uint32_t addr = firstEntryAddr; addr < firstEntryAddr + bufferLength;) + { + multiboot_memory_map_t entry = *reinterpret_cast(addr); + + if(entry.type == MULTIBOOT_MEMORY_AVAILABLE) + { + std::printf("Start Addr: %X | Length: %b\n", + static_cast(entry.addr), static_cast(entry.len)); + + // anything before the kernel we ignore + if (entry.addr < minAddr) + { + // if the entire entry is before the kernel, continue + if (entry.addr + entry.len <= minAddr) + { + addr += sizeof(entry.size) + entry.size; + continue; + } + // otherwise shrink it and use the rest + entry.len -= (minAddr - entry.addr); + entry.addr = minAddr; + } + __ba_registerAllocatableMemory(reinterpret_cast(entry.addr), entry.len); + } + addr += sizeof(entry.size) + entry.size; + } +} +} + +extern "C" +{ +multiboot_info_t* gMultibootHeader; + +void _init(); +void _fini(); +void main(); + +void kernel_main() +{ + _init(); + + /* Initialize terminal interface */ + tty::initialize(); + + std::printf("Kernel End: %p\n", &gKernelEnd); + + /* Initialize the heap */ + assert(gMultibootHeader->flags & MULTIBOOT_INFO_MEM_MAP); + initHeapFromMultibootHeader(gMultibootHeader->mmap_addr, gMultibootHeader->mmap_length); + + main(); + + _fini(); +} +} // extern "C"