aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-05-04 15:30:24 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-05-04 15:30:24 +0200
commit1530a85d5aefcf6497ff2129023e9a0b002603dd (patch)
treeea6098d0dcafabba0ffc2f28ea5c136f731996b9
parent64a17f3e0683a0a492a3fed9c4c17a4335d1f421 (diff)
Solving many issues: Aligning kernel stack, improve syscall mechanism,
DISABLING RED-ZONE !!!!
-rw-r--r--src/Makefile2
-rw-r--r--src/boucane.cc31
-rw-r--r--src/core/apic.cc2
-rw-r--r--src/core/asm.hpp4
-rw-r--r--src/core/idt.cc2
-rw-r--r--src/core/int.S22
-rw-r--r--src/core/paging.cc5
-rw-r--r--src/core/scheduler.cc75
-rw-r--r--src/core/scheduler.hpp2
-rw-r--r--src/core/scheduler_asm.S33
-rw-r--r--src/core/syscalls.cc9
-rw-r--r--src/drivers/framebuffer.cc11
-rw-r--r--src/drivers/psftext.cc1
-rw-r--r--src/libs/stdio.cc14
-rw-r--r--src/linker.ld2
15 files changed, 138 insertions, 77 deletions
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 $0xAEBC, %rax");
asm("mov $2, %rdi;int $0x30");
+ for(u32 delay=0;delay<=TASK_DELAY;delay++){}
+ }
+}
+
+void task3(){
+ while(1){
+ 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 %es, %rax
push %rax
- mov 56(%rsp), %rax # Restore %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 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(){
+
+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;y<fb_cfg.height;y++){
if(npixel<fb_cfg.height){
for(u32 x=0;x<fb_cfg.width;x++){
- u32 *pixel_dst=(u32*)(fb_cfg.location+x*(fb_cfg.depth/8)+y*fb_cfg.pitch);
- u32 *pixel_src=(u32*)(fb_cfg.location+x*(fb_cfg.depth/8)+npixel*fb_cfg.pitch);
- *pixel_dst=*pixel_src; // Faster than writing pixel by pixel
+ u8 *pixel_dst=(u8*)(fb_cfg.location+x*(fb_cfg.depth/8)+y*fb_cfg.pitch);
+ u8 *pixel_src=(u8*)(fb_cfg.location+x*(fb_cfg.depth/8)+npixel*fb_cfg.pitch);
+ pixel_dst[0]=pixel_src[0];
+ pixel_dst[1]=pixel_src[1];
+ pixel_dst[2]=pixel_src[2];
+ if(fb_cfg.depth==32)
+ pixel_dst[3]=pixel_src[3];
+
}
}
else{
diff --git a/src/drivers/psftext.cc b/src/drivers/psftext.cc
index 1df4dd3..d0094d8 100644
--- a/src/drivers/psftext.cc
+++ b/src/drivers/psftext.cc
@@ -58,6 +58,7 @@ void psftext_putchar(char c){
}
glyph+=psf_status.header.glyph_width/8;
}
+
psf_status.x++;
if(psf_status.x>psf_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;