diff --git a/src/Makefile b/src/Makefile index 486b8f2..0390042 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ EXEC := boucane -CC := g++ -mcmodel=large -nostdlib -nostdinc -no-pie -fno-builtin -fno-stack-protector -I ./ -I include +CC := g++ -Wno-write-strings -Wno-int-to-pointer-cast -mcmodel=large -nostdlib -nostdinc -no-pie -fno-builtin -fno-stack-protector -I ./ -I include LD_SCRIPT := linker.ld # Note that BOOT_OBJ do not match boot.S diff --git a/src/boot/multiboot2.cc b/src/boot/multiboot2.cc index 0cc8a25..1ed62f8 100644 --- a/src/boot/multiboot2.cc +++ b/src/boot/multiboot2.cc @@ -4,9 +4,9 @@ #include "libs/stdio.hpp" u32* mb2_find_tag(u32 *mb2_info_addr, char type){ - PAGE_MAP(mb2_info_addr); + PAGE_VIRT_MAP(mb2_info_addr,PAGING_OPT_DEFAULTS); u32 size=(u32)VIRT(mb2_info_addr)[0]; // Todo: check for size - PAGE_RMAP(mb2_info_addr, size); + PAGE_VIRT_RMAP(mb2_info_addr, PAGING_OPT_DEFAULTS,size); char *location=((char*)VIRT(mb2_info_addr))+8; // Goto first tag char *start=(char*)VIRT(mb2_info_addr); diff --git a/src/boucane.cc b/src/boucane.cc index 96c9ba7..caf0b8d 100644 --- a/src/boucane.cc +++ b/src/boucane.cc @@ -1,4 +1,5 @@ #include "boucane.hpp" +#include "core/apic.hpp" #include "core/paging.hpp" #include "drivers/memtext.hpp" #include "core/idt.hpp" @@ -9,6 +10,7 @@ #include "libs/stdio.hpp" #include "libs/string.hpp" #include "drivers/bmp.hpp" +#include "core/scheduler.hpp" u64 kvar_kernel_vma; u64 kvar_stack_pma; @@ -25,26 +27,35 @@ void (*printk)(char *str,...)=printf; extern u64 gdt64_tss; void configure_tss(){ - u64 tss_addr=(u64)&kvar_tss; - u32 desc1=(tss_addr&0xFFFF)<<16|(sizeof(TSS)&0xFFFF); - tss_addr>>=16; - u32 desc2=(tss_addr&0xFF)|((tss_addr>>8)<<24); - tss_addr>>=16; - u32 desc3=tss_addr; + // Get TSS physical address + u64 tss_addr=(u64)PHY(&kvar_tss); + u32 limit=sizeof(TSS); - // Options - u32 options=0b1001; // 64-bits TSS type - options|=(0b1000<<4); // Present + u32 desc1=(tss_addr&0xFFFF)<<16|(limit&0xFFFF); + u32 desc2=(tss_addr&0xFF); + desc2|=0b1001<<8; // Type + desc2|=0b111<<13; // Permission & present + u32 desc3=((limit>>8)&0xFFFF)|(limit>>24); // Configure GDT u32 *gdt_entry=(u32*)&gdt64_tss; gdt_entry[0]=desc1; - gdt_entry[1]=desc2|(options<<8); + gdt_entry[1]=desc2; gdt_entry[2]=desc3; gdt_entry[3]=0; // Configure segment kvar_tss.rsp0=(u64)VIRT(kvar_stack_pma); + asm( + "mov $0x28, %ax \n\t" + "ltr %ax" + ); +} + +void task1(){ + u64 a=0xEEEEEE; + DUMP(a); + while(1); } extern "C" void boucane(u64 mb_info){ @@ -60,11 +71,12 @@ extern "C" void boucane(u64 mb_info){ asm volatile ("movq $res_binary_res_logo_bmp_end, %0":"=m"(kvar_logo_bmp_end)); // Init data structures - configure_tss(); asm volatile ("call load_gdt"); + configure_tss(); paging_enable(); memtext_init(); idt_enable_interrupt(); + apic_enable(); // Looking for framebuffer FRAMEBUFFER fb_info; @@ -101,7 +113,7 @@ extern "C" void boucane(u64 mb_info){ printk("RAM:%dMB\n", mem); } - printk("%x",&kvar_tss); - DUMP(&gdt64_tss); + //create_task((void*)task1, 50); + //scheduler_start(); while(1); } \ No newline at end of file diff --git a/src/core/apic.cc b/src/core/apic.cc index 0663014..6722a3d 100644 --- a/src/core/apic.cc +++ b/src/core/apic.cc @@ -5,49 +5,56 @@ #include "asm.hpp" #include "libs/stdio.hpp" -char enable=0; #define APIC_LAPIC_ADDR 0xFEE00000 #define APIC_IOAPIC_ADDR 0xFEC00000 #define APIC_LAPIC_REG_SPURIOUS 0xF0 +#define APIC_LAPIC_TIMER_LVT 0x320 +#define APIC_LAPIC_TIMER_IC 0x380 +#define APIC_LAPIC_TIMER_DVD 0x3E0 +#define APIC_PRIOR 0x80 +#define APIC_DFR 0xE0 +#define APIC_EOI 0xB0 + +u8 lapic_space[4096] __attribute__((aligned(4096))); +u8 ioapic_space[4096] __attribute__((aligned(4096))); void apic_enable(){ - // Allocate APIC registers TODODODODOOD!!!!! - // paging_allocate_addr(kpml4, APIC_LAPIC_ADDR, APIC_LAPIC_ADDR, - //PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD); - //paging_allocate_addr(kpml4, APIC_IOAPIC_ADDR, APIC_IOAPIC_ADDR, - //PAGING_OPT_RW|PAGING_OPT_P|PAGING_OPT_PCD); + // Memory Allocation + PAGE_MAP(lapic_space,APIC_LAPIC_ADDR, PAGING_OPT_DEFAULTS); + PAGE_MAP(lapic_space,APIC_LAPIC_ADDR,PAGING_OPT_DEFAULTS); - // Configure APIC register location - u32 h=APIC_LAPIC_ADDR>>32; - u32 l=(APIC_LAPIC_ADDR&0xFFFFFFFF); - l|=0x800; // Enable apic - WRITE_MSR(0x1B,h,l); + // Configure APIC register location and enable it via MSR + u64 lapic_addr=(u64)APIC_LAPIC_ADDR; + u32 high=lapic_addr>>32; + u32 low=((u64)APIC_LAPIC_ADDR&0xFFFFFFFF); + low|=0x800; // Enable apic + WRITE_MSR(0x1B,high,low); - // Enable apic 2 - u8 *c_base=(u8*)APIC_LAPIC_ADDR; - c_base+=APIC_LAPIC_REG_SPURIOUS; - u32* base=(u32*)c_base; - *base=0x100|(*base); + // Configure LAPIC device using mmap + apic_write(APIC_LAPIC_REG_SPURIOUS, 0x100&apic_read(APIC_LAPIC_REG_SPURIOUS)); + apic_write(APIC_DFR, 0xFFFFFFFF); + apic_write(APIC_PRIOR, 0); + apic_write(APIC_LAPIC_TIMER_DVD, 1); + apic_write(APIC_LAPIC_TIMER_LVT, (1<<17)|61); + apic_write(APIC_LAPIC_TIMER_IC, 100000); - u8 *c_base2=(u8*)APIC_IOAPIC_ADDR; - u32* base2=(u32*)c_base2; - *base2=0x12; - base2=(u32*)(c_base2+0x10); - *base2=(0x0<<12)|0x3C; - enable=1; + // Configure I/O APIC + u32 *ioapic_reg=(u32*)ioapic_space; + *ioapic_reg=0x12; // Select the 0x12 IRQ + ioapic_reg=(u32*)(((u64)ioapic_space)+0x10); // Now use the IOREGWIN to write + *ioapic_reg=(0x0<<12)|60; // Enable IRQ 1 (0x12) and assign it to the vector 0x3C (index 60 in the IDT) +} + +void apic_write(u32 reg, u32 value){ + u32 *lapic_reg=(u32*)(lapic_space+reg); + *lapic_reg=value; +} + +u32 apic_read(u32 reg){ + u32 *lapic_reg=(u32*)(lapic_space+reg); + return *lapic_reg; } extern "C" void ack(){ - if(enable){ - u8 data; - do { - inb(0x64,data); - } - while((data&0x01) == 0); - inb(0x60,data); - - u8 *c_base=(u8*)(APIC_LAPIC_ADDR|0xB0); - u32* base=(u32*)c_base; - *base=*base|0; - } + apic_write(APIC_EOI, 0); } \ No newline at end of file diff --git a/src/core/apic.hpp b/src/core/apic.hpp index 1446edd..c64c509 100644 --- a/src/core/apic.hpp +++ b/src/core/apic.hpp @@ -3,4 +3,7 @@ #include "boucane.hpp" -void apic_enable(); \ No newline at end of file + +void apic_enable(); +void apic_write(u32 reg, u32 value); +u32 apic_read(u32 reg); \ No newline at end of file diff --git a/src/core/idt.cc b/src/core/idt.cc index d2b7ccc..495b332 100644 --- a/src/core/idt.cc +++ b/src/core/idt.cc @@ -6,7 +6,7 @@ u32 idt[IDT_MAX_ENTRIES][4] __attribute__((aligned(4096)));; IDT_REGISTER IDTR; -extern u64 INT_DEFAULT,INT_0,INT_14,INT_KBD; +extern u64 INT_DEFAULT,INT_0,INT_14,INT_KBD,INT_CLK; void idt_enable_interrupt(void){ IDTR.base=((u64)idt); @@ -32,6 +32,10 @@ void idt_enable_interrupt(void){ d.offset=(u64)&INT_KBD; idt_write_descriptor(d, i); } + else if(i==61){ // Clock + d.offset=(u64)&INT_CLK; + idt_write_descriptor(d, i); + } else { d.offset=(u64)&INT_DEFAULT; idt_write_descriptor(d, i); diff --git a/src/core/int.S b/src/core/int.S index 861d5cc..9505191 100644 --- a/src/core/int.S +++ b/src/core/int.S @@ -32,7 +32,14 @@ INT_14: .globl INT_KBD INT_KBD: - call_printk $MSG_INT_KBD + #call_printk $MSG_INT_KBD + call ack + iretq + +.globl INT_CLK +.extern clock +INT_CLK: + call clock call ack iretq diff --git a/src/core/paging.cc b/src/core/paging.cc index bad776f..7231352 100644 --- a/src/core/paging.cc +++ b/src/core/paging.cc @@ -7,6 +7,7 @@ char paging_status[PAGING_MAX_PAGE / 8]; u64 kpages[MAX_TABLES][512] __attribute__((aligned(4096))); int kpages_next=1; // First page is for the pml4 +u64* kpml4; u64* paging_allocate_table(){ u64 addr=(u64)kpages[kpages_next]; @@ -18,6 +19,12 @@ u64* paging_allocate_table(){ } return allocated; } +u64* paging_allocate_utable(){ + u64 *table=PAGE_ALLOCATE(); + for(u32 i=0;i<512;i++) + table[i]=0; + return table; +} void paging_enable() { // Init status @@ -38,17 +45,17 @@ void paging_enable() { // Setting up new kernel address space for(u64 i=0;i<=0x10000000;i+=4096){ // Higher half mapping - PAGE_MAP(i); + PAGE_VIRT_MAP(i,PAGING_OPT_DEFAULTS); // Allow access to RAM: - paging_allocate_addr(kpages[0], i, i, PAGING_OPT_P|PAGING_OPT_RW, 1); + paging_allocate_addr(kpages[0], i, i, PAGING_OPT_DEFAULTS, 1); } // 4096 bytes stack - PAGE_MAP_PHY(-4096, kvar_stack_pma); + PAGE_MAP(kvar_kernel_vma-4096, kvar_stack_pma,PAGING_OPT_DEFAULTS); // Load new pml4 - u64 kpage_phy=((u64)kpages[0]-kvar_kernel_vma); - lpml4(kpage_phy); + kpml4=(u64*)((u64)kpages[0]-kvar_kernel_vma); + lpml4(kpml4); } u64* paging_allocate_contiguous(int npages){ @@ -146,7 +153,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char // Solve pdp if(pml4_table[pml4] == 0){ - pml4_table[pml4]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE()); + pml4_table[pml4]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable()); pml4_table[pml4]|=options; paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables); return; @@ -156,7 +163,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char u64* pdp_table=(u64*)(PAGE(pml4_table[pml4])); pdp_table=useKernelTables ? VIRT(pdp_table) : pdp_table; if(pdp_table[pdp] == 0){ - pdp_table[pdp]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE()); + pdp_table[pdp]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable()); pdp_table[pdp]|=options; paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables); return; @@ -166,7 +173,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char u64* pd_table=(u64*)(PAGE(pdp_table[pdp])); pd_table=useKernelTables ? VIRT(pd_table) : pd_table; if(pd_table[pd] == 0){ - pd_table[pd]=(u64)(useKernelTables ? paging_allocate_table() : PAGE_ALLOCATE()); + pd_table[pd]=(u64)(useKernelTables ? paging_allocate_table() : paging_allocate_utable()); pd_table[pd]|=options; paging_allocate_addr(pml4_table,virt,phy,options,useKernelTables); return; @@ -175,19 +182,17 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char // Solve address u64* pt_table=(u64*)(PAGE(pd_table[pd])); pt_table=useKernelTables ? VIRT(pt_table) : pt_table; - if(pt_table[pt] == 0){ - pt_table[pt]=PAGE(phy); - pt_table[pt]|=options; - return; - } - + pt_table[pt]=PAGE(phy); + pt_table[pt]|=options; + return; } u64* paging_create_task(int npages){ - u64 *pml4=PAGE_ALLOCATE(); + u64 *pml4=paging_allocate_utable(); - for(int i=0;i>39&0x1FF; diff --git a/src/core/paging.hpp b/src/core/paging.hpp index caaaf9e..c9b9442 100644 --- a/src/core/paging.hpp +++ b/src/core/paging.hpp @@ -16,31 +16,31 @@ /// @brief Options #define PAGING_OPT_P 1 #define PAGING_OPT_RW (1<<1) +#define PAGING_OPT_US 4 #define PAGING_OPT_PCD (1<<3) +#define PAGING_OPT_DEFAULTS (PAGING_OPT_P|PAGING_OPT_RW) /// @brief Get page address that contain addr #define PAGE(addr) (addr&(~(0xFFF))) #define VIRT(addr) ((u64*)(((u64)addr)+kvar_kernel_vma)) +#define PHY(addr) ((u64*)(((u64)addr)-kvar_kernel_vma)) -/// @brief Mapping facilities -#define PAGE_ID_MAP(addr) paging_allocate_addr(kpages[0],(u64)(addr),(u64)(addr),PAGING_OPT_P|PAGING_OPT_RW,1) -#define PAGE_ID_RMAP(addr, n) { \ +/// @brief Mapping facilities +#define PAGE_MAP(virt,phy,opt) paging_allocate_addr(kpages[0],(u64)(virt),(u64)(phy),(opt),1) +#define PAGE_RMAP(virt,phy,opt,n) { \ for(u64 i=0;i<(n);i+=4096){ \ - paging_allocate_addr(kpages[0],((u64)(addr))+i,((u64)(addr))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \ + paging_allocate_addr(kpages[0],((u64)(virt))+i,((u64)(phy))+i,(opt),1); \ }} -#define PAGE_MAP(addr) paging_allocate_addr(kpages[0],(u64)((addr)+kvar_kernel_vma),(u64)(addr),PAGING_OPT_P|PAGING_OPT_RW,1) -#define PAGE_RMAP(addr, n) { \ +#define PAGE_VIRT_MAP(phy,opt) paging_allocate_addr(kpages[0],(u64)(phy)+kvar_kernel_vma,(u64)(phy),(opt),1) +#define PAGE_VIRT_RMAP(phy,opt,n) { \ for(u64 i=0;i<(n);i+=4096){ \ - paging_allocate_addr(kpages[0],(((u64)(addr))+kvar_kernel_vma)+i,((u64)(addr))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \ -}} -#define PAGE_MAP_PHY(addr,phy) paging_allocate_addr(kpages[0],(u64)((addr)+kvar_kernel_vma),(u64)(phy),PAGING_OPT_P|PAGING_OPT_RW,1) -#define PAGE_RMAP_PHY(addr,phy, n) { \ - for(u64 i=0;i<(n);i+=4096){ \ - paging_allocate_addr(kpages[0],(((u64)(addr))+kvar_kernel_vma)+i,((u64)(phy))+i,PAGING_OPT_P|PAGING_OPT_RW,1); \ + paging_allocate_addr(kpages[0],(((u64)(phy))+kvar_kernel_vma)+i,((u64)(phy))+i,(opt),1); \ }} + /// @brief All PAE table structures are allocated here extern u64 kpages[MAX_TABLES][512]; +extern u64 *kpml4; /// CF boucane.hpp extern u64 kvar_kernel_vma,kvar_stack_pma,kvar_userspace_pma; @@ -57,6 +57,8 @@ void paging_enable(); */ u64* paging_allocate_contiguous(int npages); +u64* paging_allocate_utable(); + /** * Deallocate a page located at addr */ diff --git a/src/core/scheduler.cc b/src/core/scheduler.cc new file mode 100644 index 0000000..00741fe --- /dev/null +++ b/src/core/scheduler.cc @@ -0,0 +1,40 @@ +#include "scheduler.hpp" + +TASK tasks[MAX_TASK]; +u32 ntasks=0; +char show_ticks=0; + +extern "C" void clock(){ + if(show_ticks) + print("."); +} +void schedule(){ + +} + + +void create_task(void* task, u32 size){ + if(ntasks>=MAX_TASK){ + printk("Could not create more tasks."); + return; + } + + TASK *t=&tasks[ntasks]; + t->id=ntasks; + t->pid=ntasks; + t->size=size; + t->pml4=paging_create_task(size/4096+1); + + // Load task using + lpml4(t->pml4); + memcpy(task, TASK_VMA, size); + lpml4(kpml4); + + ntasks++; +} + +void scheduler_start(){ + TASK *t=&tasks[0]; + lpml4(t->pml4); + asm("jmp switch"); +} \ No newline at end of file diff --git a/src/core/scheduler.hpp b/src/core/scheduler.hpp new file mode 100644 index 0000000..15b4caf --- /dev/null +++ b/src/core/scheduler.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "boucane.hpp" + +#define MAX_TASK 5 +#define TASK_VMA 0x0 + +typedef struct { + u32 rax, rbx, rcx, rdx; + u32 cs, rip; + u32 ss, rsp, rbp; + u32 rsi, rdi; + u32 ds, es, fs, gs; + u32 eflags; + u32 ss0, rsp0; +} __attribute__((packed)) REGS; + +typedef struct { + u32 id; + u32 pid; + u64* pml4; + u32 size; + REGS registers; +} __attribute__((packed)) TASK; + +extern char show_ticks; + +extern "C" void clock(); +void schedule(); +void create_task(void*task, u32 size); +void scheduler_start(); \ No newline at end of file diff --git a/src/core/scheduler_asm.S b/src/core/scheduler_asm.S new file mode 100644 index 0000000..fc8bc50 --- /dev/null +++ b/src/core/scheduler_asm.S @@ -0,0 +1,27 @@ +.globl switch + + + + + +switch: + + + mov $0x23, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + push $0x23 # + push $0x80 + pushf + pop %rax + #orl $0x200, %%eax + mov $0xffffbfff, %rbx + and %rbx, %rax + push %rax + push $0x1B + push $0x0 + + iretq diff --git a/src/drivers/acpi.cc b/src/drivers/acpi.cc index ec7a2ff..f514927 100644 --- a/src/drivers/acpi.cc +++ b/src/drivers/acpi.cc @@ -32,7 +32,7 @@ char acpi_init(void* rsdp_p){ } char acpi_load_rsdt(){ - PAGE_ID_MAP(rsdp.rsdt_addr); // Ensure page is accessible + PAGE_MAP(rsdp.rsdt_addr,rsdp.rsdt_addr,PAGING_OPT_DEFAULTS); // Ensure page is accessible memcpy((void*)rsdp.rsdt_addr, &rsdt, sizeof(rsdt)); rsdt.first_entry_addr_ptr=rsdp.rsdt_addr+36; if(rsdt.header.signature !=ACPI_RSDT_SIGNATURE){ @@ -54,7 +54,7 @@ char acpi_load_madt(){ u32 *addr=(u32*)(rsdt.first_entry_addr_ptr+i*4); // Load header ACPI_TABLE_HEADER header; - PAGE_ID_MAP(*addr); + PAGE_MAP(*addr,*addr,PAGING_OPT_DEFAULTS); memcpy((void*)*addr, &header, sizeof(header)); // Check if it is MADT if(header.signature==ACPI_MADT_SIGNATURE){ diff --git a/src/drivers/framebuffer.cc b/src/drivers/framebuffer.cc index f5b537b..ce7790e 100644 --- a/src/drivers/framebuffer.cc +++ b/src/drivers/framebuffer.cc @@ -11,11 +11,11 @@ void framebuffer_init(FB_CFG config){ // indeed fb_cfg.location could be to big and // thus leading to cross u64 size limit while summing it with // kvar_kernel_vma in paging.cc/hpp - u64 start=0xFFFFFFFFFFFFFFFF - fb_cfg.pitch*fb_cfg.height; + u64 start=0xFFFFFFFFFFFFFFFF - (fb_cfg.pitch*fb_cfg.height); // Ensure we start writing at the begining of the page since // start is not necessarly 4096 bytes aligned start=PAGE(start); - PAGE_RMAP_PHY(start-kvar_kernel_vma,fb_cfg.location, fb_cfg.pitch*fb_cfg.height); + PAGE_RMAP(start,fb_cfg.location, PAGING_OPT_DEFAULTS,fb_cfg.pitch*fb_cfg.height); fb_cfg.location=start; } diff --git a/src/drivers/memtext.cc b/src/drivers/memtext.cc index f010271..bf460b0 100644 --- a/src/drivers/memtext.cc +++ b/src/drivers/memtext.cc @@ -8,7 +8,7 @@ char memtext_buffer[MEMTEXT_BUFFER_SIZE]; u64 memtext_x=0; void memtext_init(){ - PAGE_RMAP(MEMTEXT_ADDR_LOCATION,8); + PAGE_VIRT_MAP(MEMTEXT_ADDR_LOCATION,PAGING_OPT_DEFAULTS); u64* p_addr=(u64*)VIRT(MEMTEXT_ADDR_LOCATION); *p_addr=(u64)memtext_buffer; diff --git a/src/drivers/vgatext.cc b/src/drivers/vgatext.cc index 6a5a1b2..84d28df 100644 --- a/src/drivers/vgatext.cc +++ b/src/drivers/vgatext.cc @@ -1,6 +1,7 @@ #include "vgatext.hpp" #include "boucane.hpp" +#include "core/paging.hpp" #define MAX_COL 80 #define MAX_LINE 25 @@ -14,7 +15,7 @@ VIDEO_STATE VS={ }; void vgatext_init(){ - PAGE_RMAP(0xB8000,4096*2); + PAGE_VIRT_RMAP(0xB8000,PAGING_OPT_DEFAULTS,2); VS.mem=(u8*)VIRT(0xB8000); }