diff --git a/.gitignore b/.gitignore index 3ce8e8d..3272ace 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ binutils/ gawk/ builddir/ config.cmake +config.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ba58b0f..c050851 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,4 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) +INCLUDE(./config.cmake) FIND_PACKAGE(PythonInterp 3 REQUIRED) ADD_SUBDIRECTORY(kernel) diff --git a/config.py b/config.py index 3d224df..dfbc6a5 100755 --- a/config.py +++ b/config.py @@ -41,3 +41,15 @@ with open("config.cmake", "w") as f: f.write('SET('+key+' 1)\n') elif val != False: f.write('SET('+key+' '+str(val)+')\n') + +with open("config.h", "w") as f: + for key, val in config.items(): + if val == True: + f.write("#define "+key+" 1\n") + elif val == False: + f.write("#undef "+key+"\n") + elif isinstance(val, int): + f.write("#define "+key+" ("+str(val)+")\n") + else: + f.write("#define "+key+' "'+val+'"\n') + diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 616e604..6aa2f2d 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,2 +1,36 @@ ENABLE_LANGUAGE(C CXX ASM-ATT) -INCLUDE(arch/$ARCH/$SYSTEM/config.cmake) +FUNCTION(LOAD_PROFILE ISA PLATFORM) + # Obtain sources for the ISA + FILE(GLOB ISA_SRCS arch/${ISA}/*.c arch/${ISA}/*.s arch/${ISA}/*.cpp) + FILE(GLOB PLATFORM_SRCS arch/${ISA}/${PLATFORM}/*.c arch/${ISA}/${PLATFORM}/*.s arch/${ISA}/${PLATFORM}/*.cpp) + + # Load flags associated with ISA and Profile + INCLUDE("arch/${ISA}/flags.cmake") + INCLUDE("arch/${ISA}/${PLATFORM}/flags.cmake") + + # Now export our output variables + SET(ISA_SRCS ${ISA_SRCS} PARENT_SCOPE) + SET(PLATFORM_SRCS ${PLATFORM_SRCS} PARENT_SCOPE) + SET(PLATFORM_LAYOUT "arch/${ISA}/${PLATFORM}/layout.ld" PARENT_SCOPE) + + # And specific flags + SET(ISA_C_FLAGS ${ISA_C_FLAGS} PARENT_SCOPE) + SET(ISA_CXX_FLAGS ${ISA_CXX_FLAGS} PARENT_SCOPE) + SET(ISA_ASM_FLAGS ${ISA_ASM_FLAGS} PARENT_SCOPE) + + SET(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} PARENT_SCOPE) + SET(PLATFORM_CXX_FLAGS ${PLATFORM_CXX_FLAGS} PARENT_SCOPE) + SET(PLATFORM_ASM_FLAGS ${PLATFORM_ASM_FLAGS} PARENT_SCOPE) + + SET(ISA_LINKER_FLAGS ${ISA_LINKER_FLAGS} PARENT_SCOPE) + SET(PLATFORM_LINKER_FLAGS ${ISA_LINKER_FLAGS} PARENT_SCOPE) +ENDFUNCTION(LOAD_PROFILE) +FILE(GLOB_RECURSE GENERIC_SRCS src/*.c src/*.cpp) +LOAD_PROFILE(${ARCH} ${SYSTEM}) +ADD_EXECUTABLE(kernel ${PLATFORM_SRCS} ${ISA_SRCS} ${GENERIC_SRCS}) +SET(CMAKE_ASM-ATT_COMPILE_OBJECT + " -m32 -x assembler-with-cpp -I../../ -I../../libk/include/ -I../../kernel/src/include/ ${ISA_ASM_FLAGS} ${PLATFORM_ASM_FLAGS} -c -o ") +SET(CMAKE_C_FLAGS "-m32 -w -Werror -Wno-unused -Wno-unused-variable -std=c11 -I../../ -I../../libk/include/ -I../../kernel/src/include/ ${ISA_C_FLAGS} ${PLATFORM_C_FLAGS}") +SET(CMAKE_CXX_FLAGS "-m32 -w -Werror -Wno-unused -Wno-unused-variable -fno-rtti -fno-exceptions -std=gnu++17 -I../../ -I../../libk/include/ -I../../kernel/src/include/ ${ISA_CXX_FLAGS} ${PLATFORM_CXX_FLAGS}") +SET_TARGET_PROPERTIES(kernel PROPERTIES LINK_FLAGS + "-T ../../kernel/${PLATFORM_LAYOUT} -N ${ISA_LINKER_FLAGS} ${PLATFORM_LINKER_FLAGS} -nostdlib -nodefaultlibs -lgcc -Wl,--gc-sections") diff --git a/kernel/arch/x86/flags.cmake b/kernel/arch/x86/flags.cmake new file mode 100644 index 0000000..062079f --- /dev/null +++ b/kernel/arch/x86/flags.cmake @@ -0,0 +1,2 @@ +SET(ISA_C_FLAGS "-m32 -I../../kernel/arch/x86/include/") +SET(ISA_CXX_FLAGS "${ISA_C_FLAGS}") diff --git a/kernel/arch/x86/pc/flags.cmake b/kernel/arch/x86/pc/flags.cmake new file mode 100644 index 0000000..06b3777 --- /dev/null +++ b/kernel/arch/x86/pc/flags.cmake @@ -0,0 +1,3 @@ +SET(PLATFORM_C_FLAGS "-I../../kernel/arch/x86/pc/include") +SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}") +SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}") diff --git a/kernel/arch/x86/pc/include/multiboot.h b/kernel/arch/x86/pc/include/multiboot.h new file mode 100644 index 0000000..7e5ac69 --- /dev/null +++ b/kernel/arch/x86/pc/include/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; +} GRUB_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 +{ + grub_uint16_t version; + grub_uint16_t cseg; + grub_uint32_t offset; + grub_uint16_t cseg_16; + grub_uint16_t dseg; + grub_uint16_t flags; + grub_uint16_t cseg_len; + grub_uint16_t cseg_16_len; + grub_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/kernel/arch/x86/pc/layout.ld b/kernel/arch/x86/pc/layout.ld new file mode 100644 index 0000000..6d7b451 --- /dev/null +++ b/kernel/arch/x86/pc/layout.ld @@ -0,0 +1,36 @@ +ENTRY(_start) +SECTIONS { + . = 0x100000; + kernel_start = .; + .text : { + KEEP(*(.text.boot)); + *(.text) + } + .data : { + start_ctors = .; + KEEP(*(.init_array)); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))); + KEEP(*(.ctors)); + end_ctors = .; + start_dtors = .; + KEEP(*(.fini_array)); + KEEP(*(.fini_array.*)); + KEEP(*(.dtors)); + end_dtors = .; + start_eh_frame = .; + KEEP(*(.eh_frame)); + KEEP(*(.eh_frame.*)); + QUAD(0); + KEEP(*(.gcc_except_table)); + KEEP(*(.gcc_except_table.*)); + *(.data) + } + .rodata : { + *(.rodata) + } + .bss : { + *(.bss) + *(COMMON) + } + kernel_end = .; +} diff --git a/kernel/arch/x86/pc/start.c b/kernel/arch/x86/pc/start.c new file mode 100644 index 0000000..8f59025 --- /dev/null +++ b/kernel/arch/x86/pc/start.c @@ -0,0 +1,9 @@ +void start() { + const char hw[] = "Hello World!"; + int i; + char* video = (char*) 0xb8000; + for (i = 0; hw[i] != '\0'; i++) { + video[i * 2] = hw[i]; + video[i * 2 + 1] = 0x07; + } +} diff --git a/kernel/arch/x86/pc/start.s b/kernel/arch/x86/pc/start.s new file mode 100644 index 0000000..321ecdd --- /dev/null +++ b/kernel/arch/x86/pc/start.s @@ -0,0 +1,116 @@ +#define ASM_FILE 1 +#include +#include +.section .text.boot +.global _start +_start: + jmp _start2 +.align MULTIBOOT_HEADER_ALIGN +.int MULTIBOOT_HEADER_MAGIC +.int 0x0 +.int -(MULTIBOOT_HEADER_MAGIC) +.align MULTIBOOT_HEADER_ALIGN +.extern start +_start2: + lgdt gdtr + mov $0x10, %cx + mov %cx, %ds + mov %cx, %es + mov %cx, %fs + mov %cx, %gs + mov %cx, %ss + ljmp $0x08, $_start3 +_start3: + mov $kernel_stack, %esp //Initialize Stack + push %ebx + push %eax //Push arguments to start() +#ifdef ENABLE_FPU + finit //Enable FPU +#endif +#ifdef ENABLE_SSE + //Check for SSE + mov $1, %eax + cpuid + test $1<<25, %edx + jz _noSSE + mov %cr0, %eax + and $0xFFFB, %ax + or $0x2, %ax + mov %eax, %cr0 + mov %cr4, %eax + or $3<<9, %ax + mov %eax, %cr4 +_noSSE: +#endif + call start +_stop: + cli + hlt + jmp _stop + + +.section .data +gdtr: + .word 9 * 8 + .int gdt +gdt: + .quad 0 //NULL + //32-bit kernel code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x9A + .byte 0xCF + .byte 0x00 + //32-bit kernel code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x92 + .byte 0xCF + .byte 00 + //32-bit user code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0xFA + .byte 0xCF + .byte 0x00 + //32-bit user data + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0xF2 + .byte 0xCF + .byte 00 + //64-bit kernel code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x9B + .byte 0xAF + .byte 0x00 + //64-bit kernel code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0x93 + .byte 0xCF + .byte 00 + //64-bit user code + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0xFB + .byte 0xAF + .byte 0x00 + //64-bit user data + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .byte 0xF3 + .byte 0xCF + .byte 00 +.section .bss +.space 16384 +kernel_stack: diff --git a/readme b/readme new file mode 100644 index 0000000..d053392 --- /dev/null +++ b/readme @@ -0,0 +1,9 @@ +to build mtgos you need the cross compilers, whose makefile is included in cross/ + +Quick walkthrough of the steps needed for building: + +1) ./config.py - this will ask you a couple questions needed for building and create a appropriate config.cmake and config.h +2) mkdir -pv build; cd build - this will enter a build directory, as an in-dir build is not supported +3) cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/.cmake .. +4) make +5) Kernel is in kernel/kernel diff --git a/toolchains/arm-none-eabi.cmake b/toolchains/arm-none-eabi.cmake index 499eca4..89bc81b 100644 --- a/toolchains/arm-none-eabi.cmake +++ b/toolchains/arm-none-eabi.cmake @@ -5,7 +5,7 @@ SET(CMAKE_SYSTEM_VERSION 0) SET(CMAKE_C_COMPILER $ENV{HOME}/opt/bin/arm-none-eabi-gcc) #CMAKE_FORCE_CXX_COMPILER($ENV{HOME}/opt/bin/i686-elf-g++ GNU) SET(CMAKE_CXX_COMPILER $ENV{HOME}/opt/bin/arm-none-eabi-g++) -SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/arm-none-eabi-as) +SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/arm-none-eabi-gcc) SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/opt) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff --git a/toolchains/i686-elf.cmake b/toolchains/i686-elf.cmake index fafd381..cdc015e 100644 --- a/toolchains/i686-elf.cmake +++ b/toolchains/i686-elf.cmake @@ -5,7 +5,7 @@ SET(CMAKE_SYSTEM_VERSION 0) SET(CMAKE_C_COMPILER $ENV{HOME}/opt/bin/i686-elf-gcc) #CMAKE_FORCE_CXX_COMPILER($ENV{HOME}/opt/bin/i686-elf-g++ GNU) SET(CMAKE_CXX_COMPILER $ENV{HOME}/opt/bin/i686-elf-g++) -SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/i686-elf-as) +SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/i686-elf-gcc) SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/opt) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff --git a/toolchains/x86_64-elf.cmake b/toolchains/x86_64-elf.cmake index 4b70c61..b62f551 100644 --- a/toolchains/x86_64-elf.cmake +++ b/toolchains/x86_64-elf.cmake @@ -5,7 +5,7 @@ SET(CMAKE_SYSTEM_VERSION 0) SET(CMAKE_C_COMPILER $ENV{HOME}/opt/bin/x86_64-elf-gcc) #CMAKE_FORCE_CXX_COMPILER($ENV{HOME}/opt/bin/i686-elf-g++ GNU) SET(CMAKE_CXX_COMPILER $ENV{HOME}/opt/bin/x86_64-elf-g++) -SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/x86_64-elf-as) +SET(CMAKE_ASM_COMPILER $ENV{HOME}/opt/bin/x86_64-elf-gcc) SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/opt) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)