FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

MITのxv6を読もう - 第3章 システムコールの呼び出し方法について -

システムコールを呼び出すには、syscall()を呼び出すのだが、xv6ではどのような方法を取っているのだろうか。

void
syscall(void)
{
    int num;

    num = proc−>tf−>eax;
    if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
        proc−>tf−>eax = syscalls[num]();
    } else {
        cprintf("%d %s: unknown sys call %d\n",
                proc−>pid, proc−>name, num);
        proc−>tf−>eax = −1;
    }
}

procのtf->eaxにシステムコールの番号が入っている。それに従って、syscallテーブルを参照して、該当するテーブルを読み出している。

static int (*syscalls[])(void) = {
    [SYS_fork] sys_fork,
    [SYS_exit] sys_exit,
    [SYS_wait] sys_wait,
    [SYS_pipe] sys_pipe,
    [SYS_read] sys_read,
    [SYS_kill] sys_kill,
    [SYS_exec] sys_exec,
    [SYS_fstat] sys_fstat,
    [SYS_chdir] sys_chdir,
    [SYS_dup] sys_dup,
    [SYS_getpid] sys_getpid,
    [SYS_sbrk] sys_sbrk,
    [SYS_sleep] sys_sleep,
    [SYS_uptime] sys_uptime,
    [SYS_open] sys_open,
    [SYS_write] sys_write,
    [SYS_mknod] sys_mknod,
    [SYS_unlink] sys_unlink,
    [SYS_link] sys_link,
    [SYS_mkdir] sys_mkdir,
    [SYS_close] sys_close,
    };

では、tf->eaxを設定しているのは?それがトラップフレームだ。

    // Layout of the trap frame built on the stack by the
    // hardware and by trapasm.S, and passed to trap().
    struct trapframe {
        // registers as pushed by pusha
        uint edi;
        uint esi;
        uint ebp;
        uint oesp; // useless & ignored
        uint ebx;
        uint edx;
        uint ecx;
        uint eax;

        // rest of trap frame
        ushort gs;
        ushort padding1;
        ushort fs;
        ushort padding2;
        ushort es;
        ushort padding3;
        ushort ds;
        ushort padding4;
        uint trapno;

        // below here defined by x86 hardware
        uint err;
        uint eip;
        ushort cs;
        ushort padding5;
        uint eflags;

        // below here only when crossing rings, such as from user to kernel
        uint esp;
        ushort ss;
        ushort padding6;
    };

このトラップフレームを利用して、カーネルとユーザプロセスでやりとりを行っている。