fix creating ring 3 tasks finally
This commit is contained in:
+9
-10
@@ -15,29 +15,28 @@ global switchProcess
|
|||||||
extern current
|
extern current
|
||||||
extern trapret
|
extern trapret
|
||||||
|
|
||||||
|
; void switchProcess(Process* next_process_ptr)
|
||||||
switchProcess:
|
switchProcess:
|
||||||
mov eax, [esp + 4] ; eax = old
|
mov edx, [esp + 4] ; edx = next_process_ptr (получаем аргумент СРАЗУ)
|
||||||
mov edx, [esp + 8] ; edx = new
|
cli ; Запретить прерывания
|
||||||
|
|
||||||
push ebp
|
push ebp
|
||||||
push ebx
|
push ebx
|
||||||
push esi
|
push esi
|
||||||
push edi
|
push edi
|
||||||
|
|
||||||
mov [eax+4], esp
|
mov eax, [current]
|
||||||
mov esp, [edx+4]
|
mov [eax + 4], esp ; current->kesp = esp
|
||||||
|
|
||||||
;mov eax, [edx+12]
|
; edx уже содержит next_process_ptr
|
||||||
;sub eax, 0xC0000000
|
mov esp, [edx + 4] ; esp = next_process_ptr->kesp
|
||||||
;mov cr3, eax
|
mov [current], edx ; current = next_process_ptr
|
||||||
|
|
||||||
pop edi
|
pop edi
|
||||||
pop esi
|
pop esi
|
||||||
pop ebx
|
pop ebx
|
||||||
pop ebp
|
pop ebp
|
||||||
|
ret
|
||||||
|
|
||||||
ret ; Для ring 0 просто возвращаемся
|
|
||||||
|
|
||||||
|
|
||||||
trapret:
|
trapret:
|
||||||
|
|||||||
+31
-21
@@ -32,44 +32,54 @@ static void processStartup()
|
|||||||
|
|
||||||
Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ring)
|
Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ring)
|
||||||
{
|
{
|
||||||
Process* p = alloc_page();//heap_alloc(sizeof(Process));
|
Process* p = (Process*)alloc_page();//heap_alloc(sizeof(Process));
|
||||||
|
memset(p, 0, sizeof(Process));
|
||||||
p->pid = ++pid_counter;
|
p->pid = ++pid_counter;
|
||||||
p->state = Ready;
|
p->state = Ready;
|
||||||
p->ring = ring;
|
p->ring = ring;
|
||||||
|
|
||||||
// Выделяем стек ядра
|
// Выделяем стек ядра
|
||||||
p->kstack = alloc_page();//heap_alloc(KSTACKSIZE);
|
p->kstack = (char*)alloc_page();//heap_alloc(KSTACKSIZE);
|
||||||
map_page(p->kstack, p->kstack, 0x7);
|
map_page(p->kstack, p->kstack, 0x3);
|
||||||
printf("kstack: %X!!!!!!!!!!!!\n", p->kstack);
|
printf("kstack: %X!!!!!!!!!!!!\n", p->kstack);
|
||||||
uint8_t* sp = (uint8_t*)(p->kstack);
|
uint8_t* sp = (uint8_t*)(p->kstack + KSTACKSIZE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sp -= sizeof(TrapFrame);
|
sp -= sizeof(TrapFrame);
|
||||||
p->tf = (TrapFrame*)sp;
|
p->tf = (TrapFrame*)sp;
|
||||||
memset(p->tf, 0, sizeof(TrapFrame));
|
memset(p->tf, 0, sizeof(TrapFrame));
|
||||||
p->tf->cs = ring == 3 ? (SEG_UCODE) | DPL_USER : (SEG_KCODE);
|
|
||||||
p->tf->ds = ring == 3 ? (SEG_UDATA) | DPL_USER : (SEG_KDATA);
|
p->tf->cs = ring == 3 ? (SEG_UCODE | DPL_USER) : (SEG_KCODE);
|
||||||
|
p->tf->ds = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA);
|
||||||
p->tf->es = p->tf->ds;
|
p->tf->es = p->tf->ds;
|
||||||
p->tf->fs = p->tf->ds;
|
p->tf->fs = p->tf->ds;
|
||||||
p->tf->gs = p->tf->ds;
|
p->tf->gs = p->tf->ds;
|
||||||
p->tf->usermode_ss = p->tf->ds;
|
|
||||||
|
p->tf->usermode_ss = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA);
|
||||||
|
|
||||||
p->tf->eflags = FL_IF;
|
p->tf->eflags = FL_IF;
|
||||||
p->tf->eip = (uint32_t)func;
|
p->tf->eip = (uint32_t)func;
|
||||||
p->tf->usermode_esp = 0x800000; // Предполагаем, что пользовательский стек настроен
|
|
||||||
|
if(ring == 3)
|
||||||
|
{
|
||||||
|
void* user_stack_physical = alloc_page();
|
||||||
|
|
||||||
|
uint32_t user_stack_virtual_top = 0xBFFFF000 - ((p->pid -1) * (USTACKSIZE + 4096)); // Уникальный верх стека для каждого процесса
|
||||||
|
uint32_t user_stack_virtual_base = user_stack_virtual_top - USTACKSIZE;
|
||||||
|
|
||||||
|
map_page(user_stack_physical, (void*)user_stack_virtual_base, 0x7/*PTE_PRESENT | PTE_READ_WRITE | PTE_USER*/); // Флаги 0x7
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sp -= sizeof(Context);
|
sp -= sizeof(Context);
|
||||||
p->context = (Context*)sp;
|
p->context = (Context*)sp;
|
||||||
p->context->eip = (uint32_t)trapret;
|
memset(p->context, 0, sizeof(Context));
|
||||||
// Настраиваем начальный контекст
|
|
||||||
//sp -= 5; // Место для edi, esi, ebx, ebp, eip
|
|
||||||
//sp -= sizeof(Context);
|
|
||||||
p->context->edi = 0;
|
|
||||||
p->context->esi = 0;
|
|
||||||
p->context->ebx = 0;
|
|
||||||
p->context->ebp = 0;
|
|
||||||
|
|
||||||
p->page_directory = kernel_page_directory;
|
p->context->eip = (uint32_t)trapret;
|
||||||
|
p->kesp = (uint32_t)sp;
|
||||||
|
|
||||||
|
p->page_directory = kpage_dir;
|
||||||
|
|
||||||
p->next = 0;
|
p->next = 0;
|
||||||
|
|
||||||
@@ -111,7 +121,7 @@ void schedule()
|
|||||||
if (next != current)
|
if (next != current)
|
||||||
{
|
{
|
||||||
//loadPageDirectory(next->page_directory);
|
//loadPageDirectory(next->page_directory);
|
||||||
printf("switching to %X\n", next->pid);
|
//printf("switching to %X\n", next->pid);
|
||||||
switchProcess(next);
|
switchProcess(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,10 +152,10 @@ void scheduler_init()
|
|||||||
task_create((uint32_t)idle, NULL, 0, 0);
|
task_create((uint32_t)idle, NULL, 0, 0);
|
||||||
|
|
||||||
void* args1[] = {(void*)42, (void*)"ebalo"};
|
void* args1[] = {(void*)42, (void*)"ebalo"};
|
||||||
//task_create((EntryPoint)task1, args1, 2, 0);
|
task_create((uint32_t)task1, args1, 2, 0);
|
||||||
void* args2[] = {(void*)69, (void*)420};
|
void* args2[] = {(void*)69, (void*)420};
|
||||||
//task_create((EntryPoint)&task2, args2, 2, 0);
|
//task_create((EntryPoint)&task2, args2, 2, 0);
|
||||||
//jump_usermode2();
|
jump_usermode2();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../include/string.h"
|
#include "../include/string.h"
|
||||||
@@ -211,7 +221,7 @@ void jump_usermode2(void) {
|
|||||||
(code_pte & 0x4) ? "user" : "supervisor");
|
(code_pte & 0x4) ? "user" : "supervisor");
|
||||||
|
|
||||||
task_create((uint32_t)user_code_virt, NULL, 0, 3);
|
task_create((uint32_t)user_code_virt, NULL, 0, 3);
|
||||||
//task_create(second_user_code_virt, NULL, 0, 3);
|
task_create((uint32_t)second_user_code_virt, NULL, 0, 3);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
// Switch to user mode with interrupts enabled
|
// Switch to user mode with interrupts enabled
|
||||||
|
|||||||
Reference in New Issue
Block a user