C 言語とその関連ツールは、SunOS 4 から Solaris 7 になって大幅に変更されています。これらの変更は、すべての開発者にさまざまな影響を与えます。オペレーティングシステムのカーネルと、そのインターフェースも SunOS 4 ソフトウェアとは大幅に異なっています。パート II では、これらの違いについて説明し、両リリース間の類似点を指摘し、既存のソフトウェアを移植したり、Solaris 7 用に新しいソフトウェアを開発したりするために必要な情報を提供し、プログラミング環境との関連についても説明します。
この章では、コンパイラ、リンカ、デバッガについて説明します。この章の内容は次のとおりです。
SunOS 4 から Solaris 7 に移行する開発者にとって最も大きな変更点は、C コンパイラがバンドルされなくなったことです。コンパイラをバンドルしない理由の 1 つに、動的なカーネルがあります。動的なカーネルでは、必要に応じて自動的にデバイスが追加されるので、カーネルの再構築にコンパイラを使用する必要がありません。
Sun WorkShop(TM) には、ANSI C 互換コンパイラのほか、拡張されたデバッグ機能とプログラム開発環境があります。このコンパイラは、Solaris 7 のネイティブオブジェクト形式である 実行形式リンク形式から成る ELF 形式で実行可能ファイルを作成します。lint と lint ライブラリも Sun WorkShop の一部として提供されています。 lint と lint ライブラリも Sun WorkShop の一部として提供されます。
Sun WorkShop については、http://www.sun.com にアクセスしてください。
『Making the Transition to ANSI C』は、バンドル製品の SunOS 4 C コンパイラとアンバンドル製品の Sun WorkWhop C コンパイラのそれぞれによって実装される C 言語の違いを解説しています。一方のコンパイラ用のソースを他方に移植するときに参照してください。このマニュアルは、http://docs.sun.com の Sun WorkShop Compiler C 4.2 AnswerBook Collection で閲覧できます。
Sun WorkShop C コンパイラのオプションフラグ -Xs は、K&R C と ANSI C で動作が異なる言語構成要素について警告します。この特別なフラグについては、『C User's Guide』を参照してください。このマニュアルは、http://docs.sun.com の Sun WorkShop Compiler C 4.2 AnswerBook Collection でも閲覧できます。
このリリースではリンクエディタ ld(1) に対していくつかの変更があります。最も重要な変更は新しい ELF のファイルフォーマットを処理する機能です。
ライブラリと実行可能プログラムを構築するには、リンカを直接起動することよりもコンパイラドライバによる方法をお勧めします。コンパイラは、リンカが必要とする多数のファイルを自動的に供給します。
ライブラリを混合することはできません - 32 ビットプログラムは 32 ビットライブラリ、64 ビットプログラムは 64 ビットライブラリとリンクする必要があります。ELF32 オブジェクトは他の ELF32 オブジェクト、ELF64 オブジェクトは他の ELF64 オブジェクトとリンクします。
新しいリンカでリネームされたオプションもあれば同じものもあり、また不要になったオプションもあります。表 15-1 では SunOS 4 の ld を Solaris 7 の ld コマンドと比較します。
表 15-1 に続く節で、リンク作業がオプションの相違によってどのように影響を受けるかについて説明します。
表 15-1 ld オプションの比較
SunOS 4 のオプション |
Solaris 7 での変更 |
注 |
---|---|---|
-align datum |
-M mapfile |
mapfile と異なるセクションの使用 |
-assert definitions |
デフォルト |
|
-assert nodefinitions |
-znodefs |
警告ではなく重大なエラーを発行 |
-assert nosymbolic |
-zdefs |
警告ではなく重大なエラーを発行 |
-assert pure-text |
-ztext |
警告ではなく重大なエラーを発行 |
-A name |
変更なし |
dlopen(3X) とdlclose(3X) はこの動作に接近可能 |
-Bdynamic |
-Bdynamic |
共用ライブラリの取り込みにのみ適用される。動的にリンクされた実行可能プログラムを構築するには -dy (デフォルト) を使用。「実行可能ファイルの作成」を参照。 |
-Bnosymbolic |
-zdefs |
|
-Bstatic |
-dn & -Bstatic |
動的なリンカを完全に除去するには、-dn オプションを指定しなければならない。アーカイブライブラリを取り込むために動的モードで -Bstatic を使用 (トグルとして使用。「実行可能ファイルの作成」を参照)。 |
-Bsymbolic |
-Bsymbolic |
このオプションを付けて-assert nosymbolic も取得する。 |
-d -dc -dp |
デフォルト |
オフに設定するには、SVR4 で -b オプションを使用しなければならない。 |
-D hex |
-M mapfile |
mapfile には、希望する結果を達成するためにいろいろなメカニズムが含まれる。 |
-e entry |
-e entry |
|
no -e |
-G |
共有オブジェクトを作成する。 |
-lx[.v] |
-lx |
共用ライブラリのメジャー番号が示すバージョンだけが現在サポートされている。 |
-Ldir |
-Ldir |
dir は実行可能プログラムに記録されない。かわりに、-R オプションを使用。 |
-M |
-m |
|
-n |
デフォルト |
SVR4 の実行可能プログラムのフォーマットは、ディスクイメージを -n として圧縮 |
-N |
変更なし |
|
-o name |
-o name |
|
-p |
デフォルト |
-M mapfile で取り消し可能。 |
-r |
-r |
|
-S |
変更なし |
|
-s |
-s |
|
-t |
変更なし |
|
-T hex |
-M mapfile |
mapfile には、希望する結果を達成するためにいろいろなメカニズムが含まれる。 |
-Tdata hex |
-M mapfile |
mapfile には、希望する結果を達成するためにいろいろなメカニズムが含まれる。 |
-u name |
-u name |
|
-x |
変更なし |
|
-X |
変更なし |
|
-y sym |
変更なし |
|
-z |
デフォルト |
Solaris 7 で共用ライブラリを作成するには、-G オプションを指定する必要があります。SunOS 4 では、-e オプションなしの場合、共用ライブラリを作成することをリンカが自分で判断します。Solaris 7 では共用ライブラリがエントリポイントを持つ可能性があるため、このオプションは使用できなくなりました。
-Bdynamic と -Bstatic オプションはまだ利用できますが、その動作はかなり異なります。現在では、これらのオプションは実行可能バインディングではなくライブラリのインクルードを指します。実行可能バインディングは、Solaris 7 で新しい -dy と -dn オプションでのみ排他的に設定されます。-dy オプションがデフォルトです。これは、動的にリンクされた実行可能ファイルを作成するために必要です。-dn オプションは、静的にリンクされた実行可能ファイルを作成するために必要です。
-Bdynamic と -Bstatic オプションは、-dy オプションを使用したときだけ適用されます。 -Bdynamic はリンクエディタに共用ライブラリを含めるように指示し、-Bstatic はアーカイブライブラリを含めるように指示します。これらのオプションは、次の -Bdynamic または -Bstatic オプション指定が現れるまで、-l 引数を管理する切り替え (トグル) として機能します。
次の例に、同様の実行可能プログラムを作成するのに使用できる SunOS 4 と Solaris 7 コマンドを示します。
sunos4.1% ld Bstatic test.o -lx
libx.a を使用して、静的な実行可能ファイルを作成する。
sunos5.x% ccdn test.o -lx
libx.a を使用して、静的な実行可能ファイルを作成する。
sunos4.1% ld Bdynamic test.o -lx
libx.so を使用して、動的な実行可能ファイルを作成する。
sunos5.x% cc test.o -lx
libx.so を使用して、動的な実行可能ファイルを作成する。
sunos4.1% ld Bdynamic test.o Bstatic -lx
libx.a を使用して、動的な実行可能ファイルを作成する。
sunos5.x% cc test.o Bstatic -lx
libx.a を使用して、動的な実行可能ファイルを作成する。
SunOS 4 では、-L オプションを付けて指定したディレクトリはリンク時に検索され、その情報は実行時に使用するために保持されていました。この動作は現在では、 -L と -R オプションに分けられています。 -L オプションはリンク時に検索するディレクトリを指定し、-R オプションはリンカに対して、実行時に使用するために保持する検索パスを指示します。詳細については、「検索パスの規則」を参照してください。
-Bdynamic と -Bstatic オプションと同様に、 -L オプションの位置には意味があります。これは、それに続く -l オプションにだけに適用されます。
動的リンカと実行時リンカが SunOS 4 リンカによって使用されたのとは異なるアルゴリズムを使って検索パスを決定します。
以下の例では、SunOS 4 と Solaris 7 の動的リンカおよび実行時リンカの検索パスを比較します。Solaris 7 では、リンクエディタと実行時リンカの検索パスは LD_LIBRARY_PATH
設定値の影響を受けることに注意してください。ただし、実行時リンカでは、プログラムが LD_LIBRARY_PATH
を設定しないで共用ライブラリを検索できるほか、共用ライブラリのローディングがさらに効率的になります。したがって、Solaris 7 では $ORIGIN
を代用することをお勧めします。prog がインストールされた位置からの組み込みライブラリの相対パスを指定してプログラムをビルドしなければならないからです。 たとえば、.../package/bin/prog は、.../package/lib/libmine.so.1 を使用します。
SunOS 4 リンカ検索パス
リンクエディタ: -L, LD_LIBRARY_PATH
, /usr/lib, /usr/local/lib
実行時リンカ: LD_LIBRARY_PATH
, -L, /usr/lib, /usr/local/lib
LD_LIBRARY_PATH
=dirlist1 がある Solaris 7 リンカ検索パス
リンクエディタ: -L, dirlist1, /usr/ccs/lib, /usr/lib
実行時リンカ: dirlist1, -R, /usr/lib
LD_LIBRARY_PATH
=dirlist1, dirlist2) がある Solaris 7 リンカ検索パス
リンクエディタ: dirlist1, -L, dirlist2, /usr/ccs/lib, /usr/lib
Solaris 7 リンカは、$ORIGIN
を使ってパスを検索します。
実行時リンカ: -R, $ORIGIN/../lib
また、Solaris 7 では、LD_LIBRARY_PATH_ 64
は LD_LIBRARY_PATH
の 64 ビット専用バージョンです。
SunOS 4 は、共用ライブラリに対してメジャーとマイナーの両方のバージョン番号をサポートしていました。Solaris 7 は、メジャーバージョン番号だけをサポートします。バイナリ互換性のサポートについては、メジャーおよびマイナーバージョン番号は SunOS 4 共用ライブラリで認識されます。これらのライブラリは、SunOS 4 ソフトウェアにあったのと同じメジャーおよびマイナーバージョン番号を保持するために必要となります。
表 15-2 は、SunOS 4 および Solaris 7 の共用ライブラリのバージョンを示します。
表 15-2 共用ライブラリの例
SunOS 4 |
Solaris 7 |
---|---|
libc.so.1.7 |
libc.so.1 |
libdl.so.1.0 |
libdl.so.1 |
SunOS 4 システムソフトウェアにおいては、 -l オプションを指定した場合、build environment linker はメジャーおよびマイナー番号をともに持つライブラリを検索しました。たとえば、-ldl を指定した場合、ライブラリ、libdl.so.1.0 がリンクされます。Solaris 7 環境では、メジャー番号はサポートされていますが、デフォルトのリンクエディタはバージョン番号を無視します。前の例では、build envrionment linker は現在では libdl.so と特定のバージョンのファイルを指すシンボリックリンクを検索します。
リンカによって参照された時、デフォルトでは、動的に実行可能なオブジェクトまたは共有オブジェクト中の dependency レコードは関連する共有オブジェクトのファイル名です。依存性の指定をより一貫した方法にするために、共有オブジェクトは実行時に参照されるべきファイル名をそれ自身に記録することができます。これはライブラリファイルをリンクする時に -h オプションによって指定します。
Solaris 7 では、シンボリックリンクはほとんどのライブラリに対して作成されています。メジャー番号をつけて新しい共用ライブラリを構築し、それから最もよく使用するライブラリのバージョンを指すシンボリックリンクを作成してください。
新しいユーティリティの dump(1) (「ファイルのバックアップと復元」を参照) により、オブジェクトファイルのデバッグ、または静的および動的リンクのチェックが容易になります。dump -L オプションは、実行可能プログラムに含まれる実行時リンカに必要な情報を表示します。この情報は、ELF ファイルの動的セクションに含まれます。 RPATH
エントリは、ld. の -R オプションにより指定された検索パスを表示します。
例を以下に示します。
libx.so.1 から libx.so へのリンクを作成します。
examples% cc -G -o libx.so.1 -h libx.so.1 libx.o examples% cp libx.so.1 /mylibs examples% ln -s /mylibs/libx.so.1 /mylibs/libx.so examples% dump -Lv libx.so.1 libx.so.1: **** DYNAMIC SECTION INFORMATION **** .dynamic : [INDEX] Tag Value [1] INIT 0x3b8 [2] FINI 0x3f4 [3] SONAME libx.so.1 [4] HASH 0x94 [5] STRTAB 0x33c [6] SYMTAB 0x14c [7] STRSZ 0x62 [8] SYMENT 0x10 [9] PLTGOT 0x10404 [10] PLTSZ 0xc [11] PLTREL 0x7 [12] JMPREL 0x3ac [13] RELA 0x3a0 [14] RELASZ 0x18 [15] RELAENT 0xc |
ライブラリが他の動的ライブラリを必要とするときは、次の例に示すように、RPATH
と共に動的ライブラリを指定するようにします。
次の例では prog.c をコンパイルし、(前の例で構築された) libx.so を動的にリンクし、バイナリが実行のためカレントディレクトリ情報を保持するように指定します。この例は、コンパイル済みプログラムの prog.c についての dump 出力を示します。ここで、前の例の SONAME
フィールドに格納された情報は、prog により NEEDED
として示されます。prog が実行されると、libx.so.1 は、libx.so でも、異なるバージョンにリンクされます。
examples% cc -o prog prog.c -L/mylibs -R/mylibs -lx example% dump -Lv prog prog: **** DYNAMIC SECTION INFORMATION **** .dynamic : [INDEX] Tag Value [1] NEEDED libx.so.1 [2] NEEDED libc.so.1 [3] INIT 0x1b1ac [4] FINI 0x1b248 [5] RPATH /mylibs [6] HASH 0x100e8 [7] STRTAB 0x17f90 [8] SYMTAB 0x12be0 [9] STRSZ 0x31e1 [10] SYMENT 0x10 [11] DEBUG 0x0 [12] PLTGOT 0x2b25c [13] PLTSZ 0x30 [14] PLTREL 0x7 [15] JMPREL 0x1b180 [16] RELA 0x1b174 [17] RELASZ 0x3c [18] RELAENT 0xc |
dbx と dbxtool は、デフォルトのシステムソフトウェアには含まれません。アンバンドル製品の Sun WorkShop には、これらの改良版が含まれています。
adb と kadb は、Solaris 7 オペレーティングシステムにバンドルされていて、SunOS 4 のツールと同じ機能を提供します。kadb はマルチプロセッサで使用できるよう改良されました。kadb のプロンプトにはプロセッサ ID が表示されます。以下の例では、プロセッサ ID が 0 になっています。
Solaris 7 環境で容易にカーネルのデバッグを行うには、次のようにします。
savecore を使用可能にします (/etc/init.d/sysetup ファイルの savecore 行のコメントを解除します)。
kadb 下でブートします (システムクラッシュ時に $c と入力します)。
adb と crash を使用します。
adb は、64 ビット用として次のように拡張されています。
?、/、= 修飾子に対応する拡張形式文字。K は、long 型またはポインタを 16 進形式で出力するために使用されます (32 ビットプログラムでは 4 バイト、64 ビットプログラムでは 8 バイトを表示) 。
64 ビット SPARC マクロのパス: /usr/lib/adb/sparcv9 と /usr/platform/platformname/lib/adb/sparcv9。
以下の kadb マクロは、マルチスレッドカーネルといっしょに使用すると特に有効です。
現在のスレッドを表示します。現在のスレッドポインタは、SPARC グローバルレジスタ g7 です。
kadb[0]: <g7$<thread |
threadlist は、システム内のすべてのカーネルスレッドのスタックトレースを表示します。このリストは非常に長くなることがあります。
kadb[0]: $<threadlist |
mutex は、所有スレッドのアドレスを表示します。この例では、グローバルで危険なドライバ mutex を使用しています。
kadb[0]: unsafe_driver$<mutex |
kadb[0]: moddebug/W 0x80000000 |
moddebug は、モジュールのロードを監視できるようにします。デバッグ専用に使用する moddebug の有効な値については、<sys/modctl.h> の最後を参照してください。
稼働中のカーネルをデバッグするには、次のコマンドを使用します。
# adb -k /dev/ksyms /dev/mem |
/dev/ksyms は、稼働中のカーネルの完全な名前を含む擬似デバイスです。
truss は、実行したシステムコール、受信シグナル、ハードウェア障害などを追跡するために開発された新しいユーティリティです。truss には、 エントリを有効にして追跡対象のプロセスで実行されたユーザーレベルの関数呼び出しを終了するオプションのほか、フォークされたプロセスの追跡やマルチスレッドプロセスの処理のように SunOS 4 の trace(1) コマンドにない大幅な改良も加えられています。
また、truss は、プロセスのシステムコール、シグナル、ハードウェア障害を追跡します。このユーティリティには、エントリを有効にして、追跡対象のプロセスで実行されたユーザーレベルの関数呼び出しの追跡を終了する新しいオプションが追加されています。
次の例は、date コマンドの追跡結果を要約したものです。-c オプションを指定すると、truss は行単位の追跡を表示せず、システムコール、シグナル、フォルトの回数をカウントして、その合計を表示します。
example% truss -c date Fri Sep 18 14:31:30 PDT 1992 syscall seconds calls errors _exit .00 1 read .00 7 write .00 1 open .03 12 close .00 12 time .00 1 brk .01 4 lseek .00 1 fstat .00 4 ioctl .00 1 execve .00 1 mmap .01 17 munmap .00 8 ---- --- --- sys totals: .05 70 0 usr time: .03 elapsed: .28 |
truss オプションの詳細については、truss(1) のマニュアルページを参照してください。Solaris 7 ではこの他に pmap(1) のような proc(4) を基本としたデバッグツールが数多く用意されています。
この章では、開発環境におけるツールとリソースの変更について説明します。この章の内容は次のとおりです。
dkio(7I)、filio、mtio(7I)、sockio(7I)、streamio(7I)、termio(7I)、 termios(7I) に関連するすべての ioctl は、Solaris 7 でサポートされます。
SunOS 4 の termios 構造体と Solaris 7 の termios 構造体との間に、互換性のない部分がいくつかあります。例えば SunOS 4 の termios 構造体にはある c_line フィールドが、Solaris 7 には含まれていません。
<sys/ttold.h> に定義がある次の ioctl は、実装されていません。
TIOCMODG
OTTYDISC
TABLDISC
KBLDISC
TIOCMIDS
TIOCSETX
NETLDISC
NTABLDISC
TIOCGETX
NTTYDISC
MOUSELDISC
次の ttycom ioctl 要求は Solaris 7 にはありません。
TIOCSCTTY
TIOCNOTTY
TIOCISPACE
TIOCPKT
TIOCGETPGRP
TIOCISIZE
TIOCUCNTL
TIOCOUTQ
TIOCTCNTL
TIOCCONS
Solaris 7 でサポートされる ioctl() を表 16-1 に示します。
表 16-1 ioctl() のサポート
ptrace() 機能は /proc の先頭に実装されています。新しいアプリケーションは直接 proc(4) を使用してください。
Solaris 7 では、ptrace() ルーチンは BCP モードで実行するアプリケーションをサポートするために単独で存在します。ptrace() ルーチンは要求値として整数 1〜9 を使用しますが、SunOS 4 ルーチンは <sys/ptrace.h> で要求値をシンボリック定数として定義します。次のシンボリック定数は、Solaris 7 と互換性があります。
PTRACE_TRACEME
PTRACE_PEEKTEXT
PTRACE_PEEKDATA
PTRACE_PEEKUSER
PTRACE_POKETEXT
PTRACE_POKEDATA
PTRACE_POKEUSER
PTRACE_CONT
PTRACE_KILL
PTRACE_SINGLESTEP
SunOS 4 の PTRACE_CONT addr 引数は、中断しているプロセスが実行を再開すべき場所を指定します。ただし、プロセスが中断したところから実行が再開する addr = 1 の場合は除きます。Solaris 7 は、addr が常に 1 に等しく、実行が常にプロセスが中断したところから再開することを要求します。また、データによって指定されたものを除いたすべてのペンディングシグナルをキャンセルします。SunOS 4 の PTRACE_CONT は、ペンディングシグナルをすべてキャンセルするとは限りません。
表 16-2 に示す SunOS 4 の有効な要求は、 Solaris 7 ptrace() ルーチンではサポートされません。
表 16-2 Solaris 7 でサポートされていない ptrace() 要求
PTRACE_ATTACH |
PTRACE_GETWINDOW |
PTRACE_DETACH |
PTRACE_SETWINDOW |
PTRACE_GETREGS |
PTRACE_22 |
PTRACE_SETREGS |
PTRACE_23 |
PTRACE_GETFPREGS |
PTRACE_26 |
PTRACE_SETFPREGS |
PTRACE_27 |
PTRACE_READDATA |
PTRACE_28 |
PTRACE_WRITEDATA |
PTRACE_SYSCALL |
PTRACE_READTEXT |
PTRACE_DUMPCORE |
PTRACE_WRITETEXT |
PTRACE_SETWRBKPT |
PTRACE_GETFPAREGS |
PTRACE_SETACBKPT |
PTRACE_SETFPAREGS |
Solaris 7 は、System V Inrerface Definition, Third Edition (SVID 3) に準拠しています。SunOS 4.1 System V ライブラリとともに書かれたプログラムは Solaris 7 への移植が簡単ですが、SunOS 4 BSD C ライブラリを使用するプログラムにとっては多くの労力を必要とします。
機能や機能グループの中には、Solaris 7 では別のライブラリに移動されたものがあります。このため、SunOS 4 のアプリケーションを Solaris 7 でコンパイルする時に、これらの移動された機能を参照することで未定義とフラグされる可能性があります。
コンパイルした後、未定義とフラグされた任意の機能のマニュアルページを確認してください。機能説明のところに、-l リンカーオプションと、シンボルを解決する必要のある任意のインクルードファイルの両方がリストされます。
共用ライブラリは現在、マイナーバージョン番号をサポートしません。
共用初期設定データファイル (.sa) はすでに不要となっており、.sa ファイルは Solaris 7 では提供されません。
前リリースでは、静的テーブルの割り当てがファイル記述子やアクティブなプロセスなどのリソースに使用されました。これらのリソースは、現在は動的に割り当てられます。つまり、空いている物理メモリによって制限されることを意味します。表 16-3 にリソースの制限を示します。
表 16-3 リソースの制限
構成 |
制限 |
---|---|
|
プロセスによって作成できるコアファイルの最大サイズ (バイト単位) |
|
プロセスが使用できる最大 CPU タイム (秒単位) |
|
プロセスのヒープの最大サイズ (バイト単位) |
|
プロセスによって作成できるファイルの最大サイズ (バイト単位) |
|
プロセスによって作成できるファイル記述子の最大数より 1 大きい値 |
|
プロセスのマップされたアドレスサイズが増大できる最大サイズ (バイト単位) |
|
プロセスのスタックの最大サイズ (バイト単位) |
ネットワークライブラリを必要とする共有オブジェクトはすべて動的にリンクしなければなりません。ネットワークライブラリは、libdl.so.1 を必要とし、アーカイブライブラリは利用できません。
表 16-4 に SunOS 4 ライブラリと Solaris 7 ライブラリ、およびそれらの位置を示します。
表 16-4 ライブラリ位置の比較
ライブラリ名 |
SunOS 4 ディレクトリ |
Solaris 7 ディレクトリ |
---|---|---|
libbsdmalloc.a |
/usr/lib |
/usr/lib |
libc.a |
/usr/lib および /usr/5lib |
/usr/lib |
libc.so.1.7 |
/usr/lib |
/usr/lib |
libc.so.2.7 |
/usr/5lib |
/usr/lib |
libc_p.a |
/usr/5lib |
なし |
/usr/lib および /usr/5lib |
/usr/ucblib および /usr/ccs/lib |
|
libcurses_p.a |
/usr/5lib |
なし |
libdbm.a |
/usr/lib |
/usr/ucblib |
libdl.so.1.0 |
/usr/lib |
/usr/lib |
libg.a |
/usr/lib |
なし |
libkvm.a |
/usr/lib |
なし |
libkvm.so.0.3 |
/usr/lib |
/usr/lib |
libl.a |
/usr/lib |
/usr/ccs/lib |
libln.a |
/usr/lib |
なし |
liblwp.a |
/usr/lib |
なし |
/usr/lib |
/usr/lib および /usr/lib/libp |
|
libmp.a |
/usr/lib |
/usr/lib |
libnbio.a |
/usr/lib |
なし |
libnsl.a |
/usr/lib |
/usr/lib |
libpixrect.a |
/usr/lib | |
libpixrect.so.2.14 |
/usr/lib |
なし |
libposix.a |
/usr/lib |
なし |
libresolv.a |
/usr/lib |
/usr/lib |
librpcsvc.a |
/usr/lib |
/usr/lib |
libsuntool.so.0.54 |
/usr/lib |
なし |
libsunwindow.so.0.55 |
/usr/lib |
なし |
/usr/5lib |
なし |
|
libsvidm_p.a |
/usr/5lib |
なし |
/usr/lib および /usr/5lib |
/usr/ucblib および /usr/ccs/lib |
|
libtermlib.a |
/usr/lib および /usr/5lib |
/usr/ccs/lib |
libxgl.so.1.1 |
/usr/lib |
/opt/SUNWits/ Graphics-sw/xgl/lib |
/usr/xpg2lib |
なし |
|
liby.a |
/usr/lib および /usr/5lib |
Solaris 7 で利用できる make ユーティリティは 2 種類あります。デフォルトである /usr/ccs/bin/make は、SunOS 4 の make コマンドと同じです。SVR4 版は /usr/ccs/bin/make で利用できます。
デフォルトの make を使うと、Makefile を変更する必要はありません。ただし、Makefile で使用するコマンドのいくつかは変更されている可能性があります。たとえば、Makefile で一般に使用される install(1) は、オプションに変更が加えられたために次の例のように予期しない結果を生じることがあります。
SunOS 4 Makefile - install:
install -o bin -g bin -m 444 target.c /usr/bin/target |
SunOS 5.7 Makefile - install:
install -u bin -g bin -m 444 target.c /usr/bin/target |
/usr/ueb にある install(1B) のバージョンは SunOS 4 のバージョンと互換性があります。
個々のインタフェースに関する情報については、付録 A 「コマンドリファレンス」 の互換性に関する表で確認してください。
Solaris 7 のソースコード管理システム (SCCS) は SunOS 4 の SCCS とは少し異なっています。コマンドとサブコマンドの同じセットが両方の環境でサポートされています。SunOS 4 システムで使用される SCCS ディレクトリおよび s.files は Solaris 7 システムでも同様に動作します。
SunOS 4 ソフトウェアでは、SCCS コマンドは /usr/sccs ディレクトリに置かれていました。Solaris 7 ではこれらのコマンドは他のプログラミングツールとともに /usr/ccs/bin に置かれています。
SunOS 4 と Solaris 7 ユーティリティの相違の 1 つに読み取り不可能な s.file の処理があります。SunOS 4 コマンドは、読み取り不可能な s.file が出現すると、エラーを出力して続行します。Solaris 7 コマンドはエラーを無視します。
バイナリ互換パッケージは開発環境としては提供されていませんが、将来のリリースとのバイナリ互換性を改善できる適切なプログラミングが必要です。
バイナリ互換パッケージは、部分的に静的にリンクされているかあるいは動的にリンクされているハイブリッドと同じく、動的または静的にリンクされたアプリケーションと互換性があります。
バイナリ互換パッケージは、「適切に動作する」ユーザアプリケーションで使用することができます。「適切に動作する」アプリケーションとは、次の条件を満たすアプリケーションを指します。
直接カーネルにトラップしない
どのシステムファイルにも直接書き込まない
/dev/kmem、 /dev/mem または libkvm を使用しない
公表されていない SunOS インタフェースを使用しない
カスタマ供給のドライバに依存しない
上記の条件を満たしていないと、アプリケーションは予想できない結果を生じることがあります。
バイナリ互換パッケージの使用方法に関する情報は、『バイナリ互換性ガイド』に説明があります。
Solaris 7 環境は現在パッケージという単位でバンドルされています。これらのパッケージには、システムに追加したり、システムから削除したりする必要があるファイルおよび情報のすべてが含まれます。
pkginfo ファイル - これはパッケージの特性を設定する ASCII ファイルです。パッケージを記述してそのインストールのための制御パラメータを設定する macro=value の対で構成されています。詳細については、pkginfo(4) のマニュアルページを参照してください。
prototype ファイル - これはパッケージの内容を定義する ASCII ファイルです。そのまま出荷できるオブジェクト (たとえば、ファイル、ディレクトリ、リンク) ごとに 1 つのエントリがあります。また、pkginfo、depend および copyright ファイルなどのパッケージ情報ファイルおよびスクリプトのインストールエントリを含みます。詳細については、prototype(4) のマニュアルページを参照してください。
copyrightファイル - これはパッケージの著作権に関する記述を提供する ASCII ファイルです。コメント行を含むその内容はパッケージのインストール時に表示されます。詳細については、copyright(4) のマニュアルページを参照してください。
パッケージの内容 - パッケージの内容が含まれます。
スクリプト - スクリプトを使用してパッケージのインストールおよび削除を制御したり、ユーザに入力を要求したり、または特定のクラスのすべてのオブジェクトに対して処理を実行できます。スクリプトは Bourne シェルが実行できるものでなければなりません。
アドオンアプリケーションソフトウェアは、フロッピーディスク、テープ、または CD-ROM から Solaris 7 システムにインストールできるようにパッケージ化されていなければなりません。『Application Packaging Developer's Guide』では、パッケージを作成するためのガイドラインを記載しています。
パッケージを作成し、操作するためのユーティリティがいくつか提供されます。 表 16-5 にパッケージの作成に便利なコマンドを示します。
表 16-5 パッケージ作成用コマンド
pkgmk コマンドへ入力するプロトタイプファイルのエントリを生成する |
|
インストール可能なパッケージを生成する |
|
パッケージフォーマットを変換する |
表 16-6 にパッケージの追加と削除に便利なコマンドを示します。
表 16-6 パッケージの追加と削除用コマンド
システムにソフトウェアパッケージを追加する |
|
要求スクリプトに対する応答を格納する |
|
システムからパッケージを削除する |
|
インストールの結果をチェックする |
表 16-7 にパッケージに関する情報を提供するコマンドを示します。
表 16-7 Cパッケージに関する情報を提供するコマンド
インストール済みパッケージに関するソフトウェアパッケージ情報を表示する |
|
この節では OPEN LOOK Intrinsic ToolKit (OLIT) と XViewTM について説明します。
OPEN LOOK Intrinsics Toolkit (OLIT) は Xt Intrinsics をベースにしています。このツールキットは多くのウィジェットセットに共通な関数セットを提供し、X 環境のユーザインタフェースコンポーネントを作成したり、流用したり、削除したりします。
XView Window Toolkit は OPEN LOOK グラフィカルユーザインタフェース (GUI) 仕様を実装しています。
XView は varargs に基づく可変長の属性値リストを使用し、ウィンドウ、メニュー、およびスクロールバーなど、作成するオブジェクトを指定します。このツールキットでは、すでに通常の動作が定義されているため、手続き型プログラミングによくあるように定型のコードを繰り返す必要がありません。
ほとんどの SunOS 4 のプログラミングツールが利用でき、同じ機能を提供しますが、多くのものが新しい位置にあります。現在バンドルされるプログラミングツールはすべて 2 つのディレクトリ、/usr/ccs/bin と /usr/ccs/lib にあります。 表 16-8 にプログラミングツールと SunOS 4 の位置を示します。
表 16-8 バンドルされるプログラミングツール
SunOS 4 コマンド |
SunOS 4 での位置 |
---|---|
/usr/sccs |
|
/usr/bin |
|
/usr/bin |
|
/usr/sccs |
|
/usr/sccs |
|
/usr/lib/cpp |
|
/usr/sccs |
|
/usr/ucb |
|
/usr/sccs |
|
/usr/sccs |
|
/usr/bin |
|
/usr/bin |
|
/usr/bin |
|
/usr/bin |
|
/usr/bin |
|
/usr/bin |
|
/usr/bin |
|
/usr/sccs |
|
/usr/sccs |
|
/usr/bin |
|
/usr/sccs |
|
/usr/sccs |
|
/usr/ucb |
|
/usr/sccs |
|
/usr/bin |
|
/usr/bin |
|
/usr/ucb |
|
/usr/bin |
|
/usr/sccs |
|
/usr/ucb |
|
/usr/sccs |
|
/usr/old |
|
/usr/sccs |
|
/usr/bin |
|
/usr/lib |
表 16-9 に、新しい Solaris プログラミングツールとその説明を示します。
表 16-9 新しいプログラミングツール
新しいコマンド |
説明 |
---|---|
COFF のオブジェクトコード逆アセンブラ |
|
オブジェクトファイルの選択された部分をダンプする |
|
ソースファイルから文字列を抽出する |
|
オブジェクトファイルのコメントセクションを操作する |
|
正規表現コンパイラ |
|
システムコールとシグナルを追跡する |
|
ptools |
多方面の /proc ユーティリティ |
表 16-10 に、SunOS 5.7 でアンバンドルである SunOS 4 コマンドを示します。
表 16-10 アンバンドル製品のプログラミングツール
アンバンドルのコマンド |
説明 |
---|---|
簡単な C プログラム整形ツール |
|
C コンパイラ |
|
プログラムにフローグラフを生成する |
|
対話方式で C プログラムを検査する |
|
C プログラム実行追跡を行う |
|
C プログラムクロスリファレンスを行う |
|
ソースレベルデバッガ |
|
ウィンドウベースのソースレベルデバッガ |
|
call-graph プロファイルデータを表示する |
|
C プログラムソースファイルをインデントおよびフォーマットする |
|
インラインのプロシージャコールの展開 |
|
C プログラムベリファイア |
|
COFF オブジェクトファイルの選択された部分をダンプする |
|
test coverage 解析および文単位のプロファイルを構築する |
この章では、プログラミング環境に関連する Solaris 7 のネットワーク機能と、改善された国際化機能について説明します。
ファイルシステムユーティリティを集中制御する分散ファイルシステム(DFS)
NFS を含んだネットワーク情報サービスプラス (NIS+)
ネームサービススイッチファイル
これらのサービスについての詳細は、『NIS+ への移行』と『NFS の管理』を参照してください。
Solaris 7 は、ネットワーク情報サービス (NIS)、SunOS 4 のネームサービス、ネットワーク情報サービスプラス (NIS+)、異機種分散システムの企業ネームサービスをサポートしています。Solaris 7 で使用できる NIS サポートについての詳細は、「NIS+ 」 を参照してください。
NIS+ は、改善されたセキュリティ、名前空間オブジェクトの詳細なモデル、NIS より高速な更新処理などを提供します。
NIS+ のプログラマインタフェースについては、『man pages section 3』を参照してください。
nsswitch.conf ファイルは、ネームサービス管理を簡略化するために設計されました。アプリケーションは、nsswitch.conf ファイルを使用してネームサービスを選択できます。これにより、ネームサービス情報をネットワークサービス内で直接定義する必要がなくなりました。nsswitch.conf ファイルの書式についての詳細は、nsswitch.conf(4) のマニュアルページを参照してください。
SunOS 4 で提供されていた Network Interface Tap (NIT) は Solaris 7 では必要なくなりました。Solaris 7 では、イーサネットドライバが真の STREAMS ドライバに変更されたので、ドライバを直接オープンして通信できます。
pfmod(7M)、bufmod(7M)、dlpi(7P) のマニュアルページを参照してください。
Solaris 7 のイーサネットドライバとその他のデータリンクドライバは、コネクションレスの Data Link Provider Interface (DLPI) バージョン 2 をサポートしています。
ソケットは Solaris 7 でサポートされています。SunOS 4 と違って、ソケットはカーネルの中にはまったく実装されなくなり、ライブラリ libsocket として STREAMS 上に実装されています。
Solaris 7 での変更のほとんどは以前の国際化機能の改善です。国際化サポートに関する詳細な情報については、『プログラミングの国際化』を参照してください。
プログラムの国際化に関わるアプリケーション開発者は次のガイドラインに従ってください。
setlocale(3C) を呼び出して LANG
環境変数を設定する
標準のコードセットを使用し、8 ビット境界を守る
strftime(3C) を使用して日付および時刻を出力する
ユーザが照合のために判読できるように strcmp(3) を strcoll(3C) に置き換える
gettext(3C) もしくは catget(3C) を呼び出してロケール固有のメッセージカタログから翻訳された文字列を検索する
Solaris 7 環境は拡張 UNIX コード (EUC)、VTF8、PCK、V165 をサポートしています。これにより、1 つのシステムで複数バイトと複数のコードセットを利用できます。
SunOS 4 は ASCII 以外の文字のシングルバイト表現をサポートしていました。Solaris 7 では、複数バイト表現がサポートされています。このサポートは数千文字もあるアジア系言語の文字セットに必要です。
libc に含まれる複数バイトライブラリには次のような機能があります。
複数バイト文字からワイド文字への文字変換
ワイド文字の標準入出力
ワイド文字の分類
ワイド文字のフォーマット化
Solaris 7 は複数バイトファイル名をサポートしていますが、ログイン名とマシン名は ASCII 文字に制限するようにしてください。
SunOS 4 のメッセージカタログのサポートは Solaris 7 で強化され、複数バイト文字を使ってメッセージカタログを作成できるようになりました。
メッセージカタログを使うと、アプリケーションはアプリケーションが実行された母国語で実行時のメッセージを表示できます。これらのメッセージカタログは、言語ロケールによって指定される母国語用にはじめに作成しなければなりません。
SunOS リリース 5.7 のロケールデータベース (/usr/lib/locale/locale) は、SunOS 5 のロケールデータベースとは全く異なります。ただし、ユーザ側からは違いは分かりません。
Solaris 7 のほとんどのシステムコマンドはメッセージ化されました。これらコマンドの多くには複数バイト機能があります。つまり、複数バイト文字表現が可能になっています。より多くのコマンドがメッセージ化されたことにより、ローカリゼーションの労力は軽減されます。
installtxt(1) コマンドは msgfmt(1) に変更されました。メッセージを抽出するには新しい xgettext(1) コマンドを使用します。
strftime(3C) を変更すると、日付および時刻フォーマットに影響を与えます。date(1) コマンドの出力フォーマットに依存するシェルプログラムは、新しいフォーマットを処理できるように修正しなければなりません。
chrtbl(8) と catdef(8) は、localedef(1) に置き換えられました。
/usr/xpg2lib/libxpg2.a アーカイブライブラリは利用できません。これらのルーチンは、libc に入りました。
表 17-1 にこれらのインタフェースの新しい位置を示します。
表 17-1 xpg2lib ライブラリルーチンの位置
ルーチン |
Solaris 7 での位置 |
---|---|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
未サポート |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
|
/usr/lib/libc |
これらのルーチンを使用するプログラムは -lxpg2 を C コンパイラに渡す必要はありませんが、libintl.h を含む必要があるものが現在あります。(これらのルーチンについては、表 17-1 を参照してください)。
setlocale(3C) によって戻される文字列におけるロケールカテゴリの順位は、SunOS 4 と Solaris 7 では異なります。この文字列は通常 setlocale(3C) への次の呼び出しによって使用され、順位は問題とされません。アプリケーションはロケールカテゴリの特定の順位に依存しないようにしてください。
オペレーティングシステムのカーネルとそのインタフェースは大幅に変更されています。SunOS 4 のデバイスドライバは、バイナリ互換を提供していません。この章では、カーネルおよびシステム開発者に影響を与える Solaris 7 の変更点について説明します。
システム構成の変更点には、動的にロード可能なカーネルとカーネルの配置、config コマンドと boot コマンド、/etc/system ファイルがあります。
以前の SunOS リリースと異なり、Solaris 7 のカーネルは動的に構成されます。現在のカーネルは小さな静的コアと動的にロードできる多くのカーネルモジュールで構成されます。ドライバ、ファイルシステム、STREAMS モジュール、またその他のモジュールは、ブート時または実行時に、必要に応じて自動的にロードされます。これらのモジュールは使用されなくなるとアンロードされます。モジュールは、そのメモリ領域が必要になるまで、メモリ内に維持されます。modinfo(1M) は、現在システムにロードされているモジュールに関する情報を提供します。
modload(1M) コマンドと modunload(1M) コマンドは、Solaris 7 ではまだ使用できますが、動作が異なります。Solaris 7 では、これらのコマンドの使用方法に制限があり、ロード可能なドライバをシステムに正しくインストールするには不十分です。modunload は現在アンロード可能な (ビジー状態ではない) モジュールをすべてアンロードする機能が含まれます。次のように modunload を使用してください。
# modunload -i 0 |
以前は 1 つのファイル /vmunix にあったカーネルの内容は、現在ではディレクトリ階層の複数のモジュールに別れています。デフォルトでは、ディレクトリ階層は /platform/'uname -i'/kernel、/kernel、/usr/kernel です。
モジュールに対するディレクトリ検索パスは、/etc/system ファイルの moddir
変数により設定できます。system(4) のマニュアルページを参照してください。通常、最初にロードされるのは /platform/'uname -i'/kernel/unix です。kernel(1M) のマニュアルページを参照してください。
SunOS 4 リリースでは、config コマンドを使用して、/vmunix がオブジェクトファイルから再リンクできるようにシステム構成ファイルを生成しました。次の Solaris 7 の機能により、このコマンドは必要なくなります。
ロード可能モジュール
/etc/system ファイル (system(4) のマニュアルページを参照)
OpenBoot PROM (OBP) からのデバイスツリー情報
/kernel/drv と /usr/kernel/drv にある driver.confファイル
システム構成情報は、現在 /etc/system ファイルに設定されています。また、このファイルはロード可能なモジュールのカーネルの処理方法も変更します。このファイルには、次の形式のコマンドが含まれます。
set parameter=value |
たとえば、SunOS 4 ソフトウェアにおいて、MAXUSERS
は config(8) を使用して設定されました。Solaris 7 では、/etc/system ファイルの中の次のような行により設定されます。
set maxusers = number |
ロード可能なモジュールに影響を与えるコマンドは、次の形式になります。
set module:variable=value |
/etc/system ファイルに対して行われた変更は、システムをリブートする際に影響を与えます (system(4) のマニュアルページを参照)。
Solaris 7 では、次のブートプログラムが使用できます。
ディスクからブートする場合、PROM は、一次ブートブロックがローカルディスクのブロック 1 から 15 にあるものと仮定とします。installboot(1M) を使用し、次のようにブートブロックを作成します。
# installboot /usr/platform/'uname -i'/lib/fs/ufs/bootblk /dev/rdsk/c0t3d0s0 |
システムファームウェアは、一次ブートストラップ (ブートブロック) プログラムをメモリにロードし、それを実行します。ブートブロックは、UFS ファイルシステムを読み取るプログラムで、二次ブートプログラム (/platform/'uname -i'/ufsboot) をメモリにロードします。
ufsboot は /kernel/unix をロードします。それから /kernel/unix は、ルートファイルシステムのマウントが可能となるまで、ufsboot を使って /kernel ディレクトリ階層からモジュールをロードします。
これらの動作の間、ブートブロックと ufsboot は、ファームウェアによって提供されるドライバを使用します。ufsboot またはブートブロックのいずれにも、ドライバコードはまったく含まれません。ufsboot が SBus カード PROM ドライバを使用するため、ufsboot コードを変更して新しいディスクタイプで新しい SBus カードを取り込む必要はありません。
ネットワークを通してブートする場合、ブートプログラムは SunOS 4 ソフトウェアのディスクレスブートと同じように実行されます。ただし、現在、ブートプログラムは inetboot と呼ばれ、クライアントの vfstab ファイルエントリは異なります。ディスクレスのブート時の情報については、『Solaris のシステム管理 (第 1 巻)』を参照してください。
表 18-1 には、SunOS 4 と Solaris 7 とのブートシーケンスの相違点を要約します。
表 18-1 ブートの相違点の要約
SunOS 4 |
Solaris 7 |
説明 |
---|---|---|
bootblk |
ディスクから ufsboot をロードする |
|
ufsboot |
ディスクから unix をロードする |
|
unix |
ブート可能なカーネルイメージ |
|
inetboot |
ネットワークから unix をマウントしてコピーする |
|
/etc/rcS |
/usr をマウントし、ファイルシステムをチェックする |
|
/etc/rc2, /etc/rc3, /etc/rc2.d, /etc/rc3.d |
システムの構成スクリプト |
|
modload, /etc/system, add_drv, rem_drv |
システムカーネルをカスタマイズし、必要なモジュールをロードする |
|
PROM モニタ、シングルユーザ、マルチユーザ |
実行レベル 0〜6、および S |
再構成ブートは、接続されたすべてのデバイスをチェックし、/devices と /dev にそれらの名前を構築するようシステムに指示します。新しいハードウェアをシステムに追加したときは、再構成ブートを行います。次のように -r オプションを使ってブートを開始します。
ok> boot -r |
既存のタイプ (ドライバはすでにインストールされている) のデバイスを別に追加して、再構成ブートを忘れた場合、次のコマンドを使用して新しいデバイスを認識するようにシステムに指示することができます。
# touch /reconfigure # _INIT_RECONFIG=YES /etc/init.d/drvconfig # _INIT_RECONFIG=YES /etc/init.d/devlinks |
この節では、「デバイス命名規則」の説明を拡張して、システムとカーネル開発者に関係するデバイス命名規則を中心に説明します。
/devices ツリーは、カーネルで認識されたデバイスのツリーを表します。このツリーは drvconfig(1M) プログラムによって構成されます。通常 drvconfig(1M) は、システムが -r フラグでブートされた場合のみ実行されます。「再構成ブート」を参照してください。drvconfig は、ブート時に接続されて準備しているデバイス (ドライバのある) を格納するように /devices を構成します。
デバイスドライバがデバイスの存在を確認すると、デバイスドライバは ddi_create_minor_node(9F) を呼び出してエントリを作成します。
デバイスをシステムに追加するには add_drv(1M) コマンドを使用します。ドライバが正常に追加された場合、add_drv(1M) は drvconfig も実行します。
Solaris 7 では、/dev は /devices の中の実際のエントリへシンボリックリンクを作成するユーティリティプログラムによって管理されます。
disks(1M)
tapes(1M)
ports(1M)
devlinks(1M)
スクリプトを実行して、 /dev から /devices へ適切なリンクを作成することができます。/devices 名がハードウェアの一意の名前であるのに対し、 /dev 名はより簡単で親しみやすいという利点があります。
システムにおける各デバイスは、デバイスドライバによって駆動されます。デバイスドライバは、デバイスの多くのインスタンスを管理します。デバイスは以下のような名前を与えられます。
物理名
論理名
インスタンス名
物理名は /devices に格納されています。物理名はハードウェアについて記述し、プラットホームおよび構成に依存します。以下に例を示します。
/devices/vme/xdc@6d,ee80/xd@0,0:g
物理名を使用すると、どのハードウェアが使用されているかを識別することができます。たとえば、 xdc@6d,ee80 は、VME A16, D32 空間のアドレス 0xee80 にあるディスクコントローラを指します。vme(4)、driver.conf(4) のマニュアルページを参照してください。
論理名は /dev に格納されています。論理名はデバイスの物理名のプラットホーム固有の内容をできるだけ抽象化しています。たとえば xd というデバイスの論理名は次のようになります。
/dev/dsk/c2d0s6 (コントローラ 2、スレーブ 0、スライス 6 (4.x パーティション `g'))
また、sd というデバイスの論理名は次のようになります。
/dev/dsk/c0t3d0s0 (コントローラ 3、ターゲット 0、lun 0、スライス 0 (4.x パーティション `a'))
論理名は、コントローラのタイプについてはなにも表していません。つまり、SCSI でも IPI でも差はなく、両方とも単にディスクであるということです。
ディスク名は、SunOS 4 リリースで使用されていた英字 a〜h ではなくスライス番号 0〜7 の SVR4 規約に従っています。
ディスク名は、ブロックディスクデバイスについては /dev/dsk/*、raw ディスクについては /dev/rdsk/* という SVR4 規約に従っています。詳細については、『Solaris のシステム管理 (第 1 巻)』を参照してください。
インスタンス名とは、システムの n 番目のデバイスを意味します。たとえば、sd20 のようになります。
インスタンス名は、ドライバエラーメッセージでレポートされることがあります。次のように dmesg(1M) の出力を見ると、物理名へのインスタンス名のバインディングを知ることができます。
sd9 at esp2: target 1 lun 1 sd9 is /sbus@1,f8000000/esp@0,800000/sd@1,0 <SUN0424 cyl 1151 alt 2 hd 9 sec 80> |
インスタンス名がデバイスに割り当てられると、その名前がそのデバイスにバインドされたままになります。
インスタンス番号はデバイスのマイナー番号でコード化されます。リブートしてもインスタンス番号を一貫したものにするために、システムはそれらを /etc/path_to_inst ファイルに記録します。このファイルは起動時にだけ読み込まれ、現在は add_drv(1M) および drvconfig(1M) コマンドによって更新されます。/etc/path_to_inst ファイルについては、path_to_inst(4) のマニュアルページを参照してください。
この章では、デバイスドライバインタフェースの変更、devinfo コマンド、移行時の注意点、STREAMS、Solaris 7 ドライバアーキテクチャについて説明します。
この章で説明する各項目についての詳細は、次のマニュアルを参照してください。
『STREAMS Programming Guide』
『システムインタフェース』
Solaris 7 では、デバイスドライバに多くの変更点があります。たとえば、新しい DDI/DKI ルーチン、Solaris SPARC DDI 固有ルーチン、新しいソフトウェアの特性、ロード可能なドライバなどです。また、以前からあったデバイスに関する多くの問題 (割込み、DVMATM、メモリマッピングなど) を、ドライバが意識しなくて済むようになりました。
以前の SunOS リリースでは、ドライバの作成者はデバイスドライバインタフェースの変更を処理しなければなりませんでした。通常、オペレーティングシステムのリリースごとに移植を行なっていました。さらに、プラットホームごとにインタフェースが異なるため、各プラットホームに合ったデバイスドライバが必要でした。Sun 社製以外の製品のデバイスドライバのリリースには、デバイスドライバを統合するためにオペレーティングシステムの再設定および再構築を行う複雑なスクリプトも中には含まれていました。したがって、デバイスドライバのサポートと保守にはコストがかかりました。
SunOS システムの以前のリリース (SunOS 4.1.3 ソフトウェア以前) と違って、Solaris 7 環境のデバイスドライバインタフェースは統一化されて、Solaris 7 SPARC DDI/DKI と呼びます。Solaris 7 SPARC DDI/DKI は、サポートされているすべてのプラットホームと、これらのプラットホームの Solaris 環境のすべての将来のリリースにデバイスドライバのバイナリ互換性を提供するために作成されました。
DDI/DKI という用語は、SVR4 リリースにある元の仕様から取ったものです。これは、デバイスドライバインタフェース / デバイスカーネルインタフェースを表します。インタフェースは次の 3 グループに分割されます。
DDI/DKI
DKI 専用
DDI 専用
DDI/DKI インタフェースは SVR4 で標準化されており、動作しているプラットホームとは関係なく SVR4 のすべての処理系で共通です。
DKI 専用インタフェースは DDI/DKI インタフェースと同様に共通であり、すべての SVR4 処理系でサポートされます。ただし、Sytem V の将来のリリースでサポートされる保証はありません。
DDI 専用インタフェースは、アーキテクチャ固有のものです。たとえば、デバイスとシステム固有ハードウェアへのアクセスおよび制御方法 (つまり、I/O レジスタ、DMA サービス、割り込み、およびメモリマッピング) が固有です。これらのインタフェースは、その他の SVR4 処理系での機能は保証されていません。
こういった特長によりドライバのサポートと保守のコストを効率よく下げることができます。この多数の SPARC プラットホームと結合した機能は、多くの新しい Sun 社製以外の製品のハードウェア開発者の役に立つでしょう。
このレベルのバイナリ互換性を提供することにより、いまでは Sun 社製以外の製品のハードウェア開発者は彼らのドライバハードウェアと一緒に DDI 準拠のデバイスドライバをシュリンクラップ形式にパッケージ化することができます。新しいドライバパッケージのインストールは、いまでは完全に自動化されています。自動構成を行うカーネルにより、ドライバを追加または削除するためにカーネルを再コンパイルする必要はなくなりました。したがって、Solaris 7 環境の DDI 準拠デバイスドライバは、他のすべての市販のソフトウェア製品と同様に扱うことができます。
Solaris 7 DDI/DKI では、DDI 専用インタフェースは Solaris 7 DDI/DKI をサポートするすべてのシステムに共通です。Sun Common SCSI Atchitecture (SCSA) のインタフェース、およびマルチスレッドカーネルでドライバを正常に機能させるために使用するロックインタフェースもまた、Solaris 7 環境では DDI 専用インタフェースとみなすことができるので注意してください。
SCSA により、デバイスドライバはホストアダプタのインプリメンテーションに関するプラットホーム固有の細部を考慮しなくてもよくなりました。SCSA を使用すると、SCSI ドライバはサポートされるすべてのプラットホームで実行できます。
上記のカテゴリのインタフェースだけを使うように制限したデバイスドライバを、「Solaris 7 DDI/DKI 準拠」といいます。 Solaris 7 DDI/DKI に準拠したデバイスドライバを一般に「DDI に準拠したデバイスドライバ」といいます。
ドライバルーチン、構造体、および DDI/DKI を構成するサポートルーチンに関するマニュアルページは、『man pages section 9: DDI and DKI Overview』および以下のセクションを参照してください。詳細については Intro(9) のマニュアルページを参照してください。
section 9E - DDI and DKI Driver Entry Points
section 9F - DDI and DKI Kernel Functions
section 9S - DDI and DKI Data Structures
Solaris 7 の devinfo コマンドは SunOS 4 の devinfo とは機能が異なります。新しい prtconf(1M) コマンドは SunOS 4 の devinfo コマンドで表示した情報を表示します。次の例で各コマンドの出力を示します。
自動構成を行うカーネルを使用すると、Solaris 7 ドライバは他のタイプのドライバよりも SBus ドライバに似ています。すべてのドライバがロード可能で、カーネルの構成は必要ありません。
SunOS 4 ソフトウェアでは、1 度に 1 つのプロセッサしかカーネルに存在できません。これはカーネル全体で 1 つのマスタロックを使うことで実現されていました。プロセッサがカーネルコードを実行したいときは、ロックを獲得し (他のプロセッサがロックで保護されたコードを実行するのを防ぐ)、終了したらロックを解放します。
Solaris 7 カーネルはマルチスレッドです。1 つのマスタロックの代わりに、コードの細分化された領域を保護するための多数の細分化されたロックがあります。たとえば、特定の v ノードへのアクセスを保護するカーネルロックや、i ノードを保護するカーネルロックがあります。一回に 1 つのプロセッサしか v ノードを処理するコードを実行できませんが、別のプロセッサが i ノードにアクセスすることは可能です。これにより多くの並列化が可能になります。
マルチスレッドカーネルは、ドライバの設計に大きな影響を与えます。splN/splr ペアを使用した古いモデルは (ユニプロセッサまたはマルチプロセッサマシンにおいて) もはや動作しません。そのかわりに MT スタイルのロックを選択することができます。ドライバの最も一般的なロックは、相互排他ロック、mutexes (仕様では splN/splr ペアとほぼ同等)、および条件変数 (sleep()/wakeup() 同期化とほぼ同等) です。
SpIN/pplr のペアは、割り込みをブロックしますが、マルチプロセッサ環境でデータ構造を保護する上では、この機能は役に立ちません。
sleep() を明示的に呼び出すまではプロセッサを所有しているという古い概念は、もはや成立しません。カーネルがプリエンプティブになっているため、CPU はスレッドからスレッドへと切り換えられます。したがって、デバイスレジスタや共有データ構造などへの同時アクセスを防ぐため、適切な MT ロックプリミティブを使用しなければなりません。
単純なデバイスドライバ用のドライバコードは、主にカーネルインタフェースルーチンで構成されていますが、そのかなりの部分が変更されます。ただし、分かりやすい変更です。SCSI ドライバのように大量のデバイス固有の処理コードを持つ複雑なデバイスドライバの場合は、ドライバインタフェースの変更はわずかです。このドライバインタフェースは、カーネルからドライバへのインタフェースか、ドライバからカーネルへのインタフェースか、または、ドライバからドライバへのインタフェースです。
Solaris 7 環境でどのようにドライバをサポートするかを決定する前に、ドライバがどのように動作するかについてもう一度調べてください。SunOS 4 のドライバの動作を調べてください (特定の処理系での動作ではなく一般的な動作)。エクスポートしていたインタフェース、提供していた ioctl()、ハードウェアの動作、ドライバがサポートしていたハードウェアの特徴、また、ドライバが複数の open() 呼び出しをサポートしていたかどうかなどです。
これらの変更はドライバに影響を与えるため、次の点を検討してください。
ドライバのエントリポイントはかなり異なる
STREAMS モジュールでの変更点は、透過的な I/O 制御、ストリームへのモジュールの自動プッシュ、新しいメッセージタイプなどです。
SunOS 4 リリースでは、特定のドライバは ioctl() 要求を行う前は STREAMS ドライバであったということを知っておく必要があります。
STREAMS 以外のドライバについては、次のように直接 ioctl() 要求ができます。
ioctl(fd, DRIVER_IOCTL, arg); |
STREAMS ドライバについては、次のように strioctl 構造を設定した後で使用しなければなりません。
ioctl(fd, I_STR, &strioctl); |
ドライバが STREAMS ベースであったかどうかを判定する簡単な方法はありませんでした。現在では、ストリームヘッドに対する認識されない ioctl() はドライバに渡されるので、ドライバが STREAMS ベースであったかどうかを知る必要がなくなりました。
特に透過的 ioctl() をサポートするため、新しいメッセージタイプが Solaris 7 リリースに追加されました。現在、カーネルとの間のユーザデータの転送をストリームヘッドに通知するための「コピーイン」 および「コピーアウト」 メッセージがあります。
STREAMS ドライバを書く詳細については、『STREAMS Programming Guide』を参照してください。
SunOS 4 の streamtab 構造体では、デバイスが open() のときに特定の STREAMS モジュールをプッシュするようドライバ側で指定できました。
Solaris 7 では、システム管理者と autopush(1M) コマンドが、いつ STREAMS モジュールをプッシュするかを指定します。必要な場合、ドライバのインストール時に autopush を実行できます。
STREAMS モジュールのプッシュに関する詳しい情報については、『STREAMS Programming Guide』を参照してください。
現在サポートされるハードウェアプラットフォームのすべてにバイナリ互換性を達成するため、DDI インタフェースはアーキテクチャ概念に沿って慎重に設計されました。基礎となる概念、つまり device ツリーは、元の SPARCstationTM 設計における devinfo ツリーの拡張です。デバイスツリーの各ノードはデバイス情報構造体または「dev_info ノード」 によって記述されます。ツリーの最下部のノードをリーフノードといいます。ディスク、テープドライブ、フレームバッファ、I/O カード、およびネットワークインタフェースなどのほとんどのデバイスは、リーフノードに関連付けられるリーフデバイスの例です。対応するデバイスドライバをリーフドライバといいます。
ツリーにおける中間ノードは一般にバスと関連づけられます (たとえば SBus、SCSI、VME)。これらのノードを「nexus ノード」といい、それらに関連づけられるドライバを「nexus ドライバ」といいます。バス nexi は特定の要素と関連づけられるアーキテクチャの詳細をカプセル化するためのエンティティです。
現在、Solaris 7 DDI/DKI だけがリーフドライバ、nexusドライバの 1 つの型、SCSI ホストバス・アダプタドライバの記述をサポートしています。
デバイスツリー構造はノード間に正式な親子関係を確立します。この親子関係はプラットフォームアーキテクチャの独立性にとって重要なポイントです。
リーフドライバがプラットホーム依存 (たとえば DMA マッピング) のサービスを必要とする場合は、システムはサービスを提供するために要求をその親の呼び出しへと透過的にに変換します。サービスを提供するのは常に nexus ドライバです。それぞれの nexus ドライバはサービスを提供するために、今度は要求をその親に渡すことができます。このアプローチにより、リーフドライバはプラットフォームのアーキテクチャとは関係なく機能することができます。
デバイスドライバ関連コマンドには、add_drv、rem_drv、modload、modunload があります。