Skip to content

Commit

Permalink
Per-process kernel stack and real userspace-kernelspace transition close
Browse files Browse the repository at this point in the history
  • Loading branch information
champo committed Nov 2, 2011
1 parent 85b0da1 commit a14e7d0
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 61 deletions.
4 changes: 2 additions & 2 deletions src/library/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @param eax, the code of the system call.
* @param ebx, depends on the system call.
* @param ecx, depends on the system call.
* @param edx, depends on the system call.
* @param edx, depends on the system call.
* @return depends on the system call.
*/

Expand All @@ -15,7 +15,7 @@ int system_call(int eax, int ebx, int ecx, int edx) {
int ret;
__asm__ __volatile__ ( "int $0x80"
: "=a" (ret)
: "0" (eax), "b" (ebx), "c" (ecx), "d" (edx)
: "a" (eax), "b" (ebx), "c" (ecx), "d" (edx)
);

return ret;
Expand Down
2 changes: 1 addition & 1 deletion src/library/call.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef __LIBRARY_CALL__
#define __LIBRARY_CALL__

int system_call(int eax, int ebx, int ecx, int edx);
inline int system_call(int eax, int ebx, int ecx, int edx);

#endif
8 changes: 6 additions & 2 deletions src/library/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
*/
size_t strlen(const char *s) {

if (s == NULL) {
return 0;
}

int i = 0;

while (*(s+i) != '\0') {
Expand Down Expand Up @@ -303,9 +307,9 @@ char *reverse(char * s) {
* @return 1 if the string contains a number, 0 if not.
*/
int is_a_number(char* str) {

int i = 0;

while(str[0] == ' ') {
str++;
}
Expand Down
1 change: 1 addition & 0 deletions src/system/fs/fd.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __SYSTEM_FS_FD__

#include "system/fs/direntry.h"
#include "system/fs/inode.h"

struct FileDescriptor;

Expand Down
10 changes: 7 additions & 3 deletions src/system/gdt.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "system/gdt.h"
#include "system/mm.h"
#include "system/common.h"
#include "system/task.h"

#pragma pack(1)

Expand Down Expand Up @@ -33,17 +34,20 @@ static void setupGDTEntry(int num, int base, int limit, short access, short gran
void setupGDT(void) {

struct GDTR gdtr;
struct TaskState* ts = task_create_tss();

gdt = kalloc(sizeof(struct SegmentDescriptor) * 5);
gdt = kalloc(sizeof(struct SegmentDescriptor) * 6);
setupGDTEntry(0, 0, 0, 0, 0);
setupGDTEntry(1, 0, 0x000FFFFF, 0x9A, 0xC0);
setupGDTEntry(2, 0, 0x000FFFFF, 0x92, 0xC0);
setupGDTEntry(3, 0, 0x000FFFFF, 0xFA, 0xC0);
setupGDTEntry(3, 0, 0x000FFFFF, 0xFC, 0xC0);
setupGDTEntry(4, 0, 0x000FFFFF, 0xF2, 0xC0);
setupGDTEntry(5, (int) ts, (int) (ts + 1) + 1, 0x89, 0);

gdtr.limit = 5 * sizeof(struct SegmentDescriptor) - 1;
gdtr.limit = 6 * sizeof(struct SegmentDescriptor) - 1;
gdtr.base = (int) gdt;

__asm__ volatile("lgdt (%%eax)"::"A"(&gdtr):);
__asm__ volatile("ltr %%ax"::"a"(TASK_STATE_SEGMENT):);
}

6 changes: 6 additions & 0 deletions src/system/gdt.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#ifndef __SYSTEM_GDT__
#define __SYSTEM_GDT__

#define KERNEL_CODE_SEGMENT 0x08
#define KERNEL_DATA_SEGMENT 0x10
#define USER_CODE_SEGMENT (0x18 | 0x3)
#define USER_DATA_SEGMENT (0x20 | 0x3)
#define TASK_STATE_SEGMENT 0x28

void setupGDT(void);

#endif
43 changes: 19 additions & 24 deletions src/system/interrupt/handler.asm
Original file line number Diff line number Diff line change
@@ -1,54 +1,51 @@
EXTERN int08, int09, interruptDispatcher, mm_set_kernel_context, mm_set_process_context
EXTERN interruptDispatcher, mm_set_kernel_context, mm_set_process_context
GLOBAL _interruptEnd

; Defines a macro that takes as an argument the interrupt number.
; Calls that interrupt.
%macro CALLER 1
%macro CALLER 2
; Save the current execution context
pushad
push gs
push fs
push es
push ds

; Set up the handler execution context
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

call mm_set_kernel_context

call %1
call %2

call mm_set_process_context
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

pop ds
pop es
pop fs
pop gs
popad

; Move the sp to where it when the interrupt was triggered
add esp, 8

sti
iret
iretd
%endmacro

_interruptEnd:

call mm_set_process_context

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
pop ds
pop es
pop fs
pop gs

iret
iretd


; Defines a macro that takes as an argument the interrupt number.
Expand All @@ -61,18 +58,16 @@ GLOBAL _int%1Handler
; Save the interrupt number (intNum).
push 0
push %1h
CALLER %2
CALLER %1, %2
%endmacro

%macro ERR_ISR 2
GLOBAL _int%1Handler
_int%1Handler:
cli

; Save the interrupt number (intNum).
push 0
push %1h
CALLER %2
CALLER %1,%2
%endmacro

; Definition of the interrupt handlers
Expand Down
1 change: 1 addition & 0 deletions src/system/interrupt/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "system/scheduler.h"

typedef struct {
int ds, es, fs, gs;
int edi, esi, ebp, esp, ebx, edx, ecx, eax;
int intNum, errCode;
int eip, cs, eflags, useresp, ss;
Expand Down
2 changes: 1 addition & 1 deletion src/system/interrupt/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void setupIDT(void) {
// Disabling interrupts to make sure we're in absolute control.
reMapPIC(PIC1_BASE_OFFSET,PIC2_BASE_OFFSET);

setIdtEntry(idt, 0x80, 0x08, (dword)&_int80Handler, ACS_INT);
setIdtEntry(idt, 0x80, 0x08, (dword)&_int80Handler, 0xEE);
setIdtEntry(idt, 0x20, 0x08, (dword)&_int20Handler, ACS_INT);
setIdtEntry(idt, 0x21, 0x08, (dword)&_int21Handler, ACS_INT);

Expand Down
2 changes: 1 addition & 1 deletion src/system/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void kmain(struct multiboot_info* info, unsigned int magic) {

struct Process* idleProcess = process_table_new(idle, NULL, NULL, 1, NO_TERMINAL, 0);
struct Process* shellProcess = process_table_new(tty_run, NULL, idleProcess, 1, NO_TERMINAL, 0);
enableInterrupts();
yield();

while (1) {}
}
Expand Down
89 changes: 65 additions & 24 deletions src/system/process/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "system/kprintf.h"
#include "library/sys.h"
#include "library/string.h"
#include "system/gdt.h"
#include "debug.h"

static int pid = 0;
Expand All @@ -25,6 +26,7 @@ inline static void push(int** esp, int val) {
void createProcess(struct Process* process, EntryPoint entryPoint, struct Process* parent, char* args, int terminal, int kernel) {

process->pid = ++pid;
process->kernel = !!kernel;
process->terminal = terminal;
process->active = 0;

Expand All @@ -35,7 +37,7 @@ void createProcess(struct Process* process, EntryPoint entryPoint, struct Proces
process->curr_cycles = 0;
process->prev_cycles = 0;
process->timeStart = _time(NULL);

process->uid = 0;
process->gid = 0;
if (parent != NULL) {
Expand Down Expand Up @@ -66,7 +68,7 @@ void createProcess(struct Process* process, EntryPoint entryPoint, struct Proces

process->entryPoint = entryPoint;
if (args == NULL) {
*process->args = 0;
process->args[0] = 0;
} else {
int i;
for (i = 0; *(args + i) && i < 255; i++) {
Expand All @@ -90,8 +92,10 @@ void createProcess(struct Process* process, EntryPoint entryPoint, struct Proces
}
}

process->mm.pagesInStack = 256;
process->mm.stackStart = allocPages(process->mm.pagesInStack);
process->mm.pagesInKernelStack = KERNEL_STACK_PAGES;
process->mm.kernelStackStart = allocPages(process->mm.pagesInKernelStack);
process->mm.esp0 = (char*)process->mm.kernelStackStart + PAGE_SIZE * process->mm.pagesInKernelStack;
process->mm.kernelStack = process->mm.esp0;

if (kernel) {
process->mm.pagesInHeap = 0;
Expand All @@ -105,19 +109,49 @@ void createProcess(struct Process* process, EntryPoint entryPoint, struct Proces
mem_check();
}

if (process->mm.stackStart == NULL) {
panic();
if (!kernel) {
process->mm.pagesInStack = 256;
process->mm.stackStart = allocPages(process->mm.pagesInStack);
if (process->mm.stackStart == NULL) {
panic();
}

process->mm.esp = (char*)process->mm.stackStart + PAGE_SIZE * process->mm.pagesInStack;
push((int**) &process->mm.esp, (int) process->args);
push((int**) &process->mm.esp, (int) exit);
} else {
process->mm.pagesInStack = 0;
process->mm.stackStart = NULL;
process->mm.esp = NULL;
}


int codeSegment, dataSegment;
if (kernel) {
codeSegment = KERNEL_CODE_SEGMENT;
dataSegment = KERNEL_DATA_SEGMENT;

push((int**) &process->mm.esp0, (int) process->args);
push((int**) &process->mm.esp0, (int) exit);
push((int**) &process->mm.esp0, 0x202);
} else {
codeSegment = USER_CODE_SEGMENT;
dataSegment = USER_DATA_SEGMENT;

push((int**) &process->mm.esp0, dataSegment);
push((int**) &process->mm.esp0, (int) process->mm.esp);
push((int**) &process->mm.esp0, 0x3202);
}

process->mm.esp = (char*)process->mm.stackStart + PAGE_SIZE * process->mm.pagesInStack;
push((int**) &process->mm.esp, (int) process->args);
push((int**) &process->mm.esp, (int) exit);
push((int**) &process->mm.esp, 0x200);
push((int**) &process->mm.esp, 0x08);
push((int**) &process->mm.esp, (int) entryPoint);
push((int**) &process->mm.esp, (int) _interruptEnd);
push((int**) &process->mm.esp, (int) signalPIC);
push((int**) &process->mm.esp, 0);
push((int**) &process->mm.esp0, codeSegment);
push((int**) &process->mm.esp0, (int) entryPoint);
push((int**) &process->mm.esp0, dataSegment);
push((int**) &process->mm.esp0, dataSegment);
push((int**) &process->mm.esp0, dataSegment);
push((int**) &process->mm.esp0, dataSegment);
push((int**) &process->mm.esp0, (int) _interruptEnd);
push((int**) &process->mm.esp0, (int) signalPIC);
push((int**) &process->mm.esp0, 0);
}

void exitProcess(struct Process* process) {
Expand All @@ -136,17 +170,24 @@ void destroyProcess(struct Process* process) {
if (process->mm.stackStart) {
freePages(process->mm.stackStart, process->mm.pagesInStack);
process->mm.stackStart = NULL;
}

if (process->mm.heap) {
mm_set_process_context();
mem_check();
mm_set_kernel_context();
mem_check();
if (process->mm.kernelStackStart) {
freePages(process->mm.kernelStackStart, process->mm.pagesInKernelStack);
process->mm.kernelStackStart = NULL;
process->mm.kernelStack = NULL;
process->mm.esp0 = NULL;
}

freePages(process->mm.heap, process->mm.pagesInHeap);
process->mm.heap = NULL;
process->mm.mallocContext = NULL;
}
if (process->mm.heap) {
mm_set_process_context();
mem_check();
mm_set_kernel_context();
mem_check();

freePages(process->mm.heap, process->mm.pagesInHeap);
process->mm.heap = NULL;
process->mm.mallocContext = NULL;
}
}

7 changes: 7 additions & 0 deletions src/system/process/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#define NO_TERMINAL -1
#define MAX_OPEN_FILES 10
#define KERNEL_STACK_PAGES 10

typedef void (*EntryPoint)(char*);

Expand All @@ -18,6 +19,11 @@ struct ProcessMemory {
void* heap;
void* mallocContext;
int pagesInHeap;

void* esp0;
void* kernelStack;
void* kernelStackStart;
int pagesInKernelStack;
};

enum ProcessStatus {
Expand All @@ -37,6 +43,7 @@ struct ProcessSchedule {

struct Process {
int pid;
int kernel;

int ppid;
struct Process* parent;
Expand Down
1 change: 1 addition & 0 deletions src/system/process/table.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "system/process/table.h"
#include "system/scheduler.h"
#include "drivers/tty/tty.h"
#include "debug.h"

#define PTABLE_SIZE 64

Expand Down
Loading

0 comments on commit a14e7d0

Please sign in to comment.