システム奮闘記:その72

Linuxのinitrdファイルって何?



Tweet

(2008年8月23日に掲載)

  initrdファイルといえば、カーネルイメージと共にあるファイルだ。
  そして、Linuxの起動する際のブートローダーのLILOでもGRUBでも
それぞれの設定ファイルで、initrdファイルを取り込もうとしている。

initrdファイルの設定
LILOの設定(/etc/lilo.conf)
prompt
timeout=50
default=linux
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
message=/boot/message
lba32

image=/boot/vmlinuz-2.4.20-8
        label=linux
        initrd=/boot/initrd-2.4.20-8.img
        read-only
        append="hdc=ide-scsi root=LABEL=/"
GRUBの設定(/boot/grub/menu.lst)
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS-4 i386 (2.6.9-42.EL)
        root (hd0,0)
        kernel /vmlinuz-2.6.9-42.EL ro root=LABEL=/1 rhgb quiet
        initrd /initrd-2.6.9-42.EL.img
赤い部分は、共にブートローダーがカーネルを読み込む際
initrdファイルを読み込む設定の部分だ。

  今まで、initrdファイルが何であるか、興味もなかった上、
Linuxの本を見ても、よくわからなかったので、長い間、放置していた。
  だが、「システム奮闘記:その71」でブートローダーのGRUBの事を取り上げた時

  initrdファイルって一体何やねん!

  だった。
 
  もちろん人に説明できない。
  これ以上、隠し通す事はできない ← これを隠蔽という (^^)


  この時点で勘の良い読者の方は「カーネルの再構築をやった事がないな」
と思われるでしょう。
  でも反論します。

  Linux-2.4系カーネルなら何度も再構築したのだ (^^)

  だが、initrdファイルが何に使うのかは、全くわからなかった。
  そして、initrdファイル作成の方法もわからなかった。

  なので、カーネル再構築をした後、initrdファイルは取り込む設定は
行わなかった。


  先に、なぜ支障がなかったのかを言いますと

  日本男児たるもの、モジュールは使わへんのだ!!

  と叫び、必要な物だけを取り込み、モジュールを一切使わなかった。

カーネル再構築でオプション選択の様子
拡大させると
必要な項目やドライバだけを取り込んで、それ以外は取り込まない。
モジュールの設定は全く行わなかった。

もちろん、日本男児とモジュールの関連性はないのだが・・・。

  なので、initrdファイルがなくても、全く支障がなかったのだ。

 だが、それはLinux-2.4系までの話だった。
 Linux-2.6系になってからは、機能拡張によって、知らないオプションが増え
しかも、オプションの意味が理解できなかった。
 そのため、モジュールなしで再構築ができない状態になったため

  Linux-2.6系では再構築ができないのらー!!

 なのだ。

 Linux-2.6系が出ても、Linux-2.4系を使いつづけた私。
 そのため、initrdファイルの事を知る必要はなかった。


 だが、年貢の納め時は来る。
 GRUBの話を取り上げた時だった。
 詳しくは「システム奮闘記:その71」(ブートローダー GRUBの設定の話)をご覧ください。
  設定ファイルに、initrdファイルの取り込み方が書いてあった。

 私は思った。
  もし、読者の方から「initrdファイルって何?」と聞かれても答えられない。
 その上、放置しておくのも、良くないはず。

 もう逃げられへんやろ・・・ (^^;;

  観念した私はinirdファイルが何かを調べる事にした。

  そこで今回は、initrdファイルの話とモジュールについての話を
書きたいと思います。

initrdファイルとの出会い  initrdファイルとの出会いだが、2004年まで遡る。 PPTP方式でインターネットVPNを行う必要があった。  カーネルのバージョンが2.4系の場合、カーネルにパッチをあてて カーネル再構築を行う必要があった。  詳しくは「システム奮闘記:その27」 (PPTP方式でインターネットVPN)をご覧ください。 RedHat7.3を使っていたので次の本を手にとった。 「RedHat Linux7で作る ネットワークサーバ構築ガイド」 (サーバー構築研究会 編著:秀和システム)  カーネル再構築の所に「イニシャルRAMディスクイメージの作成」が 載っていた。だが、説明を読んでも・・・ 内容が理解できへん (TT) だったので、本の丸写しで作成した。 その後、カーネル再構築をする何度も機会出てきた。  その際に、initrdファイルを設定しなくても、問題なく動いたので initrdファイルの設定を行わなくなった。  なぜ、問題なく動いたのかについて、全く追求する事なく、 initrdファイルは「何かのおまじないだろう」の程度で放置し、 そして、ズルズルと、そのまま過ごしていたのだった (^^;;

initrdファイルって何やねん!

initrdファイルとは、一体、何なのか?  色々な本やサイトを調べていくと、次のような記述がある。  「RAMディスク上で展開するファイル」  「メモリ上に展開されるファイル」  せやけど・・・  よくわからへん (TT)  だった。  別に、RAMディスクを使っていないのに「RAMディスク上で展開する」と 書いてあっても、ピンとこない。 調べていくうちに「initrd」が何の略語かを知る。  Inital RAM Disk の略語なのだ。 RAMディスク、即ち、メモリ上に作ったディスクを初期化するというのだ。  でも、これだけだと、ピンとこない。  諦めずに調べていくうちに、次のサイトに行き着いた。 「路地裏 ソース解読研究所」(initrdのその中へ:ミラクルリナックス社) サイトに書かれている通りにやってみる。
initrdファイルの種類を見てみる
[root@server]# file ./initrd-2.6.18-53.el5.img 
./initrd-2.6.18-53.el5.img: gzip compressed data, from Unix, 
last modified: Fri Aug  8 08:15:03 2008, max compression
[root@server]# 
initrdファイルがgzipで圧縮されたファイルである事を
初めて知った。

 そこでinitrdファイルを解凍してみる。

initrdファイルの解凍
[root@server]# ls
initrd-2.6.18-53.el5.img
[root@server]# mv initrd-2.6.18-53.el5.img initrd-2.6.18-53.el5.gz
[root@server]# gzip -d initrd-2.6.18-53.el5.gz
[root@server]# ls
initrd-2.6.18-53.el5
[root@server]# 
initrdファイルの拡張子を「gz」に変更した後で
gzipで解凍してみたら、解凍できた。

 次に、cpioコマンドを使って展開するというのだ。

initrdファイルの展開
[root@server]# cat initrd-2.6.18-53.el5 | cpio -id
13734 blocks
[root@server]# 
Linux(UNIX)上でファイルを、ひとまとめにしたり、
展開するためのコマンドは、tarコマンドだと思っていたが、
この時、初めてcpioコマンドで、ファイル群をひとまとめにしたり
展開する事ができるのを知った。

 そして、lsコマンドで展開した後を見てみる。

initrdファイルを展開した後を見てみる
[root@server]# ls
bin  dev  etc  init  initrd-2.6.18-53.el5  lib  proc  sbin  sys  sysroot
[root@server]#

 色々、ディレクトリが存在してみる。
  なので、各ディレクトリを見てみる事にした。

libディレクトリ
[root@server lib]# ls
ata_piix.ko     ext3.ko      mptspi.ko
dm-mirror.ko    firmware     ohci-hcd.ko
dm-mod.ko       jbd.ko       scsi_mod.ko
dm-snapshot.ko  libata.ko    scsi_transport_spi.ko
dm-zero.ko      mptbase.ko   sd_mod.ko
ehci-hcd.ko     mptscsih.ko  uhci-hcd.ko
[root@server lib]# 
各種ドライバが格納されていた。

  次に、binディレクトリを見てみる。

binディレクトリを見てみる
[root@server bin]# ls
dmraid  insmod  kpartx  lvm  modprobe  nash
[root@server bin]# 
何やら実行ファイルが置かれている。

 そして、devディレクトリを見てみる。

devディレクトリを見てみる
[root@server dev]# ls
console  ram   systty  tty10  tty3  tty7   ttyS1
mapper   ram0  tty     tty11  tty4  tty8   ttyS2
null     ram1  tty0    tty12  tty5  tty9   ttyS3
ptmx     rtc   tty1    tty2   tty6  ttyS0  zero
[root@server dev]# ls
各種デバイスのファイルがある。

 これらを見ていると、なんだか小さなLinuxのような気がする。

 さて、initファイルがある。
 この中身を見てみる事にした。

initファイル
#!/bin/nash

mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
echo Mounting sysfs filesystem
mount -t sysfs /sys /sys
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mkdir /dev/pts
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
mkdir /dev/shm
mkdir /dev/mapper
echo Creating initial device nodes
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mknod /dev/systty c 4 0
mknod /dev/tty c 5 0
mknod /dev/console c 5 1
mknod /dev/ptmx c 5 2
mknod /dev/rtc c 10 135
mknod /dev/tty0 c 4 0
mknod /dev/tty1 c 4 1
mknod /dev/tty2 c 4 2
mknod /dev/tty3 c 4 3
mknod /dev/tty4 c 4 4
mknod /dev/tty5 c 4 5
mknod /dev/tty6 c 4 6
mknod /dev/tty7 c 4 7
mknod /dev/tty8 c 4 8
mknod /dev/tty9 c 4 9
mknod /dev/tty10 c 4 10
mknod /dev/tty11 c 4 11
mknod /dev/tty12 c 4 12
mknod /dev/ttyS0 c 4 64
mknod /dev/ttyS1 c 4 65
mknod /dev/ttyS2 c 4 66
mknod /dev/ttyS3 c 4 67
echo Setting up hotplug.
hotplug
echo Creating block device nodes.
mkblkdevs
echo "Loading uhci-hcd.ko module"
insmod /lib/uhci-hcd.ko 
echo "Loading ohci-hcd.ko module"
insmod /lib/ohci-hcd.ko 
echo "Loading ehci-hcd.ko module"
insmod /lib/ehci-hcd.ko 
mount -t usbfs /proc/bus/usb /proc/bus/usb
echo "Loading jbd.ko module"
insmod /lib/jbd.ko 
echo "Loading ext3.ko module"
insmod /lib/ext3.ko 
echo "Loading scsi_mod.ko module"
insmod /lib/scsi_mod.ko 
echo "Loading sd_mod.ko module"
insmod /lib/sd_mod.ko 
echo "Loading scsi_transport_spi.ko module"
insmod /lib/scsi_transport_spi.ko 
echo "Loading mptbase.ko module"
insmod /lib/mptbase.ko 
echo "Loading mptscsih.ko module"
insmod /lib/mptscsih.ko 
echo "Loading mptspi.ko module"
insmod /lib/mptspi.ko 
echo "Loading libata.ko module"
insmod /lib/libata.ko 
echo "Loading ata_piix.ko module"
insmod /lib/ata_piix.ko 
echo "Loading dm-mod.ko module"
insmod /lib/dm-mod.ko 
echo "Loading dm-mirror.ko module"
insmod /lib/dm-mirror.ko 
echo "Loading dm-zero.ko module"
insmod /lib/dm-zero.ko 
echo "Loading dm-snapshot.ko module"
insmod /lib/dm-snapshot.ko 
echo Waiting for driver initialization.
stabilized --hash --interval 250 /proc/scsi/scsi
mkblkdevs
echo Scanning and configuring dmraid supported devices
echo Scanning logical volumes
lvm vgscan --ignorelockingfailure
echo Activating logical volumes
lvm vgchange -ay --ignorelockingfailure  VolGroup00
resume /dev/VolGroup00/LogVol01
echo Creating root device.
mkrootdev -t ext3 -o defaults,ro /dev/VolGroup00/LogVol00
echo Mounting root filesystem.
mount /sysroot
echo Setting up other filesystems.
setuproot
echo Switching to new root and running init.
switchroot
モジュールを取り込むシェルの感じだ。

(注意)
nashというシェルだが、RedHat系独特の物らしい。
他のディストリビューションでは、別の方法らしいが
確認していないので、何とも言えない。

 ここまで見て、initrdファイルが展開される事がわかった。
 そして、モジュールをカーネルに装着させるのも、わかった。


  もし、ブートローダーの設定で、initrdファイルを
読み込まないようにしたら、どうなるのか。
 早速、やってみた。

もし、initrdファイルを読み込まない場合は
GRUBの設定 (menu.lstファイル)
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS-4 i386 (2.6.9-42.EL)
        root (hd0,0)
        kernel /vmlinuz-2.6.9-42.EL ro root=LABEL=/1 rhgb quiet
        #initrd /initrd-2.6.9-42.EL.img
initrdファイルを読み込まないようにしてみた。
そしてLinuxを再起動させてみると、以下の画面が出てきた。
カーネルパニックの様子
カーネルパニックを起こして、カーネルが起動しなくなる。
そのため、initrdファイルが大事な物である事がわかる。

 initrdファイルが起動時に重要な役割を果たす事がわかったが、
具体的に、どんな役割を果たすのかについては、まだ見えてこない。


 こんな時は

 モヤモヤ感が残るのらー!!

 そこで引き続き、すっぽんの如く、食い下がらずに調べていくことにした。

 すると、次のサイトに行き着いた。
 「ソースコード・リテラシーのススメ」(技術評論社のサイト)


 内容では、最初に、モノシリックカーネルとマイクロカーネルの違いついて
書かれていた。
 えらい所まで辿り着いたなぁと思いつつ、モノシリックカーネルや
マイクロカーネルがどんな物かを知らないだけに読む事にした。



 モノシリックカーネルは、Windows9X系、UNIXカーネル、
そして、Linuxで採用されている。

モノシリックカーネルとは何か
カーネルが全ての機能を抱えこんだ形態をとっている。
開発が行いやすいという利点があるようだ。

だが、機能が増加したり、ドライバの数が増加すると
カーネルが肥大化する問題が発生する。

 もう一方は、マイクロカーネルと呼ばれるものだ。
 WindowsNT系に採用されている。

マイクロカーネルとは
カーネルそのものは、OSの機能を最小限にとどめ、
その他の機能は全て外部に出して動かす仕組みだ。

各機能がカーネルの外部にあるため、連携させるには
プロセス間通信を使うのだが、この部分でに負荷がかかり
思ったような性能が出せない問題があるようだ。

 モノシリックカーネルとマイクロカーネルとの論争では
Linuxを作ったリーナスさんと、minixのタネンバウム教授の間で
激しい論争があったのは有名だ。

 でも、「論争があった」という事は知っていても、
具体的に、どんな論争だったのかはわからなかった。
 今回の記事のおかげで、OSの設計思想の違いについて
論争があった事を知った (^^)


 ところで、ここでは論争の話には触れません。
 だって、事務員の私にカーネルの設計の話や議論の内容について

 書けるほどの知識はないもーん (^^)

 と書いて逃げる私。


  モノシリックカーネルを採用したLinux。
 だが、Linuxの機能が増えるにつれ、
次の問題が発生するようになった。

こんな問題が発生
モノシリックカーネルの設計では、OSの全ての機能や
各種ドライバをカーネル内部に取り込む形態になっている。

そのため機能が増加すれば、カーネルが大きくなる。
OSの機能だけでなく、ハードウェアが増加すれば、
それに対応するドライバの数も増えていくため
どんどんカーネルが肥大化する道を歩む事になった。

もちろん、この問題をリーナスさんは知らなかったわけではない。

 肥大化だけが問題ではない。
 カーネルの肥大化による弊害が出てくるのだ。

カーネルの肥大化による弊害
全てのドライバ等を取り込む事で、各ドライバが干渉しあう事がある。
ドライバ同士、干渉しあう事によって、カーネルの稼働が
不安定になったりする。不安定なカーネルの要因だ。

人間の体でも肥満体になれば、各所に問題が発生し、
体全体が不安定(生活習慣病)の要因になってしまうだけに
まるで人間の体と一緒だなぁと思ってしまう。

  そこで考え出されたのがモジュール化だった。

モジュール化とは何か?
ドライバを外部にだして、カーネルの肥大化を抑える。

 メタボなカーネルの治療のために、ドライバをカーネルの外に出し
必要な物だけを取り込むという。

必要な物だけを取り込む
必要なドライバだけをカーネルに取り込む仕掛けによって
不要なドライバをカーネル内部に抱え込まないようにする。

それにより、カーネルの減量を行うのだ。

 カーネルの減量だが、最初はドライバなどの周辺部分のようだが、
どんどん色々な所に及んで、カーネル機能までモジュール化が
すすんできた。

カーネル機能までモジュール化
ファイルシステムやスケジューラーといったOS機能まで
モジュール化できるようになった。

 だが、行き過ぎた減量が体に良くないのと同様に、
行き過ぎたモジュール化は、以下の問題を引き起こす事になる。

行き過ぎたモジュール化の問題点(1)
カーネル起動の際、ブートローダーによって
カーネルイメージがメモリ上に読み込まれる。

 問題はここからだ。

行き過ぎたモジュール化の問題点(2)
ブートローダーによってカーネルイメージは取り込まれる。
その後、カーネル自身によって、起動が行われるのだ。

だが、この時、ドライバ等が入ったモジュールは読み込まれない。

 もし、カーネル自身が、ハードディスクのドライバ等が
取り込まれていない場合、以下の問題を引き起こす。

行き過ぎたモジュール化の問題点(3)
カーネルにハードディスクのドライバやファイルシステムが
取り込まれていない場合、ハードディスクが認識できない問題を
引き起こしてしまう。
そのため、ドライバ等があるモジュールファイルが読めなかったり
カーネル起動時の設定ファイルが読めないという事態を引き起こす。

 いくら減量でも、行き過ぎると、起動ができなくなる問題が起こる。
 まるで減量しすぎて体力を失い、動けなくなる状態だ。
 本末転倒になってしまう。


 折角、減量したのだから元には戻したくはない。
 そこで、考え出されたのは、起動の補助をするための仕掛けだ。
 それが、initrdファイルなのだ。

initrdファイルとは
initrdファイルは、起動に必要なドライバ等のモジュールや
モジュールをカーネルに取り込むためのプログラムが入っている。

 ブートローダーがカーネルを取り込む際に、一緒にinitrdファイルも
取り込むようにしておく。

ブートローダーはinitrdファイルも取り込む
ブートローダーがカーネルイメージだけでなく、initrdファイルも
取り込むようにしておく。

 すると、以下のような状態になる。

カーネルイメージとinitrdファイルが読み込まれた状態
カーネルイメージとinitrdファイルがメモリ上に読み込まれた状態になる。
initrdファイルが読み込まれた事は、ハードウェアを認識するために必要な
ドライバや、起動時に必要なLinuxの機能のモジュールを取り込んだ事になる。

 そして、メモリ上に読み込んだinitrdファイルがメモリ上で展開する。

initrdファイルがメモリ上で展開される
メモリ上に取り込まれたinitrdファイルが展開される。
そして、読み込んだカーネルイメージにモジュールを取り付ける。

メモリ上(RAMディスク)で展開され、そこでハードウェアの認識を行うので
初期化用RAMディスク(Initial RAM Disk)と言われる所以だ。
ようやく「initrd」と命名される理由がわかった。

 メモリ上でカーネルイメージに、必要なモジュールを取り付ける事で
ようやくハードウェアが認識できるようになる。

ハードウェアが認識できるようになる
減量しすぎて、ハードウェア等のドライバを外に出してしまっても、
initrdファイルを作成し、それをブートローダーがカーネルイメージを
読み込む際に、initrdファイルを読み込む事によって
必要なドライバをカーネルに装着できるため、カーネルは
ハードウェア等を認識できるようになる。

 なるほど、だからinitrdファイルは重要なのか!

 頭の中がすっきりした感じだ (^^)


 initrdファイルは、モノシリックカーネルが抱える肥大化の宿命に
「待った」をかけ、カーネルの減量した結果、産み出された物であり、
Linuxの歴史の必然(?)だというのが、わかった。


initrdファイルの作成方法

(注意) カーネル2.6系の話で進めています。  実際にカーネル再構築時に、initrdファイルを作ってみる事にしてみた。 Linux-2.6系の最新版「2.6.26.2」(2008/8/19現在) をダウンロードする。 そして展開させる。
Linux-2.6.26.2を展開させる
[root@server]# bzip2 -d linux-2.6.26.2.tar.bz2
[root@server]# tar xvf linux-2.6.26.2.tar
linux-2.6.26.2/
linux-2.6.26.2/.gitignore
linux-2.6.26.2/.mailmap
linux-2.6.26.2/COPYING

(途中、省略)

[root@server]# ls
kernels  linux-2.6.26.2  linux-2.6.26.2.tar  redhat
[root@server]# 
カーネルのオプション設定
[root@server]# cd linux-2.6.26.2
[root@server]# make menuconfig
scripts/kconfig/mconf arch/x86/Kconfig
#
# using defaults found in /boot/config-2.6.18-53.el5
#
/boot/config-2.6.18-53.el5:10:warning: trying to assign nonexistent symbol SEMAP
HORE_SLEEPERS
/boot/config-2.6.18-53.el5:75:warning: trying to assign nonexistent symbol MODUL
E_SIG

(カーネルのオプション設定の画面:省略)

*** End of Linux kernel configuration.
*** Execute 'make' to build the kernel or try 'make help'.

[root@server]# 
コンパイル開始
[root@server]# make
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf -s arch/x86/Kconfig
  CHK     include/linux/version.h

(途中、省略)

  LD [M]  net/tipc/tipc.ko
  CC      net/wireless/cfg80211.mod.o
  LD [M]  net/wireless/cfg80211.ko
[root@server]#

  ここまではカーネル本体のコンパイルだ。
 次に、モジュールのコンパイルに入る。


モジュールをコンパイル
[root@server]# make modules
  CHK     include/linux/version.h
  CHK     include/linux/utsrelease.h
  CALL    scripts/checksyscalls.sh
  Building modules, stage 2.
  MODPOST 892 modules
WARNING: modpost: Found 2 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
[root@server]#
モジュールのインストール
[root@server]# make modules_install
  INSTALL arch/x86/crypto/aes-i586.ko
  INSTALL arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.ko
  INSTALL arch/x86/kernel/cpu/cpufreq/p4-clockmod.ko
  INSTALL arch/x86/kernel/cpuid.ko

(途中、省略)

  INSTALL net/sctp/sctp.ko
  INSTALL net/tipc/tipc.ko
  DEPMOD  2.6.26.2
[root@server]# 
カーネルのインストール
[root@server]# make install
sh /usr/src/linux-2.6.26.2/arch/x86/boot/install.sh 2.6.26.2 arch/x86/boot/bzImage System.map "/boot"
[root@server]#
/boot ディレクトリーの中を見てみる
[root@server]# cd /boot/
[root@server]# ls
System.map                initrd-2.6.18-53.el5.img  vmlinuz
System.map-2.6.18-53.el5  initrd-2.6.26.2.img       vmlinuz-2.6.18-53.el5
System.map-2.6.26.2       lost+found                vmlinuz-2.6.26.2
config-2.6.18-53.el5      message
grub                      symvers-2.6.18-53.el5.gz
[root@server]# 
色がついた部分が、新しくインストールしたカーネル関係のファイル。
赤い部分が、initrdファイルだ。自動的にできている。

 自動的にできているやん!

 これには意外だった。

 mkinitrdコマンドを使って生成する話にもっていこうとしたが
自動生成されるとは・・・。
 世の中、筋書き通りにはいかない良い例だ (^^)

  Linux-2.4系には自動生成はなかったと思う。
 これは便利だ (^^)

mkinitrdコマンドでinitrdファイルの作成

カーネルの再構築時に、自動的にinitrdファイルが生成される。 だが、mkinitrdコマンドを使ったinitrdファイルの作成方法を 説明しないと、手抜きになってしまうので、紹介します。  さて、いきなりmkinitrdコマンドを使うわけではない。  まずは、depmodコマンドを使う。
まずは、depmodコマンドを使う
[root@server]# depmod 2.6.26.2
depmodコマンドは、カーネルモジュールの集計表を作成するコマンドだ。
青い部分は、カーネルバージョンの指定になる。
もし、オプションをカーネルバージョンの指定ではなく
「-a」にすると、現在、稼働中のカーネルのバージョンの
モジュールが対象になる。

作成した集計表は次のファイルになる。

/lib/modules/(カーネルバージョン)/modules.dep

 さて、生成した集計ファイルであるmodules.depファイルを見てみる。

modules.depファイルの中身
/lib/modules/2.6.26.2/kernel/drivers/ide/legacy/ide-cs.ko:
/lib/modules/2.6.26.2/kernel/drivers/ide/ide-cd_mod.ko: /lib/modules/2.6.26.2/kernel/drivers/cdrom/cdrom.ko
/lib/modules/2.6.26.2/kernel/drivers/usb/misc/idmouse.ko:
/lib/modules/2.6.26.2/kernel/drivers/usb/misc/emi62.ko:
/lib/modules/2.6.26.2/kernel/drivers/usb/misc/usbtest.ko:
/lib/modules/2.6.26.2/kernel/drivers/usb/misc/ldusb.ko:
/lib/modules/2.6.26.2/kernel/drivers/usb/misc/emi26.ko:

(以下、省略)
上のように、ドライバがどのディレクトリに保管されているかの表になっている。

depmodコマンドは、initrdファイルの作成時だけでなく、
ドライバをインストールした際にも、モジュール表に追加するために
depmodコマンドを使う。

depmodコマンドで生成されるのは、modules.dep以外にも、
同じディレクトリ内にある、modules.aliasや、
modules.symbols が挙げられる。

  そして、mkinitrdコマンドを使う。

mkinitrdコマンドを使って、initrdファイルの作成
[root@server]# mkinitrd /boot/initrd-2.6.26.2.img 2.6.26.2
/boot ディレクトリに、initrdファイルを作成する様子だ。
赤い部分はカーネルのバージョンの指定だ。

 これで、initrdファイルの完成だ。



 ここでふと思った。
 initrdファイルに取り込むモジュールは、

 何の情報を基づいて選択しているのだろうか?

  そうなのだ。
 initrdファイルを展開した時、限定されたモジュールしか
入っていないのだ。

  そこで、何の情報に基づいてモジュールを選択しているのか
調べてみる事にした。


 すると、/etc/modprobe.confファイルの情報だというのだ。

/etc/modprobe.confファイルの中身
alias eth0 pcnet32
alias scsi_hostadapter mptbase
alias scsi_hostadapter1 mptspi
alias scsi_hostadapter2 ata_piix
(注意)

環境によって中身が変わってきますので、
必ずしも、上と一致しなくても問題はありません。

 この設定の状態で作成された、initrdファイルを展開してみた。
 すると以下のモジュールが取り込まれていた。

/etc/modprobe.confファイルの中身
alias eth0 pcnet32
alias scsi_hostadapter mptbase
alias scsi_hostadapter1 mptspi
alias scsi_hostadapter2 ata_piix
initrdファイルに取り込まれたモジュール
[root@server]# cp /boot/initrd-2.6.26.2.img .
[root@server]# mv initrd-2.6.26.2.img initrd-2.6.26.2.gz
[root@server]# gzip -d initrd-2.6.26.2.gz 
[root@server]# cat initrd-2.6.26.2 | cpio -id
13902 blocks
[root@server]# cd lib
[root@server]# ls
ata_piix.ko     ext3.ko      ohci-hcd.ko
dm-log.ko       firmware     scsi_mod.ko
dm-mirror.ko    jbd.ko       scsi_transport_spi.ko
dm-mod.ko       libata.ko    sd_mod.ko
dm-snapshot.ko  mptbase.ko   uhci-hcd.ko
dm-zero.ko      mptscsih.ko
ehci-hcd.ko     mptspi.ko
[root@server]#
合計19個のモジュールが格納されていた。

 そこで、modprobe.confによって取り込まれる
モジュールが変化するのか、自分の目で確かめる事にした。

/etc/modprobe.confファイルの中身を変更
#alias eth0 pcnet32
#alias scsi_hostadapter mptbase
#alias scsi_hostadapter1 mptspi
#alias scsi_hostadapter2 ata_piix
全てコメント文にして、内容を無効にしてみた。
initrdファイルに取り込まれたモジュール
[root@server]# cp /boot/initrd-2.6.26.2.img .
[root@server]# mv initrd-2.6.26.2.img initrd-2.6.26.2.gz
[root@server]# gzip -d initrd-2.6.26.2.gz 
[root@server]# cat initrd-2.6.26.2 | cpio -id
13494 blocks
[root@server]# cd lib
[root@server]# ls
dm-log.ko       ext3.ko      ohci-hcd.ko
dm-mirror.ko    firmware     scsi_mod.ko
dm-mod.ko       jbd.ko       scsi_transport_spi.ko
dm-snapshot.ko  mptbase.ko   sd_mod.ko
dm-zero.ko      mptscsih.ko  uhci-hcd.ko
ehci-hcd.ko     mptspi.ko
[root@server]#
合計17個のモジュールが格納されていた。

modprobe.confファイルの内容を無効にした事で
取り込まれたモジュールの数が2個減っている。

でも、残りの17個のモジュールの判断は
どこで行っているだろうか?

  一体、残り17個は、どうやって判断しているねん!

 と思った。

 しかし、いくら調べても手がかりすら見つからない。
 謎のままだと気持ち悪いのだが、わからない物は仕方ない。

 そこでお得意の

 「忍法・先送りの術」なのらー!!

 をやってみる (^^)

 もし、「先送りするな! キチンと調べろ!」と言われても

 事務員なので、わかりませーん (^^)V

 と常套手段で逃げるのだ。


その後  Linux-2.4系を再構築していた時、オプションは全て 「取り込む」か「取り込まない」という白黒ハッキリさせた 方法をやっていた。  でも、この問題は、必要かどうかのオプションについては 「取り込む」にしておかないとダメだった。  どっちかわからない場合は「取り込む」としていたため 余分なモジュールをカーネルに取り込む問題があった。  でも、今回の事で、「どっちかわからない」という場合は 「モジュール」を選んでおき、initrdファイルを生成する事で 「どっちかわからない」という問題を解消してくれるし、 カーネルパニックを引き起こす可能性が低くなる。  Linux-2.4系から2.6系になった時、知らないオプションが増え とても再構築が行える自信はなかったのだが、 今回の勉強のお蔭で、私も安心(?)して、Linux-2.6系のカーネルの 再構築が行えるようになった (^^)
まとめ initrdファイルが一体、何なのかを長年、調べる事なく 放置してきました。  今回、調べてみると、Linuxカーネルが発展する上で 抱える問題が垣間見えたのと、その問題を解消すべく 産み出された手法としてのinitrdファイルだというのを知った。  なかなか調べても「これだ!」と思う情報が見つからなかったり あったとしても、私が理解できないために、思うように 調べられなかったのが残念ですが、一旦、ここでまとめてみました。  もし、色々、わかりだしたら、補遺という形で追加したり、 より詳しい内容として、別の機会で取り上げてみたいと思います。

次章:「
北京旅行の話:その2」を読む
前章:「ブートローダーGRUBの設定の話を読む
目次:システム奮闘記に戻る

Tweet