次のページ 前のページ 目次へ

10. 技術的 FAQ

10.1 バグの報告

バグを報告する前に、答えがこの文書に載っていないことの確認をお願いします。 また、 http://www.linux-mips.org/archives/linux-mips のサーチエンジンを使って、あなたの問題をメーリングリストアーカイブから探してみてください。

これで解決しなかった場合は、バグレポートをお願いします。 カーネルのバグレポートに不慣れな方はまず、 REPORTING-BUGS (Linux 2.1 以降では、これはカーネル添付文書になっています) を読んで、必要な全ての情報がレポートに含まれるようにしてください。 特に、Oops メッセージの解析手順の部分が重要です。これがなければ、レジスタダンプの値から意味を持つ情報を引き出すことはほとんど不可能です。 ほとんどの問題では、使っているシステムの正確な情報も重要です。 まず、システムはプロセッサだけからなる訳ではないこと、MIPS システムは、Intel システムよりシステム間の違いが大きいことを念頭に置いてください。 一般的に言って、System.map のような大きなファイルを添付することは、明示的にそれを求められない限りやるべきではありません。 また、アーキテクチャ非依存のカーネルバグを見つけたと思っている場合でも、念のため linux-mips@linux-mips.org にも CC をお願いします。

10.2 Linux/MIPS のインストールとよくある問題

NFS ブートに失敗する

通常はこれはこの現象に出くわした人たちが tar アーカイブを Linux ではなく IRIX で展開したためです。NFS 越しのデバイスファイルの定義は Unix 間で標準化されていないため、この問題が起きます。現象としては、NFS ファイルシステムをマウントした直後にシステムが ``Warning: unable to open an initial console.'' というエラーメッセージで死ぬと言うものです。

今のところ、この問題の回避策は、インストールに使うアーカイブを NFS サーバに展開する際に Linux システムを使うことです。この Linux システムは MIPS 機である必要は無く、NFS サーバ自体はどのような UNIX 機でも問題ありません。

カーネルがコンパイルできない

Linux/MIPS でのシステムが、同じようによく保守されているわけではありません。 一般的に言って、多くのユーザのいるマシンには細かい経験の蓄積が進んでいますし、その結果良くサポートされています。

kernel.org からダウンロードしたカーネルには最新の MIPS サポートは含まれていませんので、MIPS サポートのみを対象として保守されている linux-mips.org からダウンロードしたものと違ってコンパイルが通らなかったり、動かなかったりするかもしれません。

自分でコンパイルしたカーネルがブート時にクラッシュする

自分でカーネルを作ったんですが、クラッシュします。Indy ではクラッシュメッセージは次のようなものです (同様の問題は他のマシンでも起きますが、メッセージは全く違ったものかもしれません)。

    Exception: <vector=UTLB Miss>
    Status register: 0x300004803<CU1,CU0,IM4,IPL=???,MODE=KERNEL,EXL,IE>
    Cause register: 0x8008<CE=0,IP8,EXC=RMISS>
    Exception PC: 0x881385cc, Exception RA: 0x88002614
    exception, bad address: 0x47c4
    Local I/O interrupt register 1: 0x80 <VR/GIO2>
    Saved user regs in hex (&gpda 0xa8740e48, &_regs 0xa8741048):
         arg: 7 8bfff938 8bfffc4d 880025dc
         tmp: 8818c14c 8818c14c 10 881510c4 14 8bfad9e0 0 48
         sve: 8bfdf3e8 8bfffc40 8bfb2720 8bfff938 a8747420 9fc56394 0 9fc56394
         t8 48 t9 8bfffee66 at 1 v0 0 v1 8bfff890 k1 bad11bad
         gp 881dfd90 fp 9fc4be88 sp 8bfff8b8 ra 88002614

    PANIC: Unexpected exception
    
この問題はバージョン 2.7 以降の Binutils のまだ直っていないバグのために起きます。当面の回避策は、 arch/mips/Makefile の

       LINKFLAGS       = -static -N
    

という行を、下記のように修正してください。

       LINKFLAGS       = -static
    

Indy のカーネルブートが次のような PROM エラーメッセージで失敗する

    >> boot bootp()/vmlinux
    73264+592+11520+331680+27848d+3628+5792 entry: 0x8df9a960
    Setting $netaddres to 192.168.1.5 (from server deadmoon)
    Obtaining /vmlinux from server deadmoon

    Cannot load bootp()/vmlinux
    Illegal f_magic number 0x7f45, expected MIPSELMAGIC or MIPSEBMAGIC.
   
この問題は Indy のとても古い版の PROM では、Linux の使う ELF バイナリフォーマットを扱うことが出来ないために発生します。 この問題の解決は、現在作業中です。

IP22 アーキテクチャのマシンが ethernet アドレスを忘れてしまいます。

IP22 アーキテクチャでは、Dallas DS1286 RTC チップを時刻とファームウェア変数を格納するために使っています。 このチップは内部に電池を持っていますが、現在すでに約十年立っていますし、経験的にこの種の RTC バッテリの寿命はかなり短いことを考慮すると、RTC はそろそろ情報を保持しなくなってきています。また、ソフトウェアが何かのミスで RTC の情報を上書きしている可能性もあります。

問題の原因が、RTC チップの不良であると判断できたなら。新品の RTC を http://www.maxim-ic.com/ や、そのほかの供給元より入手できます。 うるさい向きとしては、更にその部品が部品棚で長いこと眠っていたものでないことを確認するのも良いでしょう。

以下が、RTC チップの再プログラム法です。ここでは、ethernet アドレスが aa:bb:cc:dd:ee:ff であると仮定しています。

    fill -w -v 0xaa 0xbfbe04e8
    fill -w -v 0xbb 0xbfbe04ec
    fill -w -v 0xcc 0xbfbe04f0
    fill -w -v 0xdd 0xbfbe04f4
    fill -w -v 0xee 0xbfbe04f8
    fill -w -v 0xff 0xbfbe04fc
   
以下のコマンドを使ってチップ内の NVRAM の内容の検証が行えます。

    dump -w -x 0xbfbe04e8
   
これは、MAC アドレスの各バイトを四回打ち出します。これは、Indy でのチップの使い方の関係で、正常な動作です。

この MAC アドレスは、システムのシリアル番号をかねていますので、IRIX 管理下のソフトウェアライセンスはこの番号に括り付けになります。また、 ethernet 標準では、48bit アドレスの特定の値に意味を持たせています。 このため、再プログラムの際の ethernet アドレスには元の ethernet アドレスを使ってください。MAC アドレスはマシンに張られたシールで確認できるでしょう。通常は、このシールには 12 桁の十六進数字のみが記されており、マシンの後ろ面のパラレルポートと左側の SCSI コネクタの間で、右側の電源との間に張られています。 シールが無くなっている場合も、syslogd の出力した Linux のブートメッセージや、 bootpd や dhcpd 設定ファイルなどからこの値を得ることができるでしょう。

ethernet アドレスを再プログラムする必要がある場合、他の NVRAM 設定も恐らく全て失われていますので、設定のために PROM シェルの setenv -p コマンドを使ってください。

私の RM 200C 用のリトルエンディアンファームウェアをどこで入手したらいいんでしょうか?

SNI のシステムはビッグとリトルの両エンディアンで動作可能です。現時点では Linux/MIPS はリトルエンディアンのファームウェアのみをサポートしています。 これはある意味で不幸なことで、SNI は Windows NT のサポートをやめたため、リトルエンディアンのファームウェアをここしばらく出荷していません。

ビッグエンディアンモードで動かした場合、ファームウェアは既にサポートされている SGI Indy に似たものですので、SNI サポートを修正するのは多分比較的容易です。 興味のあるハッカーは Ralf Bächle (ralf@gnu.org) まで連絡ください。

ld が signal 6 で死にます

       collect2: ld terminated with signal 6 [Aborted]
   
これは古い binutils の既知のバグです。少なくとも binutils 2.8.1 以降と最新のパッチの組み合わせにアップグレードする必要があります。

一部の版の PROM に ELF サポートがない問題

古い版の IP22 PROM は Linux カーネルの使う ELF フォーマットを知らず、 Linux が直接ブートできません。 この問題に当たると、以下のようなエラーメッセージになります。

    >> boot -f linux root=/dev/sda1

    Cannot load scsi(0)disk(1)rdisk(0)partition(8)/linux.
    Illegal f_magic number 0x7f45, expected MIPSELMAGIC or MIPSEBMAGIC.
    Unable to load linux: ``linux'' is not a valid file to boot.
    >>
   
この問題の望ましい解決策はもちろん PROM のアップグレードですが、すべてのシステムで提供されているわけではありません。

代替手段として、Irix 5 以降の Sash をカーネルを ブートするために使うことができます。Sash は ELF バイナリをロードするやり方を知っており、それが IRIX のカーネルか Linux のカーネルかを気にしません。PROM モニタで ``Sash'' と打ってください。 別のシェルプロンプトがでたなら、それが Sash からのプロンプトです。 後は普通通り Linux を起動してください。

Sash は EFS と XFS ファイルシステムを読め、bootp / tftp でカーネルを読むこともできます。

カーネルソースと共に配布されている elf2ecoff ツールを使って ELF バイナリを ECOFF 形式に変換することもできます。または、カーネルのビルド時に単に ``make vmlinux.ecoff'' とすることで ECOFF 形式のカーネルを作成できます。

ネットブートを試みているんですが、私のマシンはカーネルをダウンロードしてくれません

この問題は、SNI RM200 と SGI の IP22 アーキテクチャの ARC ファームウェアで起きます。

ブートクライアントが BOOTP パケットに返答しているのにも関わらず (tcpdump や ethereal のようなパケットスニファで確認できます)、 BOOTP サーバからカーネルをダウンロードしない場合です。 これはあなたのブートサーバがカーネル 2.3 系、またはそれ以降のものを使っているときに起きます。 この問題が起きた場合には、ブートサーバで root になって "echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc" と入力すれば回避できます。

TFTP サーバからのダウンロードが止まって、タイムアウトします

この問題は、TFTP サーバがローカルポート番号 32768 以上を使おうとしているせいで起きている場合があります。Linux 2.3 以降を使っている場合には、TFTP サーバは 32768 以降を使います。 この問題は、サーバで "echo 2048 32767 > /proc/sys/net/ipv4/ip_local_port_range" とすれば回避できるでしょう。

DHCP バージョン 2 のバグ

DHCP バージョン 2 を使っていると、次の問題に出くわすかもしれません。 現象:あなたのマシンは BOOTP を受信し、三回返答しますが、 TFTP を始めようとしません。この問題はシステムをブートする前に PROM モニタで "unsetenv netaddr" と入力することで回避できます。 DHCP バージョン 3 はこの問題を修正しています。

ブート時に "Warning: unable to open an initial console" というメッセージが出ます

この問題には二つの可能性と解決策があります。 まず、あなたのシステムで設定されたコンソールに対して、ドライバが実際にあるかどうかを確認してください。 この点には問題が無く、問題が解決しないなら、 あなたは Linux ディストリビューションと root ファイルシステムに存在する、よくあるバグの犠牲になっているものと考えられます。 Linux システムのコンソールは、キャラクタデバイスで、メジャー番号 5、マイナー番号 1 で、かつユーザとグループが共に root で書き込み権 622 であるべきです。 もしそうなっていないなら、ファイルシステムのルートディレクトリに cd して、以下のコマンドを root になって実行してください。

   rm -f dev/console
   mknod --mode=622 dev/console
  
これは NFS ルートファイルシステムでも、NFS サーバで直接行うこともできます。 しかしメジャー番号とマイナー番号は NFS により変更されてしまうので、この作業は Linux システムから (MIPS システムが唯一の NFS クライアントであっても) 行う必要があります そうしなければ、Linux クライアントがそこからブートする際にメジャー番号や マイナー番号が誤ったものになってしまいます。

SGI システムにインストールする際に IRIX が必要でしょうか。

様々なインストール手順の記載の中で、ディスクの分割を行うために IRIX が使われています。これが必要になっていたのは、その手順が書かれた時点では linux で走るディスク分割ツールがなかったためです。 現在は、fdisk の新しいバージョンか、GNU Parted を用いれば、ディスクを IRIX のディスクラベル (expert モードで選択可能になりました) を用いて分割可能になりました。 ボリュームヘッダは dvhtool で操作できます。注意点として、dvhtool の使い方は IRIX のものとは異なります。

また、予備のオペレーティングシステムとしての IRIX は、インストール時に ramdisk や nfsroot で苦戦する手間を減らし、便利ではあります。但し、一言注意。 中身を失いたくないなら、IRIX ディスクラベルを持っていないディスクを IRIX fx(8) に指定しては絶対にいけません。IRIX は問い合わせなしにディスクの内容を 壊し ます。

IRIX と Linux を同じシステムで共存できますか

はい。但し、必ず前の節の IRIX の fx(8) についての注意を読んで下さい。

Insmod が _gp_disp シンボルが未定義だと文句を言います

_gp_disp は MIPS の PIC コード中で使われているマジックシンボルです。 このエラーは、システムをクラッシュから救ってくれたため、むしろ有り難いものです。 この場合の問題の要点は、カーネル作成時の Makefile のオプションと、カーネルモジュール作成時のオプションは同じにすべきだということです。 特に、オプション -mno-pic -mno-abicalls -G 0 が重要です。

SGI マシンのシリアルコンソール

使っているカーネルに、シリアルインターフェースとシリアルコンソールのための適切なドライバが組み込まれるようにしてください。 Indy と Challenge S では ARC 環境変数 consoled1d2 のどちらか (コンソールとして使おうとしているシリアルインターフェース側) に設定してください。

ブート時に、全てのカーネルメッセージがシリアルコンソールに現れ、 init が動き出した時点から何も出なくなるという問題に出くわしたのなら、 多分あなたの /dev/console の設定が間違っているのでしょう。 カーネルソースをインストールしているなら Linux カーネルソースの /usr/src/linux/Documentation/serial-console.txt に詳しい情報がみつかります。

SGI の機種で、有効なメモリ量が変です

ブート時に Indy のカーネルは有効なメモリ量を次のようなメッセージで表示します。

   Memory: 27976k/163372k available (1220k kernel code, 2324k data)
   
最初の 2 つの数字が大きく違うのは、Indy のメモリアドレス空間内には先頭の 128MB がイメージとして現れるためです。この 2 つの数字の違いはこのため 大体 128MB ぐらいで、何かの問題を示しているわけではありません。 カーネル 2.3.23 からはこの 128MB の差は数えられないようになっています。

Indy PROM 関連の問題

一部の人たちが、マシンを保守パーツ等でアップグレードした後にこの問題を報告しています。 Indy の PROM には、何種類かの版があります。古い PROM 版のマシンで新しい種類の CPU にアップグレードした場合、例えば R4600SC を R5000SC モジュールにするなどした場合、次のようなメッセージを出してセルフテストがクラッシュします。

    Exception: <vector=Normal>
    Status register: 0x30004803<CU1,CU0,IM7,IM4,IPL=???,MODE=KERNEL,EXL,IE>
    Cause register: 0x4000<CE=0,IP7,EXC=INT>
    Exception PC: 0xbfc0b598
    Interrupt exception
    CPU Parity Error Interrupt
    Local I/O interrupt register 1: 0x80 <VR/GIO2>
    CPU parity error register: 0x80b<B0,B1,B3,SYSAD_PAR>
    CPU parity error: address: 0x1fc0b598
    NESTED EXCEPTION #1 at EPC: 9fc3df00; first exception at PC: bfc0b598
   
この場合、マシンの PROM を新しい版にアップグレードするか、古い CPU に戻す必要があります (通常 R4000SC と R4400SC モジュールは動くはずです)。はっきり言っておきますが、この問題は Linux とは無関係です。ここでこれを取り上げているのは幾人かの Linux ユーザがこれについて質問を出していたからです。

私の Indy でメモリがこんなにシステムで使われてしまうのはなぜ?

ブート時に Indy の `Memory: ...' メッセージは 128 MB のメモリがシステムで使われていると答えます。これは正常です。 PC アーキテクチャで、メモリアドレスの 640KB から 1024KB までに隙間が開いているのと同様、Indy のメモリアドレス空間内に最初の 128MB がイメージとして現れる部分があるためです。Linux はそのことを知っていて、そのメモリを単に無視するため、このようなメッセージが出るのです。

10.3 Milo

Milo は、ARC ファームウェアのリトルエンディアン MIPS システムをブートさせるためのブートローダであり、現在 Jazz ファミリと SNI RM 200 に使われています。Milo は Alpha システムで使われる Milo と名前が同じで目的もほぼ同じですが、この二つの Milo にはそれ以外に共通点はありません。この二つは別々の人たちが開発しましたし、 コードも全く別々で、違うハードウェアプラットフォームで動作します。 この二つが同じ名前なのは、単に歴史的な「事故」というべきものです。

Milo は、RM200C 以外の ARC プラットフォームでは必要なくなっています。 他のすべてのプラットフォームでは、ECOFF カーネル (またはより新らしいファームウェア下では ELF カーネル) を、Milo や相当品の必要なしに直接実行可能です。RM200C ではファームウェアのおかしな振る舞いのため、Milo 0.27.1 がカーネルのブートのために引き続き必要です。

Milo のビルド

Milo のビルドの手順は、Milo パッケージの README ファイルに詳細にわたって書かれています。Milo はカーネルのヘッダファイルに多少の依存関係を持ちますが、 このヘッダファイルはカーネルリリースと共に変わるものですから、Milo を簡単に作成できないことが良くあります。但し、Milo の配布ファイルには Milo と Pandora 両方のバイナリが含まれています。Milo のビルドは簡単ではありません。 もし Milo を自分で変更したいと言うことでなければ、とりあえずのお勧めは Milo tarball に含まれているバイナリを用いることです。

Pandora

Pandora は技術文書のないシステムを解析することを主たる目的として開発された簡単なデバッガです。 Pandora には逆アセンブラやメモリダンプ機能などが含まれています。 単に Linux を使いたいだけならば、Pandora を (サイズは小さいですが) インストールする必要はないでしょう。

10.4 ローダブルモジュール

Linux/MIPS でモジュールを使うのは実に簡単です。他の Linux システムのモジュール機能を使っていた人が期待するとおりに動きます。 モジュールを使ったシステムを走らせたい場合、少なくとも 980919 版以降のカーネルと、バージョン 2.1.121 より新しい modutils を使ってください。これより古いものは動きません。

10.5 クロスコンパイラ環境の構築方法

入手できるバイナリ

クロスコンパイラ環境を構築する一番やさしい方法は、バイナリを ftp://ftp.linux-mips.org/pub/linux/mips/crossdev/ からダウンロードしてくることです。 真面目な話、Linux/MIPS の 8 年の歴史から、Linux/MIPS で多くのユーザが直面する最大の問題がこれであるということが明らかになっています。 Linux/i386 用のビッグエンディアンターゲット向けのパッケージは次のものです。

    binutils-mips-linux-2.13.2.1-1.i386.rpm
    egcs-c++-mips-linux-1.1.2-4.i386.rpm
    egcs-g77-mips-linux-1.1.2-4.i386.rpm
    egcs-libstdc++-mips-linux-2.9.0-4.i386.rpm
    egcs-mips-linux-1.1.2-4.i386.rpm
    egcs-objc-mips-linux-1.1.2-4.i386.rpm
   
そして、次がリトルエンディアン向けのパッケージのリストです。
    binutils-mipsel-linux-2.13.2.1-1.i386.rpm
    egcs-c++-mipsel-linux-1.1.2-4.i386.rpm
    egcs-g77-mipsel-linux-1.1.2-4.i386.rpm
    egcs-libstdc++-mipsel-linux-2.9.0-4.i386.rpm
    egcs-mipsel-linux-1.1.2-4.i386.rpm
    egcs-objc-mipsel-linux-1.1.2-4.i386.rpm
   
64-bit MIPS カーネル向けには、現在二つのパッケージのみが入手できます。
    egcs-mips64-linux-1.1.2-4.i386.rpm
   
と、リトルエンディアン 64 bit システム向け
    egcs-mips64el-linux-1.1.2-4.i386.rpm
   
です。

これらの全部をインストールする必要はなく、殆どの人は C++、Objective C と Fortran 77 の各コンパイラは省略してよいでしょう。 Intel 版のバイナリは GNU libc 2.2 にリンクされているので、 アップグレードする際にはこれもインストールする必要があるでしょう。

おすすめのコンパイラのバージョン

Binutils

お勧めなのは、binutils 2.13.2.1 です。

gcc

2003-05-16 より前の Linux 2.4 カーネルをコンパイルするのに最低必要な gcc のバージョンは egcs 1.1.2 です。それ以降の 2.4 系列、および 2.5、2.6 カーネルをコンパイルするのに最低必要な gcc のバージョンは gcc 2.95.3 です。 古すぎるコンパイラでは、コンパイラがコアダンプしたり、音もなくコンパイルに失敗したカーネルができたりします。 ツールが新しい場合コード生成が改善されていますが、これはできあがったカーネルの性能にはほとんど影響しません。 一方、ツールが新しい場合コードの生成が劇的に遅くなる傾向にありますから、MIPS ポートのメンテナを含む一部の人たちは、古くなっているにもかかわらず旧コンパイラを使い続ける傾向にあります。

ユーザ側のアプリケーションとライブラリを作成するには、多分新しいコンパイラが欲しくなるでしょう。 一般的に言って、2.95.3 はとても安定して、同時にまずまず高速であると考えられています。 C++ 言語の進化と、C++ ユーザの ABI の関係で使えるコンパイラに制約が出てくる場合があるかもしれません。 恐らく、とても新しい gcc 3.2 などのコンパイラがよい選択になるでしょう。

ここで、カーネルとユーザ用アプリケーションで同じコンパイラを使う必要はないことに留意ください。 同じコンパイラを使う必要があるのは、すべての C++ コードに対してのみです。

glibc

この文書ではまだ glibc 2.0.6 をビルドする方法を採り上げていますが、これはもう新規プロジェクトには推奨できません。 バイナリサイズのために glibc 2.0.6 を検討していたユーザは、ucLibc を代わりに検討ください。コンパイラをビルドするだけが目的なら、glibc をクロスコンパイラ環境にインストールする必要はありません。

uClibc

uClibc はとても小さな libc の置き換えで、 http://www.uclibc.org から入手できます。MIPS 向けのものは、 ftp://ftp.realitydiluted.com/linux/MIPS/toolchains にあります。

自分でクロスコンパイラを作成する

最初に次のソースパッケージをダウンロードしてきてください。

これらのパッケージはお好みの GNU アーカイブサイトか、 ftp.linux-mips.org から入手できます。更に、パッチが必要になります。MIPS に限った話ではありませんが、バンドルされていないパッチはいつでも最新のものとは限りませんし、 ビルドするには MIPS に固有ではない追加パッチが必要になるかもしれません。 これらの別配布のパッチは異なったバージョン番号付けを行っていることもありますので、お勧めの方法は ftp.linux-mips.org で配布されている RPM パッケージから、ソースとパッチを入手することです。

また、上記のものが現在お勧めのバージョンです。 古いバージョンは動くかどうか分かりません。 もし古いバージョンを使おうと頑張っているということでしたら、バグレポートは送らないでください。 どちらにせよ見ませんので。また、インストールする際には、binutils、egcs、 glibc の順に行ってください。古いバージョンが既に入っている場合を除いては、 この順番を変えると うまくいきません

必要なディスク容量

インストール時に、ファイル群をインストールする先のディレクトリを指定しなければなりません。 以下ではそのディレクトリを <prefix> と呼ぶことにします。 特定の条件で発生するような問題を避けるため、<prefix> の値はそのマシンの本来の gcc と同じ値にするのが最良です。 例えば gcc が /usr/bin/gcc としてインストールされているなら、<prefix> として /usr を選んでください。 これからインストールしようとしているパッケージすべてに対して、同じ <prefix> を用いる必要があります。

コンパイル中には、binutils には約 31MB のディスクの空きが必要です。 また、インストールするためには <prefix> のあるパーティションに 7MB の空きが必要です。egcs の作成には 71MB が、インストールには 14MB が必要です。 GNU libc はコンパイルに 149MB の空きが、そしてインストールには 33MB が必要です。注意してほしいのは、これは単なる目安だということです。 この値は、異なるプロセッサ、オペレーティングシステム、コンパイラオプションなどによって大きく異なるかもしれません。

バイトオーダ

MIPS アーキテクチャの特徴的な機能の一つは、R8000 以外のすべてのプロセッサが、設定によってビッグエンディアンとリトルエンディアンのどちらででも動作できることです。 バイトオーダとは、メモリ中にプロセッサが複数のバイトを格納するやり方です。 ビッグエンディアンのマシンでは、最大の桁側のバイト値が最小のアドレス位置に格納されます。 リトルエンディアンのマシンでは、これが最大のアドレス位置に格納されます。 複数の数字からなる数を左から右に書くか、逆順で書くかの違いだ、と考えてください。 クロスコンパイラ環境を正しく設定するためには、クロスコンパイラのターゲットとなるマシンのバイトオーダを知らなければなりません。 ターゲットマシンのエンディアンの設定を既に知っているのでなければ、 マシンのバイトオーダについて ハードウェアプラットフォーム の節を参照ください。

設定に使う名前

autoconf を使うパッケージの多くは、様々なアーキテクチャとオペレーティングシステムをサポートしています。 これら多くの設定を区別するため、名前が <cpu>-<company>-<os> や <cpu>-<company>-<kernel>-<os> のように付けられています。この表現を使えば、Linux/MIPS の設定の名前は ビッグエンディアン向けには mips-unknown-linux-gnu で、リトルエンディアン向けには mipsel-unknown-linux-gnu です。この二つの名前は多少長いため、順に mips-linux と mipsel-linux という省略形が許されています。 クロスコンパイル時の各パッケージのインストールでは、全パッケージに同じ名前を 使わなければいけません。 また、他の名前、例えば mips-sni-linux や mipsel-sni-linux も正しい設定名ですが、mips-linux と mipsel-linux のほうを使ってください。 これらの名前は Linux カーネルソースなどの他のパッケージでも使っていますので、 上記の二つ以外のものを使うとクロスコンパイル時に変更を行う必要が出てきます。

以下ではターゲットの設定に使う名前は <target> と呼びます。

GNU Binutils のインストール

ここは最初の、最もやさしい部分です (少なくとも多少は真っ当な UNIX 系の OS 上でインストールしようとしている場合には、ですが)。 十分な空き容量のあるディレクトリに cd して、次の処理を行ってください。

    gzip -cd binutils-<version>.tar.gz | tar xf -
    cd binutils-<version>
    patch -p1 < ../binutils-<version>-mips.patch
    ./configure --prefix=<prefix> --target=<target>
    make CFLAGS=-O2
    make install
   
これで通常は正しく動作します。但し、GCC 2.7.x をコンパイラに使っている一部のマシンではコアダンプすることが知られています。 これは GCC の既知のバグで、ホストマシンのコンパイラを GCC 2.13.2.1 以降のものにすることで修正できます。

assert.hについて

一部の人たちの環境には古い assert.h ヘッダファイルがインストールされています。 これはおそらく古いクロスコンパイル環境の残骸だと思いますが、このファイルが残っていると autoconf はなにも言わずに失敗します。 assert.h が必要になることはありません。これは昔の版の GCC のバグのせいでインストールされたものの残骸です。 <prefix>/<target>/include/assert.h があなたのインストール環境に無いことを確認してください。 あった場合は、単に消してください。 これはどの版のクロスコンパイル環境でもインストールされるべきでは決してありませんし、トラブルの元にもなります。

カーネルソースのインストール

カーネルソースのインストールは簡単です。 単にお好みのどこかのディレクトリに置き、設定するだけです。設定は必ず行ってください。 というのは、その過程で作成されるファイルが、インストールされるからです。 設定の最後のほうで CONFIG_CROSSCOMPILE を有効にすることを忘れないでください。 引っかかる可能性のある問題は、場合によると bash のような GNU プログラムのインストールが必要になるかもしれないこと、また PATH 環境変数を直して、ベンダの提供したものではなく GNU 版のプログラムが先に呼ばれるようにしなければならないかもしれない、という二点だけです。 インストール後に、直接 <prefix>/<target>/include に行って二個のシンボリックリンク、asm と linux を include/asm と include/linux を指すように作成してください。 この作業は、次のステップ中に必要なヘッダファイルが見つかるようにするために、やっておかなければなりません。

egcs の最初のインストール

さて、ここからが難所になります。いわゆるブートストラップ (ニワトリと卵) 問題のためです。今回の場合、egcs のインストールには glibc があらかじめインストールされている必要がありますが、 まだ動作するクロスコンパイラができていないので glibc のコンパイルができないのです。 ありがたいことに、これを突破する必要があるのは、 クロスコンパイラを作る最初の一回だけです。 この後 glibc をインストールし終えたら、物事はずっとスムーズに行きます。 では、行きましょう。

    gzip -cd egcs-1.1.2.tar.gz | tar xf -
    cd egcs-<version>
    patch -p1 < ../egcs-1.1.2-mips.patch
    ./configure --prefix=<prefix> --with-newlib --target=<target>
    make SUBDIRS="libiberty texinfo gcc" ALL_TARGET_MODULES= \
            CONFIGURE_TARGET_MODULES= INSTALL_TARGET_MODULES= LANGUAGES="c"
   
慎重に、gcov、protoize、unprotoize とライブラリは作らないように進めます。 gcov はクロスコンパイラ環境では意味をなしませんし、protoize と unprotoize は gcc の makefile のバグのため、既存の自マシン用のプログラムを上書きしてしまうかもしれません。 最後に、ライブラリは glibc がまだインストールされていないため、作成できません。 すべてうまくいったら、次のようにインストールしてください。
     make SUBDIRS="libiberty texinfo gcc" INSTALL_TARGET_MODULES= \
             LANGUAGES="c" install
   
カーネルを作成するためのクロスコンパイラがほしいだけなら、ここで終了です。 libc のクロスコンパイルは、ユーザアプリケーションをクロスコンパイル場合にのみ必要になります。

ここまでやってきたことのテスト

ここまでやってきたことが実際正しく動作するかを確認するには、この時点でカーネルをコンパイルしてみればよいでしょう。 MIPS カーネルソースのディレクトリに cd して、`make clean; make dep; make'' と打ってみてください。 すべて問題なければ、``make clean'' を行って、再度ソースをきれいにしておいてください。

GNU libc のインストール

注意:glibc 2.0.6 を egcs 1.0.3a より新しいコンパイラでコンパイルするのは お薦めできません。一部のプログラムが、 バイナリの互換性問題にあたってしまうかもしれませんので。egcs 1.0.3a を使うか、公開されているバイナリパッケージを使うことを勧めます。 また、GNU libc をクロスコンパイルするのは常に次善の方法です、 というのはクロスコンパイル時にはコンパイルされない部分があるからです。 適切なやり方が見つかって安定性が確認されしだい、ここでそのやり方を文書化したいと思います。 それでは、注意が済みましたので、レシピを。

       gzip -cd glibc-2.0.6.tar.gz | tar xf -
       cd glibc-2.0.6
       gzip -cd glibc-crypt-2.0.6.tar.gz | tar xf -
       gzip -cd glibc-localedata-2.0.6.tar.gz | tar xf -
       gzip -cd glibc-linuxthreads-2.0.6.tar.gz | tar xf -
       patch -p1 < ../glibc-2.0.6-mips.patch
       mkdir build
       cd build
       CC=<target>-gcc BUILD_CC=gcc AR=<target>-ar RANLIB=<target>-ranlib \
             ../configure --prefix=/usr --host=<target> \
             --enable-add-ons=crypt,linuxthreads,localedata --enable-profile
       make
     
これでコンパイル済みの GNU libc ができましたが、まだインストールする必要があります。 ここで単に make install と 打ってはいけません。 これをやるとホストマシンのシステムファイルが Linux/MIPS 向けのファイルに置き換わって、破壊的な結果になります。 そうではなく、GNU libc をどこか他のどこかのディレクトリ <somedir> に一旦インストールして、そこからクロスコンパイルに必要になる部品を実際のターゲットディレクトリに移動します。
       make install_root=<somedir> install
     
ここで、<somedir> に cd して、最後に GNU libc を手動でインストールします。
       cd usr/include
       find . -print | cpio -pumd <prefix>/<target>/include
       cd ../../lib
       find . -print | cpio -pumd <prefix>/<target>/lib
       cd ../usr/lib
       find . -print | cpio -pumd <prefix>/<target>/lib
     
GNU libc には詳しいオンラインドキュメントが含まれています。 あなたのシステムには既にこのドキュメントのどれかの版が含まれているでしょうから、もし info ページをインストールしたくない場合 (1MB 弱節約できます) や、既にインストールされている場合には、次の手順を飛ばしてください。
       cd ../info
       gzip -9 *.info*
       find . -name \*.info\* -print | cpio -pumd <prefix>/info
     
ブートストラップしない人は、ここでインストールはおしまいです。

egcs の再作成

最初の egcs の作成は GNU libc が無いため途中で止まっていました。今は libc もインストールしてあるので、ここで egcs の再作成を行えます。 今回はクロスコンパイラとして完全なインストールができます。

       gzip -cd egcs-<version>.tar.gz | tar xf -
       cd egcs-<version>
       patch -p1 < ../egcs-1.1.2-mips.patch
       ./configure --prefix=<prefix> --target=<target>
       make LANGUAGES="c c++ objective-c f77"
     
見たとおり、手順は最初の時と殆ど同じですが、今回は --with-newlib オプションは省略します。このオプションは libgcc のビルドが libc が無いことで落ちるのを防ぐために必要でした。インストールは次のようにします。
       make LANGUAGES="c c++ objective-c f77" install
     
さて、殆ど完了です。もし Objective C や F77 コンパイラが不要なら、上記のコマンドから省くことができます。各々 3MB 位の節約になります。gcov、protoize と unprotoize は作成しないでください。

C++、Objective C や F77 コンパイラを作成すべきでしょうか?

この答えは、クロスコンパイラ環境の目的に大きく依存します。 もしあなたが Linux カーネルを再作成することだけを考えているなら、何もかものセットアップを進める必要はなく、Objective C と F77 コンパイラは省いても問題ないでしょう。但し、C++ コンパイラを作成する必要はあります。これは egcs ディストリビューションに含まれるライブラリを作成するには C++ が必要なためです。

クロスコンパイルでの既知の問題

IRIX がクラッシュする

Origin 200 で IRIX 6.5.1 を走らせている場合、Linux カーネルソースから “make depend” を実行するとクラッシュすることがあります。 Indy 上の IRIX 6.5 と Origin 200 の IRIX 6.5.4 は動くことが分かっています。

System V 系のホストでのリソース制限

System V 系の Unix システム、例えば IRIX や Solaris には子プロセスに渡せる引数の個数に制限があり、この制限を Linux カーネルや GNU libc のクロスコンパイル時に超えてしまうことがあります。 IRIX システムでは引数のリストの最大長の既定値は 20KB ですが、Linux では少なくとも 128KB はあります。このサイズは root から `systune ncargs 131072'' コマンドを使って変更できます。

GDB

GDB をクロスデバッガとして作成することに興味を持つのは、カーネル開発者だけでしょう。 カーネル開発者にとっては、GDB は命綱かもしれません。 このようなリモートデバッグの設定はいつも二つの部分、あるマシン上で動く GDB リモートデバッガと、デバッグ対象の Linux/MIPS カーネルの動くターゲットマシン、 からなります。この二台のマシン間は通常シリアルラインで接続されています。 ターゲットマシンのカーネルには『デバッグ用プラグ』を備えておき、 リモートシリアルプロトコルを用いる GDB ホストマシンと通信できるようにしておく必要があります。

ターゲットのアーキテクチャに依存しますが、おそらく『デバッグ用プラグ』は自分で作り込む必要があります。 だいたいの場合は、シリアルライン用のとても簡単なルーチンを作る必要があるだけです。 この作業は、殆どのマシンが通常 8250 や 16450 相当品 を用いたよく似たシリアルハードウェアを用いているため、とても簡単なものです。

【訳注: 8250 と 16450 は殆ど同じ。16550A はソフトウェア上位互換で、最近の PC-AT用のシリアルとして使われているものです。】

10.6 カーネルのコンパイル

プロセッサタイプを選択する

R2000, R3000 ファミリ

これらのプロセッサでは、単に R3000 オプションを選択してください。 このオプションで作成されたカーネルは R2000 と R3000 ファミリのプロセッサ以外では走りません。

R4000, R5000 ファミリ

Nevada ファミリを除いては、これらのプロセッサはカーネルの観点からはすべて互換です。 最良の性能が得られるオプションを選択してください。

R6000

Linux は現在 R6000 をサポートしていないので、以下は完全に理論上のみの話です。 R6000 のキャッシュと MMU アーキテクチャは、変とは言わないまでも独特で、 とても扱いにくいため多量の対処作業が必要になります。 このため R6000 カーネルは他のプロセッサでは動かないでしょうし、 他のプロセッサ用のカーネルも R6000 では動かないでしょう。

Nevada

Nevada の愛称は、QED (現PMC Sierra) 社の RM5230, 5231, R5260, R5261, R5270 ファミリプロセッサに付けられたものです。このオプションでは、 他のプロセッサではサポートされていない追加命令が有効にされるため、 このオプションを選択していいのは、本当にこの一群のプロセッサのどれかを使っているときのみです。 自信がなければ、 R4x00 か R5000 ( 上記参照) を使えば、Nevada ファミリのプロセッサでも動作するカーネルができますが、一部のプロセッサ固有の最適化は行われません。

SB1

Sibyte SB1 プロセッサの時のみこのオプションを選択してください。 このプロセッサ向けに作成されたカーネルは他のプロセッサでは動きませんし、 逆もまた真です。

【訳注: SB1 はコア名で、このコアを採用しているのは Broadcom BCM1250, BCM1125 などです。Sibyte は Broadcom に買収されていますが、Sibyte の名称はまだ残しています。】

R10000

R10000, R12000 または R14000 システムで Linux を実行する場合にはこれを選んでください。 このオプションを付けて作られたカーネルは R4000 や R5000 ファミリプロセッサでは動作しません。

MIPS32

MIPS32 ファミリメンバで Linux を走らせる場合、これを指定してください。

オプションの互換性

カーネル設定手順は、誤った設定が不可能になるような強過ぎる制約を入れてはいません。 例えば SGI Indy ではフレームバッファは使えませんが、有効にすることはできますし、その結果後でコンパイルエラーになります。 この状況は将来 CML2 が標準のカーネル設定言語になれば改善されるでしょうが、2.2 と 2.4 カーネルでは、自分で足下に気を付ける必要があります。

クロスコンパイル

カーネルは非 MIPS システム上でのクロスコンパイル作成が可能となるように、注意深く開発されています。 一旦クロスコンパイラの設定という崖を登ってしまいさえすれば、クロスコンパイルは容易です。 これを行うためには、二つの選択枝があります。最初のものは、 CROSS_COMPILE=<target>- (最後のダッシュに注意) の後に mips-linux, mipsel-linux, mips64-linux, mips64el-linux のいずれかを続けたものを、make を起動する際の追加引数として渡す方法です。 このうちのどれにするかは、ターゲットマシンが ビッグエンディアンかリトルエンディアンか、32-bit か 64-bit か、 によります。

もう一つの、多分より易しいやり方は、CONFIG_CROSSCOMPILE 設定オプションを与える方法です。カーネルはそれにより、CROSS_COMPILE に正しい値を自動的に設定しますので、コマンド行が少し簡単になります。

32-bit vs. 64-bit

標準では Linux/MIPS カーネルソースツリーは 32-bit ターゲットを作成するようになっています。もし、64-bit の 2.4.x カーネルをビルドしたい場合は、make が呼び出されるすべての箇所で ARCH=mips64 の追加引数を渡してやる必要があります。2.6.x ではこれは通常の設定オプションになっています。


次のページ 前のページ 目次へ