Debug GDT enable multitasking
This commit is contained in:
parent
4f08ba2b1d
commit
e59104ffb5
14 changed files with 283 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
|||
EXEC := boucane
|
||||
CC := 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++ -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
|
||||
|
|
|
@ -28,15 +28,18 @@ extern u64 gdt64_tss;
|
|||
|
||||
void configure_tss(){
|
||||
// Get TSS physical address
|
||||
u64 tss_addr=(u64)PHY(&kvar_tss);
|
||||
u64 tss_addr=(u64)&kvar_tss;
|
||||
u32 limit=sizeof(TSS);
|
||||
|
||||
u32 desc1=(tss_addr&0xFFFF)<<16|(limit&0xFFFF);
|
||||
tss_addr>>=16;
|
||||
u32 desc2=(tss_addr&0xFF);
|
||||
desc2|=0b1001<<8; // Type
|
||||
desc2|=0b111<<13; // Permission & present
|
||||
u32 desc3=((limit>>8)&0xFFFF)|(limit>>24);
|
||||
|
||||
desc2|=0b11101001<<8; // Type, Permission, present
|
||||
tss_addr>>=8;
|
||||
desc2|=tss_addr<<24;
|
||||
tss_addr>>=8;
|
||||
u32 desc3=tss_addr;
|
||||
|
||||
// Configure GDT
|
||||
u32 *gdt_entry=(u32*)&gdt64_tss;
|
||||
gdt_entry[0]=desc1;
|
||||
|
@ -46,6 +49,7 @@ void configure_tss(){
|
|||
|
||||
// Configure segment
|
||||
kvar_tss.rsp0=(u64)VIRT(kvar_stack_pma);
|
||||
kvar_tss.iomap_address=0;
|
||||
asm(
|
||||
"mov $0x28, %ax \n\t"
|
||||
"ltr %ax"
|
||||
|
@ -53,9 +57,15 @@ void configure_tss(){
|
|||
}
|
||||
|
||||
void task1(){
|
||||
u64 a=0xEEEEEE;
|
||||
DUMP(a);
|
||||
while(1);
|
||||
while(1){
|
||||
asm("mov $1, %rdi;int $0x30");
|
||||
}
|
||||
}
|
||||
|
||||
void task2(){
|
||||
while(1){
|
||||
asm("mov $2, %rdi;int $0x30");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void boucane(u64 mb_info){
|
||||
|
@ -77,7 +87,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)){
|
||||
|
@ -97,23 +107,25 @@ 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("System informations -- BOOT:%s ", 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);
|
||||
}
|
||||
|
||||
//create_task((void*)task1, 50);
|
||||
//scheduler_start();
|
||||
show_ticks=1;
|
||||
create_task((void*)task1, 50);
|
||||
create_task((void*)task2, 50);
|
||||
scheduler_start();
|
||||
while(1);
|
||||
}
|
|
@ -17,23 +17,23 @@
|
|||
|
||||
u8 lapic_space[4096] __attribute__((aligned(4096)));
|
||||
u8 ioapic_space[4096] __attribute__((aligned(4096)));
|
||||
|
||||
char enable=0;
|
||||
void apic_enable(){
|
||||
// Memory Allocation
|
||||
PAGE_MAP(lapic_space,APIC_LAPIC_ADDR, PAGING_OPT_DEFAULTS);
|
||||
PAGE_MAP(lapic_space,APIC_LAPIC_ADDR,PAGING_OPT_DEFAULTS);
|
||||
|
||||
PAGE_MAP(lapic_space,APIC_LAPIC_ADDR, PAGING_OPT_PCD|PAGING_OPT_DEFAULTS);
|
||||
PAGE_MAP(ioapic_space,APIC_IOAPIC_ADDR,PAGING_OPT_PCD|PAGING_OPT_DEFAULTS);
|
||||
|
||||
// Configure APIC register location and enable it via MSR
|
||||
u64 lapic_addr=(u64)APIC_LAPIC_ADDR;
|
||||
/* 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);
|
||||
WRITE_MSR(0x1B,high,low);*/
|
||||
|
||||
// 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_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);
|
||||
|
@ -43,6 +43,7 @@ void apic_enable(){
|
|||
*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)
|
||||
enable=1;
|
||||
}
|
||||
|
||||
void apic_write(u32 reg, u32 value){
|
||||
|
@ -55,6 +56,15 @@ u32 apic_read(u32 reg){
|
|||
return *lapic_reg;
|
||||
}
|
||||
|
||||
extern "C" void ack(){
|
||||
apic_write(APIC_EOI, 0);
|
||||
extern "C" void apic_ack(){
|
||||
if(enable){
|
||||
/* u8 data;
|
||||
do {
|
||||
inb(0x64,data);
|
||||
}
|
||||
while((data&0x01) == 0);
|
||||
inb(0x60,data); */
|
||||
|
||||
apic_write(APIC_EOI, 0);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include "boucane.hpp"
|
||||
|
||||
|
||||
extern "C" void apic_ack();
|
||||
void apic_enable();
|
||||
void apic_write(u32 reg, u32 value);
|
||||
u32 apic_read(u32 reg);
|
|
@ -3,31 +3,35 @@
|
|||
|
||||
gdt64:
|
||||
gdt64_null:
|
||||
.long 0
|
||||
.long 0
|
||||
.word 0xFFF
|
||||
.word 0x0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 1
|
||||
.byte 0
|
||||
gdt64_cs:
|
||||
.long 0
|
||||
.byte 0
|
||||
.byte 0b10011100
|
||||
.byte 0b00100000
|
||||
.byte 0b10011010 # Present and non-conforming Readable
|
||||
.byte 0b00100000 # Long mode
|
||||
.byte 0
|
||||
gdt64_ds:
|
||||
.long 0
|
||||
.byte 0
|
||||
.byte 0b10010010
|
||||
.byte 0b10010010 # Present, writable
|
||||
.word 0
|
||||
gdt64_cs_user:
|
||||
.long 0
|
||||
.byte 0
|
||||
.byte 0b11111100
|
||||
.byte 0b00100000
|
||||
.byte 0b11111010 # Present, Privilege 3 and non-conforming Readable
|
||||
.byte 0b00100000 # Long mode
|
||||
.byte 0
|
||||
gdt64_ds_user:
|
||||
.long 0
|
||||
.byte 0
|
||||
.byte 0b11110010
|
||||
.byte 0b11110010 # Present, Privilege 3 and writable
|
||||
.word 0
|
||||
gdt64_tss:
|
||||
gdt64_tss: # Will be setup in the boucane() function
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
|
|
|
@ -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,INT_CLK;
|
||||
extern u64 INT_DEFAULT,INT_0,INT_10,INT_14,INT_KBD,INT_CLK,INT_SYSCALL;
|
||||
|
||||
void idt_enable_interrupt(void){
|
||||
IDTR.base=((u64)idt);
|
||||
|
@ -28,6 +28,10 @@ void idt_enable_interrupt(void){
|
|||
d.offset=(u64)&INT_14;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
else if(i==10){
|
||||
d.offset=(u64)&INT_10;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
else if(i==60){ // Keyboard
|
||||
d.offset=(u64)&INT_KBD;
|
||||
idt_write_descriptor(d, i);
|
||||
|
@ -36,12 +40,20 @@ void idt_enable_interrupt(void){
|
|||
d.offset=(u64)&INT_CLK;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
else if(i==0x30){ // Syscall
|
||||
IDT_DESCRIPTOR d2;
|
||||
d2.ign=0;
|
||||
d2.ist=0;
|
||||
d2.selector=0x08;
|
||||
d2.options=IDT_OPT_P|IDT_OPT_PRVL_3|IDT_OPT_TYPE_INT;
|
||||
d2.offset=(u64)&INT_SYSCALL;
|
||||
idt_write_descriptor(d2, i);
|
||||
}
|
||||
else {
|
||||
d.offset=(u64)&INT_DEFAULT;
|
||||
idt_write_descriptor(d, i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Enable interrupts
|
||||
asm(
|
||||
"lidt (IDTR) \n\t"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#define IDT_OPT_P (1 << 15)
|
||||
#define IDT_OPT_TYPE_INT 0xE << 8
|
||||
#define IDT_OPT_TYPE_TRAP 0xF << 8
|
||||
#define IDT_OPT_PRVL_0 0
|
||||
#define IDT_OPT_PRVL_1 (1 << 13)
|
||||
#define IDT_OPT_PRVL_2 (2 << 13)
|
||||
|
|
|
@ -1,50 +1,112 @@
|
|||
.code64
|
||||
|
||||
.extern printk
|
||||
.extern ack
|
||||
.extern apic_ack
|
||||
|
||||
.macro call_printk msg
|
||||
.macro CALL_PRINTK msg
|
||||
mov \msg, %rdi
|
||||
mov $0, %eax # Required for variadic functions
|
||||
mov $printk,%rcx
|
||||
call *(%rcx)
|
||||
.endm
|
||||
|
||||
.macro SAVE_REGS
|
||||
push %r8
|
||||
push %r9
|
||||
push %r10
|
||||
push %r11
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
push %rax
|
||||
push %rbx
|
||||
push %rcx
|
||||
push %rdx
|
||||
push %rbp
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rax
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
pop %rax
|
||||
.endm
|
||||
|
||||
.macro RESTORE_REGS
|
||||
pop %rdi
|
||||
pop %rsi
|
||||
pop %rbp
|
||||
pop %rdx
|
||||
pop %rcx
|
||||
pop %rbx
|
||||
pop %rax
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
pop %r11
|
||||
pop %r10
|
||||
pop %r9
|
||||
pop %r8
|
||||
.endm
|
||||
|
||||
.globl INT_DEFAULT
|
||||
INT_DEFAULT:
|
||||
SAVE_REGS
|
||||
RESTORE_REGS
|
||||
iretq
|
||||
|
||||
.globl INT_0
|
||||
INT_0:
|
||||
call_printk $MSG_INT_0
|
||||
CALL_PRINTK $MSG_INT_0
|
||||
INT_0_INFINITE:
|
||||
jmp INT_0_INFINITE
|
||||
iretq
|
||||
|
||||
.globl INT_10
|
||||
INT_10:
|
||||
CALL_PRINTK $MSG_INT_10
|
||||
INT_10_INFINITE:
|
||||
jmp INT_10_INFINITE
|
||||
iretq
|
||||
|
||||
.globl INT_14
|
||||
INT_14:
|
||||
call_printk $MSG_INT_14
|
||||
mov $0, %eax
|
||||
call printk
|
||||
CALL_PRINTK $MSG_INT_14
|
||||
INT_14_INFINITE:
|
||||
jmp INT_14_INFINITE
|
||||
iretq
|
||||
|
||||
.globl INT_KBD
|
||||
INT_KBD:
|
||||
#call_printk $MSG_INT_KBD
|
||||
call ack
|
||||
SAVE_REGS
|
||||
CALL_PRINTK $MSG_INT_KBD
|
||||
call apic_ack
|
||||
RESTORE_REGS
|
||||
iretq
|
||||
|
||||
.globl INT_CLK
|
||||
.extern clock
|
||||
INT_CLK:
|
||||
SAVE_REGS
|
||||
call clock
|
||||
call ack
|
||||
call apic_ack
|
||||
RESTORE_REGS
|
||||
iretq
|
||||
|
||||
.globl INT_SYSCALL
|
||||
.extern syscall
|
||||
INT_SYSCALL:
|
||||
SAVE_REGS
|
||||
call syscall
|
||||
RESTORE_REGS
|
||||
iretq
|
||||
|
||||
|
||||
MSG_INT_0:
|
||||
.asciz "Zero Division error!"
|
||||
MSG_INT_10:
|
||||
.asciz "Invalid TSS!"
|
||||
MSG_INT_14:
|
||||
.asciz "Page fault!"
|
||||
MSG_INT_KBD:
|
||||
|
|
|
@ -52,7 +52,7 @@ void paging_enable() {
|
|||
|
||||
// 4096 bytes stack
|
||||
PAGE_MAP(kvar_kernel_vma-4096, kvar_stack_pma,PAGING_OPT_DEFAULTS);
|
||||
|
||||
|
||||
// Load new pml4
|
||||
kpml4=(u64*)((u64)kpages[0]-kvar_kernel_vma);
|
||||
lpml4(kpml4);
|
||||
|
@ -190,9 +190,15 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, char
|
|||
u64* paging_create_task(int npages){
|
||||
u64 *pml4=paging_allocate_utable();
|
||||
|
||||
for(int i=0;i<npages;i++){
|
||||
paging_allocate_addr(pml4, i*4096, (u64)PAGE_ALLOCATE(), PAGING_OPT_P|PAGING_OPT_RW|PAGING_OPT_US, 0);
|
||||
int i;
|
||||
for(i=0;i<npages;i++){
|
||||
paging_allocate_addr(pml4, i*4096, (u64)PAGE_ALLOCATE(), PAGING_OPT_DEFAULTS|PAGING_OPT_US, 0);
|
||||
}
|
||||
// Allocate a page for the user stack
|
||||
paging_allocate_addr(pml4, i*4096, (u64)PAGE_ALLOCATE(), PAGING_OPT_DEFAULTS|PAGING_OPT_US, 0);
|
||||
// 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;
|
||||
|
|
|
@ -1,40 +1,107 @@
|
|||
#include "scheduler.hpp"
|
||||
#include "boucane.hpp"
|
||||
#include "core/apic.hpp"
|
||||
|
||||
TASK tasks[MAX_TASK];
|
||||
u32 ntasks=0;
|
||||
PROC procs[MAX_TASK];
|
||||
u32 nproc=0;
|
||||
char show_ticks=0;
|
||||
char scheduling=0;
|
||||
u32 active_process=0;
|
||||
|
||||
extern "C" void clock(){
|
||||
if(show_ticks)
|
||||
print(".");
|
||||
if(scheduling)
|
||||
schedule();
|
||||
}
|
||||
void schedule(){
|
||||
// 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.r8=stack[0];
|
||||
t->registers.r9=stack[1];
|
||||
t->registers.r10=stack[2];
|
||||
t->registers.r11=stack[3];
|
||||
t->registers.r12=stack[4];
|
||||
t->registers.r13=stack[5];
|
||||
t->registers.r14=stack[6];
|
||||
t->registers.r15=stack[7];
|
||||
t->registers.rdi=stack[8];
|
||||
t->registers.rsi=stack[9];
|
||||
t->registers.rbp=stack[10];
|
||||
t->registers.rdx=stack[11];
|
||||
t->registers.rcx=stack[12];
|
||||
t->registers.rbx=stack[13];
|
||||
t->registers.rax=stack[14];
|
||||
t->registers.rip=stack[15];
|
||||
t->registers.cs=stack[16];
|
||||
t->registers.eflags=stack[17];
|
||||
t->registers.rsp=stack[18];
|
||||
t->registers.ds=stack[19];
|
||||
|
||||
// Goto next task
|
||||
active_process++;
|
||||
if(active_process>=nproc)
|
||||
active_process=0;
|
||||
|
||||
t=&procs[active_process];
|
||||
kvar_tss.rsp0=t->registers.rsp0;
|
||||
|
||||
// Clock acknownledgement
|
||||
apic_ack();
|
||||
|
||||
asm volatile(
|
||||
"mov %0, %%rdi \n\t"
|
||||
"jmp switch \n\t"
|
||||
:: "a" (t)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void create_task(void* task, u32 size){
|
||||
if(ntasks>=MAX_TASK){
|
||||
if(nproc>=MAX_TASK){
|
||||
printk("Could not create more tasks.");
|
||||
return;
|
||||
}
|
||||
|
||||
TASK *t=&tasks[ntasks];
|
||||
t->id=ntasks;
|
||||
t->pid=ntasks;
|
||||
PROC *t=&procs[nproc];
|
||||
t->id=nproc;
|
||||
t->pid=nproc;
|
||||
t->size=size;
|
||||
t->pml4=paging_create_task(size/4096+1);
|
||||
|
||||
u32 npages=size%4096 ? size/4096 + 1 : size/4096;
|
||||
// Note that paging_create_task() allocate 2 more pages (one for the user stack and
|
||||
// the other for the kernel stack)
|
||||
t->pml4=paging_create_task(npages);
|
||||
t->registers.rsp=TASK_VMA+npages*4096+4096; // User stack
|
||||
t->registers.rsp0=TASK_VMA+npages*4096+4096*2; // Kernel stack on the last page
|
||||
|
||||
t->registers.rip=TASK_VMA;
|
||||
t->registers.cs=0x1B; // 0x18 and 0x3 privilege
|
||||
t->registers.ds=0x23; // 0x20 and 0x3 privilege
|
||||
|
||||
// Load task using
|
||||
lpml4(t->pml4);
|
||||
memcpy(task, TASK_VMA, size);
|
||||
lpml4(kpml4);
|
||||
|
||||
ntasks++;
|
||||
|
||||
nproc++;
|
||||
}
|
||||
|
||||
void scheduler_start(){
|
||||
TASK *t=&tasks[0];
|
||||
lpml4(t->pml4);
|
||||
asm("jmp switch");
|
||||
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)
|
||||
);
|
||||
}
|
|
@ -4,24 +4,32 @@
|
|||
|
||||
#define MAX_TASK 5
|
||||
#define TASK_VMA 0x0
|
||||
#if (TASK_VMA % 0x7)
|
||||
#error TASK_VMA value is not 4096 bits aligned!
|
||||
#endif
|
||||
|
||||
// DO NOT CHANGE THE FOLLOWING STRUCTURE WITHOUT CONCIDERING UPDATING
|
||||
// THE SWITCH FUNCTION INTO scheduler_asm.S
|
||||
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;
|
||||
u64 rax, rbx, rcx, rdx;
|
||||
u64 cs, rip;
|
||||
u64 ss, rsp, rbp;
|
||||
u64 rsi, rdi;
|
||||
u64 ds, es, fs, gs;
|
||||
u64 eflags;
|
||||
u64 rsp0;
|
||||
u64 r8,r9,r10,r11,r12,r13,r14,r15;
|
||||
} __attribute__((packed)) REGS;
|
||||
|
||||
// DO NOT CHANGE THE FOLLOWING STRUCTURE WITHOUT CONCIDERING UPDATING
|
||||
// THE SWITCH FUNCTION INTO scheduler_asm.S
|
||||
typedef struct {
|
||||
u64* pml4;
|
||||
REGS registers;
|
||||
u32 id;
|
||||
u32 pid;
|
||||
u64* pml4;
|
||||
u32 size;
|
||||
REGS registers;
|
||||
} __attribute__((packed)) TASK;
|
||||
} __attribute__((packed)) PROC;
|
||||
|
||||
extern char show_ticks;
|
||||
|
||||
|
|
|
@ -2,26 +2,33 @@
|
|||
|
||||
|
||||
|
||||
|
||||
.extern kvar_stack_pma
|
||||
|
||||
switch:
|
||||
|
||||
|
||||
mov $0x23, %ax
|
||||
# TODO: Check if we come from kernel mode (use kernel stack)
|
||||
# TODO: restore all registers
|
||||
|
||||
mov 96(%rdi), %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
push $0x23 #
|
||||
push $0x80
|
||||
mov (%rdi), %rax
|
||||
mov %rax, %cr3
|
||||
|
||||
push 96(%rdi)
|
||||
push 64(%rdi)
|
||||
pushf
|
||||
pop %rax
|
||||
#orl $0x200, %%eax
|
||||
mov $0xffffbfff, %rbx
|
||||
or $0x200, %rax # Enable interrupt
|
||||
mov $0xffffffffbfff, %rbx # NT flag
|
||||
and %rbx, %rax
|
||||
push %rax
|
||||
push $0x1B
|
||||
push $0x0
|
||||
|
||||
push 40(%rdi)
|
||||
push 48(%rdi)
|
||||
|
||||
|
||||
# Perform task switching
|
||||
iretq
|
||||
|
|
8
src/core/syscalls.cc
Normal file
8
src/core/syscalls.cc
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include "boucane.hpp"
|
||||
|
||||
extern "C" void syscall(){
|
||||
u64 call_number;
|
||||
asm volatile("mov %%rdi, %0":"=r"(call_number));
|
||||
printk("%d",call_number);
|
||||
for(int i=0;i<10000000;i++){}
|
||||
}
|
|
@ -15,7 +15,7 @@ void framebuffer_init(FB_CFG config){
|
|||
// Ensure we start writing at the begining of the page since
|
||||
// start is not necessarly 4096 bytes aligned
|
||||
start=PAGE(start);
|
||||
PAGE_RMAP(start,fb_cfg.location, PAGING_OPT_DEFAULTS,fb_cfg.pitch*fb_cfg.height);
|
||||
PAGE_RMAP(start,fb_cfg.location, PAGING_OPT_PCD|PAGING_OPT_DEFAULTS,fb_cfg.pitch*fb_cfg.height);
|
||||
fb_cfg.location=start;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ void framebuffer_draw(FB_PIXEL p){
|
|||
p.y=p.y>(fb_cfg.width)?fb_cfg.width:p.y;
|
||||
p.x=p.x<0?0:p.x;
|
||||
p.y=p.y<0?0:p.y;
|
||||
|
||||
|
||||
u8 *pixel=(u8*)(fb_cfg.location+p.x*(fb_cfg.depth/8)+p.y*fb_cfg.pitch);
|
||||
pixel[0]=p.r;
|
||||
pixel[1]=p.g;
|
||||
|
|
Loading…
Add table
Reference in a new issue