aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile5
-rw-r--r--src/boot/boot.S6
-rw-r--r--src/boot/multiboot2.cc55
-rw-r--r--src/boot/multiboot2.hpp8
-rw-r--r--src/boucane.cc13
-rw-r--r--src/core/paging.cc173
-rw-r--r--src/core/paging.hpp66
-rw-r--r--src/libs/string.cc7
-rw-r--r--src/libs/string.hpp2
-rw-r--r--tools/bochsrc2
10 files changed, 331 insertions, 6 deletions
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<PAGING_KERNEL_SPACE_MAX_PAGE;i++){
+ int addr=i*4096;
+ paging_allocate_addr(pml4,addr,addr, PAGING_OPT_P|PAGING_OPT_RW); // Identity map
+ }
+ // Load new pml4
+ asm volatile(
+ "movq %0, %%rax \n\t"
+ "movq %%rax, %%cr3 \n\t"
+ :: "r" (pml4));
+}
+
+u64 paging_as_phy(u64* pml4_table, u64 virt){
+ u16 pml4=virt>>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))>>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<size;i++){
+ ptr[i]=value;
+ }
+}
+
void itoa(u64 i, char *a){
// Check if lower than 0
u8 neg=0;
diff --git a/src/libs/string.hpp b/src/libs/string.hpp
index a7dce0a..74bebc0 100644
--- a/src/libs/string.hpp
+++ b/src/libs/string.hpp
@@ -7,6 +7,8 @@
*/
void memcpy(void *src, void *dst, u32 size);
+void memset(void *dst, char value, u64 size);
+
/**
* Convert int to char array
*/
diff --git a/tools/bochsrc b/tools/bochsrc
index fd9fe69..e73dc72 100644
--- a/tools/bochsrc
+++ b/tools/bochsrc
@@ -1,2 +1,4 @@
romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
+
+cpu: count=1, ips=10000000, reset_on_triple_fault=0