yo almost, i guess...

This commit is contained in:
2025-05-16 16:34:30 +03:00
parent 44d09ab13f
commit 5d012b410d
3 changed files with 42 additions and 14 deletions
+6 -6
View File
@@ -4,10 +4,10 @@
#include <stdint.h> #include <stdint.h>
// Сегменты для ядра и пользователя // Сегменты для ядра и пользователя
#define SEG_KCODE 1 // Сегмент кода ядра #define SEG_KCODE 0x08 // Сегмент кода ядра
#define SEG_KDATA 2 // Сегмент данных ядра #define SEG_KDATA 0x10 // Сегмент данных ядра
#define SEG_UCODE 3 // Сегмент кода пользователя #define SEG_UCODE 0x18 // Сегмент кода пользователя
#define SEG_UDATA 4 // Сегмент данных пользователя #define SEG_UDATA 0x20 // Сегмент данных пользователя
#define DPL_KERNEL 0 // Уровень привилегий ring 0 #define DPL_KERNEL 0 // Уровень привилегий ring 0
#define DPL_USER 3 // Уровень привилегий ring 3 #define DPL_USER 3 // Уровень привилегий ring 3
@@ -25,7 +25,7 @@ typedef enum TaskState
typedef void (*EntryPoint)(void); typedef void (*EntryPoint)(void);
// Структура контекста для переключения между процессами // Структура контекста для переключения между процессами
typedef struct Context { typedef struct __attribute__((packed)) Context {
uint32_t edi; uint32_t edi;
uint32_t esi; uint32_t esi;
uint32_t ebx; uint32_t ebx;
@@ -34,7 +34,7 @@ typedef struct Context {
} Context; } Context;
// Структура trap frame для перехода в ring 3 // Структура trap frame для перехода в ring 3
typedef struct TrapFrame { typedef struct __attribute__((packed)) TrapFrame {
uint32_t edi; uint32_t edi;
uint32_t esi; uint32_t esi;
uint32_t ebp; uint32_t ebp;
+9 -1
View File
@@ -33,9 +33,17 @@ sys_exit_handler:
global test_user_function global test_user_function
test_user_function: test_user_function:
nigg:
mov eax, 0xB00B1E5 ; 0xDEADBEEF mov eax, 0xB00B1E5 ; 0xDEADBEEF
int 0x80 int 0x80
jmp $ jmp nigg
global second_user_function
second_user_function:
heh:
mov eax, 0xFACE5EA7
int 0x80
jmp heh
section .data section .data
sys_exit_msg: db "Returned from Ring 3", 0 sys_exit_msg: db "Returned from Ring 3", 0
+27 -7
View File
@@ -41,6 +41,10 @@ Process* task_create(EntryPoint func, void** args, uint32_t arg_count, uint32_t
uint32_t* sp = (uint32_t*)(p->kstack + KSTACKSIZE); uint32_t* sp = (uint32_t*)(p->kstack + KSTACKSIZE);
if (ring == DPL_USER) { if (ring == DPL_USER) {
void* user_stack = alloc_page();
map_page(user_stack, (void*)0x800000, 0x7); // U/S=1, R/W=1
// Настраиваем trap frame для ring 3 // Настраиваем trap frame для ring 3
sp -= sizeof(TrapFrame) / 4; sp -= sizeof(TrapFrame) / 4;
p->tf = (TrapFrame*)sp; p->tf = (TrapFrame*)sp;
@@ -52,14 +56,16 @@ Process* task_create(EntryPoint func, void** args, uint32_t arg_count, uint32_t
p->tf->ss = p->tf->ds; p->tf->ss = p->tf->ds;
p->tf->eflags = FL_IF; p->tf->eflags = FL_IF;
p->tf->eip = (uint32_t)func; p->tf->eip = (uint32_t)func;
p->tf->esp = USTACKSIZE; // Предполагаем, что пользовательский стек настроен p->tf->esp = 0x800000 + USTACKSIZE; // Предполагаем, что пользовательский стек настроен
// Добавляем адрес возврата для trapret // Добавляем адрес возврата для trapret
sp -= 1; sp -= 1;
*sp = (uint32_t)trapret; *sp = (uint32_t)trapret;
} else { } else {
// Для ring 0 не используем trap frame p->tf = NULL; // Для ring 0 TrapFrame не нужен!
p->tf = NULL; sp -= sizeof(Context) / 4; // Только контекст
p->context = (Context*)sp;
p->context->eip = (uint32_t)func; // Прямой переход в func
} }
// Настраиваем начальный контекст // Настраиваем начальный контекст
sp -= 5; // Место для edi, esi, ebx, ebp, eip sp -= 5; // Место для edi, esi, ebx, ebp, eip
@@ -142,19 +148,21 @@ void jump_usermode2(void) ;
void scheduler_init() void scheduler_init()
{ {
task_create((EntryPoint)idle, NULL, 0, 0); task_create((EntryPoint)&idle, NULL, 0, 0);
task_create((EntryPoint)idle, NULL, 0, 0); task_create((EntryPoint)&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((EntryPoint)&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"
extern void test_user_function(void); extern void test_user_function(void);
extern void second_user_function(void);
void jump_usermode2(void) { void jump_usermode2(void) {
void* code_phys = alloc_page(); void* code_phys = alloc_page();
if (!code_phys) { if (!code_phys) {
@@ -162,12 +170,17 @@ void jump_usermode2(void) {
while (1); while (1);
} }
void *second_code_phys = alloc_page();
// Temporarily map code_phys into kernel space // Temporarily map code_phys into kernel space
uint32_t kernel_temp_virt = 0xC0500000; uint32_t kernel_temp_virt = 0xC0500000;
uint32_t kernel_temp_virt2 = 0xC0600000;
map_page(code_phys, (void*)kernel_temp_virt, 0x3); // R/W in kernel map_page(code_phys, (void*)kernel_temp_virt, 0x3); // R/W in kernel
map_page(second_code_phys, (void*)kernel_temp_virt2, 0x3); // R/W in kernel
// Copy user code // Copy user code
memcpy((void*)kernel_temp_virt, test_user_function, 4096); // Use memcpy memcpy((void*)kernel_temp_virt, test_user_function, 4096); // Use memcpy
memcpy((void*)kernel_temp_virt2, second_user_function, 4096); // Use memcpy
printf("Copied code at 0x%x: 0x%x 0x%x 0x%x\n", printf("Copied code at 0x%x: 0x%x 0x%x 0x%x\n",
kernel_temp_virt, kernel_temp_virt,
@@ -177,6 +190,7 @@ void jump_usermode2(void) {
// Unmap temporary kernel mapping // Unmap temporary kernel mapping
unmap_page((void*)kernel_temp_virt); unmap_page((void*)kernel_temp_virt);
unmap_page((void*)kernel_temp_virt2);
printf("Copied code to 0x%x (virt 0x%x)\n", printf("Copied code to 0x%x (virt 0x%x)\n",
@@ -184,17 +198,21 @@ void jump_usermode2(void) {
// Настраиваем Ring 3 // Настраиваем Ring 3
uint32_t user_stack_top; uint32_t user_stack_top;
uint32_t user_stack_top2;
void* user_code_virt = setup_user_process(code_phys, &user_stack_top); void* user_code_virt = setup_user_process(code_phys, &user_stack_top);
if (!user_code_virt) { if (!user_code_virt) {
printf("Failed to setup user process\n"); printf("Failed to setup user process\n");
while (1); while (1);
} }
void *second_user_code_virt = setup_user_process(second_code_phys, &user_stack_top2);
printf("user_code_virt: 0x%x, user_stack_top: 0x%x\n", printf("user_code_virt: 0x%x, user_stack_top: 0x%x\n",
(uint32_t)user_code_virt, user_stack_top); (uint32_t)user_code_virt, user_stack_top);
//map_page(alloc_page(), (void*)0x400000, 0x7); //map_page(alloc_page(), (void*)0x400000, 0x7);
map_page(alloc_page(), (void*)0x800000, 0x7); map_page(alloc_page(), (void*)0x800000, 0x7);
map_page(alloc_page(), (void*)0x900000, 0x7);
uint32_t code_pte = get_pte(user_code_virt); uint32_t code_pte = get_pte(user_code_virt);
printf("Before iret: Code PTE at 0x%x: 0x%x (phys 0x%x, %s, %s)\n", printf("Before iret: Code PTE at 0x%x: 0x%x (phys 0x%x, %s, %s)\n",
@@ -203,7 +221,9 @@ void jump_usermode2(void) {
(code_pte & 0x4) ? "user" : "supervisor"); (code_pte & 0x4) ? "user" : "supervisor");
task_create(user_code_virt, NULL, 0, 3); task_create(user_code_virt, NULL, 0, 3);
//task_create(second_user_code_virt, NULL, 0, 3);
return;
// Switch to user mode with interrupts enabled // Switch to user mode with interrupts enabled
asm volatile ( asm volatile (
"pushf\n" "pushf\n"