カーネル レベルでのシステム コール sys_fork() の実装に取り組んでいます。要件に従って、親プロセスを子プロセスにコピーしました。問題は、子のトラップ フレーム (親のトラップ フレームのコピー) を子のカーネル スタックにコピーして、mips_usermode() でアサーションを渡す方法です。
2 に答える
私は自分の問題を理解しました。
しかし、私が言おうとしているのは、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は、例外やコンテキストスイッチに関連するものを格納するためのカーネル側のメモリのチャンクです。
sys_fork実装の場合、コンテキストスイッチフレームに関連するデータが含まれるため、trapframeをロードする前に、必ず最初にt_stackをクリーンアップしてください。
これに関する訂正やコメントは大歓迎です。
私もOS161に取り組んでいます。これが私が問題に取り組む方法です。
sys_fork で、親のトラップ フレームを 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 のスタック チェックに合格します。