NetBSD/i386でのELFへの移行

1999年7月5日に、NetBSD currentのi386 portは実行ファイルの形式を a.outからELFに変更しました。ELFへの移行はコンパイル済みのsnap shotを 入手して行うのが良いとされています。

これに反して、ソース・ベースでの以降を行ってみました。以前に書いた 「NetBSD 1.3.2からcurrentへの移行」の ページの記述と同じか、ちょっと手順を増やす程度で可能でした。

なお、移行を行ったNetBSD currentは、1999年7月13日の時点で、 シェルにはsh(1)と互換なシェルを使用した記述をしています。

さらに1999年8月1日版にて、サイド実行した結果で更新しました。

NetBSDのWebにNetBSD ELF FAQというページがあります。 ここに、Updating a system from a.out to ELFというのが、現在の公式な方法と言えます。

いくつかのメモ

前準備

前もっての準備作業です。

  1. currentのソースを入手します。
  2. 現在の共有ライブラリをaoutエミュレーションで参照されるディレクトリに コピーしておきます。aoutエミュレーション環境では、 まず/emul/aoutを先頭に付けたパスでファイルを探索します。なければ、 従来のパスで探索します。
    	# cd /
    	# mkdir /emul
    
    	または、
    	
    	# mkdir /usr/emul	(どこか空きのあるファイルシステム)
    	# ln -s /usr/emul /emul
    
    	とした後で、
    
    	# mkdir /emul/aout
    	# tar vcf - `find usr -xdev -name '*.so.*' -print` | \
    		(cd /emul/aout; tar xfBp -)
    
  3. 念のため、コピーしたファイルを保護しておくと良いでしょう。
    	# chflags -R schg /emul/aout
    

カーネル作成とリブート

a.outも実行できる、ELFをサポートしたカーネルを作成します。

  1. config(8)が1999年7月13日版では更新されていますので、 こちらを最初に作成します。
    	# cd /usr/src/usr.sbin/config
    	# make depend
    	# make
    	# make install
    
  2. カーネルを作成します。 カーネルの構成ファイルに、
    options 	COMPAT_AOUT	# binary compat for NetBSD a.out binaries
    
    を入れておきます。
    	# cd sys/arch/i386/conf
    	# config MYKERNEL	(自分で使ってるconfigのファイル)
    	# cd ../compile/MYKERNEL
    	# make depend
    	# make
    	# mv /netbsd /netbsd.old; mv netbsd /
    	# reboot
    

コンパイラ等の更新

ユーザ・ランドの更新のための準備で、 まずELFを作成できるELFベースにコンパイラ等を更新します。

  1. 現在のプログラムはa.outエミュレーション環境で動作しています。 きちんとソース・ツリーを参照できる様に以下の様に環境変数を設定します。
    	# DESTDIR=/../.
    	# export DESTDIR
    
  2. オブジェクトの形式を明示的にELFを使用することを環境変数に設定します。
    	# OBJECT_FMT=ELF
    	# export OBJECT_FMT
    
  3. objディレクトリを使用している場合は、ここで作成しておきます。
    	# cd /usr/src
    	# make obj
    
  4. makefileのルールのファイルを更新します。
    	# cd /usr/src/share/mk
    	# make install
    
  5. インクルード・ファイルを更新します。
    	# cd /usr/src
    	# make includes
    
  6. インストールされているa.outベースのライブラリの一部を削除しておきます。
    	# rm /../usr/lib/lib*_p.a  /../usr/lib/lib*_pic.a
    
    私は削除する代わりに、
    	# mv /../usr/lib/lib*_p.a  /../usr/lib/lib*_pic.a /var/tmp
    
    としました。
  7. ELFに移行するための環境変数を設定します。
    	# BOOTSTRAP_ELF=1
    	# export BOOTSTRAP_ELF
    
  8. bfdライブラリのヘッダをELFベースに更新します。
    	# cd /usr/src/gnu/lib/libbfd
    	# make cleandir
    	# make bfd.h
    
  9. コンパイルのためのツールを更新します。 まだ、ELFベースでの実行形式を作成できないため、 ちょっとした細工が含めてあります。
    	# cd /usr/src/gnu/usr.bin
    	# for i in binutils gas.new ld.new egcs ; \
    	do \
    		(cd $i ; \
    		make cleandir ; \
    		make depend ; \
    		make ; \
    		OBJECT_FMT=a.out make ); \
    	done
    
  10. できたものをインストールします。
    	# for i in binutils gas.new ld.new egcs; \
    	do \
    		(cd $i; make install); \
    	done
    
    これでa.out形式のプログラムによる、 ELFを生成可能なコンパイル環境ができました。

実行時のリンク・エディタの作成

ダイナミック・リンクされたELFの実行形式には、実行時のリンク・エディタ ld.so(1)が必要です。ELF形式をインストールした時点で動作不能と なってしまうため、予めインストールしておく必要があります。

  1. ld.so(1)の作成に必要なため、予め標準Cライブラリの一部を 作成します。
    	# cd /usr/src/lib/libc
    	# make cleandir
    	# make depend
    	# make libc_pic.a
    
  2. C言語のスタートアップ・モジュールを更新します。
    	# cd /usr/src/lib/csu
    	# make cleandir
    	# make depend
    	# make
    	# make install
    
  3. ld.so(1)を更新します。
    	# cd /usr/src/libexec/ld.elf_so
    	# make cleandir
    	# make depend
    	# make
    	# make install
    

ユーザランドの更新

やっと、NetBSD currentの追っかけでは毎度のユーザランドの更新を行います。

	# cd /usr/src
	# make cleandir	(/etc/mk.confにUPDATE=yesしてなければ不要)
	# make build

カーネルの更新

カーネルを完全にELF形式にします。

	# cd sys/arch/i386/conf
	# config MYKERNEL	(自分で使ってるconfigのファイル)
	# cd ../compile/MYKERNEL
	# make depend
	# make
	# mv /netbsd /netbsd.old; mv netbsd /
	# reboot

他のファイルの更新

標準のソース・ツリーに含まれないプログラムを、 ELF形式にするために再コンパイルしてください。但し、必ず必要なわけではありません。

お願い

自分で実行した結果を忠実に再現したつもりですが、シンタックスの誤りや、 やってみたらうまくいかなかったといった場合には、報告して頂けると幸いです。


目次へ コメントの送付


Copyright 1999, 2000, 2001, 2002, 2003
Takahiro Kambe. All rights reserved.