(これは、CUSECというイベントでの、カーネルは怖くないという話の続き)
カーネルプログラミングを始めるにはどうしたらいいか、アドバイスを求めたことがある。その時は、こう回答があった。
- 仕事のためにカーネルを理解する必要がなくても、やってみたらどうだろう?
- Linuxカーネルメーリングリストに登録してみて、精一杯理解しようと頑張ってみよう。
- メインのLinuxカーネルの一部にならないコードを書いているなら、時間の無駄だ。
これは私にとっては、全然、少しも役に立たなかった。そんなわけで、ここでは、あなたなりにOSやLinuxカーネルがどう働くか、楽しみながら理解していくための、いくつかの戦略について書いてみたい。私はそれほどたくさんのことを知っているわけではないけれど、それでも以前よりはよく知っているつもりだ。
これらの方法のほとんどに関して、あなたはC言語と、ほんの少しのアセンブリ言語をいくらか理解する必要がある(最低でもコピー&ペーストできること)。私は、少しだけC言語のプログラムを書いたし、もうすっかり忘れてしまったがアセンブリ言語の講義も取ったものだ。
方法1 : 自分のOSを書く
これはちょっと恐ろしい方法に思えるかもしれない。でも、そんなことはない!私は、rustbootという、既に開発され動いているもの(これ重要)から始めた。すると、例えばスクリーンを赤の代わりに青にしたり、文字を表示したり、キーボードからの割り込みが動くようにすると言った、シンプルなことができるようになった。
MikeOSも、始めに触るのが楽しそうなものの一つだ。あなた自身のOSと言っても、巨大でプロ向きなものである必要はないことを忘れないようにしよう。スクリーンを赤の代わりに紫にできたり、5行詩を表示できたのなら、それで成功だ。
あなたのOSを動かすのに、qemuのようなエミュレータを使いたくなるかもしれない。OSDev_wikiは役に立つだろう。途中に起きるであろう問題に関するたくさんのFAQがある。
方法2 : カーネルモジュールを書く
もう既にLinuxを動かしているなら、何もしないカーネルモジュールを書くことぐらいは簡単なことだ。
これが「Hello, hacker school!」とカーネルログに表示するモジュールのソースだ。18行だけのコードだ。基本的に、初期化とクリーンアップの関数を登録すれば、それでおしまいだ。実は私は、__init
と__exit
マクロが何をしているのかもよくわかっていないけれど、使ってしまった!
何らかの処理をするカーネルモジュールを書くのは、もう少し難しい。私は、何をするのかを決めて(例えば、カーネルをパケットが通過するたびにメッセージを書き込む、など)、それからKernel Newbiesの記事をいくつか読み、たくさんググって、どうやってやるのかの答えを見つけるためにたくさんのコードをコピペした。私が書いたカーネルモジュールの例のいくつかは、kernel-module-funリポジトリに置いてある。
方法3 : Linuxカーネルインターンシップに参加する
LinuxカーネルはGNOME Outreach Program for Womenに参画している。このプログラムは、非常に素晴らしく、楽しいものだ。どういうことかというと、あなたが女性で、3か月間カーネルに関する仕事ができるなら、それまで経験がなくてもカーネル開発に関わることができる上に、給料まで支払われる(5000ドル)というものだ。どういう仕組みかについてのKernel Newbiesの記事もある。
興味があるならこれに申し込んでみる価値はある。カーネルパッチを書くのに取りかかろう。それは楽しいことだ。このプログラムをコーディネートしてくれているLinuxカーネル開発者のSarah Sharpさんは、とても魅力的な人だ。彼女のブログの、プログラムの第1期の間にカーネルに取り込まれた137のパッチに関する記事は読んでみるべきだ。これらのパッチはあなたのものだ!申し込み方法を確認しよう。
もしあなたが女性でないなら、Google Summer of Codeが同じようなイベントになるだろう。
方法4 : カーネルコードを読む
これはひどいアドバイスに聞こえるかもしれない。「カーネルがどう動くか知りたい?ソースを読めよバカ!」
でもこれは楽しいことだ!何にも理解できないかもしれない。私も、何もわからなくてバカになった気がしたけれど、他の人に聞いてみても「そうだよ、それがLinuxカーネルさ!」と口をそろえて言うものだ。
友人のDaveが最近、カーネルソースをオンラインで読めるLXRを教えてくれた。ここでは、たくさんの役に立つクロスリファレンスのリンクがある。例えば、chmod
システムコールを理解したいなら、Linuxカーネルのchmod_common定義部分を見ればいいというわけだ!livegrep.comも同じような用途にはとてもいいサービスだ。
私がコメントをつけたchmod_common
のソースコードがこれだ。
static int chmod_common(struct path *path, umode_t mode)
{
struct inode *inode = path->dentry->d_inode;
struct iattr newattrs;
int error;
// 何しているか不明
error = mnt_want_write(path->mnt);
if (error)
return error;
// ミューテックスだ! 競合しないように! =D
mutex_lock(&inode->i_mutex);
// chmodの権限を確認している。。。んだと思う
error = security_path_chmod(path, mode);
if (error)
goto out_unlock;
// ここでモードを変更しているはず!
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
error = notify_change(path->dentry, &newattrs);
out_unlock:
mutex_unlock(&inode->i_mutex); // 処理終了したのでmutexも解放!
mnt_drop_write(path->mnt); // ???
return error;
}
こういったことは楽しい時間で、カーネルの中身を詳しく知るのに役立つんだと気づいた。ほとんどのコードについてははっきり理解できてはいないが、(このchmodのコードのように)一部については少し分かりやすい部分もある。
リンクをまとめると、
- KspiceブログのJessica McKellarさんのブログ記事
- Linuxデバイスドライバでは、それ自体を以下のように書いている。これは便利だ。
この本は、あなた自身のドライバをどう書くかと、カーネル周辺の関連事項をどうハックするかを教えるものだ。
- OSDev wikiは、OSを自分で書くなら素晴らしいサイトになる。
- Kernel Newbiesはカーネル開発者の最初の一歩になるリソースだ。私はIRCチャンネルではあまりいい経験がない。
- Sarah Sharpさんは、カーネル開発者で、Linuxカーネル奉仕活動をしており、素晴らしい人だ。
- LWN.netのValerie Auroraさんの投稿
あなたの意見もぜひとも聞きたい。もし既にカーネルの仕事をしているなら、カーネルハッキングはどこから始めたのだろう?もしまだしていないなら、どのやり方があなたにとって一番アプローチしやすいだろう?