aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/boot/boot.S4
-rw-r--r--src/bringelle.c32
-rw-r--r--src/utils/gdt.c15
-rw-r--r--src/utils/gdt.h4
-rw-r--r--src/utils/pic.c44
-rw-r--r--src/utils/pic.h3
6 files changed, 87 insertions, 15 deletions
diff --git a/src/boot/boot.S b/src/boot/boot.S
index ba25a84..0092567 100644
--- a/src/boot/boot.S
+++ b/src/boot/boot.S
@@ -4,6 +4,8 @@
.extern gdt_memcpy
.extern mb_load_fb_tag
+.set STACK_LOCATION, 0x50000
+
.section .multiboot
.set MB_MAGIC, 0xE85250D6
@@ -65,7 +67,7 @@ cs_new:
# Update stack segment
movw $0x18, %ax
movw %ax, %ss
-movl $0x50000,%esp
+movl $STACK_LOCATION,%esp
# Load
mov $0x38, %eax
diff --git a/src/bringelle.c b/src/bringelle.c
index 5fd315b..8faaecc 100644
--- a/src/bringelle.c
+++ b/src/bringelle.c
@@ -2,10 +2,15 @@
#include "utils/pic.h"
#include "boot/multiboot.h"
#include "utils/mem.h"
+#include "utils/gdt.h"
char show_tics=0;
+extern GDT_TSS TSS;
+
void utask(){
+ char msg[]="Message from the task :D";
+ asm("mov $0x1, %%eax;int $0x30"::"b"(msg));
while(1);
}
@@ -15,14 +20,33 @@ void bringelle(){
// Kernel boot sequence
pic_enable_interrupt();
- print("Interrupts enabled!\n");
-
+ print("Interrupts enabled\n");
+ print("Kernel started !\n");
// Utask
+ print("Launch user task ");
+ show_tics=1;
memcpy((void*)utask,(void*)0x300000, 100); // 100 bytes seems reasonable to load utask
+ asm (
+ "cli \n\t" // Ensure we do not get interrupted
+ "movl %%ss, %%eax \n\t"
+ "movl %%eax, %0 \n\t" // Save kernel ss segment into the TSS
+ "movl %%esp, %1 \n\t" // Save kernel esp into the TSS BEFORE setting up the stack
+ "pushl $0x33 \n\t" // Push task ss which is 0x30 along with prlv which is 0x3
+ "pushl $0x400000 \n\t" // Push task esp
+ "pushfl \n\t" // Retrieve flags
+ "popl %%eax \n\t"
+ "orl $0x200, %%eax \n\t" // Enable interrupt for the user task
+ "and $0xffffbfff, %%eax \n\t" // Clear the NT flags
+ "push %%eax \n\t" // Push task flags
+ "push $0x23 \n\t" // Push task cs which is 0x20 along with prlv which is 0x3
+ "push $0 \n\t" // Push task entry point
+ "mov $0x2B, %%eax \n\t" // GDT entry 0x28 along with prlv which is 0x3
+ "mov %%eax, %%ds \n\t" // Setting up user data segment
+ "iret \n\t" // Launch user task
+ : "=m" (TSS.ss0), "=m" (TSS.esp0)
+ );
- print("Kernel started ");
- show_tics=1;
while(1);
}
diff --git a/src/utils/gdt.c b/src/utils/gdt.c
index fd86f5f..c380283 100644
--- a/src/utils/gdt.c
+++ b/src/utils/gdt.c
@@ -5,7 +5,7 @@ struct GDT_REGISTER GDTR = { 0, 0 };
GDT_TSS TSS;
void gdt_memcpy(){
- GDTR.limit=8*8; // Each entry is 8 bytes and 8 entries
+ GDTR.limit=8*GDT_MAX_ENTRIES; // Each entry is 8 bytes and 8 entries
GDTR.base=0x800;
gdt_write_entry((GDT_ENTRY){0,0,0,0},0); // First one must be null
@@ -60,12 +60,10 @@ void gdt_memcpy(){
// Init TSS segment
TSS.t_reserved=0;
TSS.io_map=0;
- TSS.ss0=0x18;
- TSS.esp0=0x50000;
GDT_ENTRY tss_desc;
tss_desc.base=(u32)&TSS; // Not used in stack descriptor
- tss_desc.limit=0x68; // Define how much entry it can contains
+ tss_desc.limit=0x68; // Define how much bytes it occupies
tss_desc.flags=0;
tss_desc.access=0x89 | GDT_PRVL_3; // Note that 0x89 is specific to TSS!
gdt_write_entry(tss_desc, 7);
@@ -89,3 +87,12 @@ void gdt_write_entry(GDT_ENTRY entry, u32 id){
// Copy descriptor into memory
memcpy(descriptor,(void*)GDTR.base+8*id,8); // Each entry is 64 bits (8 bytes)
}
+
+int gdt_user_ds_base(){
+ char *addr=(char*)GDTR.base+48;
+ int *base0_15=(int*)addr+2;
+ int *base16_31=(int*)addr+7;
+ int base0_15_content=*base0_15 & 0xFFFF;
+ int base16_21_content=*base16_31 & 0xFFFF;
+ return(base16_21_content<<16 & base0_15_content);
+} \ No newline at end of file
diff --git a/src/utils/gdt.h b/src/utils/gdt.h
index 01a01bf..f010891 100644
--- a/src/utils/gdt.h
+++ b/src/utils/gdt.h
@@ -3,6 +3,8 @@
#include "types.h"
+#define GDT_MAX_ENTRIES 8
+
// Access byte
#define GDT_AC 1 // Access bit
#define GDT_RW 1 << 1 // Read/Write bit
@@ -70,4 +72,6 @@ void gdt_memcpy();
*/
void gdt_write_entry(GDT_ENTRY entry, u32 id);
+int gdt_user_ds_base();
+
#endif
diff --git a/src/utils/pic.c b/src/utils/pic.c
index f811d04..7681a13 100644
--- a/src/utils/pic.c
+++ b/src/utils/pic.c
@@ -1,6 +1,7 @@
#include "pic.h"
#include "asm.h"
#include "mem.h"
+#include "syscall.h"
struct IDT_REGISTER IDTR={
200*8,
@@ -9,32 +10,65 @@ struct IDT_REGISTER IDTR={
/// Bridge between IDT and functions call
asm (
-"PIC_IRQ_DEFAULT:"
+".macro SAVE_REGS \n\t"
+ "pushal \n\t"
+ "push %ds \n\t"
+ "push %es \n\t"
+ "push %fs \n\t"
+ "push %gs \n\t"
+ "push %ebx \n\t"
+ "mov $0x10,%bx \n\t"
+ "mov %bx,%ds \n\t"
+ "pop %ebx \n\t"
+".endm \n\t"
+".macro RESTORE_REGS \n\t"
+ "pop %gs \n\t"
+ "pop %fs \n\t"
+ "pop %es \n\t"
+ "pop %ds \n\t"
+ "popal \n\t"
+".endm \n\t"
+"PIC_IRQ_DEFAULT: \n\t"
+ "SAVE_REGS \n\t"
"movb $0x20, %al \n\t"
"outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
"iret \n\t"
"PIC_IRQ_PRINT: \n\t"
+ "SAVE_REGS \n\t"
"call _8042_keypress \n\t"
"movb $0x20, %al \n\t"
"outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
"iret \n\t"
"PIC_IRQ_CLOCK: \n\t"
+ "SAVE_REGS \n\t"
"call clock \n\t"
"movb $0x20, %al \n\t"
"outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+"PIC_IRQ_SYSCALL: \n\t"
+ "SAVE_REGS \n\t"
+ "call syscall \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
"iret \n\t"
);
-extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT,PIC_IRQ_CLOCK;
+extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT,PIC_IRQ_CLOCK, PIC_IRQ_SYSCALL;
void pic_enable_interrupt(){
// Map first default 32 entries
for(int i=0;i<200;i++){
- pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_TYPE_1},i);
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_INT_GATE},i);
if(i==32)
- pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_CLOCK,IDT_TYPE_1},i);
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_CLOCK,IDT_INT_GATE},i);
if(i==33)
- pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_TYPE_1},i);
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_INT_GATE},i);
+ if(i==48)
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_SYSCALL,IDT_TRAP_GATE},i);
}
// Now configure 8952A
diff --git a/src/utils/pic.h b/src/utils/pic.h
index 2734437..5ee1ab2 100644
--- a/src/utils/pic.h
+++ b/src/utils/pic.h
@@ -3,7 +3,8 @@
#include "types.h"
-#define IDT_TYPE_1 0x8E00
+#define IDT_INT_GATE 0x8E00
+#define IDT_TRAP_GATE 0xEF00
typedef struct IDT_ENTRY {
u16 segment;