diff options
author | Marvin Borner | 2020-08-07 21:14:20 +0200 |
---|---|---|
committer | Marvin Borner | 2020-08-07 21:14:20 +0200 |
commit | 79f2fa136f26a0b87917336e089485712ee49bd6 (patch) | |
tree | ccf19f23e11191e6e71d89921913d4edb00a6042 /src/features | |
parent | 5e4374f938d259903fa21cb62b3f3b77b126198b (diff) |
Dual-tasking works.
I don't know why triple-tasking doesn't though...
Diffstat (limited to 'src/features')
-rw-r--r-- | src/features/load.c | 1 | ||||
-rw-r--r-- | src/features/proc.asm | 25 | ||||
-rw-r--r-- | src/features/proc.c | 36 |
3 files changed, 47 insertions, 15 deletions
diff --git a/src/features/load.c b/src/features/load.c index 5382c77..cc1a094 100644 --- a/src/features/load.c +++ b/src/features/load.c @@ -14,5 +14,6 @@ void bin_load(char *path, struct proc *proc) proc->regs.ebp = (u32)stack; proc->regs.esp = (u32)stack; + proc->regs.useresp = (u32)stack; proc->regs.eip = (u32)data; } diff --git a/src/features/proc.asm b/src/features/proc.asm new file mode 100644 index 0000000..3d6bbc4 --- /dev/null +++ b/src/features/proc.asm @@ -0,0 +1,25 @@ +%define USER_CODE_SEGMENT 0x18 +%define USER_DATA_SEGMENT 0x20 +%define RING3_MASK 0b11 + +global proc_jump_userspace +extern _esp +extern _eip +proc_jump_userspace: + mov ax, USER_DATA_SEGMENT | RING3_MASK + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov eax, dword [_esp] + push USER_DATA_SEGMENT | RING3_MASK + push eax + pushf + + sti + + push USER_CODE_SEGMENT | RING3_MASK + push dword [_eip] + + iret diff --git a/src/features/proc.c b/src/features/proc.c index 46b55fb..a14aaea 100644 --- a/src/features/proc.c +++ b/src/features/proc.c @@ -16,10 +16,8 @@ struct proc *last; void scheduler(struct regs *regs) { - if (current) { - printf("%d", current->pid); + if (current) memcpy(¤t->regs, regs, sizeof(struct regs)); - } timer_handler(); @@ -34,7 +32,19 @@ void scheduler(struct regs *regs) else current = current->next; + /* proc_print(); */ memcpy(regs, ¤t->regs, sizeof(struct regs)); + + if (regs->cs != GDT_USER_CODE_OFFSET) { + regs->gs = GDT_USER_DATA_OFFSET; + regs->fs = GDT_USER_DATA_OFFSET; + regs->es = GDT_USER_DATA_OFFSET; + regs->ds = GDT_USER_DATA_OFFSET; + regs->ss = GDT_USER_DATA_OFFSET; + regs->cs = GDT_USER_CODE_OFFSET; + regs->eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS; + } + printf("%d", current->pid); } void proc_print() @@ -64,19 +74,10 @@ void proc_attach(struct proc *proc) struct proc *proc_make() { - /* if (current) */ - /* current->state = PROC_ASLEEP; */ struct proc *proc = malloc(sizeof(*proc)); proc->pid = pid++; proc->state = PROC_RUNNING; - - // Configure registers (default data) - proc->regs.ds = GDT_DATA_OFFSET; - proc->regs.es = GDT_DATA_OFFSET; - proc->regs.fs = GDT_DATA_OFFSET; - proc->regs.gs = GDT_DATA_OFFSET; - proc->regs.cs = GDT_CODE_OFFSET; - proc->regs.eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS; + proc->next = NULL; if (current) proc_attach(proc); @@ -84,6 +85,9 @@ struct proc *proc_make() return proc; } +extern void proc_jump_userspace(); + +u32 _esp, _eip; void proc_init() { cli(); @@ -93,6 +97,8 @@ void proc_init() bin_load("/init", root); strcpy(root->name, "root"); proc_print(); - sti(); - hlt(); + + _eip = root->regs.eip; + _esp = root->regs.esp; + proc_jump_userspace(); } |