Как сделать так, чтобы дочерний процесс разветвлялся через sys_fork(), чтобы его стек ядра содержал фрейм-ловушку?

Я работаю над реализацией системного вызова sys_fork() на уровне ядра. Я сделал копирование родительского процесса в дочерний процесс в соответствии с требованиями. Проблема заключается в том, как скопировать дочернюю ловушку (копию родительской ловушки) в дочерний стек ядра, чтобы передать утверждение в mips_usermode()?

2 ответа

Я тоже работаю на OS161. Вот как я решаю проблему.

В sys_fork я копирую trapframe родителя в пространство кучи ядра, выделенное через kmalloc:

struct trapframe* ctf = (struct trapframe*)kmalloc(sizeof(struct trapframe));
*ctf = *tf; // tf points to parent's trapframe;

Затем я использую thread_fork для создания дочернего потока:

// passing address space using the second parameter of 
// child_forkentry, quite dirty
thread_fork(curthread->t_name, child_forkentry, ctf, (unsigned long)as, NULL);

В child_forkentry, который является первой функцией, вызываемой потомком, я делаю следующее:

struct trapframe tf; // tf will be allocated on child's kernel stack
tf = *ctf 
misp_usermode(&tf);

Это пройдет проверку стека в mips_usermode.

Я понял мою проблему.

Но то, что я собираюсь сказать, относится к системе OS161. Так что всем, кто работает в этой системе, это будет полезно.

Хорошо, на стороне ядра есть функция, которая занимается переключением контекста. Эта функция сохраняет все данные, связанные с кадром переключения контекста, в стек ядра потоков.

Поэтому все, что вам нужно сделать, это выполнить те же шаги, и вместо того, чтобы переключать структуру фрейма, вам нужно заменить его на структуру фрейма ловушки.

Вот реализация для этого:

vaddr_t stacktop;
struct trapframe *tf;
stacktop = ((vaddr_t)thread->t_stack) + STACK_SIZE;  //t_stack is the kernel stack
tf = ((struct trapframe *) stacktop) - 1;

t_stack - это просто кусок памяти на стороне ядра для хранения всего, что связано с исключениями или переключением контекста.

Обязательно сначала очистите t_stack, прежде чем загружать его trapframe, поскольку он будет содержать данные, относящиеся к фрейму переключения контекста в случае реализации sys_fork.

Любые исправления или комментарии по этому поводу приветствуются.

Другие вопросы по тегам