64ビットコンピューティング: 32ビット環境での共存
執筆者: Tim Waugh
64ビットコンピューティング入門
80年代に筆者が初めて手にしたコンピュータはCommodore 64でした。この名前は、64 KBのメモリを搭載していたことに由来しています。今日では、そのような小さなスペースに収まるアプリケーションはほとんど見当たらず、アプリケーションのサイズはますます大きくなっています。Webブラウザは、Webページをダウンロードしなくても数十メガバイトのメモリを消費する場合があります。コンピュータはアプリケーションを高速で実行できるようにいっそう大容量のRAMを搭載し、アプリケーションはますます幅広い機能を備えてそれを利用しています。
RAMの容量を増大させるとともに、RAMへの高速アクセスも必要になります。大部分の家庭用コンピュータは32ビットのマイクロプロセッサを搭載していますが、すでに能力不足になりつつあります。
64ビットのマイクロプロセッサは64ビットを保持する整数レジスタを備えており、メモリストレージとCPUレジスタ間で64ビットのデータを単一動作で移動させることができます。HP® Alpha™プロセッサ、Apple® PowerPC G5™、およびAMD® Opteron™/Intel® EM64Tなどがその例です。あとの方に挙げたプロセッサはAlphaとは異なり、64ビット動作に対応して設計されていると同時に、以前の32ビットプロセッサ用のプログラムも実行できます。
これにより、通常は以前のソフトウェアを継続使用できるため、旧システムからの移行がはるかに容易になります。実際、当面は64ビットコンピュータの新製品が、32ビットプロセッサ用にコンパイルされたオペレーティングシステムを搭載して販売されることもありそうです。
このタイプのプロセッサに関して興味深いことの1つは、64ビットのオペレーティングシステムで32ビットプログラムと64ビットプログラムの両方を同時に実行できることです。Linux(つまり、GNUツールチェーンとLinuxカーネル)は、このタイプの各種プロセッサで実行できるように移植が行われています。
64ビットコンピュータを手にする幸運に恵まれていない皆さんは、32ビット環境と64ビット環境を併用する場合の考慮事項を十分に理解できていないかもしれません。では、それらについて説明しましょう。
考慮事項
ファイルシステムのレイアウト
64ビットオペレーティングシステムは、新しい命令セット用にコンパイルされたライブラリを提供します。ダイナミックリンクされた32ビットバイナリアプリケーションを実行するには、そのアプリケーションが必要とするライブラリも、すべて32ビット命令セットで利用できる必要があります。また、それらのライブラリがほかのライブラリにダイナミックリンクされている場合は、リンク先のライブラリも、Cライブラリそのもの(GNUシステムにおけるglibcなど)に至るまで、すべてその形式で利用できることが必要です。
そのため、32ビットプログラムを64ビットシステムで実行するには、Cライブラリのセットが2つ(それとは別により多くのライブラリ)オペレーティングシステムによって提供される必要があり、それらの追加のライブラリはファイルシステム内に存在している必要があります。ある特定のライブラリに複数のインスタンスがあり、各インスタンスがプロセッサによってサポートされている異なる命令セットに対応する場合、そのライブラリは通常、multilibと呼ばれます。
追加のライブラリを配置する場所については、決まったソリューションはありません。どのアプローチを採用しても同じようなものであり、任意に決定できます。Red Hat Enterprise LinuxとFilesystem Hierarchy Standard(FHS)では通常、32ビットライブラリに/lib/(および/usr/lib/)ディレクトリが使用され、64ビットライブラリに/lib64/(および/usr/lib64/)ディレクトリが使用されます。Debianでは、64ビットライブラリに/lib/、32ビットライブラリに/lib32/が使用されます。ディレクトリの選別はダイナミックローダによって行われるため、64ビットプロセッサで実行される32ビットプログラムに対して透過的です。
|
32ビット(互換)ライブラリ |
64ビット(ネイティブ)ライブラリ |
| Fedora Core |
/lib/,
/usr/lib/ |
/lib64/,
/usr/lib64/ |
| Debian |
/lib32/,
/usr/lib32/ |
/lib/,
/usr/lib/ |
表1. multilibのディレクトリ構造
32ビットプログラムはファイルシステム内のどこに配置すべきだろうか、/lib/と同様の方式を/bin/ディレクトリにも適用すべきだろうかと考えるかもしれません。しかし、普通はその必要はありません。オペレーティングシステムが提供するバイナリプログラムは、通常、64ビット命令セット用にコンパイルする必要があるだけです。サードパーティ製パッケージでインストールされるバイナリプログラムは、オペレーティングシステムが提供するバイナリプログラムとは名前が異なります。それに加えて、サードパーティ製パッケージでは多くの場合、ファイルは/usr/local/または/opt/にインストールされます。
プラグイン
旧型プロセッサ用にコンパイルされたソフトウェアを新型プロセッサで実行できることは確かに便利ですが、事情はそれほど単純ではありません。アプリケーションのなかには、スタンドアロンプログラムの形式ではなく、他のアプリケーションへのプラグインとして提供されるものもあります。そうした例の1つは、Webブラウザ用のMacromedia Flashプラグインです。現在、このプラグインはLinuxで利用できますが、32ビットのIntel互換プロセッサでしか動作しません。
Webブラウザのプラグインは、Webブラウザプログラムによって動的にロードされるライブラリです。現在、Linuxでは、64ビットプログラムによって32ビットライブラリを動的にロードすることは不可能です。そのため、(たとえば)64ビットのMozilla Firefoxは、Fedora Core上でMacromedia Flashプラグインをまったく利用できません。
1つの対応策は、64ビットのMozilla Firefoxパッケージをアンインストールし、32ビットのFedora Coreディストリビューションから同等のパッケージをインストールすることです。こうすれば、Webブラウザが32ビットアプリケーションになるため、Flashなどの32ビットプラグインをロードすることが可能です。ただし、この場合は64ビットプラグインをまったく利用できなくなります。
スクリプトとインタプリタ
このmultilib環境では、インタプリタ型言語で作成したプログラムの方が、Cなどで作成してコンパイルしたものよりも、いくぶん利用しやすいといえます。しかし、その場合でも面倒な問題はあります。
シェルスクリプトでも、実行環境のアーキテクチャの影響を受ける場合があります。たとえば、シェルスクリプトがunameコマンドの出力に応じて異なる動作をすることがあります。このコマンドは、unameシステムコールを使用してシステムハードウェアのさまざまな側面についてカーネルに問い合わせます。
unameコマンドの動作は、setarchコマンドを使用して調整できます。たとえば、AMD64搭載マシンでは、uname -mはx86_64を出力しますが、setarch i686 uname -mはi686を出力します。このコマンドは、setarch RPMパッケージからインストールされます。
その他の問題
Red Hat Enterprise Linuxでは1つのパッケージを32ビット形式と64ビット形式の両方で同時にインストールできるため、パッケージングの問題も対処されています。パッケージは、同一システムに32ビット形式と64ビット形式の両方でインストールされるものと、されないものとの2つのグループに分類できます。2回インストールされるものはmultilibパッケージと呼ばれ、正しく動作するには特定の要件を満たす必要があります。multilibパッケージは、glibc、zlib、gtk2のようなシステムライブラリに多くみられます。
同じRPMパッケージについて2つのインスタンスをインストールする場合は、競合を避けるために特定のルールに従います。コンパイル済みのプログラム(ライブラリではありません)については、64ビットバージョンがインストールされ、32ビットバージョンは廃棄されます。その他のタイプのファイルは、32ビットパッケージと64ビットパッケージの両方ですべて厳密に同一である必要があります。
ビルド時間の問題
最初の一連の問題は、RPM specファイルの記述に関係します。これらのファイルは、RPMパッケージのビルドプロセスに指示を与え、生成されるファイルをインストールするファイルシステム内の位置を指定します。1つのRPM specファイルには、複数のサブパッケージを記述できます。たとえば、cups.specには、cups、cups-libs、およびcups-devel RPMパッケージが記述されています。
主な問題は、/libまたは/usr/libで始まるパスに関係します。64ビットアーキテクチャでは、これらはほとんど常に/lib64および/usr/lib64となる必要があり、それはmultilib RPM以外のパッケージにも当てはまります。
ライブラリがパッケージングされている場合は、RPM specファイルでマクロの%{_libdir}を使用する必要があります。これは、適宜/usr/libまたは/usr/lib64に置き換えられます。類似したマクロである%{_lib}は、必要に応じてlibまたはlib64に置き換えられます。
一般に、RPM specファイルでは、ライブラリは専用のサブパッケージに収める必要があります。これによって、多くの潜在的問題を防止できます。
インストール時間の問題
bashパッケージは、バグレポートのための小規模なシェルスクリプト(bashbug)を提供します。このスクリプトはメッセージをメーリングリストに送信し、ハードウェアアーキテクチャ、使用されているコンパイラフラグ、バージョン番号、その他のいくつかの情報を詳細に報告します。コンパイラフラグが32ビットパッケージと64ビットパッケージで異なるため、2つのシェルスクリプトの内容は異なります。
bashはmultilibパッケージであるため、問題が発生します。このバグレポートプログラムを両方のパッケージで/usr/bin/bashbugとしてコールすることはできません。さもないと競合が発生します。コンパイル済みプログラム間の競合を解決するためのRPMのルール(64ビットバージョンを優先すること)は、シェルスクリプトには適用されません。この問題は、32ビットパッケージではプログラムをbashbug-32と命名し、64ビットパッケージではbashbug-64と命名することで解決されています。
multilibパッケージのインスタンスを両方ともインストールするときに競合を引き起こす可能性のあるもう1つの問題は、圧縮に関係しています。パッケージのなかには、一部のファイル(マニュアルなど)がgzipコマンドを使用して圧縮されているものがあります。このコマンドは圧縮ファイルにタイムスタンプを埋め込むため、注意が必要です。競合を回避するには、コンパイル済みプログラム以外のすべてのファイルがmultilibパッケージの2つのバージョン間で同一である必要があります。32ビットパッケージが64ビットパッケージの1秒後にビルドされた場合、圧縮ファイル内のタイムスタンプが各パッケージで異なることになります。
この問題の防止策は、gzip -nオプションを使用することです。このオプションを指定すると、タイムスタンプは圧縮ファイルに埋め込まれません。
結論
関連する詳細事項はここで説明したよりもはるかに数多くあり、修正すべきmultilib RPMパッケージの問題はまだあります。通常は、すべてが非常にうまく機能します。1つの大きな問題は、オープンソースコミュニティにmultilib環境での経験と知識が不足していることです。たとえば、ライブラリはすべて/usr/libに配置されるということがいまだに前提とされています。64ビットコンピュータは普及しつつあり、筆者としては状況が引き続き改善していくことを望んでいます。
あと30年かそこらで、32ビットコンピューティングの時代は終わります。「1970年以降の秒数」で時間を計る方式は、32ビットの整数では表現できない時間幅を計る必要に迫られます。おそらく、そのときまでに我々はみな128ビットコンピュータを使用していることでしょう。
執筆者について
Tim Waughはレッドハットのシステムエンジニアであり、主にスキャニング/プリンティング、DocBook、VNC、一部のシェルユーティリティを担当しています。彼は1995年以来Linuxを使用しており、妻とともにサリー(イングランド)で暮らしています。