diff --git a/src/Makefile b/src/Makefile index 2fe67a6..6e6b5c2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,14 +5,15 @@ LD_SCRIPT := linker.ld # Note that BOOT_OBJ do not match boot.S # Indeed boot.o generated by boot.S should appear # first in the kernel binary (thus it must be linked first, cf the $(EXEC) rule) -BOOT_OBJ := $(addsuffix .cc,$(basename $(shell find ./boot -name '*.cc' -name '*.S' ! -name "boot.S"))) +BOOT_OBJ := $(addsuffix .o,$(basename $(shell find ./boot -name '*.cc' -o -name '*.S' ! -name "boot.S"))) DRIVERS_OBJ := $(addsuffix .o,$(basename $(shell find ./drivers -name '*.cc' -o -name '*.S'))) -LIBS_OBJ := $(addsuffix .cc,$(basename $(shell find ./libs -name '*.cc' -o -name '*.S'))) +LIBS_OBJ := $(addsuffix .o,$(basename $(shell find ./libs -name '*.cc' -o -name '*.S'))) CORE_OBJ := $(addsuffix .o,$(basename $(shell find ./core -name '*.cc' -o -name '*.S'))) all: $(EXEC) $(EXEC): boot/boot.o $(BOOT_OBJ) $(DRIVERS_OBJ) $(LIBS_OBJ) $(CORE_OBJ) boucane.o + echo $(BOOT_OBJ) $(CC) -n -T $(LD_SCRIPT) -nostdlib -o $@ $^ %.o: %.S diff --git a/src/boot/boot.S b/src/boot/boot.S index d90c4d8..5e4d82c 100644 --- a/src/boot/boot.S +++ b/src/boot/boot.S @@ -43,11 +43,11 @@ mb_header_end: .section .text .code32 # Require since grub do not enable long mode -MB_INFO: - .int 0xABCDEF # Will contains the Multiboot2 information data structure address +MB_INFO: # Will contains the Multiboot2 information data structure address + .long 0x0 _start: -mov %ebx,(MB_INFO) +mov %ebx, (MB_INFO) # Zeroing the .bss section mov $_bss_start, %eax mov $_bss_end, %ebx diff --git a/src/boot/multiboot2.cc b/src/boot/multiboot2.cc new file mode 100644 index 0000000..b0e8c14 --- /dev/null +++ b/src/boot/multiboot2.cc @@ -0,0 +1,55 @@ +#include "multiboot2.hpp" +#include "libs/string.hpp" +#include "libs/stdio.hpp" + +u32* mb2_find_tag(u32 *mb2_info_addr, char type){ + u32 size=(u32)mb2_info_addr[0]; + + char *location=((char*)mb2_info_addr)+8; // Goto first tag + char *start=(char*)mb2_info_addr; + + while((location-start) < size){ + // Goto next 64bit align address + while(((u64)location&0x7) != 0) + location++; + // Parse type + u32 cur_type=((u32*)location)[0]; + u32 cur_size=((u32*)location)[1]; + + if(cur_type==type){ + return (u32*)location; + } + location+=cur_size; + } + + return 0; +} + +char mb2_find_bootloader_name(u32* mb2_info_addr, char *return_name){ + u32* addr=mb2_find_tag(mb2_info_addr,2); + if(addr){ + u32 size=addr[1]; + memcpy(addr+2, return_name, size); + return 1; + } + return 0; +} +char mb2_find_new_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size){ + u32* addr=mb2_find_tag(mb2_info_addr,15); + if(addr){ + *return_size=addr[1]; + *return_addr=(u64)addr+2; + return 1; + } + return 0; +} + +char mb2_find_old_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size){ + u32* addr=mb2_find_tag(mb2_info_addr,14); + if(addr){ + *return_size=addr[1]; + *return_addr=(u64)addr+2; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/src/boot/multiboot2.hpp b/src/boot/multiboot2.hpp new file mode 100644 index 0000000..da12e5f --- /dev/null +++ b/src/boot/multiboot2.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "core/types.hpp" + +u32* mb2_find_tag(u32 *mb2_info_addr, char type); +char mb2_find_bootloader_name(u32* mb2_info_addr, char *return_name); +char mb2_find_new_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size); +char mb2_find_old_rsdp(u32* mb2_info_addr, u64 *return_addr, u32 *return_size); \ No newline at end of file diff --git a/src/boucane.cc b/src/boucane.cc index 8baa1ba..aa06152 100644 --- a/src/boucane.cc +++ b/src/boucane.cc @@ -1,10 +1,21 @@ #include "boucane.hpp" #include "core/idt.hpp" +#include "boot/multiboot2.hpp" +#include "core/paging.hpp" + +extern u32 MB_INFO; extern "C" void boucane(){ clear(); - printk("Booting Boucane v%d.%d.%d",VERSION_MAJOR,VERSION_MINOR, VERSION_PATH); + printk("Booting Boucane v%d.%d.%d\n",VERSION_MAJOR,VERSION_MINOR, VERSION_PATH); idt_enable_interrupt(); + paging_enable(); + + u64 p; + u32 size; + if(mb2_find_old_rsdp((u32*)MB_INFO,&p,&size)){ + printk("RSDP Table found!"); + } while(1); } \ No newline at end of file diff --git a/src/core/paging.cc b/src/core/paging.cc new file mode 100644 index 0000000..b9ab94e --- /dev/null +++ b/src/core/paging.cc @@ -0,0 +1,173 @@ +#include "paging.hpp" +#include "core/types.hpp" +#include "libs/stdio.hpp" +#include "libs/string.hpp" + +char paging_status[PAGING_MAX_PAGE / 8]; + +void paging_enable() { + // Init status + for (int i = 0; i < PAGING_MAX_PAGE / 8; i++) { + paging_status[i] = 0; + } + + // Allocate paging for the kernel (to not override the source + // code during the next paging_allocate_table() calls) + paging_allocate_contiguous(PAGING_KERNEL_USED_PAGE); + + // Setting up new kernel address space + u64* pml4=paging_allocate_table(); + for(int i=0;i>39&0x1FF; + u16 pdp=virt>>30&0x1FF; + u16 pd=virt>>21&0x1FF; + u16 pt=(virt>>12)&0x1FF; + + u64* pdp_table=(u64*)PAGE(pml4_table[pml4]); + u64* pd_table=(u64*)PAGE(pdp_table[pdp]); + u64* pt_table=(u64*)PAGE(pd_table[pd]); + return((PAGE(pt_table[pt]))|(virt&0xFFF)); +} +u64* paging_allocate_contiguous(int npages){ + int n_contiguous=0; + for (int i = 0; i < PAGING_MAX_PAGE / 8; i++) { + for (int j = 0; j < 8; j++) { + char bit=(paging_status[i]&(0x1<>j; + if(bit!=1){ + n_contiguous++; + } + else { + n_contiguous=0; + } + if(n_contiguous==npages){ + n_contiguous--; // Since we use it now as index, not a counter + int start_page=(i*8+j)-n_contiguous; + while(n_contiguous>=0){ + int cur_page=(i*8+j)-n_contiguous; + paging_status[cur_page/8]|=(0x1<<(cur_page%8)); // Allocate + n_contiguous--; + } + u64 phy_addr=(4096*start_page); + return (u64*) phy_addr; + } + } + } + + printk("Could not allocate %d contigous pages. Kernel panic!",npages); + while(1); + return 0; +} + +void paging_deallocate(u64 addr){ + u64 page_number=PAGE(addr)/4096; + char byte=paging_status[page_number/8]; + paging_status[page_number/8]=byte&(~(1<<(page_number%8))); +} + +void paging_deallocate_pml4(u64* pml4){ + for(int i=0;i<512;i++){ + u64* pdp=(u64*)PAGE(pml4[i]); + if(pml4[i]==0) + continue; + for(int j=0;j<512;j++){ + u64* pd=(u64*)PAGE(pdp[j]); + if(pdp[j]==0) + continue; + for(int k=0;k<512;k++){ + u64* pt=(u64*)PAGE(pd[k]); + if(pd[k]==0) + continue; + for(int l=0;l<512;l++){ + if(pt[l]==0) + continue; + paging_deallocate_table((u64*)PAGE(pt[l])); + } + paging_deallocate_table((u64*)PAGE(pd[k])); + } + paging_deallocate_table((u64*)PAGE(pdp[j])); + } + paging_deallocate_table((u64*)PAGE(pml4[i])); + } + paging_deallocate_table((u64*)PAGE((u64)pml4)); +} + +void paging_dump(int min, int max) { + for (int i = 0; i < PAGING_MAX_PAGE / 8; i++) { + if(i>=min && i<=max){ + printk("Byte %d ", i); + for (int j = 0; j < 8; j++) { + char bit = (paging_status[i] & (0x1 << j)) >> j; + printk("%d", bit); + } + print("\n"); + } + } +} + +u64* paging_allocate_table(){ + u64* table=paging_allocate_contiguous(8); + memset(table, 0, 32768); // nb_entries * entry size = 512 * 64 + return table; +} + +void paging_deallocate_table(u64* table){ + char *c_table=(char*)PAGE((u64)table); + for(u8 i=0;i<8;i++){ + paging_deallocate((u64)c_table); + c_table+=4096; + } +} + +void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options){ + u16 pml4=virt>>39&0x1FF; + u16 pdp=virt>>30&0x1FF; + u16 pd=virt>>21&0x1FF; + u16 pt=virt>>12&0x1FF; + options&=0xFFF; // Ensure options are on 12bits + + // Solve pdp + if(pml4_table[pml4] == 0){ + pml4_table[pml4]=(u64)paging_allocate_table(); + pml4_table[pml4]|=options; + paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + // Solve pd + u64* pdp_table=(u64*)PAGE(pml4_table[pml4]); + if(pdp_table[pdp] == 0){ + pdp_table[pdp]=(u64)paging_allocate_table(); + pdp_table[pdp]|=options; + paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + // Solve pt + u64* pd_table=(u64*)PAGE(pdp_table[pdp]); + if(pd_table[pd] == 0){ + pd_table[pd]=(u64)paging_allocate_table(); + pd_table[pd]|=options; + paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + // Solve address + u64* pt_table=(u64*)PAGE(pd_table[pd]); + if(pt_table[pt] == 0){ + pt_table[pt]=PAGE(phy); + pt_table[pt]|=options; + return; + } + + printk("Virtual address %x already in use. Kernel panic!",virt); + while(1); + +} \ No newline at end of file diff --git a/src/core/paging.hpp b/src/core/paging.hpp new file mode 100644 index 0000000..1457d10 --- /dev/null +++ b/src/core/paging.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include "core/types.hpp" + +#define PAGING_MAX_PAGE (20*512) +/** + * Current number of page (from the beginning of the ram) used by the kernel that + * should not be used by the paging allocation mechanism and should not be granted + * for allocation + */ +#define PAGING_KERNEL_USED_PAGE (2*512) +/// @brief New number of page reachable at the end of the paging_enable() call +#define PAGING_KERNEL_SPACE_MAX_PAGE (20*512) +#define PAGING_ALLOCATE() paging_allocate_contiguous(1) +#define PAGING_OPT_P 1 +#define PAGING_OPT_RW (1<<1) + +/// @brief Get page address that contain addr +#define PAGE(addr) (addr&(~(0xFFF))) + +/** + * Setup and enable PAE paging + */ +void paging_enable(); + +/** + * Allocate the next available page + * and return its physical address + */ +u64* paging_allocate_contiguous(int npages); + +/** + * Deallocate a page located at addr + */ +void paging_deallocate(u64 addr); + +/** + * Dump a specific range of bytes in the paging_status + */ +void paging_dump(int min, int max); + +/** + * Deallocate all the pages linked to a pml4 + */ +void paging_deallocate_pml4(u64* pml4); + +/** + * Deallocate all the pages related to a pml4 structure + */ +void paging_deallocate_table(u64* table); + +/** + * Allocate table structure (pml4, pdp etc..) + */ +u64* paging_allocate_table(); + +/** + * Map virtual page associated to virt + * to the physical page associated with phy + */ +void paging_allocate_addr(u64* pml4_table,u64 virt, u64 phy, u16 options); + +/** + * Get associated physical address + */ +u64 paging_as_phy(u64* pml4_table, u64 virt); \ No newline at end of file diff --git a/src/libs/string.cc b/src/libs/string.cc index 73c3318..3966407 100644 --- a/src/libs/string.cc +++ b/src/libs/string.cc @@ -8,6 +8,13 @@ void memcpy(void* src, void* dst, u32 size){ *(c_dst+i)=*(c_src+i); } +void memset(void *dst, char value, u64 size){ + char* ptr=(char*)dst; + for(u64 i=0;i