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

9. リニアメモリのベースアドレス(MemBase)に関する事項

最初に警告です: MemBase 値に誤った値を定義すると、(もちろんオペレーティ ングシステムに)重大な被害を与えたり、殺したりします。特に、MemBase 値 にシステムメモリの範囲内の値を定義するのは、地獄への片道切符を渡すのと 同じことです。

9.1 MemBase 値を変えようとする「前に」知っておくべきこと

規則 #1: まずは、指定するのではなく、サーバ自身にメモリベース値を 見つけさせましょう。必ず全てのファイルをディスクに "sync" し、重要なア プリケーションも全て終了させてください。電源スイッチを即座に切る羽目に なっても、絶対ファイルシステムに悪影響が出ないようにしておきましょう。

最も危険なカードは VESA ローカルバス(VLB)用の ET4000W32p のリビジョン a と b です。このサーバはリニアベースアドレスを自動検出しますが、この 値は全てのシステムでうまく使えるわけではありません。

ほとんど危険のないカードは PCI バス用のカードです。PCI BIOS は通常正し い MemBase 値を割り当ててくれるので、以下に述べるようなごちゃごちゃし たことは全く行う必要がありません。

サーバが間違った MemBase 値を取得した場合、システムがひどくクラッシュ してしまうかもしれません(例: ビデオメモリがシステムメモリとちょうど重 なってしまった場合)。この場合、即座にリセットしてください。正常に シャットダウンしようとしてはいけません。というのも、X サーバが VGA メ モリへの書き込みを行っていると思いながら、実はシステムメモリへの書き込 みを行ってしまうのです。つまり、壊れたデータがディスクに書き込まれてし まいます。サーバを起動する前に sync を実行していれば、被害は全く出ない (正常終了しなければならないファイルシステムのチェックだけ)でしょう。 サーバの出力をテストを行っているシステムのファイルにリダイレクトしては いけません(sync の後にデータを書き込むことになってしまいます)。

これは最悪のケースのシナリオなので、こうなってしまうことは滅多にないで しょう。上記の説明は、読者の皆さんに適切な準備を必ずしてもらい、被害を 出さないようにするためのものです。

サーバが使えるリニアメモリベース値を見つけられない時には、実験を行うし かありません。これについて、このセクションの残りの部分で説明します。

9.2 MemBase 値の選択

適切な MemBase を見つける作業は実にトリッキーです。カードが使っている MemBase 値を決める方法がない場合、システムメモリの数 MB 上の位置を試す のが最初の推定として良いものでしょう。例えば、メモリを 16MB 積んでいる システムの場合、MemBase 値に 0x01000000 (=16M) や 0x01400000 (=20M) を 定義するとうまく動作するかもしれません。

しかし、これは PCI でないシステムでしか動作しないと思います。というの も、PCI システムは大抵、2GB の点も越えて全てのハードウエアをマップする からです。しかし、繰り返しになりますが、PCI のシステムではサーバは正し いリニアベースアドレスをほぼ確実に検出することができます。唯一の例外は 複数の PCI 用 VGA カードが付いているシステムの場合です。

VESA ローカルバス(VLB)ボードの大部分では、アドレスのデコードに関する問 題が別にあります。ほとんどのマザーボードはアドレス空間の最初の 32, 64, 128 MB しか展開しません(これを確認する良い方法は、ボードに装着できる DRAM の最大量を調べることです。DRAM をサポートしている分のアドレス空間 だけは少なくとも展開できるでしょう)。

このようなボードの場合は、この範囲に収まる MemBase 値か、あるいはシス テムメモリに回り込んで戻ってくるような実アドレスを指定 しなければなりません。後者の場合に、128MB のアドレスしかデコード しないシステムに対して MemBase を 128MB に設定すると、実際にはアドレス 0 としてデコードされます。この値はおそらく、ちょうどカーネルメモリが配 置されている場所でしょう。これが、MemBase をシステムメモリのすぐ上に配 置するという一般的なガイドラインが最初に挙げられる理由です。 こうしておくと、デコードされたボードのアドレス範囲の内部に実際に入って いる見込みが十分あります。ただし、これはマザーボードのメモリ空間全体が RAM で占められていない場合のことです。

9.3 別のアプローチ

マザーボードがデコードするメモリアドレス空間空間の大きさがわからない場 合、0x1FC00000 のような「自明でない」アドレスを試してみましょう。 このアドレスには"1" にセットされたビットがあり、たとえ一部がデコードさ れなくても全てのマザーボードでも動作します。0x10000000 等を使うと、マ ザーボードがアドレスの上位ビットをデコードしない場合には、システムメモ リとアドレスがちょうど重なってしまうことがある点を覚えておいてください。 これを行うのは一度だけでしょう。

9.4 他の試みが全て失敗したら…

一部の VLB ボードは 1GB を越える領域(0x80000000 以上)にしかリニアフレー ムバッファをマップできません。したがって、0x80000000 以上の MemBase 値 を使わなければなりません。

この他にも、16MB 以下の領域にしかリニアフレームバッファをマップで きない VLB ボードがあります。ですから、メモリを 12MB 以下にしてシステ ムを起動して、MemBase 値を 0x00C00000 (=12M) に指定してみるのもよいで しょう。 (一部のオペレーティングシステムでは、起動時にパラメータを指定してメモ リの大きさを制限することができます。このようなオペレーティングシステム では、メモリの大きさを変えてみるためにコンピュータを分解する必要はあり ません。)

残念ながら、使っているシステムにアドレスを教えてやるための簡単な方法は 存在しません(大抵の場合、詳しいことはマザーボードのマニュアルに書かれ ていません)。成功するためには試行錯誤しかないのです。サーバのコードで は大部分のボードでうまく動作するデフォルト値を用意しているのですが、こ こを読んでいるからには当然、読者の皆さんがお使いのボードはこれに該当し ていないのでしょう…。

9.5 制限

リニアメモリのベース値を配置する場所については、制限がいくつかあります。 ET4000W32 系の全てのボードでは、4MB 単位で指定しなければなりません(つ まり 16MB, 20MB に配置できますが、18M には配置できません)。 ET6000 の場合には、16MB 単位で指定する必要があります(ET6000 ドライバは 自動的にリニアメモリのベース値を決められるはずですので、そもそも MemBase 値を指定する必要はないはずです)。

ET4000W32i の場合は面倒です。リニアアドレスのベース値はカードがハード ウェア的に持っているので、これをカードから読み戻す確実は方法がありませ ん。そこで、何らかの方法でこのアドレスを調べ、指定してやる必要がありま す。現在のコードでは賢い方法で推定しているのですが、保証はできません。

ISA カードならば話はずっと簡単です。ISA では 24 個のアドレス線しか使わ ないので、リニアメモリは 16MB の範囲に収まらなければ「なりません」。 ET4000 カードでは 4MB 単位でリニアメモリを指定しなければならないことも 考慮に入れると、リニアメモリを使いたい場合には、マシンのシステムメモリを 12MB より多くしてはならないということになります。したがって、ISA カー ドの場合に現実的に使える MemBase 値は 0x00C00000 だけです。この値は ISA の W32 カードをサーバが検出した場合に、サーバが自動的に選択する値 でもあります。

警告: コンピュータに 12MB を越えるシステムメモリを積んではいけません。 積んでいる場合には、12MB を越える領域のメモリへのアクセスを全て無効に しなければなりません。一部のオペレーティングシステムでは、利用できるメ モリの量を起動時に指定することができるので、リニアメモリを使おうとする 度に物理的にメモリを取り外す必要はありません。

9.6 リニアモードでは単に動作しないボードがあります

その通りです。 そういう場合は、運が悪いのです。

動作しない理由は少なくとも 2 つ考えられます。

最初の理由はありふれています。ボードのメーカーがリニアアドレッシングを 使うために必要な配線やハードウェアを省いていることです。つまり、どんな に努力しても問題を解決することはできません。リニアアドレッシングが物理 的に不可能なのですから。

2番目の理由は、現在の XFree86 の Tseng 用のリニアアドレッシングのコー ドが、ボードの設計が想定している方法と互換でないことです。XFree86 の Tseng 用のコードでは、(ISA, VLB, PCI いずれも含む)バスのアドレス線と Tseng VGA チップのアドレス線が 1:1 で対応していることを想定しています。 こういうことはあまりないと思うので、たぶん原因ではないでしょう。

このように 1:1 に対応していないボードもごくまれにあります(例: 2つのア ドレス線を入れ換えているもの)。このタイプのハードウェアをサポートする ことは可能ですが、現時点では実装は行っていません。

他には、ボードがアドレスをデコードするハードウェアを外部に持っている場 合があります。このハードウェアは、バスのアドレス線の数と VGA チップに 繋がるアドレス線の数(少ない)を合わせるためのものです。

このようなボードの 1 つは、3 つの NOR ゲート(74F02 チップ 1 つ)を使っ て 6 つの上位アドレスの線を W32i チップの 3 つのアドレスピンに接続して います。これは明らかに 2:1 のマッピングを表し、1:1 のマッピングではあ りません。したがって、このボードは XFree86 のリニアモード実装方法とは 「互換」ではありません。

9.7 リニアアドレスが間違っているかどうかはどうやって調べるのですか?

単純な話では: 全く動作しない、マシンが凍ってしまう、クラッシュしてしま う、その他諸々の問題が起きた時です。

しかし、必ずしも明らかなわけではありません。問題が起こらないこともあり ます。単に画面が真っ黒になったり、画面にゴミが表示されたりしますが、ス クリーンに何も描画されません。最初のアプリケーションを起動した時にコア ダンプすることもあります。

このような場合にアクセラレーションを有効にしていたら、ほぼ確実にサーバ の出力に"WAIT_ACL: timeout" というメッセージが複数回現われているでしょ う。この理由は、アクセラレータのレジスタもリニアメモリにマップされてい ることです。そして、もしリニアメモリが動作しなければ、アクセラレータも 動作しません。

しかし、WAIT_ACL のメッセージは必ずしもリニアメモリアドレスの誤りを意 味するわけではない点に注意してください。このメッセージが出力される原因 は他にもたくさんあります。しかし、8bpp のバンク切り替えモードの時には このメッセージが全く現われない場合には、リニアメモリの問題を考えるとよ いでしょう(「バンク切り替え」は「リニア」の反対のモードです。 XF86Config ファイル中で "option linear" が指定されていなければ、デフォ ルトでバンク切り替えモードとなります)。


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