Solaris 7 64 ビット 開発ガイド

第 3 章 32 ビットと 64 ビットインタフェースの比較

第 2 章「64 ビットの使用方法」で説明したように、ほとんどの 32 ビットアプリケーションは、変更しなくても 64 ビット Solaris 環境で動作します。アプリケーションによっては、64 ビットアプリケーションとして再コンパイルしたり、完全 64 ビットプログラムに変換する必要があります。この章では、アプリケーションを再コンパイルしたり、64 ビットに変換する必要がある開発者向けに、第 2 章「64 ビットの使用方法」で述べた項目に基づいて説明します。

アプリケーションプログラミングインタフェース

64 ビットオペレーティング環境でサポートされている 32 ビットアプリケーションプログラミングインタフェース (API) は、32 ビットオペレーティング環境でサポートされている API と同じです。したがって、32 ビットアプリケーションを 32 ビットおよび 64 ビットの環境間で変更する必要はありません。ただし、64 ビットアプリケーションとして再コンパイルする場合には修正作業が必要になります。64 ビットアプリケーション用にコードを修正するためのガイドラインについては、第 4 章「アプリケーションの変換」を参照してください。

64 ビット API とは、基本的に UNIX 98 ファミリーの API です。その仕様は、派生型を使って書かれています。64 ビットバージョンを作成するには、その派生型のいくつかを 64 ビットに拡張します。これらの API を使って正しく書かれたアプリケーションは、32 ビットと 64 ビット間でソースを移植できます。

アプリケーションバイナリインタフェース

SPARCTM V8 ABI は、既存のプロセッサ固有のアプリケーションバイナリインタフェース (ABI) で、32 ビット SPARC バージョンの Solaris 実装はこのインタフェースに基づいています。 SPARC V9 ABI は、 SPARC V8 ABI を拡張して 64 ビット動作をサポートし、拡張アーキテクチャの新しい機能を定義しています。追加情報については、「アプリケーションに関する新しい情報」を参照してください。

互換性

32 ビットおよび 64 ビットアプリケーション間のさまざまなレベルの互換性について説明します。

アプリケーションバイナリ

既存の 32 ビット SPARC アプリケーションは、バイナリの互換性があり、32 ビットまたは 64 ビットのオペレーティングシステム環境で実行できます。唯一の例外は、 libkvm/dev/kmem、または /proc を使用するアプリケーションです。詳細は、第 2 章「64 ビットの使用方法」を参照してください。

アプリケーションソースコード

32 ビットアプリケーションに対しては、ソースレベルの互換性が維持されています。64 ビットアプリケーションについては、アプリケーションプログラミングインタフェースに使用される派生型に変更が加えられています。正しい派生型およびインタフェースを使用しているアプリケーションは、32 ビットに対してソースレベルで互換性があり、より容易に 64 ビットに移行することができます。

デバイスドライバ

32 ビットデバイスドライバは、64 ビットオペレーティングシステムでは使用できないため、32 ビットデバイスドライバは、64 ビットオブジェクトとして再コンパイルしなければなりません。さらに、64 ビットドライバは、32 ビットと 64 ビットの両方のアプリケーションをサポートしなければなりません。64 ビットオペレーティングシステム環境に提供されているドライバはすべて、32 ビットと 64 ビットの両方のアプリケーションをサポートしています。ただし、基本ドライバモデル、つまり DDI (Device Driver Interface) でサポートされているインタフェースに変更はありません。必要な作業は、LP64 データ型モデルの環境で適切となるようにコードを修正することです。詳細は、『Writing Device Drivers』を参照してください。

どの Solaris オペレーティング環境を実行するか

Solaris は、2 つの first class アプリケーションバイナリインタフェース (ABI) を同時にサポートしています。言い換えれば、2 つの独立した、完全に機能するシステムコールパスが、64 ビットカーネルに接続されており、2 組のライブラリがアプリケーションをサポートします。図 2-1 を参照してください。

64 ビットオペレーティングシステムは、64 ビット CPU ハードウェア上でのみ動作しますが、32 ビットオペレーティングシステムは、32 ビットと 64 ビットのどちらの CPU ハードウェア上でも動作します。32 ビット Solaris と 64 ビット Solaris の環境は同じように見えるので、特定のハードウェアプラットフォーム上でどちらのバージョンが動作しているかをすぐには判断できません。isainfo(1) コマンドを使用すると、これを簡単に確認することができます。この新しいコマンドは、システムでサポートされているアプリケーション環境に関する情報を出力します。

次に示すのは、64 ビットオペレーティングシステムが実行されている UltraSPARCTM システムで実行した isainfo(1) コマンドの出力例です。


% isainfo -v
64-bit sparcv9 applications
32-bit sparc applications  

同じコマンドを古い SPARC システム、または 32 ビットオペレーティングシステムが実行されている UltraSPARC システム上で実行した場合は、次のように出力されます。


% isainfo -v
32-bit sparc applications

同じコマンドを x86 システム上で実行すると次のようになります。


% isainfo -v
32-bit i386 applications

isainfo(1) コマンドのオプションの 1 つに -n オプションがあります。このオプションは、動作中のプラットフォームにネイティブな命令セットの名前を出力します。


% isainfo -n
sparcv9

対応するネイティブのアプリケーション環境のアドレス空間のビット幅は、次のようにして確認できます。


% echo "Welcome to "`isainfo -b`"-bit Solaris"
Welcome to 64-bit Solaris

uname -r で OS のバージョンを調べるか、または /usr/bin/isainfo が存在するかどうかを調べて、64 ビット機能があるかどうかを判定することによって、以前のバージョンの Solaris で実行しなければならないアプリケーションであるかどうかを判断することができます。

関連コマンドの isalist(1) は、シェルスクリプトに使用するのに適しており、プラットフォームでサポートされている命令セットをすべて出力するのに使うことができます。isalist(1) で出力される命令セットアーキテクチャのなかには、かなりプラットフォームに固有なものもありますが、isainfo(1) ではシステム上で最も移植性のあるアプリケーション環境の属性だけを出力します。これら 2 つのコマンドとも、 sysinfo(2) システムコールの SI_ISALIST サブオプションを使って構築されています。詳細は isalist(1) のマニュアルページを参照してください。

次の例は、64 ビットオペレーティングシステムが動作している UltraSPARC システム上で isalist(1) コマンドを実行したときの出力です。


% isalist
sparcv9+vis sparcv9 sparcv8plus+vis sparcv8plus sparcv8 
sparcv8-fsmuld sparcv7 sparc 

サポートされる命令セットのリストは、パフォーマンスおよび機能のレベル順にソートされて出力されます。このコマンドの使用法についての詳細は、isalist(1) のマニュアルページを参照してください。また、optisa(1) のマニュアルページも参照してください。


注 -

上記の isalist(1) コマンドの出力例中にある sparcv9+vis および sparcv8+vis は、システムが UltraSPARC-1 拡張命令セットをサポートしていることを示しています。この拡張命令セットはすべての SPARC V9 システムでサポートされているわけではないので、移植できるアプリケーションはこの拡張命令セットに依存しないようにしてください。また、UltraSPARC に固有の機能に合わせてコーディングしないようにしてください。


プログラミング例

次に示すプログラミング例では、LP64 と ILP32 のデータ型モデルの効果を直接的に示しています。同じプログラムを 32 ビットまたは 64 ビットプログラムとしてコンパイルすることができます。


注 -

デフォルトのコンパイル環境は、移植性が維持されるように 32 ビットアプリケーションを作成するように設定されています。



% cat foo.c
#include <stdio.h>
int
main(int argc, char *argv[])
{
		(void) printf("char is ¥t¥t%lu bytes¥n", sizeof (char));
		(void) printf("short is ¥t%lu bytes¥n", sizeof (short));
		(void) printf("int is ¥t¥t%lu bytes¥n", sizeof (int));
		(void) printf("long is ¥t¥t%lu bytes¥n", sizeof (long));
		(void) printf("long long is ¥t¥t%lu bytes¥n", sizeof (long long));
		(void) printf("pointer is ¥t%lu bytes¥n", sizeof (void *));
		return (0);
} 

32 ビットコンパイルの例


% cc -O -o foo32 foo.c
% foo32 
char is          1 bytes
short is         2 bytes
int is           4 bytes
long is          4 bytes
long long is     8 bytes
pointer is       4 bytes   

64 ビットコンパイルの例


% cc -xarch=v9 -O -o foo64 foo.c 
% foo64
char is          1 bytes
short is         2 bytes
int is           4 bytes
long is          8 bytes
long long is     8 bytes 
pointer is       8 bytes