gonna ask tsoding for help, fuck this shit
This commit is contained in:
+13
-19
@@ -35,29 +35,23 @@ typedef struct __attribute__((packed)) Context {
|
|||||||
|
|
||||||
// Структура trap frame для перехода в ring 3
|
// Структура trap frame для перехода в ring 3
|
||||||
typedef struct __attribute__((packed)) TrapFrame {
|
typedef struct __attribute__((packed)) TrapFrame {
|
||||||
uint32_t edi;
|
uint32_t gs,fs,es,ds;
|
||||||
uint32_t esi;
|
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||||
uint32_t ebp;
|
|
||||||
uint32_t ebx; // Убрано oesp
|
uint32_t interrupt, error;
|
||||||
uint32_t edx;
|
|
||||||
uint32_t ecx;
|
uint32_t eip, cs, eflags, usermode_esp, usermode_ss;
|
||||||
uint32_t eax;
|
|
||||||
uint16_t gs;
|
|
||||||
uint16_t fs;
|
|
||||||
uint16_t es;
|
|
||||||
uint16_t ds;
|
|
||||||
uint32_t trapno;
|
|
||||||
uint32_t err;
|
|
||||||
uint32_t eip;
|
|
||||||
uint32_t cs;
|
|
||||||
uint32_t eflags;
|
|
||||||
uint32_t esp;
|
|
||||||
uint32_t ss;
|
|
||||||
} TrapFrame;
|
} TrapFrame;
|
||||||
|
|
||||||
typedef struct Process
|
typedef struct Process
|
||||||
{
|
{
|
||||||
uint32_t pid; // Process ID
|
uint32_t pid; // Process ID
|
||||||
|
|
||||||
|
uint32_t kesp;
|
||||||
|
uint32_t kesp_bottom;
|
||||||
|
uint32_t *pagedir;
|
||||||
|
|
||||||
TaskState state; // Состояние процесса
|
TaskState state; // Состояние процесса
|
||||||
char* kstack; // Стек ядра
|
char* kstack; // Стек ядра
|
||||||
Context* context; // Контекст для переключения
|
Context* context; // Контекст для переключения
|
||||||
@@ -67,7 +61,7 @@ typedef struct Process
|
|||||||
uint32_t* page_directory; // Директория страниц
|
uint32_t* page_directory; // Директория страниц
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
Process* task_create(EntryPoint 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);
|
||||||
void scheduler_init();
|
void scheduler_init();
|
||||||
void schedule();
|
void schedule();
|
||||||
void scheduler_lock();
|
void scheduler_lock();
|
||||||
|
|||||||
+2
-2
@@ -106,9 +106,9 @@ __attribute__((interrupt)) void isr_timer(struct interrupt_frame *frame)
|
|||||||
pit_init(100);
|
pit_init(100);
|
||||||
pic_end_int(0x0);
|
pic_end_int(0x0);
|
||||||
|
|
||||||
scheduler_lock();
|
//scheduler_lock();
|
||||||
schedule();
|
schedule();
|
||||||
scheduler_unlock();
|
//scheduler_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void isr_custom(struct interrupt_frame *frame)
|
__attribute__((interrupt)) void isr_custom(struct interrupt_frame *frame)
|
||||||
|
|||||||
+15
-19
@@ -16,39 +16,33 @@ extern current
|
|||||||
extern trapret
|
extern trapret
|
||||||
|
|
||||||
switchProcess:
|
switchProcess:
|
||||||
; Сохраняем регистры текущего процесса
|
mov eax, [esp + 4] ; eax = old
|
||||||
|
mov edx, [esp + 8] ; edx = new
|
||||||
|
|
||||||
|
push ebp
|
||||||
push ebx
|
push ebx
|
||||||
push esi
|
push esi
|
||||||
push edi
|
push edi
|
||||||
push ebp
|
|
||||||
|
|
||||||
; Сохраняем указатель стека в current->context
|
mov [eax+4], esp
|
||||||
mov edi, [current]
|
mov esp, [edx+4]
|
||||||
mov [edi + 12], esp ; PCB.CONTEXT находится по смещению 12
|
|
||||||
|
|
||||||
; Загружаем следующий процесс
|
;mov eax, [edx+12]
|
||||||
mov esi, [esp + 20] ; next (первый аргумент)
|
;sub eax, 0xC0000000
|
||||||
mov [current], esi
|
;mov cr3, eax
|
||||||
mov esp, [esi + 12] ; Загружаем esp из next->context
|
|
||||||
|
|
||||||
; Восстанавливаем регистры
|
|
||||||
pop ebp
|
|
||||||
pop edi
|
pop edi
|
||||||
pop esi
|
pop esi
|
||||||
pop ebx
|
pop ebx
|
||||||
|
pop ebp
|
||||||
|
|
||||||
|
|
||||||
; Проверяем ring процесса
|
|
||||||
mov eax, [esi + 20] ; PCB.RING находится по смещению 20
|
|
||||||
cmp eax, 3
|
|
||||||
je .ring3
|
|
||||||
sti
|
|
||||||
ret ; Для ring 0 просто возвращаемся
|
ret ; Для ring 0 просто возвращаемся
|
||||||
.ring3:
|
|
||||||
jmp trapret ; Для ring 3 переходим через trapret
|
|
||||||
|
|
||||||
trapret:
|
trapret:
|
||||||
; Восстанавливаем общие регистры из trap frame
|
; Восстанавливаем общие регистры из trap frame
|
||||||
popal ; edi, esi, ebp, oesp, ebx, edx, ecx, eax
|
;popal ; edi, esi, ebp, oesp, ebx, edx, ecx, eax
|
||||||
|
|
||||||
; Восстанавливаем сегментные регистры
|
; Восстанавливаем сегментные регистры
|
||||||
pop gs
|
pop gs
|
||||||
@@ -56,6 +50,8 @@ trapret:
|
|||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
|
popad
|
||||||
|
|
||||||
; Пропускаем trapno и err
|
; Пропускаем trapno и err
|
||||||
add esp, 8 ; trapno (4 байта) + err (4 байта)
|
add esp, 8 ; trapno (4 байта) + err (4 байта)
|
||||||
|
|
||||||
|
|||||||
+9
-8
@@ -30,7 +30,7 @@ static void processStartup()
|
|||||||
// Возврат из этой функции приведёт к вызову trapret
|
// Возврат из этой функции приведёт к вызову trapret
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* task_create(EntryPoint 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 = alloc_page();//heap_alloc(sizeof(Process));
|
||||||
p->pid = ++pid_counter;
|
p->pid = ++pid_counter;
|
||||||
@@ -53,10 +53,10 @@ Process* task_create(EntryPoint func, void** args, uint32_t arg_count, uint32_t
|
|||||||
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->ss = p->tf->ds;
|
p->tf->usermode_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 = 0x800000; // Предполагаем, что пользовательский стек настроен
|
p->tf->usermode_esp = 0x800000; // Предполагаем, что пользовательский стек настроен
|
||||||
|
|
||||||
sp -= sizeof(Context);
|
sp -= sizeof(Context);
|
||||||
p->context = (Context*)sp;
|
p->context = (Context*)sp;
|
||||||
@@ -111,6 +111,7 @@ void schedule()
|
|||||||
if (next != current)
|
if (next != current)
|
||||||
{
|
{
|
||||||
//loadPageDirectory(next->page_directory);
|
//loadPageDirectory(next->page_directory);
|
||||||
|
printf("switching to %X\n", next->pid);
|
||||||
switchProcess(next);
|
switchProcess(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,11 +138,11 @@ void jump_usermode2(void) ;
|
|||||||
|
|
||||||
void scheduler_init()
|
void scheduler_init()
|
||||||
{
|
{
|
||||||
task_create((EntryPoint)&idle, NULL, 0, 0);
|
task_create((uint32_t)idle, NULL, 0, 0);
|
||||||
//task_create((EntryPoint)&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((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();
|
||||||
@@ -209,8 +210,8 @@ void jump_usermode2(void) {
|
|||||||
(code_pte & 0x2) ? "writable" : "read-only",
|
(code_pte & 0x2) ? "writable" : "read-only",
|
||||||
(code_pte & 0x4) ? "user" : "supervisor");
|
(code_pte & 0x4) ? "user" : "supervisor");
|
||||||
|
|
||||||
task_create(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(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