雑記帳

ソフトを中心に雑記を書いてる割とすぐ転職したい人。コメント貰えると私が喜びます。

Linuxカーネル解読室(5日目)

ここから実コードが出てくるので面倒になった。
俺みたいなインチキSEが読むにはツライです。
でもガンバル!!
ちなみに、2章くらいまでは http://p.tl/Rq0n に丸写しされているようなので興味があったら閲覧してみて下さい。

  • 第4章 1.4 プロセスディスパッチャの実装
    • ここではIntel x86Linuxコードで解説が書いてある。
    • switch_mm関数=プロセス空間切替、switch_to関数=レジスタ切替の2つが本体。
    • コードを丸写してみる。(kernel/sched.cのcontext_switch()関数)
task_t* context_switch(runqueue* rq, task_t *prev, task_t* next)
{
    struct mm_struc* mm = next->mm;
    struct mm_struct* oldmm = prev->active_mm;
    if( unlikely(!mm) ){
        next->active->mm = oldmm;
        atomic_inc(&oldmm->mm_count);
        enter_lazy_tlb(oldmm, next);
    } else
        switch_mm(oldmm, mm, next);

    if( unlikely(!prev->mm) ) {
        prev->active->mm = NULL;
        WARN_ON( rq->prev_mm );
        rq->prev_mm = oldmm;
    }
    
    switch_to( prev, next, prev );
    return prev;
}
    • switch_toマクロの解説が書いてある。EIPレジスタ(命令ポインタ)、ESPレジスタ(スタックポインタ)の切り替えが重要。
    • switch_toマクロの途中で呼ばれる__switch_to関数ではEIPとESP以外のレジスタの切り替えを行う。

今日はここまでにしときます。
コードと1時間くらいにらめっこしてて、やっぱり良く分からなかったのでググったら先人の記録に当たりました。ありがたや。
明日(もう今日かも)は、上のリンク先の説明を見ながら少しアセンブリと戦います。
明後日まで掛かりたくはないなぁ。