2006年6月9日金曜日

(VMware)FreeBSD 6.1Rのカーネル再構築

昔は、OSをインストールしたら、まずはカーネル(kernel)のリコンフィグ(reconfiguration=再構築/または単にbuild=ビルド/カーネルをコンパイルしなおすこと)を行い、使用しているハードウェアにあったデバイスドライバを追加したり、OSの動きが軽快になるようにチューニングしたりする、というのが、まず最初にやるべき作業だったような気がします。しかし最近では、デバイスドライバもモジュール化されているし、/boot/loader.confや/etc/sysctl.confなどで様々なパラメータを調節できるようになっているため、カーネルを再構築する必要もありません。



私も、Solarisではカーネルの再構築ってやったことないですし(てゆーかできるの?)、Linuxでも、もう何年もやった記憶がありません。ただ、FreeBSDでは、なんとなく趣味というか、たいていカーネル再構築をやってます。



自分専用にカスタマイズしたカーネルを作って、自分だけのカーネルでパソコンを動かす、ってところに、なんとなく愛着がわいてくるような気がしませんか?



昔のパソコンは、今ほど処理速度が速くないので、カーネル再構築によって、「カーネルのぜい肉を落とす」ことで、けっこう効果があったと思います(OSの起動時間が短縮されるくらい、という話もある・・・)。
VMwareで、仮想マシンの中でFreeBSDで動かすときは、それなりにオーバーヘッドもあるわけだし、じゃあ、ぜい肉を落としてやったっていーんじゃないでしょうか。



● 参考
「FreeBSDハンドブック」の、「カスタムカーネルの構築とインストール」
http://www.jp.freebsd.org/www.FreeBSD.org/doc/ja_JP.eucJP/books/handbook/kernelconfig-building.html





■ カーネルのソースコードをFTPでダウンロード



私はいつもFTPでFreeBSDをインストールしているのですが、必要なもの最小限しかインストールしないので、カーネルのソースコードは、後から別途ダウンロードする必要があります。



FreeBSDのソースコードは、このあたりに置かれています。



ftp://ftp3.jp.freebsd.org/pub/FreeBSD/releases/i386/6.1-RELEASE/src/



ここにおかれているファイルは、tarとgzipで圧縮したあと、フロッピーディスクに入る程度のファイルサイズへ分割されたものです。カーネルのソースコードは、「ssys.??」というファイルが該当します。



FreeBSDで、ftpコマンドを使ってダウンロードする方法は、以下のとおり。



(ダウンロードしたファイルを置くディレクトリへ、あらかじめ移動しておくのが楽)
freebsd# cd /usr/src



freebsd# ftp ftp3.jp.freebsd.org
Trying 2001:e40:100:207::2...
ftp: connect to address 2001:e40:100:207::2: No route to host
Trying 210.188.213.230...
Connected to ring.sakura.ad.jp.
220 ProFTPD 1.3.0rc2 Server (ring.sakura.ad.jp) [::ffff:210.188.213.230]
Name (ftp3.jp.freebsd.org:nhh): ftp ←(ftpと入力)
331 Anonymous login ok, send your complete email address as your password.
Password: ←(メールアドレスをパスワード代わりに入力)
230-
          ##################################################
          #     Welcome to the RingServer FTP service.     #
          ##################################################



  Localtime [Thu Jun  8 22:13:23 2006 JST+0900]
  Current [13] users / Max [100] users



230 Anonymous access granted, restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.



(ディレクトリ移動・・・ところで、ここでTABキーを押してファイル名補完ができるので、びっくりしました)
ftp> cd /pub/FreeBSD/releases/i386/6.1-RELEASE/src



(バイナリモードでファイル転送するように指示)
ftp> bin
200 Type set to I



(ssys*にマッチするファイルをすべてダウンロード)
ftp> mget ssys*
mget ssys.aa [anpqy?]? a ←(aで、これ以降いちいち尋ねずにすべてYesと答えるようになる)
Prompting off for duration of mget.



(ダウンロードがはじまる)



229 Entering Extended Passive Mode (|||64410|)
150 Opening BINARY mode data connection for ssys.aa (1425408 bytes)
100% |*************************************|  1392 KB  886.28 KB/s    00:00 ETA
226 Transfer complete.
1425408 bytes received in 00:01 (873.16 KB/s)
229 Entering Extended Passive Mode (|||50087|)
150 Opening BINARY mode data connection for ssys.ab (1425408 bytes)
100% |*************************************|  1392 KB    0.97 MB/s    00:00 ETA
226 Transfer complete.
1425408 bytes received in 00:01 (985.12 KB/s)



  (省略)



229 Entering Extended Passive Mode (|||51647|)
150 Opening BINARY mode data connection for ssys.inf (486 bytes)
100% |*************************************|   486      29.78 KB/s    00:00 ETA
226 Transfer complete.
486 bytes received in 00:00 (11.70 KB/s)



(ダウンロード完了)
ftp> bye
221 Goodbye.



(ダウンロードされたファイル)
freebsd# ls
ssys.aa         ssys.ae         ssys.ai         ssys.am         ssys.inf
ssys.ab         ssys.af         ssys.aj         ssys.an
ssys.ac         ssys.ag         ssys.ak         ssys.ao
ssys.ad         ssys.ah         ssys.al         ssys.ap



■ ソースコードの展開



ssys.??にマッチするファイルをcatで連結して、tar+gzipの展開をします。



freebsd# cat ssys.?? | tar zxf -



展開されたファイルは、sysというサブディレクトリの中にあります。



freebsd# ls sys
Makefile        ddb             kern            netkey          posix4
alpha           dev             libkern         netnatm         powerpc
amd64           doc             modules         netncp          rpc
arm             fs              net             netsmb          security
boot            gdb             net80211        nfs             sparc64
bsm             geom            netatalk        nfs4client      sys
cam             gnu             netatm          nfsclient       tools
coda            i386            netgraph        nfsserver       ufs
compat          i4b             netinet         opencrypto      vm
conf            ia64            netinet6        pc98
contrib         isa             netipsec        pccard
crypto          isofs           netipx          pci



■ カーネルのコンフィギュレーションファイルを作成



ディレクトリ/usr/src/sys/i386/conf/にて、GENERICカーネルのコンフィギュレーションファイルを元に、カスタム・カーネル用のコンフィギュレーションファイルを作成します。



 (ディレクトリ移動)
freebsd# cd /usr/src/sys/i386/conf/
 (ちなみに、/sysというシンボリックリンクがあるので、cd /sys/i386/confとするのが粋なFreeBSDユーザーです)



 (ファイルをコピーして)
freebsd# cp GENERIC VMware
 (またまたちなみに、ここでのファイル名は、ホスト名をすべて大文字にしたものにするのが慣例と言われています・・・が、そんな慣例は、けっこう昔から破ってます)



 (エディタでファイルを編集)
freebsd# vi VMware



いらないデバイスは、行頭に「#」マークをつけて、ガシガシと、コメントアウトしていきます。



ただし、必要なものまで消してしまうと、カーネルのコンパイルに失敗します。このへんは、経験と勘が必要かも。



私が先ほど作ったVMware用のカーネルのコンフィギュレーション・ファイルは、コメントアウトした行と、改行だけの行を除くと、こんな感じになりました。最後の2行は、VMwareでエミュレーションされるオーディオデバイス用のドライバです。





# grep -v '^#' VMware | sed -e '/^$/d'
machine         i386
cpu             I686_CPU
ident           VMware
options         SCHED_4BSD              # 4BSD scheduler
options         PREEMPTION              # Enable kernel thread preemption
options         INET                    # InterNETworking
options         INET6                   # IPv6 communications protocols
options         FFS                     # Berkeley Fast Filesystem
options         SOFTUPDATES             # Enable FFS soft updates support
options         UFS_ACL                 # Support for access control lists
options         UFS_DIRHASH             # Improve performance on big directories
options         MD_ROOT                 # MD is a potential root device
options         NFSCLIENT               # Network Filesystem Client
options         NFSSERVER               # Network Filesystem Server
options         NFS_ROOT                # NFS usable as /, requires NFSCLIENT
options         MSDOSFS                 # MSDOS Filesystem
options         CD9660                  # ISO 9660 Filesystem
options         PROCFS                  # Process filesystem (requires PSEUDOFS)
options         PSEUDOFS                # Pseudo-filesystem framework
options         GEOM_GPT                # GUID Partition Tables.
options         COMPAT_43               # Compatible with BSD 4.3 [KEEP THIS!]
options         COMPAT_FREEBSD4         # Compatible with FreeBSD4
options         COMPAT_FREEBSD5         # Compatible with FreeBSD5
options         SCSI_DELAY=5000         # Delay (in ms) before probing SCSI
options         KTRACE                  # ktrace(1) support
options         SYSVSHM                 # SYSV-style shared memory
options         SYSVMSG                 # SYSV-style message queues
options         SYSVSEM                 # SYSV-style semaphores
options         _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extension
s
options         KBD_INSTALL_CDEV        # install a CDEV entry in /dev
options         AHC_REG_PRETTY_PRINT    # Print register bitfields in debug
                                        # output.  Adds ~128k to driver.
options         AHD_REG_PRETTY_PRINT    # Print register bitfields in debug
                                        # output.  Adds ~215k to driver.
options         ADAPTIVE_GIANT          # Giant mutex is adaptive.
device          apic                    # I/O APIC
device          pci
device          ata
device          atadisk         # ATA disk drives
device          atapicd         # ATAPI CDROM drives
options         ATA_STATIC_ID   # Static device numbering
device          scbus           # SCSI bus (required for SCSI)
device          da              # Direct Access (disks)
device          atkbdc          # AT keyboard controller
device          atkbd           # AT keyboard
device          psm             # PS/2 mouse
device          vga             # VGA video card driver
device          sc
device          agp             # support several AGP chipsets
device          pmtimer
device          lnc             # NE2100, NE32-VL Lance Ethernet cards
device          loop            # Network loopback
device          random          # Entropy device
device          ether           # Ethernet support
device          tun             # Packet tunnel.
device          pty             # Pseudo-ttys (telnet etc)
device          md              # Memory "disks"
device          bpf             # Berkeley packet filter
device          uhci            # UHCI PCI->USB interface
device          usb             # USB Bus (required)
device          ugen            # Generic
device          umass           # Disks/Mass storage - Requires scbus and da
device          sound
device          snd_es137x





「VMware.FreeBSD.CONFIG.txt」をダウンロード







■ カーネルのビルド



2通りの方法があって、「make buildkernel KERNCONF=ほげ」という新しいビルド方法があるのですが、ここでは、昔ながらの方法を紹介します。



まず、configコマンドを実行して、カーネルをコンパイルするための準備作業を行います。



freebsd# pwd
/usr/src/sys/i386/conf
freebsd# config VMware
Kernel build directory is ../compile/VMware
Don't forget to do ``make cleandepend; make depend''



これこれしろ、というメッセージにしたがって・・・



freebsd# cd ../compile/VMware/



昔はcleandependなんてものはなくて、つい最近増えたんですけど、素直に指示に従います。make dependも、それなりに時間がかかるので、「; make」も付け足して、一度に全部のコマンドを入力しちゃいます。



freebsd# make cleandepend; make depend; make
rm -f .depend
cd ../../../modules; MAKEOBJDIRPREFIX=/usr/src/sys/i386/compile/VMware/modules K
MODDIR=/boot/kernel MACHINE=i386 KERNBUILDDIR="/usr/src/sys/i386/compile/VMware"
make  cleandepend
===> 3dfx (cleandepend)
(しばらく待つ・・・)



(途中ばっさりと省略)



awk -f /usr/src/sys/modules/zlib/../../conf/kmod_syms.awk zlib.kld  export_syms
| xargs -J% objcopy % zlib.kld
ld -Bshareable  -d -warn-common -o zlib.ko zlib.kld
objcopy --strip-debug zlib.ko



ファイルサイズを見てみます。



freebsd# ls -l kernel
-rwxr-xr-x  1 root  wheel  3785839 Jun  8 23:19 kernel



ちなみに、オリジナルのカーネル(GENERICカーネル)の場合は・・・
freebsd# ls -l /boot/kernel/kernel
-r-xr-xr-x  1 root  wheel  6639826 May  7 13:32 /boot/kernel/kernel



カスタム・カーネルは、だいぶ、ダイエットされたようですね。



■ 新しいカーネルをインストール



新しいカーネルは、「make install」で、/boot/kernel/以下へインストールすることができます。



freebsd# make install
thiskernel=`sysctl -n kern.bootfile` ;  if [ ! "`dirname "$thiskernel"`" -ef /bo
ot/kernel ] ; then  chflags -R noschg /boot/kernel ;  rm -rf /boot/kernel ;  els
e  if [ -d /boot/kernel.old ] ; then  chflags -R noschg /boot/kernel.old ;  rm -
rf /boot/kernel.old ;  fi ;  mv /boot/kernel /boot/kernel.old ;  sysctl kern.boo
tfile=/boot/kernel.old/"`basename "$thiskernel"`" ;  fi
kern.bootfile: /boot/kernel/kernel -> /boot/kernel.old/kernel
mkdir -p /boot/kernel
install -p -m 555 -o root -g wheel kernel /boot/kernel



(省略)



===> zlib (install)
install -o root -g wheel -m 555   zlib.ko /boot/kernel
kldxref /boot/kernel



■ 新しいカーネルでブートする



リブートすれば、新しいカーネルで、FreeBSDが起動します。



freebsd# reboot
Connection to vmware closed by remote host.
Connection to vmware closed.



新しいカーネルで起動したあと、ログインし、「uname -a」コマンドを実行すると、カーネルをコンパイルしたときの日付などが表示されます。



freebsd# uname -a
FreeBSD freebsd.vmware.local 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Thu Jun  8 23:19:32 JST 2006     nhh@freebsd.vmware.local:/usr/src/sys/i386/compile/VMware  i386



■ 新しいカーネルで正常にブートできなかった場合



必要なデバイスドライバまで削除してしまったとか、コンフィギュレーション・ファイルに問題があった場合、正常にOSが動作しなくなる恐れがあります。



そういうときは、1つ前のカーネルでブートしなおします。



実は、「make install」で新しいカーネルをインストールしたとき、これまで使っていたカーネルは、/boot/kernel.oldというディレクトリに、そっくりそのまま残されています(1つ前のものしか残されないので、もっと残しておきたい場合は、自分で適当にディレクトリ名を変更して保存しておくこと)。



freebsd# ls -ld /boot/kernel*
drwxr-xr-x  2 root  wheel  9216 Jun  8 23:56 /boot/kernel
drwxr-xr-x  2 root  wheel  9216 May 13 09:13 /boot/kernel.old



シングルユーザーモードでもいいので、なんとかカーネルが起動して、rootでログインできた場合は、/boot/kernel.oldというディレクトリ名を、/boot/kernelに戻して、もう一度再起動すれば、1つ前のカーネルでブートさせることができます。





(シングルユーザーモードでブートしたときは、リードオンリーでマウントされているので、書き換え可能になるように、マウントしなおす)
# mount -u /



(古いカーネルを、復活させる)
# cd /boot
# mv kernel kernel.hoge
# mv kernel.old kernel



カーネルのブート途中にpanicしてしまうなど、最悪の場合は、ブートローダの段階で、ブートすべきカーネルを選択しなおします。



まず、FreeBSDをブートする最初の段階で、ブートローダーに入ります。デーモンくんやFreeBSDロゴが表示されているメニューが表示された場合は、「Escape to loader prompt」を選択します。



「OK」というプロンプトが表示されているので、以下のようにして、ブートすべきカーネルを切り替えます、



Fbsdkern1



(すでにカーネル/boot/kernel/kernelがロードずみなので、アンロードする)

OK unload

(カーネルをロードする)

OK load /boot/kernel.old/kernel

(-s をつけて、シングルユーザーモードで起動)

OK boot -s

1つ前の/boot/kernel.old/kernelというカーネルでブートします。



Fbsdkern2



ロードするカーネルのファイル名がわからなくなってしまった場合は、「ls /boot」のようなコマンドで、ファイル名の一覧を表示できます。

OK ls /boot

Fbsdkern3



とにかく、カーネルが起動できたら、rootでログインして、上記の説明同様に、古いカーネルを復活させます。



# mount -u /
# cd /boot
# mv kernel kernel.hoge
# mv kernel.old kernel



Fbsdkern4





■ 関連情報





0 件のコメント:

コメントを投稿