
% bdftopcf hoge.bdf > hoge.pcf
% gzip hoge.pcf
# cp *.pcf.gz /usr/X11R6/lib/X11/fonts/misc/
# mkfontdir /usr/X11R6/lib/X11/fonts/misc/
# vi fonts.alias (fonts.aliasに、aliasを追加)
# xset fp rehash
% kterm -fn a10 -fr r10 -fk k10
ナガ10をいれてみたが、あまりにもフォントが小さすぎた・・・
ので、mplusをinstallして使うことにした。
mplusの作者に感謝!!
<http://www-3.xdsl.ne.jp/~coz/comp/mplus/j-fonts/index.html>
<http://kappa.allnet.ne.jp/kanou/fonts/x11bdfs.html>
<http://ezine.daemonnews.org/2002/02/japanese-netbsd.html>
を参考に、日本語環境を構築することにした。
sushiは、なぜか動作しなかったので、手動でinstallする。
(ftpでIPv6を使っているため?)
# usermod -G wheel <username> (userをwheelグループに追加する)
# setenv PKG_PATH ftp://ftp.jp.netbsd.org/pub/..../All
# pkg_add bash
# pkg_add kterm
# pkg_add ja-less
# pkg_add w3m
# pkg_add Canna-server
# pkg_add kinput2
NetBSDでのクロスコンパイルの方法
<http://ezine.daemannews.org/200211/xdevnetbsd.html>
インストール失敗。
gameのインストール中にsegmentation falutで止まった X-<
gameを選択しないでインストールしたら、ちゃんとinstallできた。
install後やった事
-/etc/rc.confで、dhclient=YES
-# useradd -m hogehoge (mは、homedirを作成する。hogehogeはユーザ名)
-/etc/wscons.confに、encoding jpを追加
-dateで、時刻の修正
-xf86setupで、Xの設定
mouseは、wsmouse
videoは、ATI rageII 2MB
-% cp /usr/X11R6/lib/X11/xinit/xinitrc ~/.xinitrc
Jason R. Thorpe氏の"A Machine-Independent DMA Framework for NetBSD"
のps版をdownloadした。
BSD Magazineの和訳をよんでみたけど、さっぱり理解できないので
原文を読む事にしたのである。
<http://www.netbsd.org/Documentation/kernel/programming.html>
<http://www.jp.netbsd.org/ja/Documentation/kernel/programming.html>
kern_clock.cのsoftclock()では、softclock_ticksを1進め、
その時刻に対応するcalloutがあれば、関数をcallしている。
タイムアウト時刻のhashごとにqueueを持っているが、queue内の
一番近いtimeout値をcq_hintに保持している。
・・・はずなのだが、queue内の走査時に、
if (c->c_time != softclock_ticks) {
if (c->c_time < bucket->cq_hint)
bucket->cq_hint = c->c_time;
...
}
と、cq_hintの再設定をしている。なぜ?
sessionとprocess groupsとはなんだ?
process group leaderなprocessは、session leaderには
なれないらしいが・・・(man setsidより)
以下のページを発見。
<http://www.freebsd.org/doc/ja_JP.eucJP/books/design-44bsd/x257.html>
<http://homepage1.nifty.com/~tetsu/ruby/tool/daemon.html>
-プロセスグループは、シグナルの影響する範囲に関係する。
-シェルからlogoutすると、起動していたプロセスにシグナルが送られる。
-セッションは、プロセスグループの集合らしい。
kern_proc.cより
int inferior(struct proc *p, struct proc *q) {
for (; p != q; p = p->p_pptr)
if (p->p_pid == 0)
return 0;
return 1;
}
ここで、終了条件は
1. p == q
2. p->p_pid == 0
と二つあるわけだが、上記のコードでは1.をforの中に使用して、2.を
ifで使用している。
自分なら、何も考えずに以下のようにしてしまいそうだ。
for (; p->p_pid != 0; p = p->p_pptr)
if (p == q)
return 1;
return 0;
この関数の意図としては、pqが成り立つ方がおそらく多いのだろう。qの条件判断がpid
その場合、p0よりも先に来ている前者のqの場合、前者は条件判断1回、後者は2回である。
コードの方がちょっとだけ高速になる。
極端な例では、引数の時点でp
終了条件をどこに持って来るかというのも、良く考えねば。
kthread_createは、kthreadの作成が必ずinit(8)の作成後になるように
保証する機能がある。
kthread_createは・・・
init(8)作成前なら、コールバック関数をkthread_qに溜める。
init(8)作成後なら、コールバック関数を直接呼ぶ。
kern_mainでは、init(8)作成後にkthread_run_deferred_queue()を呼ぶ。
kthread_run_deferred_queue()は、kthread_qに溜っている全関数を呼ぶ。
実際のkthreadの作成は、コールバック関数がkthread_create1()を呼ぶ時に
行われる。
kthread_createに十分な情報を引数として渡して、kthread_run_deferred_queue()
が直接kthread_create1()をコールすれば良い気もするが、各createルーチンでは、
kthread_create1()を呼ぶだけではなく、ちょっとした条件判断等も行っている。
そのため、kthread_run_deferred_queue()での一括createは行えない。
SLPQUEは、SSLEEPとSSTOPなprocessが入る場所。
ltsleeo():
timeoutが指定されていたら、callout_resetでendtsleepを指定。
mi_switch()をコール。
endtsleep(p):
pのstatがSSLEEPなら、setrunnable()をコール。STOPならunsleepをコール。
unsleep():
SLQPから外す。
awaken():
wakeup()かwakeup_one()から呼ばれる。
statをSRUNにし
P_INMEMなら、setrunque()をコールし、need_resched()をコール
!P_INMENなら、swapperをsched_wakeupする。
sched_wakeup:
SLPQでident(wchan)が一致し、かつstatがSSLEEPのprocに対して
awaken()を呼ぶ。
SSTOPの場合SLPQから外すだけっぽい。
(SLPQに入っているのは、SSLEEPかSSTOPのprocのみ)
wakeup():
ロックして、sched_wakeup()を呼ぶ。
wakeup_one():
ロックして、SSLEEPのprocのうち、priorityの一番小さいものを起こす。
いなかったら、SSTOPのうち、priorityの一番小さいものを起こす。
yield():
自らcontext switchをする。余り使用されていないようだ。
preempt(newp):
newpにpreemptする。(今はpreempt機能は未実装で、yieldと同じ動作をする)
mi_switch():
issignal()、ltsleep()、yield()、preempt()から呼ばれる。
経過時間などを記録し、cpu_switch()をコール。
setrunnable():
SSTOPでもSSLEEPでもrunnableに戻す。
unsleep()し、awaken()と同じような事(P_INMEMなら〜)をする。
awaken()とは、need_reschedを必ず呼ぶかどうかが異なる?
setrunqueue(p):
pをrunqueに入れる。
remrunque(p):
pをrunqueから外す。
-1secにhz回、kern_clock:hardclockが呼ばれる。
-hardclock()は、processのrrticksを1減らし、0以下になったら
roundrobin()をコールする。
-roundrobin()は、rrticksをセットし直し、need_resched()をコールする。
rrticksは、initclockでhzの1/10に初期化される。つまり、100msec毎に
roundrobin()が呼ばれる。
-need_resched()では、ast(asynchronous system trap)フラグを1にする。
kernelモードからuserモードに戻る際、フラグが1ならpreemptする。
-pool_cache_getは、cacheに何も無い時はpool_getし、constructorを
コールする。pool_cacheにobjectがある場合は、それを返す。
-pool_cache_putは、pool_cacheにobjectを返す(その時に
destructorは呼ばない)。一つのpool_cacheには16個のobject(の
ポインタ)を格納できるが、足りなくなったらcacheをallocateする。
-destructorが呼ばれるのは、pool_cacheからbackendのpoolに戻される時。
-pageが残り少なくなって来たら、pagedaemon(uvm)がpool_drain()を
コールする。すると、未使用pool_cacheが破棄される。
ようやくqueue.hを理解した。
LIST : 双方向リスト
SLIST : singly-linked list。remove時に前の要素のnextポインタの
設定のため、前の要素をlistをたどって検索する必要あり
SIMPLEQ : SLISTと基本的には同じだが、headが最後の要素の
nextへのポインタを持っているため、INSERT_TAILが可能。
SLISTと異なり、removeはREMOVE_HEADしか用意されていない。
TAILQ : LISTで、headが最後の要素へのポインタを持っている。
TAILQ_FOREACH_REVERSEは、varの一つ前の要素を指すために、
prevのprevのnextというように、逆順にたどって行く。
CIRCLEQ : headも含んだ双方向リスト。ただ、他のリストとは異なり、
prevは、前の要素のnextへのポインタ(**)ではなく、
要素へのポインタ(*)である。
また、headはfirstとlastへのポインタを持っている。
subr_pool.cを読むのは、明日にしよう。
NetBSDのqueueのentryは、
struct xxx {
struct yyy *next;
struct yyy **prev;
};
と、なっている。図示すると、
elm1 elm2
+-------+ --->+-------+
+field+ | | +field+
| next----- | | |
| ↑------------prev|
+-+-----+ +-+-----+
分りにくいな・・・
nextは、次の要素(elm2)を指している。
prevは、前の要素(elm1)を指す必要は無くて、前の要素のnextポインタさえ
指していれば、リスト操作ができる。
nextも次の要素のnextポインタを指してしまうと、リスト操作はできるが
elmの他の要素を(ストレートには)見ることができなくなってしまう。
# linuxではそのようになっていて、offsetof()でnextからelmの位置を
# 無理矢理出していたような気がする
OpenBSDは、Theo(セオ)氏の揉め事がきっかけで、NetBSDから分裂
したものらしい。
<http://freebsd.flathill.gr.jp/~flathill/FreeBSD/chat/log/1999/log990531-0601.html>
<http://cruel.org/openbsd/>
Porting BSD UNIX to a New Platform
by Lawrence Kesteloot
<http://tofu.alt.net/~lk/291.paper/291.paper.html>
NetBSDでのカーネルの構築の方法
<http://www.jp.netbsd.org/ja/Documentation/kernel/>
Linux(debian)の構築方法は、何回見ても覚えれなかったが、
これなら覚えれそう。
15:33に、make開始。
16:04終了。30分しかかかってないけど、こんなもんなのか?
昔は、一晩とかかかっていたような気がするんだけど・・・
softc構造体とは、Software Contextの略で、
デバイスのプライベートな情報を格納するらしい。
<http://www.ht.sfc.keio.ac.jp/move/momodoc/usbdriver>
NetBSDのrcスクリプトは、スクリプト間の依存関係が記述されている。
そのため、rc.0, rc.1や、010inetc等のように、ファイル名や
ランレベルで依存関係を処理しなくて良い。
<http://www.jp.netbsd.org/ja/Documentation/rc/>
/etc/rcを見てみると、rcorderコマンドで、実際に
起動する順序をきめているようだ。
次号は9/13発売。NetBSDの内部構造の解説があるらしい。
絶対に買わねば
特集1 NetBSDの設計と実装
特集2 セキュアプログラミングのすすめ
<http://www.ascii.co.jp/BSDmag/next/index.html>
一応UVMのページを書いておこう
<http://ccrc.wustl.edu/pub/chuck/tech/uvm/>
webでUVMの資料をさがしたが、これくらいしか見付からなかった。
英語のページなら、いろいろあるのかも知れないが。
UVMの勉強中
<http://www.netbsd.org/Documentation/kernel/uvm.html>
にある、Charles Cranorのpaperを読んでみるが、英語なので
眠くなって来る・・・