  Large Disk HOWTO
  Andries Brouwer, aeb@cwi.nl 著
  v2.2j, 12 September 1999
  平本 光二 hiramoto@nanako.or.jp 訳
  2000年2月18日作成

  ディスクのジオメトリと1024シリンダ制限のすべて。

  この文書の最新バージョンは、 www.win.tue.nl を参照してください。 (訳
  注: オリジナルの英語版のこと。日本語版の最新バージョンについては
  www.linux.or.jp を参照してください)

  1.  問題

  例えばあなたが 1024 シリンダを超えるディスクを持っているとしましょう。
  その上あなたがディスク I/O のために古い INT13 BIOS インターフェースを
  使う OS を持っているとしましょう。これは問題です。なぜなら、このインタ
  ーフェースは I/O 動作時のシリンダ指定に 10 ビットのフィールドを使うの
  で、 1024 番以降のシリンダにはアクセスできないのです。 (訳注: 2^10 =
  1024)

  幸い、Linux は BIOS を使いませんので問題ありません。

  まぁ、次の二点を除いてですが。

  1. システム起動時には Linux はまだ稼動していませんので、 BIOS 問題から
     逃げられません。これは LILO やそれに類するブートローダにとって問題
     になります。

  2. 複数の OS で一つのディスクを使いまわす場合、どこにパーティションが
     あるのか、それぞれの OS がしっかり把握していなければなりません。言
     い換えると、Linux と DOS を一つのディスク上で使用する場合、両者は同
     じ方法でパーティションテーブルを解釈する必要があります。これは
     Linux カーネルと fdisk にとって問題になります。

     以下に、関連する問題の詳細を示します。なお、私はカーネルのバージョ
     ン2.0.8 を参照しています。他のバージョンでは少し違うかもしれませ
     ん。

  2.  要約

  新しい大容量ディスクを用意しました。どうすればいいんしょう?  そう、ソ
  フトウェア的には、fdisk (cfdisk の方がよりよい) でパーティションを作成
  し、mke2fs でファイルシステムを作り、 mount で新しいファイルシステムを
  ファイル階層に追加すればいいんです。

  最近では大容量ハードディスクについて問題になることはまず無いので、この
  HOWTO を読む必要もまず無いでしょう。問題のように思われるものの大部分
  は、大容量ハードディスクを使用する上で問題になるだろうと思い込んでディ
  スクマネージャをインストールしたり、 fdisk のエキスパートモードにいっ
  ちゃったり、明示的にディスクのジオメトリを LILO やカーネルのコマンドラ
  インで指定したりすることによって引き起こされます。

  しかし、典型的な問題は以下のようなものです。

  1. 太古のハードウェアを使ってる

  2. 同じディスク上にいくつかの OS を載せる

  3. 起動時(時々起きる)

     アドバイス:

  大容量 SCSI ディスクについて: Linux はずっと昔からサポートしています。
  特別なことをする必要はありません。

  (8.4GB を越えるような) 大容量 IDE ディスクについて: 最新の安定版カーネ
  ル (2.0.34 かそれ以降)を使ってください。通常はそれが一番です。特
  に、BIOS に LBA などのディスク (ジオメトリ) 変換を要求しないという賢明
  な選択ができるような場合には。

  (33.8GB を越えるような) とても大容量の IDE ディスクについて: 後述の
  ``34GB を越えるディスクでの IDE の問題'' を参照してください。

  もし起動時に LILO がハングしたら、設定ファイルの /etc/lilo.conf に
  ``linear'' も指定してください。

  カーネル/LILO/fdisk に明示的にジオメトリを与えることにより解決するよう
  なジオメトリの問題であるかもしれません。

  古い fdisk を使っていて、パーティションが重なっている(``overlapping'')
  という警告が出たら: 警告は無視するか、cfdisk を使ってください(こちらの
  方がよい)。

  ディスクのサイズが何か変だと思う時は、二進と十進の ``単位'' を混同して
  いないか確認してください。そして、空き領域を調べるために df を使用する
  時は、 df は管理上のオーバーヘッドのために空のディスク上でもパーティ
  ションサイズより数パーセント小さい値を報告することを覚えておいてくださ
  い。 (訳注: 詳細は ``「問題なし: df より fdisk の方がパーティションが
  大きく見える」'' の章を参照してください)

  さぁ、これでもまだ何か問題があると思われるのならば、あるいはあなたが単
  に知りたがりやならば、以下も読んでください。

  3.  単位とサイズ

  1キロバイト (kB) = 1000バイト。 1メガバイト (MB) = 1000 kB。 1ギガバイ
  ト (GB) = 1000 MB。 1テラバイト (TB) = 1000 GB。これは SI 単位系です。
  しかし、1 MB = 1024000バイトを適用して 1.44 MB フロッピーと表現した
  り、 1 MB = 1048576バイトと考える人がいます。この文書では、二進法の方
  を Ki, Mi, Gi, Ti と表現して、これを標準とします。そうすると、フロッピ
  ーは 1440 KiB (1.47 MB, 1.41 MiB) となり、 1 MiB =       1048576 バイ
  ト (1.05 MB) 1 GiB =    1073741824 バイト (1.07 GB) 1 TiB =
  1099511627776 バイト (1.1  TB) となります。

  まったく正しいことに、ディスクドライブのメーカは SI 単位系に従い十進法
  を使っています。しかし、Linux の起動メッセージやいくつかの fdisk のよ
  うなプログラムは二進法を表現するために MB や GB というシンボルを使用し
  てたり、二進法と十進法がごちゃ混ぜになってたりします。よって、あなたが
  ディスクを買った時に表記されていた容量よりも実際の容量の方が小さいと考
  える前に、まず十進法で(または単にバイト単位で)実際のサイズを計算してみ
  てください。

  二進数単位の専門用語や省略形に関しては、 Knuth に代案があります。 KKB,
  MMB, GGB, TTB, PPB, EEB, ZZB, YYB と記述して、ラージ キロバイト(large
  kilobyte), ラージ メガバイト(large megabyte), ... ラージ ヨタバイ
  ト(large yottabyte( と読むというものです。彼はこのように書いています:
  「文字を二重にしているのは、二進数という性質と、 (訳注: 10進数での値よ
  り)大きい性質を暗示しているのです」これはよい提案です - 「ラージギガバ
  イト (large gigabyte)」は「ギビバイト (gibibyte)」より発音しやすいです
  から。しかしながら、我々の目的のためにただ一つ重要なことは、メガバイト
  (megabyte) がちょうど 1000000 バイトであることを強調することで、もし何
  か他のことを意味するのならば他の用語や省略形が必要であるということで
  す。

  3.1.  セクタサイズ

  この文書ではセクタは 512 バイトです。これは大抵の場合は真ですが、いく
  らかの MO ディスクは 2048 バイトのセクタサイズを使用しているので (訳
  注: 640MB や 1.3GB(GIGAMO) の 3.5 インチ MO・PD・DVD-RAM などが該当し
  ます)、以下の説明においては実際の容量は 4倍にして考える必要がありま
  す。 (このようなディスクに fdisk を使用する時は、バージョン 2.9i かそ
  れ以降を使用し、 `-b 2048' オプションを与えなければなりません)

  3.2.  ディスクサイズ

  C シリンダ、H ヘッド、S セクタ毎トラックのディスクは、全体で C*H*S セ
  クタを持ち、C*H*S*512 バイトを格納することができます。例えば、ディスク
  のラベルに C/H/S=4092/16/63 と書かれていたら、このディスクは
  4092*16*63=4124736 セクタを持ち、 4124736*512=2111864832 バイト (2.11
  GB) を格納することができます。 8.4GB より大容量なディスクには
  C/H/S=16383/16/63 を与えるという工業規格 (industry convention) がある
  ので、そのようなディスクのサイズはもはやディスクから報告された C/H/S
  値からは読み取ることはできません。

  4.  ディスクアクセス

  ディスクに対して何かを読み書きするためには、例えばセクタやブロックの番
  号を与えるなどの方法で、ディスク上の位置を指定する必要があります。ディ
  スクが SCSI ディスクの場合はこのセクタ番号は直接 SCSI コマンドにするこ
  とができ、ディスクはそれを理解します。ディスクが IDE ディスク で LBA
  を使用している場合は SCSI の場合とまさに同じ方法です。しかしディスクが
  古く、RLL や MFM や、LBA 時代以前の IDE だったりする場合は、ディスク上
  の希望の位置を指定するために、ディスクのハードウェアは(シリンダ、ヘッ
  ド、セクタの)三つの値を要求します。

  リニアナンバリングとこの三次元表記の対応は次のようになっています: C シ
  リンダ H ヘッド S セクタ毎トラックを持つディスクにとって、三次元または
  CHS 表記による位置 (c,h,s) は、リニアまたは LBA 表記による位置 c*H*S +
  h*S + (s-1) と同じです。 (マイナス 1 する理由は、この三次元表記では伝
  統的に 0 ではなく 1 からセクタを数え始めるからです)

  それゆえ、とても古い非 SCSI ディスクにアクセスするためには、そのジオメ
  トリ、つまり C,H,S という値を知っている必要があります。

  4.1.  BIOS によるディスクアクセスと 1024 シリンダ制限

  Linux は BIOS を使っていませんが、いくつかの他のシステムは使っていま
  す。 LBA 時代以前の BIOS は、入力として (c,h,s) を要求する INT13 とい
  うディスク I/O ルーチンを提供していました。 (より正確にいうと、AH (レ
  ジスタ)で実行するファンクションを、 CH でシリンダ数の下位 8ビットを、
  CL の 7-6 ビットでシリンダ数の上位 2ビットを、5-0ビットでセクタ数を、
  DH でヘッド数を、そして DL でドライブナンバー(80h か 81h)を指定しま
  す。これはパーティションテーブルの設計の章で説明しています。)

  かくして、10 ビットのシリンダ数、8 ビットのヘッド数、そして 6 ビットの
  トラックセクタ数(1-63 の値をとる)からなる 3 バイトに CHS はエンコード
  されます。つまりシリンダ数は 0 から 1023 の値をとることができ、 1024
  シリンダより上は BIOS では表現できないということになります。

  DOS や Windows (訳注: Windows95 以前の Windows 3.1 等)といったソフト
  ウェアは、 LBA をサポートした IDE ディスクが導入された時にも変更されま
  せんでしたので、ディスクジオメトリを必要とし続けました。それは、(LBA
  を使った) 実際のディスク I/O の際には(ジオメトリは) もはや必要でないに
  も関わらず、 BIOS を通じてのみディスク I/O を行っていたからです。これ
  はさらに、今時のディスクを使っていても、 BIOS と会話するような場合や他
  の OS が必要とする場合には、 Linux もジオメトリを必要とすることを意味
  します。
  この状態は 4年くらい前まで続いていて、 INT13 ファンクションで扱えない
  サイズのディスク (つまり (c,h,s) のための 10+8+6=24ビットでは 8.5GB 以
  上を扱えない) が市場に登場し、新しい BIOS インターフェースがデザインさ
  れました。それは拡張 INT13 ファンクションと呼ばれ、絶対ブロック数で始
  まる 8バイトを含む 16バイトのディスクアドレスパケットを DS:SI が指すと
  いうものです。

  Microsoft の世界がこれらの拡張 INT13 ファンクションに移行するのは非常
  に遅いです (訳注: Windows95 以降では対応しています)。おそらく「ディス
  クジオメトリ」というコンセプトはあと数年は必要でしょう。

  4.2.  BIOS と IDE の「壁」(上限)の歴史

     ATA 仕様書 (IDE ディスク用) - 137 GB まで
        65536 シリンダ (0-65535 の範囲)、16 ヘッド (0-15 の範囲)、 255
        セクタ毎トラック (1-255 の範囲) まで扱えます。よって最大で
        267386880 セクタの容量があり(512 バイト単位で)、 136902082560 バ
        イト (137 GB) になります。これは(西暦1999年の時点では)まだ問題と
        はなっていませんが、あと数年もしたら問題になるかもしれません。

     BIOS Int 13 - 8.5 GB まで
        1024 シリンダ (0-1023 の範囲), 256 ヘッド (0-255 の範囲), 63 セ
        クタ毎トラック (1-63 の範囲) まで扱えます。よって最大で
        8455716864 バイト (8.5 GB) になります。これは今日では深刻な制限
        で、 DOS では今日の大容量ディスクが使えないことを意味していま
        す。

     528 MB の壁
        BIOS Int 13 コールと IDE ディスク I/O の両方に同じ c,h,s の値を
        使った場合、両方の制限が組み合わされ、 1024 シリンダ・16 ヘッ
        ド・63 セクタ毎トラックまでしか使用できず、最大容量は 528482304
        バイト (528MB) となります。これが DOS と古い BIOS の組み合わせに
        よる悪名高い 504MiB の壁です。これは 1993年ごろに問題となり、人
        々はすべての種類のぺてんに訴えました。すなわちハードウェ
        ア(LBA)、ファームウェア(BIOSによる変換)、そしてソフトウェア(ディ
        スクマネージャ)です。「変換」の概念は 1994年にでっちあげられまし
        た: BIOS は、ドライブと会話する時のジオメトリと、それとは異な
        る、偽の、 DOS と会話する時のジオメトリを使い、そしてその 2つの
        間で変換を行います。

     2.1GB の壁 (1996年 4月)
        いくつかの古い BIOS では、シリンダ数を格納するための CMOS RAM 内
        のフィールドを 12 ビット分しか確保していません。そのため、この数
        字は最大でも 4095 以下となり、たった 4095*16*63*512=2113413120
        バイトしかアクセスできなくなります。大容量ディスクを接続した時
        に、ブート時にハングしたりするという影響が出ます。この制限によっ
        て、かえって 4092/16/63 というジオメトリを持つディスクが一般的に
        なりました。そして今日でも、多くのディスクドライブが 4092/16/63
        に見せかけるためのジャンパを持っています。 over2gb.htm も参照し
        てください。その他の BIOS はハングはしませんが、2.5 GB の代わり
        に 429 MB といったように非常に小容量なディスクとして検出してしま
        います。 (訳注: つまりこの例では、上記の 2113413120 で割った剰余
        がディスクの総容量として検出されているわけです)

     3.2 GB の壁
        これは Phoenix BIOS ファームウェアの 4.03 と 4.04 のバグで、
        3277 MB を越える容量のドライブを繋いで CMOS セットアップを行うと
        システムがロックしてしまいます。 over3gb.htm を参照してくださ
        い。

     4.2 GB の壁 (1997年 2月)
        単純な BIOS 変換 (ECHS=拡張(Extended)CHS、しばしば `Large disk
        support' やあるいは単に `Large' と呼ばれます)は、ヘッド数を 2倍
        しシリンダ数を半分にするという動作を、 DOS から見えるシリンダ数
        が 1024 以下になるまで繰り返します。現在 DOS と Windows 95 は
        256 ヘッダを扱えませんし、一般的にディスクは 16 ヘッドであると答
        えるので、これはつまりこの単純なメカニズムが
        8192*16*63*512=4227858432 バイト(偽のジオメトリは 1024 シリン
        ダ・128 ヘッド・63 セクタ/トラック) までしか動作しないことを意味
        します。 ECHS はセクタ毎トラックの数は変更しないことに注意してく
        ださい。そしてこれが 63 ではない場合は制限はもっときつくなりま
        す。 over4gb.htm を参照してください。

     7.9 GB の壁
        最初にヘッド数を 15 に調整することで上記のような問題 (ECHS を復
        習してください)を避けることのできる少し賢い BIOS は、それによっ
        て 240 ヘッドまでの偽のジオメトリを得ることができるので、
        1024*240*63*512=7927234560 バイトまで有効となります。

     8.4 GB の壁

        最後に、BIOS が可能な限りの変換に成功し、 255 ヘッドと 63 セクタ
        毎トラックを使うと (`assisted LBA' あるいは単に `LBA' と呼ばれ
        る)、 1024*255*63*512=8422686720 バイトまで到達できます。 8.5GB
        制限のちょっと手前ですが、これは 256 ヘッダのジオメトリを避けな
        ければならないからです。 (この変換はまず、ディスク容量が
        1024*H*63*512 に収まるようにヘッド数 H を 16, 32, 64,128, 255 か
        ら選び、次に総容量を (H*63*512) で割ってシリンダ数 C を計算しま
        す。)

     33.8 GB の壁 (1999年 8月)

        次のハードルは 33.8GB を越えるサイズで訪れました。この問題は、デ
        フォルトの 16 ヘッド 63 セクタ毎トラックでは、シリンダ数が short
        int に納めることができない 65535 より大きい数になってしまうこと
        です。今日では、ほとんどの BIOS がそのようなディスクを扱えないで
        しょう。 (例えば正常に動作する新しいフラッシュ(ROM)のイメージを
        得るには Asus upgrades を参照してください) 2.2.14 / 2.3.21 より
        古い Linux カーネルではパッチが必要です。後述の ``34 GB 超のディ
        スクにおける IDE の問題'' を参照してください。

  このトピックについてのその他の議論については、 Breaking the Barriers
  を参照してください。さらに詳細については、 IDE Hard Drive Capacity
  Barriers を参照してください。

  8.4 GB を越えるハードディスクは、自分のジオメトリを 16383/16/63 と答え
  ると思われます。これは要するに「ジオメトリ」というものが時代遅れである
  ことを意味し、ディスクの総容量はもはやジオメトリからは計算できません。

  5.  ブート

  システムをブートすると、 BIOS は一台目のディスク(またはフロッピーや
  CDROM)からセクタ 0 (MBR - Master Boot Record として知られている)を読み
  出し、そこにあるコード - 通常は何らかのブートストラップローダ - へジャ
  ンプします。この小さなブートストラッププログラムは普通はそれ自身のディ
  スクドライバは持ってなく BIOS サービスを利用します。これは、Linux カー
  ネルが最初の 1024 シリンダ内に完全に収まっている時のみブート可能である
  ことを意味します。

  この問題はとても簡単に解決できます: BIOS がアクセス可能なディスク - お
  そらく一台目か二台目のディスク - の最初の 1024 シリンダ内に完全に収ま
  るパーティションに、カーネル(と、LILO のマップファイルのようにもしかし
  たらブートアップの最中に使用されるかもしれない他のファイル) を配置すれ
  ばいいのです。

  したがって、カーネル用の領域として 10 MB くらいの小さなパーティション
  を、一台目か二台目のディスクの先頭から 1024 シリンダ内に完全に収まるよ
  うに作成してください。これを /boot としてマウントし、 LILO がここにカ
  ーネルを置くようにしてください。

  5.1.  LILO と `linear' オプション

  もう一つの注意点は、ブートローダと BIOS がディスクジオメトリについて意
  見が一致している必要があることです。 LILO はジオメトリについてカーネル
  に問い合わせますが、ディスクドライバの作者の大多数は、 BIOS が使用する
  であろう LILO が告げる値の代わりに、パーティションテーブルからジオメト
  リを得るという悪い癖を受け継いでいます。したがって、カーネルから供給さ
  れるジオメトリはしばしば役に立ちません。このような場合、LILO に
  `linear' オプションを与えましょう。この効果は、ブートローダのインスト
  ール時に LILO がジオメトリ情報を必要とせず (マップ中にリニアアドレ
  ス(訳注: のうち下位 24bit)を格納する)、しかしブート時にリニアアドレス
  を変換する、というものです。何故これがデフォルトではないのでしょう?
  そうですね、一つ不具合があるのです: `linear' オプションを付ける
  と、LILO はシリンダ数を知る必要がなくなり、したがってカーネルの一部が
  1024シリンダ制限を越えて格納されても警告を出さなくなり、しまいにはブー
  トしないシステムが出来て終わる可能性があるのです。

  5.2.  1024 シリンダが 1024 シリンダではない

  Tim Williams はこういってます: 「私は Linux のパーティションを最初の
  1024 シリンダ以内に作成しましたが、それでもなお起動しませんでした。1GB
  以内に移動したらやっと動きました。」どうしてなんでしょう?  そう、これ
  は AHA2940UW コントローラに接続された SCSI ディスクで、このコントロー
  ラはファームウェアと BIOS の設定オプションに依存して H=64, S=32 (1シリ
  ンダは 1 MiB = 1.05 MB になる)か、 H=255, S=63 (1シリンダは 8.2 MB に
  なる)のどちらか使用します。間違いなく BIOS が前者の設定になっていて、
  よって 1024 シリンダ制限が 1 GiB になっています。しかし Linux が後者の
  値を使っている間は LILO は制限が 8.4GB であると思っているわけです。

  6.  ディスクジオメトリ、パーティション、重複(overlap)

  ディスク上にいくつかの OS が存在する場合、それぞれの OS は一つかそれ以
  上のディスクパーティションを使用します。これらのパーティションの不一致
  は破滅的な結果をもたらすことがあります。

  MBR には(基本)パーティションがどこに存在するかを記述したパーティション
  テーブルが存在します。 4つの基本パーティションのために 4つのテーブルの
  エントリがあり、それは以下のようになっています。

       struct partition {
               char active;    /* 0x80: ブート可, 0: ブート不可 */
               char begin[3];  /* 最初のセクタの CHS */
               char type;
               char end[3];    /* 最後のセクタの CHS */
               int start;      /* 32 bit のセクタ番号 (0 から数え始める) */
               int length;     /* 32 bit のセクタ総数 */
       };

  (CHS は シリンダ/ヘッド/セクタを表します。)

  この情報は冗長です: 24ビットの begin および end フィールドによってと、
  32ビットの start および length フィールドによっての両方で、パーティ
  ションの位置が与えられています。

  Linux は start と length のフィールドのみを使用するので、それゆえに
  2^32 セクタまでのパーティションを取り扱うことができます。つまり、2 TiB
  (= 2048 GiB) のパーティションです。これは現在利用できるディスクの 100
  倍くらい大きいので、あと 8年間くらいは大丈夫でしょう。 (そう、パーティ
  ションは非常に大きくできます。しかし深刻な制限があります。自然な整数が
  32bit のハードウェア(訳注: 例えば CPU が Intel x86 系統のマシン) 上の
  ext2 ファイルシステム上では、 2 GiB 以上のファイルは作成できないので
  す。)

  DOS は begin と end フィールドを使用し、ディスクアクセスのために BIOS
  INT13 コールを使用しますので、 BIOS 変換を使っても 8.4GB 以下のディス
  クしか制御できません。 (FAT16 ファイルシステムの制限により、パーティ
  ションは 2.1GB より大きくできません。) 同じことが Windows 3.11・WfWG
  (Windows for WorkGroup)・ Windows NT 3.* にもいえます。

  Windows 95 は拡張 INT13 インターフェースをサポートしており、パーティ
  ションをその方法でアクセスする必要があることを示すための特別なパーティ
  ションタイプを使います(b, 6, 5 の代わりに c, e, f)。これらのパーティ
  ションタイプが使われている場合、 begin と end フィールドにはダミーの情
  報 (1023/255/63) が格納されます。 Windows 95 OSR2 からは FAT32 ファイ
  ルシステム (パーティションタイプは b または c)が導入され、 2 TiB まで
  のパーティションを作成できます。

  実際には何も悪くないのに「重複(overlapping)」パーティションについて
  fdisk からたわごとを聞かされるのはなぜでしょう?  やれやれ - 何か「悪
  い」のです: DOS がしているように、そのパーティションの begin と end
  フィールドを見た場合、それがオーバーラップしているのです。 (そしてそれ
  は正しくありません。なぜならそれらのフィールドは 1024 以上のシリンダ数
  を格納することができません - 1024 シリンダ以上の部分を使うと、常にオー
  バーラップが発生するのです。) しかし、Linux や、パーティションタイプが
  c, e, f であるパーティションの場合に Windows 95 がしているように、
  start と length フィールドを見る場合には、それはまったく問題ありませ
  ん。そう、cfdisk が納得していて Linux でしかディスクを使わないのなら
  ば、警告は無視してください。DOS と共有している場合は注意してください。
  /dev/hdx のパーティションテーブルを見るには cfdisk -Ps /dev/hdx と
  cfdisk -Pt /dev/hdx コマンドを使ってください。。

  7.  変換とディスクマネージャ

  (ヘッド数、シリンダ数、トラック数というような) ディスクジオメトリは
  MFM や RLL 時代の産物で、当時は物理的なハードウェア構造を反映していま
  した。現在では、IDE でも SCSI でも、ディスクの「本当の」ジオメトリにつ
  いて興味を持つ人はいません。実際のところ、1トラックあたりのセクタ数は
  可変で、ディスクの外周の方がよりセクタ数が多くなっています。つまり、一
  意に決まるような「本当の」 1トラックあたりのセクタ数というものは存在し
  ません。それとはまるっきり反対に: IDE コマンド INITIALIZE DRIVE
  PARAMETERS (91h) は現在では、ヘッド数と 1トラックあたりのセクタ数をど
  れだけ持っていることになっているかをディスクに設定するために提供されて
  います。今時の大容量ディスクが実際にはヘッドを 2つしか持っていなくても
  BIOS に対しては 15 か 16 ヘッドであると報告したり、また BIOS がユーザ
  のソフトウェアに対してそれをさらに 255 ヘッドだと報告したりするのは、
  ごく普通です。

  ユーザーにとって最善なのは、ディスク上にあたかも一直線にセクタ番号が並
  んでいる(0, 1, ...)としてディスク上のどこにセクタが存在するかといった
  ことをファームウェアに任せられることです。このリニアナンバリングは LBA
  と呼ばれます。

  概念は以下の通りです。 DOS やいくつかのブートローダは (c,h,s) 表記を
  使って BIOS と会話します。 BIOS は、ユーザが使用する偽のジオメトリを
  使って (c,h,s) を LBA 表記に変換します。ディスクが LBA を受け付ける場
  合は、この値をディスク I/O に使用します。さもなければ、ディスクが使っ
  ているジオメトリを使って (c',h',s') に変換し直し、ディスク I/O に使い
  ます。

  `LBA' という表現の使用におけるちょっとした混乱があることに注意してくだ
  さい: ディスクの性能を記述する用語としてならば `Linear Block
  Addressing' (CHS アドレッシングの逆)を意味します。BIOS 設定での用語と
  してならば、しばしば `assisted LBA' と呼ばれる変換方式を意味します。 -
  前述の ```8.4 GB の壁''' を見てください。

  (訳注: ハードディスクの)ファームウェアが LBA を理解しないけど、 BIOS
  がジオメトリ変換を利用できる場合は、似たようなことが起きます。 (BIOS
  設定ではこれはしばしば `Large' と表示されます。) 今、BIOS が OS にジオ
  メトリ (C,H,S) を示して、ディスクコントローラと話す時に (C',H',S') を
  使うとします。通常は S=S', C=C'/N, H=H'*N となります。 N は、C' <=
  1024 となる最も小さい 2 の乗数です。 (これは、C' = C/N とする際の丸
  め(切捨て)によって無駄になる容量を最小限にするためです。) さらに、この
  方法では 8.4GB (7.8 GiB) までアクセスできます。

  (BIOS の 三つ目の設定オプションは通常 `Normal' と呼ばれ、どんな変換も
  行いません。)

  BIOS で `Large' や `LBA' を利用できない場合は、ソフトウェアによる解決
  方法もあります。 OnTrack や EZ-Drive のようなディスクマネージャは BIOS
  のディスク制御ルーチンを自分自身のものと置き換えます。普通これは、ディ
  スクマネージャのコードを MBR とそれに続くセクタ (OnTrack ではこのコー
  ドを DDO: Dynamic Drive Overlay と呼んでいます) に配置することで実現さ
  れており、他のすべての OS の前に起動されます。ディスクマネージャがイン
  ストールされている所で、 OS をフロッピーから起動すると、何か問題がある
  かもしれません。

  ディスクマネージャの効果は多かれ少なかれ BIOS による変換と同じです -
  しかし特に、同じディスク上でいくつかの異なる OS を動作させると、ディス
  クマネージャに由来する多くのトラブルが起きる可能性があります。

  Linux は OnTrack Disk Manager のバージョン 1.3.14 からと、 EZ-Drive の
  バージョン 1.3.29 からをサポートしています。詳細を以下に述べます。

  8.  IDEディスクのためのカーネルでのディスク変換

  Linux カーネルが IDE ディスク上に何らかのディスクマネージャの存在を検
  出した場合、そのディスクマネージャがするのと同じ方法でディスクを再マッ
  プしようとするので、Linux は例えば OnTrack や EZ-Drive を使っている
  DOS のように同じディスクパーティションを見ることになります。しかし、ジ
  オメトリが(訳注: LILOの)コマンドラインから指定された場合は再マップは行
  われません - つまり `hd=cyls,heads,secs' (訳注: `hdx=cyls,heads,secs'
  が正しい) というコマンドラインオプションはディスクマネージャとの互換性
  を失わせてしまいます。

  再マップは、C <= 1024 になるか H = 255 になるまで、 (H*C が一定である
  ように) ヘッド数(H)を 4, 8, 16, 32, 64, 128, 255 と増やしていきます。

  詳細は以下のようになります - 以下のサブセクションの題名はブートマネー
  ジャに対応すると思われる文字列です。以降、パーティションタイプはすべて
  16 進数であらわします。

  8.1.  EZD

  最初の基本パーティションタイプが 55 であるとき、 EZ-Drive が存在すると
  判断されます。ジオメトリは上で説明したように変換され、セクタ 0 にある
  パーティションテーブルは無視されます。その代わりに、パーティションテー
  ブルはセクタ 1 から読み出されます。ディスクのブロック番号は変更されま
  せんが、セクタ 0への書き込みは、セクタ 1 への書き込みに強制されます。
  この振る舞いは、ide.c (訳注: カーネル 2.2.12 では drivers/block/ide.h)
  の中で
   #define FAKE_FDISK_FOR_EZDRIVE  0 としてカーネルを再構築すれば切り替
  えられます。

  8.2.  DM6:DDO

  (一台目のドライブの)最初の基本パーティションタイプが 54 であると、
  OnTrack ディスクマネージャが組み込まれていると判断されます。ジオメトリ
  はすでに述べた方法で変換され、ディスク全体が 63 セクタ分ずらされます
  (つまり、元々のセクタ 63 はセクタ 0 と呼ばれることになります)。この結
  果、新しい(パーティションテーブルを含む) MBR は、新しいセクタ 0 から読
  み込まれます。もちろん、このずらしは DDO のための空間を確保するため
  で、これが一台目のディスク以外にはずらしが入らない理由です。

  8.3.  DM6:AUX

  (一台目のディスク以外の)基本パーティションがタイプ 51 か 53 のときに
  は、 OnTrack ディスクマネージャが効いていると判断されます。ジオメトリ
  の変換は上に述べた通りです。

  8.4.  DM6:MBR

  古い OnTrack ディスクマネージャは、パーティションタイプではなくシグネ
  チャで検出されます。 (検出方法: MBR のバイト 2,3 にある数をオフセット
  と考え、このオフセット値が430以下であるか確認します。次にこのオフセッ
  ト位置にある short int 値が 0x55AA で、なおかつ、次の 1 バイトが奇数か
  どうかを監査します。) 変換方法は、上に述べた通りです。

  8.5.  PTBL

  最後に、基本パーティションの start と end の値から、変換が行われてるこ
  とを知る方法があることをご紹介しましょう。もし、あるパーティションが
  start と end にそれぞれセクタ番号 1 と 63 を持っていて、さらに end の
  ヘッド番号として 31, 63, 127, または 254 を持っているとすると、パー
  ティションの終わりはシリンダ境界におかれる慣習であること、 IDE インタ
  ーフェースは最大 16 ヘッドであることから、 BIOS による変換がおこなわれ
  ていることが分かり、また、ジオメトリはヘッド数 32, 64, 128, または 255
  を使って再マップされていることが分かります。しかし、現在のジオメトリが
  すでにトラックあたり 63 セクタで、たくさんのヘッドがあるというなら、変
  換は行いません (ヘッドがたくさんあるというのは、すでに変換が行われてい
  るということですから)。

  9.  結論

  結局どうだというのでしょう? Linux 利用者にとっては一点だけが重要です。
  それは、LILO と fdisk が正しいジオメトリを使わなければならないことで
  す。ここでの「正しい」とは、fdisk に関しては同じディスク上の他の OS が
  そのジオメトリを使用しているという意味であり、また LILO に関しては起動
  時に BIOS とやり取りして起動が成功するジオメトリであるということで
  す。(普通はこの 2つは一致します。)

  fdisk は、どうやってジオメトリを調べるのでしょう?  HDIO_GETGEO ioctl
  を使用してカーネルに問い合わせるのです。しかし、利用者は対話的に、ある
  いはコマンドラインからジオメトリを強制できます。

  LILO は、どうやってジオメトリを調べるのでしょう?  HDIO_GETGEO ioctl を
  使用してカーネルに問い合わせるのです。しかし、利用者は /etc/lilo.conf
  内の "disk=" オプションを使って、ジオメトリを強制できます
  (lilo.conf(5) を参照してください)。 linear オプションを LILO に指定す
  ることもできます。その場合、LILO は CHS アドレスの代わりに LBA アドレ
  スをマップファイルに格納し、起動するときにそれを使用します。 (ドライブ
  のジオメトリを問い合わせるために INT 13 のファンクション 8 を使います)

  カーネルは(fdisk や LILO に訊かれた)答をどうやって調べるのでしょうか?
  ええと、おそらく手動か、または カーネルにそのようなオプションを渡すよ
  うにブートローダに質問されて、最初に利用者が `hda=cyls,heads,secs' と
  いうカーネルコマンドラインオプション(bootparam(7) を参照のこと) によっ
  て明示的にこれを指定するかもしれません。例えば、/etc/lilo.conf 内に
  `append = "hda=cyls,heads,secs"' というような行を追加することにより、
  そのようなオプションを LILO に与えることができます(lilo.conf(5) を参照
  のこと)。でなければ、カーネルは BIOS かハードウェアから取得した値を
  使って何とかして推量するでしょう。

  (Linux 2.1.79 からは) /proc ファイルシステムを使用することによってジオ
  メトリについてのカーネルの見解を変更することが可能です。例えばこんな感
  じです。

       # sfdisk -g /dev/hdc
       /dev/hdc: 4441 cylinders, 255 heads, 63 sectors/track
       # cd /proc/ide/ide1/hdc
       # echo bios_cyl:17418 bios_head:128 bios_sect:32 > settings
       # sfdisk -g /dev/hdc
       /dev/hdc: 17418 cylinders, 128 heads, 32 sectors/track
       #

  9.1.  LILO のパラメータを計算する

  カーネルのコマンドラインに `hda=cyls,heads,secs' と追加することによっ
  て信頼できるジオメトリを強要するのは、時には便利です。ほとんど大抵の場
  合は secs=63 にします。それから heads を指定します。 (今日での便利な値
  は heads=16 と heads=255 です) cyls に指定すべき値は何でしょう?  この
  値は C*H*S セクタの総容量から正確に求めることができます。例えば
  71346240 セクタ (36529274880 バイト)のドライブでは、 C は
  71346240/(255*63)=4441 として計算でき (計算には bc プログラムを使えま
  す)、 hdc=4441,255,63 というブートパラメータを得ることができます。どの
  ようにして正確な総容量を知ることができるのでしょう?  例えば、

       # hdparm -g /dev/hdc | grep sectors
        geometry     = 4441/255/63, sectors = 71346240, start = 0
       # hdparm -i /dev/hdc | grep LBAsects
        CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=71346240

  というようにトータルで 71346240 セクタであることを知る 2つの方法があり
  ます。カーネルの出力

       # dmesg | grep hdc
       ...
       hdc: Maxtor 93652U8, 34837MB w/2048kB Cache, CHS=70780/16/63
        hdc: [PTBL] [4441/255/63] hdc1 hdc2 hdc3! hdc4 < hdc5 > ...

  は(少なくとも) 34837*2048=71346176 か(少なくとも) 70780*16*63=71346240
  セクタであることを教えてくれます。この場合では、2番目の値は (訳注: 上
  記 hdparm での値と) 偶然にもまったく同じですが、一般的にこれらの値は端
  数が切り捨てられています。これは hdparm が利用できない時にディスクサイ
  ズを概算するいい方法です。決して cyls に大きすぎる値を与えないように!
  SCSI ディスクの場合には、正確なセクタ数はカーネルのブートメッセージに
  表示されます:

       SCSI device sda: hdwr sector= 512 bytes. Sectors= 17755792 [8669 MB] [8.7 GB]

  (MB や GB は丸められていますが、切り捨てられてはいません。また 2進で計
  算しています)

  10.  詳細

  10.1.  IDE の詳細 -  7つのジオメトリ

  IDE ドライバはジオメトリに関する 5 つの情報源を持っています。一つ目
  (G_user) はコマンドラインでユーザによって指定されたもの。二つ目
  (G_bios) は BIOS の Fixed Disk Parameter Table (一台目と二台目のディス
  クに限る) で、 32 ビットモードに移行する前のシステム起動時に読み込まれ
  ます。三つ目 (G_phys) と四つ目 (G_log) は IDENTIFY DEVICE コマンドに対
  して IDE コントローラが答える情報で、それぞれ「物理」「現状の論理」ジ
  オメトリです。

  一方、ドライバはジオメトリとして二つの値を必要とします。一つ (G_fdisk)
  は HDIO_GETGEO ioctl が返す値、もう一つ (G_used) は I/O を行う際に実際
  に使用される値です。 G_user が与えられていれば、 G_fdisk と G_used は
  それで初期化されます。 G_user が与えられず、CMOS から情報 (G_bios) が
  取得できれば、それに設定されます。それ以外のときには、G_phys に設定さ
  れます。 G_log が妥当であるようなら、G_used はそれに設定されます。ある
  いは、G_used の値が妥当ではなく、G_phys が妥当であるようなら、 G_used
  には G_phys の値が設定されます。ここでの「妥当」とは、ヘッド数が 1-16
  の範囲に入っていることです。

  言い換えると、コマンドラインでの指定は、BIOS からの値を上書きして
  fdisk がどのようにディスクをとらえるかを決めます。しかし、もし、(ヘッ
  ドが 16 を超える)変換後のジオメトリを指定するとカーネル I/O ではその値
  は破棄され、IDENTIFY DEVICE コマンドからの値が使用されます。

  G_bios はそんなに信用できないことに注意してください: SCSI からシステム
  を起動するために一台目と二台目のディスクが SCSI ディスクだったとして
  も、 sda のために BIOS が報告するジオメトリはカーネルでは hda のために
  使われます。そのうえ、BIOS セットアップで認識させていないディスクは
  BIOS からは見えません。これは次のようなことを意味します。例えば、BIOS
  セットアップで hdb が認識されていない IDE オンリーのシステムでは、一台
  目と二台目のディスクについて BIOS が報告するジオメトリは hda と hdc の
  ものでしょう。 (訳注: つまりディスク hdb に対して、 hdc のジオメトリが
  適用されるということです。)

  10.2.  SCSI に関する詳細

  SCSI での事態は少し違っていて、 SCSI コマンドは既に論理ブロック番号を
  使っているので、ジオメトリは実際の I/O に関してはまったく不適切なもの
  です。しかし、パーティションテーブルのフォーマットは未だに IDE と同じ
  なので、 fdisk はいくつかのジオメトリをでっち上げなければならず、また
  HDIO_GETGEO も使わなければなりません - 確かに、fdisk は IDE ディスクで
  あろうが SCSI ディスクであろうが区別はしません。以下の詳細な記述を読め
  ば、種々のドライバがそれぞれ、ちょっとずつ異なったジオメトリをでっち上
  げるのが分かります。本当に困ったもんだ。

  DOS やその類を使わないのならば、すべての拡張変換設定を避けて、 64 ヘッ
  ド 32 セクタ毎トラックを使ってください (これだと 1 MiB/シリンダとなり
  とても便利です)。またこれならば、ディスクをあるコントローラから他のコ
  ントローラに繋ぎ換えても問題は起きないでしょう。いくつかの SCSI ディス
  クドライバ(aha152x, pas16, ppa, qlogicfas, qlogicisp)は DOS との互換性
  にとても神経質で、 Linux のみのシステムでも 8 GiB を越えるディスクの使
  用を許してくれないでしょう。これはバグです。

  本当のジオメトリはどうなっているのでしょう?  それは簡単、そんなものは
  ありません。多分知りたくもないでしょうが、まぁ、そんなものがあったとし
  ても絶対に 決して fdisk や LILO やカーネルにそんなものを指定しないでく
  ださい。ジオメトリは SCSI コントローラとディスクの間でだけ使うべきもの
  です。くどいようですが、 SCSI ディスクのジオメトリを fdisk や LILO や
  カーネルに指定するような奴は阿呆だけです。

  それでも好奇心のあまりどうしてもと言い張るのであれば、ディスク自身に問
  い合わせることができます。 SCSI コマンドには、総容量を調べる READ
  CAPACITY コマンドがあります。また、MODE SENSE コマンドの Rigid Disk
  Drive Geometry ページ(ページ04) はシリンダ数とヘッド数を教えてくれ(変
  更はできません)、 Format ページ(ページ03)はセクタあたりのバイト数とト
  ラックあたりのセクタ数を教えてくれます。後者は普通ノッチに依存します。
  つまり、トラックあたりのセクタ数は可変でして、外側のトラックには内側よ
  りたくさんのセクタが入っています。 Linux の scsiinfo プログラムはこう
  いった情報を教えてくれます。こういった情報は詳細を極めた上に複雑この上
  なく、おまけに明らかに誰も(多分 OS ですら)こんな情報は使いません。その
  上、fdisk と LILO に関する限り、普通に返される C/H/S = 4476/27/171 な
  どという値は使い物になりません。というのは、パーティションテーブルは
  C/H/S に 10/8/6 ビットづつしか割り当てていないからです。 (訳注：原著者
  に問い合わせたところ、ノッチとは「一つのディスクの中で、トラックあたり
  のセクタ数が同じ領域」とのことです。)

  では、カーネルは HDIO_GETGEO のための情報をどこから持ってくるのでしょ
  う?  これは SCSI コントローラから持ってくるか、何らかの賢い方法で作っ
  てしまいます。ドライバによっては我々が「真実」を欲しがっていると考えて
  いるようですが、どっこい、我々は DOS や OS/2 の FDISK (や、Adaptec の
  AFDISK なんか) が使う数字が欲しいだけです。

  Linux の fdisk は H と S つまり、ヘッド数とトラックあたりのセクタ数だ
  けを使って LBA を C/H/S アドレスに変換しますが、シリンダ数 C は使用し
  ないことに注意してください。ドライバによっては、ドライバが 1023*255*63
  セクタに対応できることを知らせるために、 (C,H,S) = (1023,255,63) であ
  ると報告してきます。不幸なことに、これからは実際の容量はわかりません
  し、 fdisk のほとんどの版で、取り扱える容量を 8 GiB に限定してしまいま
  す。これは、今日の実際の上限となっています。

  以下の記述では、M をディスクの総容量、C,H,S をシリンダ、ヘッド、トラッ
  クあたりのセクタ数とします。 C を M / (H*S) で定義されると考えるな
  ら、H,S を得るだけで十分です。

  H=64, S=32 を初期値とします。

     aha1740, dtc, g_NCR5380, t128, wd7000:
        H=64, S=32 です。

     aha152x, pas16, ppa, qlogicfas, qlogicisp:
        C > 1024 になるまでは、H=64, S=32。それ以降は、H=255, S=63, C =
        min(1023, M/(H*S))。 (このため、C は丸められており、 H*S*Cはディ
        スクの総容量 M とはなりません。これは、たいていの版の fdisk で問
        題となります)。 ppa.c のコードでは、M ではなく、M+1 を使用してお
        り、 sd.c のバグにより、 M は 1 のオフセットを持っていると書かれ
        ています。

     advansys:
        C > 1024 になるまでは、H=64, S=32。それ以降は BIOS の `> 1 GB'
        オプションが入っていれば H=255, S=63 です。

     aha1542:
        コントローラに 2 つの内のどちらの変換方法を用いているか問いあわ
        せ、 H=255, S=63 か、H=64, S=32 の何れかを使用します。前者を使っ
        ている場合は、起動メッセージとして "aha1542.c: Using extended
        bios translation" と表示されます。

     aic7xxx:
        C > 1024 になるまでは H=64, S=32。それ以降は 、"extended" 起動パ
        ラメータがドライバに与えられているか、 SEEPROM か BIOS の「拡
        張」ビットが立てられているならば、 H=255, S=63です。 Linux
        2.0.36 では、 SEEPROM が見付からない場合はこの拡張変換を常に有効
        にしますが、 Linux 2.2.6 では、SEEPROM が見付からない場合は拡張
        変換は、ユーザがをれを使用するように起動パラメータを指定した時の
        み有効になります (SEEPROM が見付かった場合は起動パラメータは無視
        されます)。これは、2.0.36 で設定したものが 2.2.6 では起動に失敗
        するかもしれない (そして、LILO に `linear' キーワードが必要に
        なったり、カーネルの起動パラメータ `aic7xxx=extended' が必要に
        なったりするかもしれない) ことを意味しています。

     buslogic:
        C >= 1024 になるまでは H=64, S=32。それ以降はコントローラの拡張
        変換が使用されている場合、 M < 2^22 (訳注: 2 GiB) ならば H=128,
        S=32 で、さもなければ H=255, S=63 です。しかし、この (C,H,S) 設
        定を行った後、パーティションテーブルを読み出します。そして、可能
        な 3 つの組み合わせ、(H,S) = (64,32), (128,32), (255,63) のうち
        から、endH=H-1 になりそうなものを探します。そして、次のような起
        動時メッセージを表示します。 "Adopting Geometry from Partition
        Table" (パーティションテーブルのジオメトリを採用します)

     fdomain:
        BIOS のドライブパラメータテーブルのジオメトリ情報を探すか、パー
        ティションテーブルを読んで、パーティションがあるなら最初のパー
        ティションの(endH+1,endS) を (H,S) として使用します。パーティ
        ションがないならば次のようになります: M < 2^21 (1 GiB) ならば
        H=64, S=32 、 M < 63*2^17 (3.9 GiB) ならば H=128, S=63 、さもな
        ければ H=255, S=63 。

     in2000:
        (H,S) = (64,32), (64,63), (128,63), (255,63)のうち、 C <= 1024
        となる最初のものを使用します。最後のものを使うときには、C は
        1023 に丸められます。

     seagate:
        C,H,S をディスクから読みます(ひぃぃぃぃっ!)。 C か S が大きすぎ
        れば、 S=17, H=2 として、 C <= 1024 となるまで H を倍にしていき
        ます。これは M > 128*1024*17 (1.1 GiB) のとき、 H が 0 に設定さ
        れることを意味します。これはバグです。

     ultrastor and u14_34f:
        コントローラのマッピングモードに応じて (H,S) = (16,63), (64,32),
        (64,63) のうちの一つが使用されます。

  ドライバがジオメトリを指定しなければ、パーティションテーブルかディスク
  総容量から経験的に値を求めます。
  パーティションテーブルを見てみましょう。パーティションの終わりをシリン
  ダ境界に置くという規則から、どのようなパーティションであってもパーティ
  ションの終わりが end = (endC,endH,endS) であるとき、単に H = endH+1
  でS = endS と計算することができます (繰り返しますが、セクタは 1 から数
  えます)。もう少し厳密にいうと、以下のようになります。もしパーティショ
  ンが存在するならば、 beginC がもっとも大きいパーティションを選びます。
  そうして、end+1 を、start と length を足す方法と、パーティションの終わ
  りがシリンダ境界にあると仮定する方法で計算します。もし両方の答えが一致
  するか、endC = 1023 かつ start+length が (endH+1)*endS の整数倍なら
  ば、このパーティションは本当にシリンダ境界にそろえられていると考えられ
  ます。もし、これがだめなようならば、つまりパーティションが全然無いか、
  大きさがなんか変ならば、ディスク容量 M のみを見ます。アルゴリズムは以
  下のようになり、この方法は、C を最大 1024, S を最大 62 に押さえるよう
  な効果があります: H = M/(62*1024) で切り上げ、 S = M/(1024*H) で切り上
  げ C = M/(H*S) で切り捨て。

  11.  Linux の IDE 8 GiB の壁

  Linux の IDE ドライバは ATA IDENTIFY DEVICE リクエストを使用することに
  より、ディスクのジオメトリと容量(とその他多くの情報)を得ます。最近ま
  で、C*H*S により計算された容量よりも 10% 以上大きい場合は、ドライバは
  返された lba_capacity の値を信用しませんでした。しかし、業界の規定によ
  り (16514064 セクタを越える) 大きな IDE ディスクは、実際のサイズとは無
  関係の、計 16514064 セクタ (7.8 GB (訳注: 7.8 GiB または 8.4 GB が正し
  い)) となる C=16383, H=16, S=63 を返し、実際のサイズは lba_capacity で
  返します。

  最近の Linux カーネル (2.0.34 や 2.1.90) はこのことを知っていて正しい
  動作をします。もし古い Linux カーネルを使っていてアップグレードもした
  くなく、その結果 8 GiB を越える大容量ディスクの 8 GiB しか扱えないよう
  ならば、 /usr/src/linux/drivers/block/ide.c 内のルーチン
  lba_capacity_is_ok を以下のように変更してください。 (訳注: でも特別な
  理由がない限り、どうせカーネルの再コンパイルを行うのならば、素直にアッ
  プグレードした方がいいと思います)

       static int lba_capacity_is_ok (struct hd_driveid *id) {
               id->cyls = id->lba_capacity / (id->heads * id->sectors);
               return 1;
       }

  より良いパッチについては、カーネル 2.1.90 を見てください。

  11.1.  BIOS の複雑化

  今いったように、大容量ディスクは実際のサイズとは無関係なジオメトリ
  C=16383, H=16, S=63 を返し、実際のサイズは LBAcapacity の値で返しま
  す。いくつかの BIOS はこれを理解せず、この 16383/16/63 をより小さいシ
  リンダ数とより大きいヘッド数、例えば 1024/255/63 や 1027/255/63 といっ
  た値に変換します。そう、カーネルは単一のジオメトリ 16383/16/63 だけで
  はなく、 BIOS によって変換されてしまったジオメトリも見分けなければなり
  ません。カーネル 2.2.2 からこれは正しく処理されます( BIOS に問い合わせ
  て H と S を得、C = capacity/(H*S) と計算することによって)。通常この問
  題は、BIOS 設定でディスクを Normal と設定することで解決します (あるい
  は、よりよい方法は、None と設定して BIOS に一切認識させない)。この HDD
  から起動させなければいけないとか、 DOS/Windows でも使うなどの理由でこ
  れが不可能で、さらにカーネルを 2.2.2 かそれ以降にアップグレードすると
  いう選択も無理ならば、カーネルの起動パラメータを使ってください。

  BIOS が 16320/16/63 と報告する場合は、それは変換後に 1024/255/63 を得
  る目的で報告されているのです。

  11.2.  ヘッド数を決めるためのジャンパ

  多くのディスクは 15 ヘッドか 16 ヘッドかのジオメトリを選択可能にする
  ジャンパを用意しています。デフォルトの設定は 16 ヘッドのディスクになっ
  ているでしょう。いずれのジオメトリでも同じ総セクタ数の時もあれば、 15
  ヘッドの方が総セクタ数が少ない時もあります。こんなセットアップの際には
  よい理由があるかもしれません: Petri Kaukasoina はこういってます:
  「10.1 GB の IBM Deskstar 16 GP (model IBM-DTTA-351010) はデフォルトで
  は 16 ヘッドにジャンパが設定されているが、この (AMI BIOS の) 古い PC
  ではブートしないので、 15 ヘッドの方にジャンパを設定する必要があった。
  hdparm -i は RawCHS=16383/15/63 で LBAsects=19807200 と報告している。
  私はすべての容量を得るために 20960/15/63 で使っている。」ジャンパの設
  定については、以下を参照してください。
  http://www.storage.ibm.com/techsup/hddtech/hddtech.htm.

  11.3.  総容量を隠すためのジャンパ

  多くのディスクはディスクをより小さく見せかけることを可能にするジャンパ
  を用意しています。それはばかげたことで、これを使用したがる Linux ユー
  ザはおそらくいないでしょうが、大容量ディスクを接続すると一部の BIOS は
  クラッシュしてしまいます。通常の解決方法は、ディスクを完全に BIOS に認
  識させないことです。しかしこれは起動ディスクではない時しか利用できない
  でしょう。

  最初の深刻な制限は 4096シリンダ制限です (これは 16 ヘッドと 63 セクタ
  毎トラックの場合 2.11GB です)。例えば、富士通 MPB3032ATU という 3.24
  GB のディスクはデフォルトで 6704/15/63 というジオメトリですが、ジャン
  パを設定することで 4092/16/63 に見せかけることが可能です。そして
  LBAcapacity に対して 4124736 セクタと報告するので、 OS はこのディスク
  が実際はもっと大容量であると知ることはできません。 (実際にディスクの容
  量が大きすぎて BIOS がクラッシュするので、ジャンパが必要になるとい
  う)このようなケースでは、ディスクのサイズについて Linux に教えるために
  ブートパラメータを指定する必要があります。

  これはあまりよくない例です。多くのディスクはジャンパを設定することによ
  り、 2GB のディスクであるかのように見せ、 4092/16/63 や 4096/16/63 と
  いった切り詰めたジオメトリを報告します。しかし LBAcapacity では完全な
  値を報告するのです。このようなディスクは正常に動作しますし、ジャンパの
  設定に関わらず Linux の下ではすべての容量を利用できます。

  もっとも最近の制限は ``33.8 GB の壁'' です。 2.3.21 より古い Linux カ
  ーネルでは、これより容量の大きな IDE ディスクをうまく処理するにはパッ
  チが必要です。この制限より大きなディスクのいくつかでは 33.8GB ディスク
  に見せかけるためのジャンパ設定が可能なものがあります。例えば、IBM
  Deskstar 37.5 GB disk (DPTA-353750) といったようなこの制限より大きな
  ディスクは、 33.8 GB のディスクに見せかけるためのジャンパ設定が可能
  で、 (訳注: 2.1 GB に見せかけることのできる) 他の大容量ディスクのよう
  に 16383/16/63 というジオメトリを報告しますが、 LBAcapacity は (訳注:
  33.8GB に相当する) 66055248 と報告します (65531/16/63 や 4111/255/63
  に相当します)。 33.8GB に見せかけるためのジャンパ設定をしたこれらの
  ディスクもまた、 Linux の下ですべての容量を利用するためにブートパラメ
  ータを必要とします。 the BIOS 33.8 GB limit も参照してください。

  12.  Linux の 65535 シリンダの壁

  HDIO_GETGEO ioctl は short (訳注: short int つまり 16ビット) でシリン
  ダ数を返します。これは、65535 シリンダより多い場合には数字が切り捨てら
  れて、例えば(典型的な SCSI の設定では 1 シリンダ 1 MiB なので) 80 GiB
  のディスクは 16 GiB に見えるかもしれないことを意味します。いったん何が
  問題なのか分かってしまえば、それを回避することは簡単です。

  12.1.  34 GB 超のディスクにおける IDE の問題

  33.8 GB より大容量なドライブは、2.3.21 より古いカーネルではうまく動作
  しません。 (訳注: この章の最後の方にも書いてありますが、2.2.14 以降で
  もサポートしています。) その詳細は以下の通りです。ある日あなたが新たに
  66835440 セクタ (34.2 GB) の IBM-DPTA-373420 ディスクを買ってきたとし
  ましょう。 2.3.21 以前のカーネルは、それのサイズを 769*16*63 = 775152
  セクタ (0.4 GB) と報告し、ちょっとがっかりするでしょう。そしてコマンド
  ラインパラメータ hdc=4160,255,63 を与えても、事態はまったく解決しない
  のです - これは無視されます。一体何が起きているのでしょう?  ルーチン
  idedisk_setup() では、ディスクが報告するジオメトリ(16383/16/63 です)を
  受け取り、ユーザがコマンドラインで指定した値で上書きします。この値は
  BIOS ジオメトリのためだけに使用されるものです。ルーチン
  current_capacity() や idedisk_capacity() は、 66835440/(16*63)=66305
  という感じでシリンダ数を再計算しますが、この値は short で格納されるの
  で、 769 になってしまいます。 lba_capacity_is_ok() は id->cyls を破壊
  するので、その後の呼び出しすべてに対して嘘の値を返し、その結果ディスク
  の容量は 769*16*63 になります。いくつかのカーネルに対してはパッチが提
  供されています。 2.0.38 用のパッチは ftp.kernel.org に用意されていま
  す。 2.2.12 用のパッチは www.uwsg.indiana.edu.  に用意されています。
  2.2.14pre カーネルはこれらのディスクをサポートしています。 2.3.* カー
  ネルシリーズでは、2.3.21 からこれらのディスクをサポートしています。ま
  た、ディスクのサイズを 33.8GB に切り詰めるために、ハードウェア的に
  ``ジャンパを設定する'' ことでも問題を「解決」することができます。ハー
  ドディスクからブートしようとするのならば、多くの場合 ``BIOS アップグレ
  ード'' が必要になるでしょう。

  13.  拡張パーティションと論理パーティション

  ``前述の通り、'' 我々は MBR (セクタ 0) の構造を知っています: シグネ
  チャ AA55、続けて 16 バイトずつの 4 つのパーティションテーブルのエント
  リ、続けてブートローダのコード。タイプが(16進数で) 5 か F か 85 のパー
  ティションテーブルエントリ (訳注: 5, F, 85 は順に拡張パーティショ
  ン、Windows95 拡張パーティション、 Linux 拡張パーティション)は特別な意
  味があります。これらは、その内部をさらに論理パーティションとして分割さ
  れる空間である、拡張パーティションであることを意味しています。 (そう、
  拡張パーティションとは単なる箱で、それ自身を使用することはできず、その
  中の論理パーティションを使うことになります。) 拡張パーティションの一番
  目のセクタの位置のみが重要です。この一番目のセクタは、四つのパーティ
  ションテーブルを含んでいます: 一つは論理パーティション、一つは拡張パー
  ティション、そして二つは未使用です。このようにして、ディスク全体に散ら
  ばったパーティションテーブルセクタの連鎖構造ができあがります。最初のセ
  クタは 3 つの基本パーティションとひとつの拡張パーティションを規定しま
  す。これに続くパーティションテーブルセクタはそれぞれ、ひとつの論理パー
  ティションと次のパーティションテーブルセクタの位置を規定します。

  これは次のことを理解するために重要です: ディスクのパーティションを切る
  際に間抜けなことをした時 (訳注: パーテイションを削除してしまった時な
  ど)、人々は「私のデータはまだそこにあるの?」ということを知りたがりま
  す。そしてその答は決まってこうです。「はい、まだあります。しかし論理パ
  ーティションを作成したら、それを記述するパーティションテーブルセクタは
  これらの論理パーティションの先頭に書き込まれるので、以前そこにあったデ
  ータは失われますよ。」

  プログラム sfdisk は完全なチェーンを表示できます。例えば、

  # sfdisk -l -x /dev/hda

  Disk /dev/hda: 16 heads, 63 sectors, 33483 cylinders
  Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0

     Device Boot Start     End   #cyls   #blocks   Id  System
  /dev/hda1          0+    101     102-    51376+  83  Linux
  /dev/hda2        102    2133    2032   1024128   83  Linux
  /dev/hda3       2134   33482   31349  15799896    5  Extended
  /dev/hda4          0       -       0         0    0  Empty

  /dev/hda5       2134+   6197    4064-  2048224+  83  Linux
      -           6198   10261    4064   2048256    5  Extended
      -           2134    2133       0         0    0  Empty
      -           2134    2133       0         0    0  Empty

  /dev/hda6       6198+  10261    4064-  2048224+  83  Linux
      -          10262   16357    6096   3072384    5  Extended
      -           6198    6197       0         0    0  Empty
      -           6198    6197       0         0    0  Empty
  ...
  /dev/hda10     30581+  33482    2902-  1462576+  83  Linux
      -          30581   30580       0         0    0  Empty
      -          30581   30580       0         0    0  Empty
      -          30581   30580       0         0    0  Empty

  #

  おかしなパーティションテーブルを構築することも可能です。拡張パーティ
  ションのチェーンが自分自身を指すか、あるいはもっと前のパーティションを
  指す場合、多くのカーネルはループに陥ります。 1つのパーティションテーブ
  ル内に 2つの拡張パーティションを持つことも可能です。これはパーティショ
  ンテーブルのチェーンが分岐することを意味します。 (これは例えば、5, F,
  85 のそれぞれを拡張パーティションとして認識できない fdisk で、F の次に
  5 を作る、という方法で可能になります) 普通の fdisk タイプのプログラム
  ではそのような状況を取り扱うことができないので、それを修復するためには
  手作業が必要となります。 Linux カーネルは、一番外側のレベルにおいて分
  岐を受け付けます。これは、2つの論理パーティションのチェーンを持つこと
  ができることを意味します。時々、これは便利です - 例えば、一方ではタイ
  プ 5 を使用して DOS から参照できるようにし、もう片方ではタイプ 85 を使
  用して DOS から見えないようにします。つまり、DOS の fdisk が、1024 シ
  リンダを越える論理パーティションによってクラッシュしないようにできるの
  です。

  14.  問題の解決

  問題を抱えたと思う人の多くは、しかし実際には何も悪い点はありません。ま
  た、抱えている問題の原因がディスクのジオメトリにあると思われる場合で
  も、実際にはディスクのジオメトリには何の問題もありません。上で述べたよ
  うなすべてのことが事態を複雑にしていますが、ディスクのジオメトリの扱い
  は非常に簡単です: まったく申し分なければ何もする必要はありません; もし
  起動時に `LI' の先に進まない場合は LILO にキーワード `linear' を与えて
  ください。カーネルの起動メッセージを見て思い出してください: (LILO や
  fdisk やカーネルコマンドラインでヘッド数やシリンダ数を与えて)ジオメト
  リをいじくればいじくるほど、正常には動作しなくなるでしょう。おおざっぱ
  にいえば、デフォルトが一番なのです。

  さらに思い出してください: Linux がディスクのジオメトリを使わない所、つ
  まりLinux が動作している間は、ディスクのジオメトリによって問題が引き起
  こされることはありません。それどころか、ディスクのジオメトリは LILO と
  fdisk だけに使用されます。そう、LILO がカーネルの起動に失敗する場合
  は、ジオメトリに問題があるかもしれません。異なる OS がパーティションテ
  ーブルを理解しない場合は、ジオメトリに問題があるかもしれません。でもそ
  れだけです。とりわけ、mount が動作しないように思える場合でも、ディスク
  のジオメトリには何の関係もありません - 問題は他の所にあります。

  14.1.  問題: SCSI から起動した時、IDE ディスクが変なジオメトリを持って
  いる

  ディスクが変なジオメトリを持つのはとてもありがちです。 Linux カーネル
  は hd0 と hd1 (80H と 81H の数字がふられた BIOS ドライブ) について
  BIOS に問い合わせ、このデータが hda と hdb のものだと仮定します。しか
  し SCSI から起動したシステム上では、最初の二つのディスクが SCSI ディス
  クでしょうから、最初の IDE ディスク hda である 5番目のディスクに対して
  sda のジオメトリが割り当てられるなんてことが起きるかもしれません。これ
  は、起動時や /etc/lilo.conf において、適切な数字 C, H, S を使ってブー
  トパラメータ `hda=C,H,S' を与えることで簡単に解決できます。

  14.2.  問題なし: 同じディスクが異なるジオメトリを持っている?

  「私はまったく同じ IBM 製のディスクを 2台持っています。しかし、fdisk
  が表示するサイズは異なっています。こんな感じ:

       # fdisk -l /dev/hdb
       Disk /dev/hdb: 255 heads, 63 sectors, 1232 cylinders
       Units = cylinders of 16065 * 512 bytes

          Device Boot  Start      End   Blocks   Id  System
       /dev/hdb1           1     1232  9896008+  83  Linux native
       # fdisk -l /dev/hdd
       Disk /dev/hdd: 16 heads, 63 sectors, 19650 cylinders
       Units = cylinders of 1008 * 512 bytes

          Device Boot  Start      End   Blocks   Id  System
       /dev/hdd1           1    19650  9903568+  83  Linux native

  何ででしょ?」

  何が起きているのでしょう?  そう、まず第一に、これらのドライブはしっか
  り 10 ギガバイト使えています: hdb は 255*63*1232*512 = 10133544960 バ
  イトで、 hdd は 16*63*19650*512 = 10141286400 バイトですが、何も悪い所
  はないしカーネルはどちらも 10.1 GB であると理解しています。では何故サ
  イズが違うのでしょう?  それは、カーネルは最初の二台の IDE ディスクにつ
  いては BIOS から情報を得、その BIOS は hdb を 255 ヘッドで再マップして
  いるからです (16*19650/255=1232 シリンダ)。この丸めによる損失は 8MB 弱
  です。

  hdd も同じ方法で再マップしたいのならば、カーネルのブートパラメータに
  `hdd=1232,255,63' を与えてください。

  14.3.  問題なし: df より fdisk の方がパーティションが大きく見える

  fdisk はブロックがディスク上にいくつ存在するかを報告します。 mke2fs を
  使ってディスク上にファイルシステムを作った場合、ファイルシステムは簿
  記(bookkeeping)のためのいくらかのスペースを必要とします - 通常はファイ
  ルシステムのサイズの 4% くらいで、 mke2fs する際に多くの inode を作る
  とより増えます。以下は例です:

  # sfdisk -s /dev/hda9
  4095976
  # mke2fs -i 1024 /dev/hda9
  mke2fs 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
  ...
  204798 blocks (5.00%) reserved for the super user
  ...
  # mount /dev/hda9 /somewhere
  # df /somewhere
  Filesystem         1024-blocks  Used Available Capacity Mounted on
  /dev/hda9            3574475      13  3369664      0%   /mnt
  # df -i /somewhere
  Filesystem           Inodes   IUsed   IFree  %IUsed Mounted on
  /dev/hda9            4096000      11 4095989     0%  /mnt
  #

  まず、4095976 ブロックのパーティションがあります。ここに ext2 ファイル
  システムを作成し、適当な所にマウントします。すると 3574475 ブロックに
  なってしまいます - 521501 ブロック (12%) は inode と他の簿記用スペース
  に消費されたのです。合計 3574475 と 3369664 の間の差は、ユーザが 13 ブ
  ロックを使用していて、さらに 204798 ブロックが root のために予約されて
  いるためであることに注意してください。後者は tune2fs で変更できます。
  この `-i 1024' はニューススプールなどの小さいファイルが山ほどある場合
  にのみ適しています。デフォルトではこうなります:

       # mke2fs /dev/hda9
       # mount /dev/hda9 /somewhere
       # df /somewhere
       Filesystem         1024-blocks  Used Available Capacity Mounted on
       /dev/hda9            3958475      13  3753664      0%   /mnt
       # df -i /somewhere
       Filesystem           Inodes   IUsed   IFree  %IUsed Mounted on
       /dev/hda9            1024000      11 1023989     0%  /mnt
       #

  今度は 137501 ブロック(3.3%)のみが inode のために使用され、その結果以
  前より 384 MB も増えてます。 (inode 1つにつき 128 バイト使ってるみたい
  です。) 一方、先の場合では 4096000 ファイル保存できるのに対し(どう見て
  も多すぎ)、このファイルシステムでは最大 1024000 ファイルが保存できます
  (これでも十分すぎます)。

  15.  日本語版について

  翻訳に関するご意見は JF プロジェクト <JF@linux.or.jp> 宛に連絡してくだ
  さい。

  v2.2j の翻訳にあたっては、堀江誠一さん shorie@ibm.net による Large
  Disk mini HOWTO v1.0 の翻訳から多くの部分を流用させていただきました。
  深く感謝します。

