連載
» 2017年06月22日 05時00分 UPDATE

main()関数の前には何があるのか(6):Linuxカーネルのソースコードを読んで、システムコールを探る (1/3)

C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。前回まで、printf()内の中身をさまざまな方法で探り、write()やint $0x80の呼び出しまでたどり着いた。今回は、さらにその先にあるLinuxカーネル側のシステムコールを見ていく。

[坂井弘亮,著]

連載目次

ハロー“Hello,World” OSと標準ライブラリのシゴトとしくみ

書籍の中から有用な技術情報をピックアップして紹介する本シリーズ。今回は、秀和システム発行の書籍『ハロー“Hello, World” OSと標準ライブラリのシゴトとしくみ(2015年9月11日発行)』からの抜粋です。

ご注意:本稿は、著者及び出版社の許可を得て、そのまま転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。


※編集部注:前回記事「printf()のソースコードで、ソースコードリーディングのコツを身に付ける」はこちら

Linuxカーネルのソースコードを読んでみよう

 「Linuxカーネルのソースコードを読む」と言われると、ハードルが高いと感じてしまう読者のかたもいるかもしれない。

 しかしここで行うのは、本格的なコードリーディングではない。

 カーネル・ソースコードを読む際によく言われることは、何を知りたいかを決めて読む、ということだ。つまり、場所を限定して読むことだ。

 そしてここではシステムコールの処理に限定して読む。あまり気負わずに、気軽に読んでみよう。

Linuxカーネルのダウンロード

 Linuxカーネルの本家ダウンロードサイトは以下だ。

https://www.kernel.org/

 mainlineと呼ばれるものが、開発中の最新カーネルだ。本書執筆時点(※2015年9月)では、バージョン4系がmainlineになっている。

 それ以外はstable、longtermと呼ばれるものがある。stableは安定バージョン、longtermは長期メンテナンスが行われるバージョンだ。

 ところで、本書のCentOS環境のLinuxカーネルのバージョンはいくつだろうか。これはunameコマンドで調べることができる。

[user@localhost ~]$ uname -r
2.6.32-504.16.2.el6.i686
[user@localhost ~]$

 バージョンは2.6.32のようだ。

 本来ならば実行環境と同じバージョンのカーネルのソースコードを読むべきだが、システムコールの仕様は頻繁に変わるようなものではないので、それほど神経質にはならなくともいいだろう。

 本書執筆時点(※2015年9月)では、本家サイトでは2.6系のlong termカーネルの最新版として、2.6.32.65というバージョンのものがダウンロードできた。ということで本書では、2.6.32.65のカーネルを参照することにしよう。

 なお上記バージョンのカーネルは、本書のサポートサイトからもダウンロードできるようにしてある。本家サイトで見当たらなかったら、そちらからダウンロードできる。詳しくは連載第1回を参照してほしい。

ディレクトリ構成を見る

 まずは軽く、ディレクトリ構成を見てみよう。

[user@localhost ~]$ cd linux-2.6.32.65
[user@localhost linux-2.6.32.65]$ ls
COPYING		MAINTAINERS	arch	firmware	ipc	net		sound
CREDITS		Makefile	block	fs		kernel	samples		tools
Documentation	README		crypto	include		lib	scripts		usr
Kbuild		REPORTING-BUGS	drivers	init		mm	security	virt
[user@localhost linux-2.6.32.65]$

 様々なディレクトリがあるようだが、ディレクトリ構成をおおまかに説明しておこう。

 まず本書で重要な部分として、archはアーキテクチャ依存の処理、fsはファイルシステム関連、kernelはカーネルのアーキテクチャ共通の処理になる。さらにdriversは各種デバイスドライバ、includeは各種ヘッダファイル、mmは仮想メモリ関連、netはネットワーク関連だ。

 さてこの中で、いったいどこを見ていけばいいのであろうか。

 見たいのはint $0x80が呼ばれたときの処理だ。つまりシステムコール命令が呼ばれたときの処理だ。

 システムコールはCPUに対しての例外発行になる。これはいわゆるソフトウェア割込みなので、割込み処理にその入り口がある。そして割込み処理はCPUごとの独自処理となるため、アーキテクチャ依存の処理となる。

 アーキテクチャ依存の処理は、ディレクトリarchの中にある。つまりそこに、目的の処理があるはずだ。

 まずはディレクトリarchの中を確認しよう。

[user@localhost linux-2.6.32.65]$ cd arch
[user@localhost arch]$ ls
Kconfig	avr32		frv	m32r		microblaze	parisc	score	um
alpha	blackfin	h8300	m68k		mips		powerpc	sh	x86
arm	cris		ia64	m68knommu	mn10300		s390	sparc	xtensa
[user@localhost arch]$

 様々なアーキテクチャが存在しているようだが、中にはx86というディレクトリがある。ここにx86依存の処理があるのだと思われる。

 確認してみよう。

[user@localhost arch]$ cd x86
[user@localhost x86]$ ls
Kbuild		Kconfig.debug	boot	ia32	kvm	math-emu	pci	video
Kconfig		Makefile	configs	include	lguest	mm		power	xen
Kconfig.cpu	Makefile_32.cpu	crypto	kernel	lib	oprofile	vdso
[user@localhost x86]$

 ここにも様々なディレクトリがあるようだ。

目的の処理を探す

 ファイルやディレクトリが大量に存在しているのを見ると圧倒されてしまいがちだが、こういうときの調べかたにはコツがある。

 基本はgrepという、検索用のコマンドをうまく使うことなのだが、使いかたはそれほど難しくはない。システムコールの処理はどこにあるのか、grepで検索してみよう。

 問題は検索のためのキーワードなのだが、ここはセンスが問われるところだ。とりあえずシステムコールの処理なので「SystemCall」や「SYSTEMCALL」で検索してみよう。

[user@localhost x86]$ grep -r SystemCall .
[user@localhost x86]$ grep -r SYSTEMCALL .
[user@localhost x86]$

 とくに何も無いようだ。

grepコマンドは「-r」というオプションを付加することで、ディレクトリを再帰的に追いかけて検索してくれる。つまり上の例では、カレントディレクトリ以下のファイルを全検索している。


 次は「syscall」をキーワードにして検索してみよう。

[user@localhost x86]$ grep -r syscall .
./include/asm/ia32_unistd.h: * Only add syscalls here where some part of the kernel needs to know
./include/asm/ia32_unistd.h:#define __NR_ia32_restart_syscall 0
./include/asm/syscalls.h: * syscalls.h - Linux syscall interfaces (arch-specific)
./include/asm/sys_ia32.h: * sys_ia32.h - Linux ia32 syscall interfaces
./include/asm/unistd_64.h:/* at least 8 syscall per cacheline */
./include/asm/unistd_64.h:__SYSCALL(__NR_uselib, sys_ni_syscall)
...

 今度は大量にヒットした。ヒット数を見てみよう。

[user@localhost x86]$ grep -r syscall . | wc -l
618
[user@localhost x86]$

 600件以上もヒットしている。これくらいの数ならば、ヒットしたファイルをすべて調べていくことは不可能ではないが、まずは調べるファイルを限定していくことを考えたほうがいいだろう。

 さて、どのようにして範囲を狭めていけばいいだろうか。

       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。