diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..862aed8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Makefile b/Makefile index aa43673..90aa8cf 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ all: clean build build: build_kernel run run: - $(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std build_kernel: $(OBJ_LINK_LIST) diff --git a/src/kernel/MMU.cpp b/src/kernel/MMU.cpp index 96867f4..dfdd9ab 100644 --- a/src/kernel/MMU.cpp +++ b/src/kernel/MMU.cpp @@ -21,9 +21,9 @@ void MMU::enable(){ //we will fill all 1024 entries in the table, mapping 4 megabytes for(unsigned int i = 0; i < 1024; i++) { - // As the address is page aligned, it will always leave 12 bits zeroed. - // Those bits are used by the attributes ;) - first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. + // As the address is page aligned, it will always leave 12 bits zeroed. + // Those bits are used by the attributes ;) + first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. } // attributes: supervisor level, read/write, present @@ -32,4 +32,10 @@ void MMU::enable(){ loadPageDirectory(this->page_directory); enablePaging(); +} + + +uint32_t MMU::readTableEntry(int entry){ + return this->page_directory[entry]; + } \ No newline at end of file diff --git a/src/kernel/MMU.h b/src/kernel/MMU.h index cb3b7f8..df65d38 100644 --- a/src/kernel/MMU.h +++ b/src/kernel/MMU.h @@ -7,6 +7,7 @@ extern "C" void enablePaging(); class MMU { public: void enable (); + uint32_t readTableEntry(int); private: uint32_t page_directory[1024] __attribute__((aligned(4096))); diff --git a/src/kernel/arch/i386/MMU/SlabAllocator.h b/src/kernel/arch/i386/MMU/SlabAllocator.h new file mode 100644 index 0000000..b9f00df --- /dev/null +++ b/src/kernel/arch/i386/MMU/SlabAllocator.h @@ -0,0 +1,33 @@ +#pragma once +/** + * We'll need something to this effect to allocate memory in the kernel + * this will hopefully someday implement a full slab allocator + **/ +enum SlabState { + empty, + partial, + full +}; + +class CacheSlab { + const int SlabSize = 4000; + void* start = 0x0; +}; + + +class Allocator { + + public: + Allocator(); + ~Allocator(); + + void* kmalloc( int size ); + void kfree (void* address); + + private: + CacheSlab** _cache; + + + + +}; \ No newline at end of file diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 2de2f8d..777501c 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -471,6 +471,17 @@ _start: /*Setup the stack pointer to point to the beginning of our stack */ /* I believe its a hight address growing down to lower adress for the stack on x86*/ mov $stack_top, %esp + + /*Reset EFLAGS*/ + pushl $0 + popf + + /* push the pointer to the Multiboot information structure*/ + pushl %ebx + + /* push the magic value */ + pushl %eax + call early_main cli load_gdt: diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index 7ec9ae1..2f2ce6f 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -88,7 +88,7 @@ void kterm_write(const char* data, size_t size) { } void kterm_writestring(const char* data ){ - AS_KERNEL(); + // AS_KERNEL(); kterm_write(data, strlen(data)); } diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 6764040..5087b0e 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -97,20 +97,115 @@ void test_serial(){ extern "C" { - void early_main(){ - - init_serial(); - print_serial("\033[31;42mEarly main called!\n"); - - } - - void kernel_main (void) { - - print_serial("Kernel main called!\n"); - + void early_main(unsigned long magic, unsigned long addr){ /** initialize terminal interface */ kterm_init(); + + multiboot_info_t *mbi; + + if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ + printf("Invalid magic number: 0x%x\n", (unsigned) magic); + return; + } + + /* Set MBI to the addresss of the multiboot information structure*/ + mbi = (multiboot_info_t *) addr; + + /* Print out the flags */ + printf("flags = 0x%x\n", (unsigned) mbi->flags); + + /* Are mem_* valid? */ + if ( CHECK_FLAG(mbi->flags,0)){ + printf("mem_lower = %uKB, mem_upper = %uKB\n"); + } + + /* is boot device valid ? */ + if (CHECK_FLAG (mbi->flags, 1)){ + printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); + } + + /* is the command line passed? */ + if (CHECK_FLAG ( mbi->flags,2)){ + printf("cmdline = %s\n", (char *) mbi->cmdline); + } + + /* Are mods_* valid? */ + if(CHECK_FLAG ( mbi->flags, 3)){ + multiboot_module_t *mod; + int i; + + printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); + + for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ + printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); + } + } + + /* Bits 4 and 5 are mutually exclusive! */ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ + printf("Both bits 4 and 5 are set.\n"); + return; + } + + /* Is the symbol table of a.out valid? */ + if (CHECK_FLAG(mbi->flags, 4)){ + multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); + + printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", + (unsigned) multiboot_aout_sym->tabsize, + (unsigned) multiboot_aout_sym->strsize, + (unsigned) multiboot_aout_sym->addr); + + } + + /* Is the section header table of ELF valid? */ + if (CHECK_FLAG(mbi->flags, 5)){ + multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); + + printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, + (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); + + } + + + // AAAAAH memory map, Yes please! + /* Are mmap_* valid? */ + if (CHECK_FLAG(mbi->flags, 6)){ + multiboot_memory_map_t *mmap; + + printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", + (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); + + for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr; + (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + + printf( + "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", + (unsigned) mmap->size, + (unsigned) (mmap->addr >> 32), + (unsigned) (mmap->addr & 0xffffffff), + (unsigned) (mmap->len >> 32), + (unsigned) (mmap->len & 0xffffffff), + (unsigned) mmap->type); + + } + + } + + /* Draw diagonal blue line */ + if (CHECK_FLAG (mbi->flags, 12)){ + printf("Can draw!"); + } + } + + void kernel_main (void) { + + + init_serial(); + /** Setup the MMU **/ //kterm_writestring("Starting MMU...\n"); @@ -120,24 +215,10 @@ extern "C" { - - /** Wrtite stuff to the screen to test the terminal**/ - kterm_writestring("Hello world!\n"); - kterm_writestring("We got newline support!\n"); - - /** Test scrolling **/ - for(int i=0; i < 5; i++){ - delay(500); - kterm_writestring("We have implemented terminal scrolling!\n"); - } + + - - /** Test objective cpp **/ - kterm_writestring("Testing C++ object support\n"); - auto testObject = Test(); - testObject.printMe(); - - + /** test interrupt handlers **/ //asm volatile ("int $0x03"); @@ -147,7 +228,7 @@ extern "C" { while (true){ //Read time indefinetely read_rtc(); - printf( "UTC time: %2d-%2d-%2d %2d:%2d:%2d : (YY-MM-DD h:mm:ss)\r" ,year, month, day, hour, minute, second); + printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); delay(1000); } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index eed09c0..a863a97 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -4,7 +4,11 @@ extern "C" { #include "arch/i386/tty/kterm.h" } +#include "multiboot.h" #include "arch/i386/idt/idt.h" #include "MMU.h" #include "io.h" #include "time.h" + + +#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) \ No newline at end of file diff --git a/src/kernel/multiboot.h b/src/kernel/multiboot.h new file mode 100644 index 0000000..269cf9b --- /dev/null +++ b/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 */