tasking: add simple base for running things in ring 3

This commit is contained in:
2025-04-07 16:13:31 +03:00
parent 03e718c2c8
commit 372b308ec8
9 changed files with 163 additions and 10 deletions
+58 -4
View File
@@ -107,14 +107,68 @@ void task2(int arg1, int arg2)
while(1){printf("task2 %X %X\n", arg1, arg2);}
}
void jump_usermode2(void);
void scheduler_init()
{
jump_usermode2();
//we create this task two times because in other case it just won't start
task_create((EntryPoint)&idle, NULL, 0);
task_create((EntryPoint)&idle, NULL, 0);
//task_create((EntryPoint)&idle, NULL, 0);
//task_create((EntryPoint)&idle, NULL, 0);
void* args1[] = {(void*)42, (void*)"ebalo"};
task_create((EntryPoint)&task1, args1, 2);
//task_create((EntryPoint)&task1, args1, 2);
void* args2[] = {(void*)69, (void*)420};
task_create((EntryPoint)&task2, args2, 2);
//task_create((EntryPoint)&task2, args2, 2);
}
extern void test_user_function(void);
void jump_usermode2(void) {
void* code_phys = alloc_page();
if (!code_phys) {
printf("No memory for user code\n");
while (1);
}
// Временно отображаем code_phys в ядре
uint32_t kernel_temp_virt = 0xC0100000;
map_page(code_phys, (void*)kernel_temp_virt, 0x3); // Present, R/W, Supervisor
// Копируем код
uint32_t* src = (uint32_t*)test_user_function;
uint32_t* dst = (uint32_t*)kernel_temp_virt;
for (int i = 0; i < 1024; i++) {
dst[i] = src[i];
}
printf("Copied code to 0x%x (virt 0x%x): 0x%x 0x%x 0x%x\n",
(uint32_t)code_phys, kernel_temp_virt, dst[0], dst[1], dst[2]);
// Настраиваем Ring 3
uint32_t user_stack_top;
void* user_code_virt = setup_user_process(code_phys, &user_stack_top);
if (!user_code_virt) {
printf("Failed to setup user process\n");
while (1);
}
printf("user_code_virt: 0x%x, user_stack_top: 0x%x\n",
(uint32_t)user_code_virt, user_stack_top);
asm volatile (
"mov $0x23, %%dx\n"
"mov %%dx, %%ds\n"
"mov %%dx, %%es\n"
"mov %%dx, %%fs\n"
"mov %%dx, %%gs\n"
"push $0x23\n"
"push %0\n"
"pushf\n"
"push $0x1B\n"
"push %1\n"
"iret\n"
:
: "r" (user_stack_top), "r" (user_code_virt)
: "dx", "memory"
);
__builtin_unreachable();
}