diff --git a/src/Makefile b/src/Makefile index 61e6899..13ea809 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ EXEC := boucane -CC := g++ -g -Wno-write-strings -Wno-int-to-pointer-cast -mcmodel=large -nostdlib -nostdinc -no-pie -fno-builtin -fno-stack-protector -I ./ -I include +CC := g++ -mno-red-zone -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/boucane.cc b/src/boucane.cc index 78884ac..ee7691d 100644 --- a/src/boucane.cc +++ b/src/boucane.cc @@ -12,6 +12,9 @@ #include "drivers/bmp.hpp" #include "core/scheduler.hpp" +/// @brief Temporary +#define TASK_DELAY 10000000 + u64 kvar_kernel_vma; u64 kvar_stack_pma; u64 kvar_userspace_pma; @@ -58,18 +61,25 @@ void configure_tss(){ void task1(){ while(1){ - asm("mov $0xABC, %rax"); asm("mov $1, %rdi;int $0x30"); + for(u32 delay=0;delay<=TASK_DELAY;delay++){} + } +} +void task2(){ + while(1){ + asm("mov $2, %rdi;int $0x30"); + for(u32 delay=0;delay<=TASK_DELAY;delay++){} } } -void task2(){ +void task3(){ while(1){ - asm("mov $0xAEBC, %rax"); - asm("mov $2, %rdi;int $0x30"); + asm("mov $3, %rdi;int $0x30"); + for(u32 delay=0;delay<=TASK_DELAY;delay++){} } } + extern "C" void boucane(u64 mb_info){ // Init linker variables asm volatile ("movq $__kernel_vma, %0":"=m"(kvar_kernel_vma)); @@ -89,7 +99,7 @@ extern "C" void boucane(u64 mb_info){ memtext_init(); idt_enable_interrupt(); apic_enable(); - + // Looking for framebuffer FRAMEBUFFER fb_info; if(mb2_find_framebuffer((u32*)mb_info, &fb_info)){ @@ -109,25 +119,26 @@ extern "C" void boucane(u64 mb_info){ __putchar=vgatext_putchar; } } - + // Booting! printk("Booting Boucane v%d.%d.%d\n",VERSION_MAJOR,VERSION_MINOR, VERSION_PATH); printk("System informations -- "); char bootloader[20]; if(mb2_find_bootloader_name((u32*)mb_info,bootloader)){ - printk("BOOT:%s ", bootloader); } - MEM_INFO mem_infos; if(mb2_find_mem((u32*)mb_info,&mem_infos)){ u64 mem=mem_infos.mem_upper-mem_infos.mem_lower; mem/=1024; printk("RAM:%dMB\n", mem); } - //show_ticks=1; - create_task((void*)task1, 50); - create_task((void*)task2, 50); + + + printk("Launching processes... "); + create_task((void*)task1, 100); + create_task((void*)task2, 100); + create_task((void*)task3, 100); scheduler_start(); while(1); } \ No newline at end of file diff --git a/src/core/apic.cc b/src/core/apic.cc index aba801a..20d3dfd 100644 --- a/src/core/apic.cc +++ b/src/core/apic.cc @@ -36,7 +36,7 @@ void apic_enable(){ // 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); + apic_write(APIC_LAPIC_TIMER_IC, 10000000); // Configure I/O APIC u32 *ioapic_reg=(u32*)ioapic_space; diff --git a/src/core/asm.hpp b/src/core/asm.hpp index a1d7437..0ffc946 100644 --- a/src/core/asm.hpp +++ b/src/core/asm.hpp @@ -1,5 +1,9 @@ #pragma once +#define cli() asm("cli") + +#define sti() asm("sti") + #define READ_MSR(reg,high,low) \ asm volatile( \ "mov %2, %%ecx;rdmsr \n\t" \ diff --git a/src/core/idt.cc b/src/core/idt.cc index db28a4e..19c17d3 100644 --- a/src/core/idt.cc +++ b/src/core/idt.cc @@ -28,7 +28,7 @@ void idt_enable_interrupt(void){ d.offset=(u64)&INT_14; idt_write_descriptor(d, i); } - else if(i==10){ + else if(i==10){ // TSS d.offset=(u64)&INT_10; idt_write_descriptor(d, i); } diff --git a/src/core/int.S b/src/core/int.S index c8612dc..c552212 100644 --- a/src/core/int.S +++ b/src/core/int.S @@ -26,18 +26,29 @@ push %rbp push %rsi push %rdi - mov %ds, %rax + xor %rax,%rax # Because I am picky + mov %gs, %rax push %rax - mov 56(%rsp), %rax # Restore %rax + mov %es, %rax + push %rax + mov %fs, %rax + push %rax + mov %ds, %rax push %rax mov $0x10, %ax mov %ax, %ds - pop %rax + mov 80(%rsp), %rax .endm .macro RESTORE_REGS pop %rax - mov %rax,%ds + mov %ax, %ds + pop %rax + mov %ax, %fs + pop %rax + mov %ax, %es + pop %rax + mov %ax, %gs pop %rdi pop %rsi pop %rbp @@ -77,6 +88,7 @@ INT_10: .globl INT_14 INT_14: + pop %rsi CALL_PRINTK $MSG_INT_14 INT_14_INFINITE: jmp INT_14_INFINITE @@ -113,7 +125,7 @@ MSG_INT_0: MSG_INT_10: .asciz "Invalid TSS!" MSG_INT_14: -.asciz "Page fault!" +.asciz "Page fault: error %x !" MSG_INT_KBD: .asciz "Key press!" MSG: diff --git a/src/core/paging.cc b/src/core/paging.cc index ebd4f9d..ca57c4d 100644 --- a/src/core/paging.cc +++ b/src/core/paging.cc @@ -95,7 +95,7 @@ void paging_deallocate(u64 addr){ } -/// TODO: Debug addess +/// TODO: Debug address void paging_deallocate_pml4(u64* pml4){ for(int i=0;i<512;i++){ u64* pdp=(u64*)PAGE(pml4[i]); @@ -149,7 +149,7 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char u16 pdp=virt>>30&0x1FF; u16 pd=virt>>21&0x1FF; u16 pt=virt>>12&0x1FF; - options&=0xFFF; // Ensure options are on 12bits + options&=0xFFF; // Ensure 12 bits // Solve pdp if(pml4_table[pml4] == 0){ @@ -199,7 +199,6 @@ u64* paging_create_task(int npages){ // Allocate a page for the kernel stack paging_allocate_addr(pml4, (i+1)*4096, (u64)PAGE_ALLOCATE(), PAGING_OPT_DEFAULTS, 0); - // Enable kernel access u16 pml4_entry=kvar_kernel_vma>>39&0x1FF; pml4[pml4_entry]=kpages[0][pml4_entry]; diff --git a/src/core/scheduler.cc b/src/core/scheduler.cc index 89c52d1..3516350 100644 --- a/src/core/scheduler.cc +++ b/src/core/scheduler.cc @@ -1,6 +1,7 @@ #include "scheduler.hpp" #include "boucane.hpp" #include "core/apic.hpp" +#include "libs/string.hpp" PROC procs[MAX_TASK]; u32 nproc=0; @@ -9,41 +10,57 @@ char scheduling=0; u32 active_process=0; extern "C" void clock(){ + u64* stack; + asm("mov %%rbp, %0": "=r"(stack)::"rax"); + stack=&stack[2]; + if(show_ticks) print("."); if(scheduling) - schedule(); + schedule(stack); } -void schedule(){ + +void tdump(PROC*t){ + printk("ss:%x rsp:%x eflags:%x cs:%x rip:%x\n", + t->registers.ss, + t->registers.rsp, + t->registers.eflags, + t->registers.cs, + t->registers.rip + ); +} + +void schedule(u64* stack){ // First get a pointer to the first process saved register. // Since this is called by clock(), %rbp contains a pointer // to the clock() %rbp value and then we access to the registers SAVE_REGS in int.S - u64* stack; - asm("mov %%rbp, %%rax;mov (%%rax), %%rbx; add $16, %%rbx; mov %%rbx,%0": "=m"(stack)::"rax","rbx"); // Save current task PROC *t=&procs[active_process]; t->registers.ds=stack[0]; - t->registers.rdi=stack[1]; - t->registers.rsi=stack[2]; - t->registers.rbp=stack[3]; - t->registers.rdx=stack[4]; - t->registers.rcx=stack[5]; - t->registers.rbx=stack[6]; - t->registers.rax=stack[7]; - t->registers.r15=stack[8]; - t->registers.r14=stack[9]; - t->registers.r13=stack[10]; - t->registers.r12=stack[11]; - t->registers.r11=stack[12]; - t->registers.r10=stack[13]; - t->registers.r9=stack[14]; - t->registers.r8=stack[15]; - t->registers.rip=stack[16]; - t->registers.cs=stack[17]; - t->registers.eflags=stack[18]; - t->registers.rsp=stack[19]; - t->registers.ss=stack[20]; + t->registers.fs=stack[1]; + t->registers.es=stack[2]; + t->registers.gs=stack[3]; + t->registers.rdi=stack[4]; + t->registers.rsi=stack[5]; + t->registers.rbp=stack[6]; + t->registers.rdx=stack[7]; + t->registers.rcx=stack[8]; + t->registers.rbx=stack[9]; + t->registers.rax=stack[10]; + t->registers.r15=stack[11]; + t->registers.r14=stack[12]; + t->registers.r13=stack[13]; + t->registers.r12=stack[14]; + t->registers.r11=stack[15]; + t->registers.r10=stack[16]; + t->registers.r9=stack[17]; + t->registers.r8=stack[18]; + t->registers.rip=stack[19]; + t->registers.cs=stack[20]; + t->registers.eflags=stack[21]; + t->registers.rsp=stack[22]; + t->registers.ss=stack[23]; // Goto next task active_process++; @@ -53,6 +70,7 @@ void schedule(){ t=&procs[active_process]; kvar_tss.rsp0=t->registers.rsp0; + // Clock acknownledgement apic_ack(); @@ -69,11 +87,12 @@ void create_task(void* task, u32 size){ printk("Could not create more tasks."); return; } - PROC *t=&procs[nproc]; + memset(t, 0, sizeof(PROC)); t->id=nproc; t->pid=nproc; t->size=size; + t->registers.eflags=0x246; u32 npages=size%4096 ? size/4096 + 1 : size/4096; // Note that paging_create_task() allocate 2 more pages (one for the user stack and @@ -85,7 +104,7 @@ void create_task(void* task, u32 size){ t->registers.rip=TASK_VMA; t->registers.cs=0x1B; // 0x18 and 0x3 privilege t->registers.ds=0x23; // 0x20 and 0x3 privilege - t->registers.ss=0; // Always 0 in long-mode + t->registers.ss=0x23; // Load task using lpml4(t->pml4); @@ -96,14 +115,14 @@ void create_task(void* task, u32 size){ } void scheduler_start(){ + cli(); scheduling=1; active_process=0; PROC *t=&procs[active_process]; kvar_tss.rsp0=t->registers.rsp0; asm( - "cli \n\t" "mov %0, %%rdi \n\t" "jmp switch \n\t" - :: "r" (t) + :: "a" (t) ); } \ No newline at end of file diff --git a/src/core/scheduler.hpp b/src/core/scheduler.hpp index 30fcf42..ba234dc 100644 --- a/src/core/scheduler.hpp +++ b/src/core/scheduler.hpp @@ -34,6 +34,6 @@ typedef struct { extern char show_ticks; extern "C" void clock(); -void schedule(); +void schedule(u64* stack); 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 index 0c9d5ba..24eaa8d 100644 --- a/src/core/scheduler_asm.S +++ b/src/core/scheduler_asm.S @@ -1,22 +1,35 @@ .globl switch - switch: # Load task page table mov (%rdi), %rax mov %rax, %cr3 + # ds + mov 96(%rdi), %rax + mov %ax, %ds + # es + mov 104(%rdi), %rax + mov %ax, %es + # fs + mov 112(%rdi), %rax + mov %ax, %fs + # gs + mov 120(%rdi), %rax + mov %ax, %gs + # First load the task stack mov 64(%rdi), %rsp # Prepare for iret - push 96(%rdi) # ds + push 56(%rdi) # ss push 64(%rdi) # rsp push 128(%rdi) # Flags pop %rax - or $0x200, %rax # Enable interrupt - mov $0xffffffffbfff, %rbx # NT flag - and %rbx, %rax + bts $9, %rax # Enable interrupt + not %rax + bts $14, %rax # NT flag + not %rax push %rax # Apply flags changes push 40(%rdi) # cs push 48(%rdi) # rip @@ -32,19 +45,12 @@ switch: push 144(%rdi) # r8 push 152(%rdi) # r9 push 160(%rdi) # r10 - push 160(%rdi) # r11 + push 168(%rdi) # r11 push 176(%rdi) # r12 push 184(%rdi) # r13 push 192(%rdi) # r14 push 200(%rdi) # r15 - # ds - mov 96(%rdi), %ax - mov %ax, %ds - mov %ax, %gs - mov %ax, %fs - mov %ax, %es - # Restore general registers pop %r15 pop %r14 @@ -61,7 +67,6 @@ switch: pop %rcx pop %rbx pop %rax - # Perform task switching iretq diff --git a/src/core/syscalls.cc b/src/core/syscalls.cc index f98e6e3..0e6ce2e 100644 --- a/src/core/syscalls.cc +++ b/src/core/syscalls.cc @@ -1,8 +1,13 @@ #include "boucane.hpp" +#include "core/asm.hpp" +#include "drivers/framebuffer.hpp" +#include "drivers/psftext.hpp" extern "C" void syscall(){ u64 call_number; - asm volatile("mov %%rdi, %0":"=r"(call_number)); + asm volatile("mov %%rdi, %0":"=m"(call_number)::"rdi"); + + cli(); printk("%d",call_number); - for(int i=0;i<10000000;i++){} + sti(); } \ No newline at end of file diff --git a/src/drivers/framebuffer.cc b/src/drivers/framebuffer.cc index 33b73d6..ecc4869 100644 --- a/src/drivers/framebuffer.cc +++ b/src/drivers/framebuffer.cc @@ -38,9 +38,14 @@ void framebuffer_scrollup(u32 npixel){ for(u32 y=0;ypsf_status.nchar){ psf_status.y++; diff --git a/src/libs/stdio.cc b/src/libs/stdio.cc index 3770cd3..e29f2cc 100644 --- a/src/libs/stdio.cc +++ b/src/libs/stdio.cc @@ -8,13 +8,13 @@ void (*__putchar)(char)=memtext_putchar; void printf(char *str,...) { u64 rsi,rdx,rcx,r8,r9; u64* rbp; - asm( "mov %%rsi, %0": "=a"(rsi)); - asm( "mov %%rdx, %0": "=a"(rdx)); - asm( "mov %%rcx, %0": "=a"(rcx)); - asm( "mov %%r8, %0": "=a"(r8)); - asm( "mov %%r9, %0": "=a"(r9)); - asm( "mov %%rbp, %0": "=a"(rbp)); - + asm volatile( "mov %%rsi, %0": "=m"(rsi)); + asm volatile( "mov %%rdx, %0": "=m"(rdx)); + asm volatile( "mov %%rcx, %0": "=m"(rcx)); + asm volatile( "mov %%r8, %0": "=m"(r8)); + asm volatile( "mov %%r9, %0": "=m"(r9)); + asm volatile( "mov %%rbp, %0": "=m"(rbp)); + // Init informations int len=strlen(str); int i=0; // Pointer to the current character diff --git a/src/linker.ld b/src/linker.ld index 7d7c3a6..a7471a9 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -3,7 +3,7 @@ ENTRY(_start) __kernel_vma = 0xFFFFFFFF80000000; __boot_pma = 1M; -__stack_pma = 0x3FFFFF; +__stack_pma = 0x3FFFF0; /* Stack should be 16-byte aligned */ __stack_size = 4096; __userspace_pma = 0x400000;