linux-0.01 読み (12)

オンラインで読む会、をやりたいんですが、よく考えたら wiki が必要だなぁ。android.shuri.jp 使っても良いか確認を取ってみよう。

昨晩 fork の途中で終了したんですが、どうもこのあたり、struct task_struct 型な属性の確認が必要になる模様。linux-0.01 だと copy_process は

  • スペース確保して
  • エラーチェックして
  • コピーして?
  • 初期化

みたいなカンジなのかどうか。

	p = (struct task_struct *) get_free_page();
	if (!p)
		return -EAGAIN;
	*p = *current;	/* NOTE! this doesn't copy the supervisor stack */
	p->state = TASK_RUNNING;

struct task_struct 型の current は sched.c で大域な変数として定義されてて、

struct task_struct *current = &(init_task.task), *last_task_used_math = NULL;

include/linux/sched.h で extern な宣言されてる模様。ええと、init_task は sched.c にて定義されてますな。

static union task_union init_task = {INIT_TASK,};

INIT_TASK は include/linux/sched.h で以下なコメントが付いてます。

/*
 *  INIT_TASK is used to set up the first task table, touch at
 * your own risk!. Base=0, limit=0x9ffff (=640kB)
 */
#define INIT_TASK \

中身は略。あと、task_union な共用体は sched.c で以下な定義。

union task_union {
	struct task_struct task;
	char stack[PAGE_SIZE];
};

なんでこんな事してるのかは不明。とは言え INIT_TASK は何らかの工夫をした部分だったりするんだろうな。このあたりも掘削しがいのある部分かも。

本題

実はこの copy_process 手続きで初期化されてる属性を確認してみたら良いのかな、と思った次第でして。
例えばいっちゃん最初の

	p->state = TASK_RUNNING;

な属性。これは未だに残ってる超有名なナニですが、ソースツリーのてっぺんで find|xargs grep した結果が以下。

$ find |xargs grep state
Binary file ./system matches
./kernel/traps.c: * state in 'asm.s'. Currently mostly a debugging-aid, will be extended
./kernel/system_call.s:state    = 0             # these are offsets into the task-struct.
./kernel/system_call.s: cmpl $0,state(%eax)             # state
./kernel/exit.c:                current->state = TASK_ZOMBIE;
./kernel/exit.c:                                if ((*p)->state==TASK_ZOMBIE) {
./kernel/console.c:static unsigned long state=0;
./kernel/console.c:             switch(state) {
./kernel/console.c:                                     state=1;
./kernel/console.c:                             state=0;
./kernel/console.c:                                     state=2;
./kernel/console.c:                             state=3;
./kernel/console.c:                             } else state=4;
./kernel/console.c:                             state=0;
./kernel/fork.c:        p->state = TASK_RUNNING;
./kernel/sched.c: *  'math_state_restore()' saves the current math information in the
./kernel/sched.c: * old math state array, and gets the new ones from the current task
./kernel/sched.c:void math_state_restore()
./kernel/sched.c: * tasks can run. It can not be killed, and it cannot sleep. The 'state'
./kernel/sched.c:                       if ((*p)->signal && (*p)->state==TASK_INTERRUPTIBLE)
./kernel/sched.c:                               (*p)->state=TASK_RUNNING;
./kernel/sched.c:                       if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
./kernel/sched.c:       current->state = TASK_INTERRUPTIBLE;
./kernel/sched.c:       current->state = TASK_UNINTERRUPTIBLE;
./kernel/sched.c:               tmp->state=0;
./kernel/sched.c:repeat:        current->state = TASK_INTERRUPTIBLE;
./kernel/sched.c:               (**p).state=0;
./kernel/sched.c:               tmp->state=0;
./kernel/sched.c:               (**p).state=0;
./kernel/asm.s: call math_state_restore
Binary file ./GTAGS matches
Binary file ./GSYMS matches
./boot/boot.s: * that we enter the kernel in a known state, and
./include/linux/sched.h:        long state;     /* -1 unrunnable, 0 runnable, >0 stopped */
./include/linux/sched.h:/* state etc */ { 0,15,15, \

長いスね。。
とは言えなんとなく fork.c と sched.c のみで使用されているのが分かります。あと、状態を表現するマクロの定義が include/linux/sched.h にて以下。

#define TASK_RUNNING		0
#define TASK_INTERRUPTIBLE	1
#define TASK_UNINTERRUPTIBLE	2
#define TASK_ZOMBIE		3
#define TASK_STOPPED		4

それぞれ、どーいった状態か、をソース根拠で確認するのは良いかも。ちなみに TASK_STOPPED は grep で代入してる箇所を見つけられんかった。これ、シグナル契機な解説が詳解 Linux カーネルにありますが、プロセスの状態遷移なマンガとかどっかに無いかな。

とりあえず

wiki の使用について確認を入れます。