OSの心臓、glibcのコンパイルとchroot:LFSで作って学ぶLinuxの仕組み(3)(1/3 ページ)
カーネルがOSの脳だとすると、glibcは心臓といえるだろう。Linuxにとってなくてはならないglibcをコンパイルすることで、構築中のLFSもひとまとまりの「OS」に大きく近づく。LFSの自力起動まで、あともう少しだ。(編集局)
筆者の都合により、2カ月ほど中断してしまったが、何とか再開することができた。その間にLFSの最新版は4.0になったが、前回提供したスクリプトは3.3用なので注意していただきたい。3.3が無事に起動した後で、4.0用のスクリプトも提供したいと思う。
おわび:lfs-compile.shのミス
第2回でlfs-compile.shというスクリプトを提供したが、このスクリプトに間違いがあったのでおわびして訂正したい。
1つは、bashのコンパイル後にshへリンクしなければならなかったのだが、このコマンドを入れ忘れていた。そのため、筆者はglibcのconfigure時に「/bin/shがない」というエラーが発生し、大いにはまってしまった。同じような現象が発生する方は、/binにshが存在するかどうかを確認し、もし存在しなければ、
# ln -sf bash sh
を実行していただきたい。
もう1つは、GCCのmake(コンパイル時)に指定するコンパイルオプション(LDFLAGS)のタイプミス(「static」を「statix」としていた)により、ライブラリをスタティックリンクでコンパイルするべきところが、ダイナミックリンクでコンパイルされていた。このために、同じくglibcのconfigureで「gccが存在しない」(実際には存在するが実行できない)というエラーが発生し、こちらも原因が分からずはまってしまった。
こちらは、ベースとなるディストリビューション上でGCCを正しいコマンドで再コンパイルしていただければいい。タイプミスがあってもコンパイルが行われるということは勉強になったが、読者諸氏にご迷惑をおかけしたことを重ねておわびしたい。
ちなみに、ダイナミックリンクでコンパイルされたものとスタティックリンクでコンパイルされたものは、サイズが大きく異なる。ベースとなるディストリビューション上にある同じファイルとのサイズ差を調べてみれば、スタティックリンクでコンパイルされたかどうか、一目瞭然で分かるはずだ。
第2回の記事中でダウンロードできるスクリプトは、すでに訂正版に入れ替えてある。また、ここでもあらためて訂正版を紹介しておく。
コンパイル用スクリプト:lfs-compile.sh
注:EUCで保存すること。
glibcコンパイル前の準備
/procファイルシステムのマウント
前回までで終了した作業の続きを行おう。次は、LFS用の/procファイルシステムのマウントである。/procファイルシステムはLinux固有の色合いが強く、必ずマウントされている。その中身に実体はなく、プロセスをファイルで表現してプロセス間の情報交換のために用いられる(注)。
注:/procについては、連載:Windowsユーザーに教えるLinuxの常識 第2回や/procによるLinuxチューニングが参考になると思う。
前回も少し触れたように、いまはまだLFS環境を構築するための準備を終えた段階にすぎない。これから行わなければならないのは、ベースとなるディストリビューションからの決別であり、LFS単独での起動である。そのために、LFS用のボリュームに作成した/procのマウントが必要なのだ。この作業は、ベースとなるディストリビューションのrootユーザーで行う。なお、chrootまでの作業をroot.shというスクリプトにまとめておいた。
コンパイル用スクリプト:root.sh
注:EUCで保存すること。
実行するコマンドは、次のとおりである(注)。
# chown root.root /mnt/lfs/proc # mount proc /mnt/lfs/proc -t proc
注:環境変数LFSが設定されていれば、/mnt/lfsの代わりに$LFSを使ってもよい。
コマンドの実行例を以下に示す。
[root@localhost root]# chown root.root /mnt/lfs/proc [root@localhost root]# mount proc /mnt/lfs/proc -t proc [root@localhost root]# mount /dev/hdb5 on / type ext3 (rw) none on /proc type proc (rw) usbdevfs on /proc/bus/usb type usbdevfs (rw) /dev/hdb1 on /boot type ext3 (rw) none on /dev/pts type devpts (rw,gid=5,mode=620) /dev/hdb2 on /mnt/lfs type ext3 (rw) none on /dev/shm type tmpfs (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) proc on /mnt/lfs/proc type proc (rw)
コマンド実行後は、mountコマンドで/procファイルシステムがマウントされたことを確認しておこう。
.bash_profileの作成
次に、LFSのrootユーザー用.bash_profileを$LFS/root/に作成する。.bash_profileの記述例を以下に示すが、PATHの設定以外は例に従う必要はない。プロンプトの表示方法など、自分の好みに合わせて編集して構わない(注)。
PS1='\u:\w:$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin export PS1 PATH
注:.bash_profileの設定については、連載:Windowsユーザーに教えるLinuxの常識 第9回を参照。
chrootの実行
いよいよ、/mnt/lfsを/(ルートディレクトリ)にするときがやってきた。といっても、まだベースとなるディストリビューションと決別できていないし、LFS単独で起動させるわけでもない。ベースとなるディストリビューションをだまして(?)、/mnt/lfsを/と見なして動作してもらおう、というわけである。
これを行うには、chrootというコマンドを使う。
# cd /mnt/lfs # chroot /mnt/lfs /usr/bin/env -i HOME=/root TERM=$TERM /bin/bash --login
カレントディレクトリを/mnt/lfsに移動していなくても、chrootコマンドを実行すれば自動的にディレクトリが切り替わるはずだが、念のためにcdコマンドを先に実行しておく。chrootコマンドのオプションについて解説すると長くなるので、今回は省略させていただく。
コマンドを実行してルートディレクトリが切り替わると、次のような状態になる。
[root@localhost lfs]# chroot /mnt/lfs /usr/bin/env -i HOME=/root TERM=$TERM /bin/bash --login I have no name!:/:$ I have no name!:/:$ pwd / I have no name!:/:$ ls bin boot dev etc home lib mnt opt proc root sbin tmp usr var I have no name!:/:$
ご覧のように、コマンドプロンプトの表示が変わり、lsコマンドを実行すると/mnt/lfsの下にあるものだけが表示される。pwdコマンドで確認しているとおり、この状態でのカレントディレクトリは/である。試しに/mnt/lfsを参照しようとすると、以下のようにエラーメッセージが表示される。
I have no name!:/:$ ls /mnt/lfs ls: /mnt/lfs: No such file or directory
/mnt/lfsを/と扱うようにしたのだから当然だ。ベースとなるディストリビューションの/mnt/lfs以外のディレクトリはまったく参照できない。
また、「I have no name!」と表示されているところは、本来ホスト名が表示されるべきだ。しかし、LFSにはまだglibcを入れていないため、ホスト名を表示することができない。いま動いているのは、前回構築した共有ライブラリに依存しないプログラムたちだけなのである。
ちなみに、chrootしている環境(仮想LFS)から元の環境(ベースとなっているディストリビューション)へ戻るには「exit」と入力すればよい。
コラム ここで再起動するとどうなる?
ここまで、あるいはこの先の作業を完了したところでコンピュータを再起動しても大丈夫なのか心配になるだろう。しかし、特に心配する必要はない。LFSはまだ単独起動できないので、ベースとなるディストリビューションが起動するだけだ。
手順どおりに作業していれば、ベースとなるディストリビューションを壊すこともない。ただし、先ほどマウントしたLFSの/procファイルシステム(/mnt/lfs/proc)は解除されてしまうから、もう一度マウントしなければならない。
/mnt/lfs/procを再度マウントしてchrootコマンドを実行すれば、/mnt/lfsが/ディレクトリの扱いになり、作業を再開できる。しかし、この状態は仮想的な環境を手に入れたにすぎず、まだ単独のOSとしては機能していないことを理解しておく必要がある。
所有権の変更
chrootを終えた状態でls -laを実行してみよう。ファイル所有者の欄はどうなっているだろうか? おそらく数値が表示されるだろう。
I have no name!:/:$ ls -la total 60 drwxr-xr-x 16 501 501 4096 Jan 26 17:55 . drwxr-xr-x 16 501 501 4096 Jan 26 17:55 .. drwxrwxr-x 2 501 501 4096 Jan 26 18:11 bin drwxrwxr-x 2 501 501 4096 Jan 26 17:54 boot drwxrwxr-x 3 501 501 4096 Jan 26 17:54 dev drwxrwxr-x 3 501 501 4096 Jan 26 18:11 etc drwxrwxr-x 2 501 501 4096 Jan 26 17:54 home drwxrwxr-x 2 501 501 4096 Jan 26 18:09 lib drwxrwxr-x 2 501 501 4096 Jan 26 17:54 mnt drwxrwxr-x 8 501 501 4096 Jan 26 17:56 opt dr-xr-xr-x 52 0 0 0 Jan 27 2003 proc drwxr-x--- 2 501 501 4096 Jan 26 18:55 root drwxrwxr-x 2 501 501 4096 Jan 26 17:54 sbin drwxrwxrwt 2 501 501 4096 Jan 26 17:54 tmp drwxrwxr-x 10 501 501 4096 Jan 26 18:09 usr drwxrwxr-x 12 501 501 4096 Jan 26 17:56 var
この数値は、ベースとなるディストリビューションでLFSユーザーに与えられていたユーザーIDなのである。/procだけ異なっているのは、ここまでの手順でrootの所有に変更しているためだ。なぜ「LFS」というユーザー名が表示されず、ユーザーIDになるかというと、chrootしたためである。これにより本来の/etc/passwdにアクセスできなくなり、ユーザーIDとユーザー名の変換ができなくなったため、ファイルシステムが記憶しているIDが表示されているのだ。
これらの所有者は、ベースとなるディストリビューションのLFSユーザーではなく、LFSのrootユーザーになるべきである。そこで、次のコマンドを実行して所有者を変更する。なお、ここから先の作業を一気に実行するスクリプトlfs-compile2.shを用意した。
コンパイル用スクリプト:lfs-compile2.sh
注:EUCで保存すること。
I have no name!:/:$ cd / I have no name!:/:$ chown 0.0 . proc I have no name!:/:$ chown -R 0.0 bin boot dev etc home lib mnt opt root sbin tmp usr var
これで、すべてのディレクトリのオーナーがユーザーID 0になったはずだ。本来、「0.0」ではなく「root.root」としてコマンドを実行するべきなのだが、まだglibcがインストールされていない関係で、ユーザーIDを使わざるを得ない。なぜ「0」がrootなのかは、/etc/passwdを調べてみると分かるだろう。
シンボリックリンクの作成
次に、シンボリックリンクを1つ作成する。次のコマンドが示すとおり、/etc/mtabを/proc/mountsにリンクする。/etc/mtabはマウント情報を記録しているファイルで、リンクを作成するのはこのファイルが古くならないようにするためだ。
I have no name!:/:$ ln -s /proc/mounts /etc/mtab
Copyright © ITmedia, Inc. All Rights Reserved.