Как сделать так, чтобы дочерний процесс разветвлялся через 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.
Любые исправления или комментарии по этому поводу приветствуются.