NetBSD@LinkStationでPlan9portを動かす(その2)

NetBSD/evbarmでのPlan9portの動作実績はないようで、動かすには多少の修正が必要だった。パッチをまとめてRussさんに送ろうと思うが*1、とりあえず現状をメモっておく。

前準備

環境変数PKG_PATHを設定して、pkg_addを使えるようにする。gccはもちろんドキュメントのビルドでperlrsyncを使うので、このあたりをインストールしておく。

mkfile

uname -iで返されるアーキテクチャ名がevbarmでLinuxのarmv*とは違うので、src/mkhdrとdist/buildmkで$OBJTYPEを決めているsed正規表現パターンを修正する。

src/libmp、src/libsecにそれぞれarm/mkfileを追加する。中身はpower/mkfileのコピーでよい。386以外のアーキテクチャは何もしないようだ(がmkfileがないとビルドに失敗する)。

libthread

NetBSD-arm.asm.sが必要になるが、これはLinux-arm.asm.sのコピーでOK。

libthreadに関して少し補足すると、FreeBSDOpenBSDの実装がほぼ共通化されているのに対して、NetBSDの実装はLinuxと共通だったりおかしなことになっている。落ち着いたら実装見直した方がよさそうな気がする。

ucontext->uc_mcontext内の汎用レジスタのメンバ名がLinuxの場合はregsで、NetBSDの場合が__regsなので、Linux.cの該当箇所は(ちゃんとマクロ書いた方がよかったのだが)とりあえずifdefで回避している。

void
makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
{
        int i, *sp;
        va_list arg;
        
#ifdef __NetBSD__
        sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
        va_start(arg, argc);
        for(i=0; i<4 && i<argc; i++)
                uc->uc_mcontext.__gregs[i] = va_arg(arg, uint);
        va_end(arg);
        uc->uc_mcontext.__gregs[13] = (uint)sp;
        uc->uc_mcontext.__gregs[14] = (uint)fn;
#else
        sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
        va_start(arg, argc);
        for(i=0; i<4 && i<argc; i++)
                uc->uc_mcontext.gregs[i] = va_arg(arg, uint);
        va_end(arg);
        uc->uc_mcontext.gregs[13] = (uint)sp;
        uc->uc_mcontext.gregs[14] = (uint)fn;
#endif
}

cmd/vbackup

NetBSD 5.0以降はmount(2)の引数が一つ追加されているので、修正が必要だった。

#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 500000000
        if(mount("nfs", mtpt, mflag, &na, sizeof na) < 0)
#else
        if(mount("nfs", mtpt, mflag, &na) < 0)
#endif

ビルド

X11は使わないので、LOCAL.configに次のように書いておく。

WSYSTYPE=nowsys

./INSTALLでコンパイルが開始される。400 MHzのARMだと2時間近くかかるので覚悟すること。

とりあえず簡単なコマンドは動いているようだが、本格的に使い物になるのかはこれから検証していく予定。

*1:最大の敗因はMercurialを使わずにtar ballを展開して作業したことか