Running in user mode
This commit is contained in:
parent
6c078289f9
commit
68ec6fa575
@ -8,16 +8,9 @@
|
||||
#include <process.h>
|
||||
#include <scheduler.h>
|
||||
|
||||
int *pid = (int *)0x20000;
|
||||
void thread_function()
|
||||
{
|
||||
*pid = process()->pid;
|
||||
|
||||
while(1)
|
||||
{
|
||||
debug("Process %d\n", *pid);
|
||||
yield();
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
@ -35,16 +28,12 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
|
||||
cpu_init();
|
||||
|
||||
struct process *p1 = new_process(thread_function);
|
||||
vmm_set_page(p1->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT);
|
||||
struct process *p2 = new_process(thread_function);
|
||||
vmm_set_page(p2->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT);
|
||||
struct process *p3 = new_process(thread_function);
|
||||
vmm_set_page(p3->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT);
|
||||
struct process *p1 = new_process((void (*)(void))0x10000);
|
||||
uint64_t page = pmm_alloc();
|
||||
vmm_set_page(p1->P4, 0x10000, page, PAGE_WRITE | PAGE_PRESENT | PAGE_USER);
|
||||
memcpy(P2V(page), (void *)(uintptr_t)thread_function, PAGE_SIZE);
|
||||
|
||||
ready(p1);
|
||||
ready(p2);
|
||||
ready(p3);
|
||||
|
||||
debug_ok("Boot \"Complete\"\n");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <cpu.h>
|
||||
#include <interrupts.h>
|
||||
|
||||
uint64_t gdt[5];
|
||||
uint64_t gdt[6];
|
||||
uint8_t tss[104];
|
||||
void gdt_init(uint64_t *, void *);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#define GDT_DPL(lvl) ((lvl)<<13)
|
||||
#define GDT_PRESENT (1<<15)
|
||||
#define GDT_LONG (1<<21)
|
||||
#define GDT_TSS (1<<8)
|
||||
#define GDT_TSS (9<<8)
|
||||
|
||||
struct gdt
|
||||
{
|
||||
@ -44,6 +44,7 @@ struct gdt BootGDT[] = {
|
||||
{0, 0},
|
||||
{0, GDT_PRESENT | GDT_DPL(0) | GDT_CODE | GDT_LONG},
|
||||
{0, GDT_PRESENT | GDT_DPL(3) | GDT_CODE | GDT_LONG},
|
||||
{0, GDT_PRESENT | GDT_DPL(3) | (1<<12) | (1<<9)},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
};
|
||||
@ -56,18 +57,27 @@ void gdt_init(uint64_t *_gdt, void *_tss)
|
||||
struct gdt *gdt = (struct gdt *)_gdt;
|
||||
memcpy(gdt, BootGDT, sizeof(BootGDT));
|
||||
|
||||
struct tss *tss = _tss;
|
||||
tss->io_mba = sizeof(struct tss);
|
||||
|
||||
uint32_t tss_limit = sizeof(struct tss);
|
||||
uint64_t tss_base = (uint64_t)_tss;
|
||||
gdt[3].flags = GDT_PRESENT | GDT_TSS;
|
||||
gdt[3].flags |= (((tss_base >> 24) & 0xFF) << 24);
|
||||
gdt[3].flags |= ((tss_base >> 16) & 0xFF);
|
||||
gdt[3].flags |= (((tss_limit >> 16) & 0xF) << 16);
|
||||
gdt[3].addr = ((tss_base & 0xFFFF) << 16) | (tss_limit & 0xFFFF);
|
||||
gdt[4].flags = 0;
|
||||
gdt[4].addr = ((tss_base >> 32) & 0xFFFF);
|
||||
gdt[4].flags = GDT_PRESENT | GDT_TSS;
|
||||
gdt[4].flags |= (((tss_base >> 24) & 0xFF) << 24);
|
||||
gdt[4].flags |= ((tss_base >> 16) & 0xFF);
|
||||
gdt[4].flags |= (((tss_limit >> 16) & 0xF) << 16);
|
||||
gdt[4].addr = ((tss_base & 0xFFFF) << 16) | (tss_limit & 0xFFFF);
|
||||
gdt[5].flags = 0;
|
||||
gdt[5].addr = ((tss_base >> 32) & 0xFFFFFFFF);
|
||||
|
||||
GDTp.len = 5*8 - 1;
|
||||
GDTp.len = 6*8 - 1;
|
||||
GDTp.gdt = gdt;
|
||||
|
||||
load_gdt(&GDTp);
|
||||
}
|
||||
|
||||
void set_tss_rsp0(void *_tss, void *rsp0)
|
||||
{
|
||||
struct tss *tss = _tss;
|
||||
tss->rsp0 = (uint64_t)rsp0;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ load_gdt:
|
||||
push rax
|
||||
retfq
|
||||
.load_gdt:
|
||||
mov rax, 0x18
|
||||
mov rax, 0x20
|
||||
ltr ax
|
||||
ret
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
void cpu_init();
|
||||
|
||||
extern uint8_t tss[];
|
||||
void set_tss_rsp0(void *tss, void *rsp0);
|
||||
|
||||
|
||||
void load_idt(void *);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#define PAGE_PRESENT 0x001
|
||||
#define PAGE_WRITE 0x002
|
||||
#define PAGE_USER 0x004
|
||||
#define PAGE_HUGE 0x080
|
||||
#define PAGE_GLOBAL 0x100
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <queue.h>
|
||||
#include <scheduler.h>
|
||||
#include <stdint.h>
|
||||
#include <interrupts.h>
|
||||
|
||||
struct process
|
||||
{
|
||||
|
@ -11,8 +11,10 @@ struct swtch_stack
|
||||
uint64_t R13;
|
||||
uint64_t R14;
|
||||
uint64_t R15;
|
||||
uint64_t isr_return_arg;
|
||||
uint64_t RBP2;
|
||||
uint64_t ret;
|
||||
registers r;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct process *sched_proc = 0;
|
||||
@ -28,7 +30,15 @@ struct process *new_process(void (*function)(void))
|
||||
|
||||
struct swtch_stack *stk = proc->stack_ptr;
|
||||
stk->RBP = (uint64_t)&stk->RBP2;
|
||||
stk->ret = (uint64_t)function;
|
||||
|
||||
stk->ret = (uint64_t)isr_return;
|
||||
stk->isr_return_arg = (uint64_t)&stk->r;
|
||||
|
||||
stk->r.rip = (uint64_t)function;
|
||||
stk->r.cs = 0x10 | 3;
|
||||
stk->r.ss = 0x18 | 3;
|
||||
stk->r.rflags = 3<<12;
|
||||
stk->r.rsp = 0x10FFF;
|
||||
|
||||
return proc;
|
||||
}
|
||||
@ -52,6 +62,7 @@ void scheduler()
|
||||
|
||||
_proc = new;
|
||||
write_cr3(new->P4);
|
||||
set_tss_rsp0(tss, new + PAGE_SIZE);
|
||||
switch_stack(&sched_proc->stack_ptr, &new->stack_ptr);
|
||||
|
||||
ready(_proc);
|
||||
@ -61,8 +72,15 @@ void scheduler()
|
||||
|
||||
void start_scheduler()
|
||||
{
|
||||
sched_proc = new_process(scheduler);
|
||||
sched_proc = P2V(pmm_calloc());
|
||||
sched_proc->pid = (uint64_t)-1;
|
||||
sched_proc->stack_ptr = incptr(sched_proc, PAGE_SIZE - sizeof(struct swtch_stack) + sizeof(registers));
|
||||
sched_proc->P4 = kernel_P4;
|
||||
|
||||
struct swtch_stack *stk = sched_proc->stack_ptr;
|
||||
stk->RBP = (uint64_t)&stk->RBP2;
|
||||
|
||||
stk->ret = (uint64_t)scheduler;
|
||||
|
||||
uint64_t stack;
|
||||
switch_stack(&stack, &sched_proc->stack_ptr);
|
||||
|
@ -5,6 +5,7 @@
|
||||
switch_stack:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
push rdi
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
@ -21,5 +22,6 @@ switch_stack:
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
pop rdi
|
||||
leaveq
|
||||
ret
|
||||
|
Loading…
x
Reference in New Issue
Block a user