linux-0.01 読み (7)

なんか emacs 起動直後に M-t でタグジャンプできなくって無理矢理 M-x gtags-find-tag するとそれ以降は M-r も M-s も C-t も OK になるみたい。これ一体何なんでしょ。

それは良いとして

ソースの中身を色々確認したログをちょろっとナニ。
ええと head.s から kickoff された init/main.c の main() 手続きが以下。

int main(void)		/* This really IS void, no error here. */
{			/* The startup routine assumes (well, ...) this */
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
	time_init();
	tty_init();
	trap_init();
	sched_init();
	buffer_init();
	hd_init();
	sti();
	move_to_user_mode();
	if (!fork()) {		/* we count on this going ok */
		init();
	}
/*
 *   NOTE!!   For any other task 'pause()' would mean we have to get a
 * signal to awaken, but task0 is the sole exception (see 'schedule()')
 * as task 0 gets activated at every idle moment (when no other tasks
 * can run). For task0 'pause()' just means we go check if some other
 * task can run, and if not we return here.
 */
	for(;;) pause();

	return 0;
}

main() 手続きに突入した時点では割り込みは disable なんですね。なんちゃら_init() な手続きも全部確認したい所ですが、こっちは明日以降の現実トウヒなネタとして残しておく事にしときます。
init() 手続きも今日はとりあえず置いておいて fork() がテーマ。

システムコール

main.c の先頭で以下な定義があります。

static inline _syscall0(int,fork)

_syscall0 マクロの定義は include/unistd.h の中で以下。

#define _syscall0(type,name) \
type name(void) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
	: "=a" (__res) \
	: "0" (__NR_##name)); \
if (__res >= 0) \
	return __res; \
errno = -__res; \
return -1; \
}

引数を取らないシステムコールをナニするマクロなのか。システムコールスタブ、というソレなのかな。inline なナニの書き方を忘れとるな。
ええと、__NR_fork が以下な定義。

#define __NR_fork	2

ちょっと別な事がしたいのでここらで止めますが、0x80 な割り込みの呼び出しと system_call.s な system_call な手続きとの対応は kernel/sched.c の sched_init 手続きの末端で呼び出される以下な手続きによる模様です。

	set_system_gate(0x80,&system_call);

上記、呼び出し時に ax レジスタに 2 が格納されてて、戻り時に ax にセットされた戻り値が __res に格納、みたいな理解で良いのかな。
ちなみに sys_call_table の中身は以下で (先頭部分のみ

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,

__NR_fork が指しているのが sys_fork となっている模様。このあたり掘りはじめるとキリが無いんですが、32bit マシンで gdb で云々してみたいのでこれで止めます。