Solving many issues: Aligning kernel stack, improve syscall mechanism,
DISABLING RED-ZONE !!!!
This commit is contained in:
parent
64a17f3e06
commit
1530a85d5a
15 changed files with 139 additions and 78 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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" \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
|
@ -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();
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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{
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue