  ハードディスクドライブの基礎知識
  佐野武俊 / Taketoshi Sano, (kgh12351@nifty.ne.jp)
  $Date: 1999/12/05 03:17:15 $, ($Revision: 1.4 $)

  ハードディスクドライブの「ジオメトリー」と「パーティション」について簡
  単に説明するために、いくつかの参考文献などからの情報をまとめたもので
  す。内容および文書の構成についての御意見をお待ちしております。

  1.  ハードディスクの「ジオメトリー」とは ?

  現在、一般的に使われているハードディスクドライブ (以下 HDD) の「ジオメ
  トリー」は、 C/H/S (シリンダー数、ヘッド数、セクター数) の 3 つの数値
  から構成されます。もともとこれらの数値の組み合わせは、 HDD の構成を示
  す情報として物理的な意味、つまり以下のような意味を持つ数値でした。

  1.1.  シリンダー

  ディスク上に存在するトラック (後述) を、その位置 (トラック番号) によっ
  て分類したもの。ドライブ中に複数のディスクが存在する場合、同じトラック
  番号 (シリンダー位置) に対応する各トラックを結ぶと円筒上に並ぶことから
  この名称があるようです。一般にドライブ中の各ディスク上に存在するトラッ
  クの本数は同じであり、「HDD のジオメトリー」として使われる「ドライブの
  シリンダー数」とは「各ディスク上のトラック数」のことです。

  1.2.  トラック

  1 枚のディスク上に多数存在している同心円状の円周のひとつひとつを指しま
  す。このトラック上に情報をビット単位で記録する磁気媒体が並んでいます。
  ディスクの回転によってトラック上を磁気ヘッドが移動し、情報の書き込
  み/読み出しを行ないます。

  1.3.  ヘッド

  媒体へ情報を記録したり、媒体から情報を読み取ったりするために使われるド
  ライブ中の磁気ヘッド。ひとつのドライブ中に複数のディスクが存在したり、
  ひとつのディスクの裏表にヘッドが存在するなどの理由によって、たいていの
  ドライブには複数のヘッドが存在しています。「HDD のジオメトリー」として
  使用される「ドライブのヘッド数」とはそのまま「ドライブ中に存在する磁気
  ヘッドの個数」だと思っておいて良いでしょう。

       最近の HDD はボイスコイルでヘッドを駆動しているため、正確な
       位置決定を目的としたサーボ面を一面持っているものもあります。
       この場合「HDD のジオメトリー」としてのデータ面 (ヘッド) の数
       は奇数になります。一方、サーボ情報をデータ面に埋め込んで高密
       度化を図ったドライブの場合にはヘッドの数が偶数になります。

  1.4.  セクター

  ディスク上の各トラックを分割する単位であり、ディスクアクセスの基本的な
  単位でもあります。 HDD の場合、通常は 1 セクターあたり 512bytes です。
  (640MB の MO では 1 セクターあたり 2048bytes となります) すべてのト
  ラックについてセクター数が同じ場合 (古い IDE HDD ではそうなっていたよ
  うです)、ディスク上の各セクターはそれぞれ扇型のような形となります。
  「HDD のジオメトリー」として使用される「セクター数」は、「トラック当り
  のセクター数」のことであり、これが (古い IDE HDD の場合のように) ドラ
  イブ全体で共通であることを前提としています。

  JF の large-disk-mini-HOWTO によれば SCSI ディスクの場合、内周のトラッ
  クと外周のトラックでセクター数が異なるため、ドライブ全体に共通する「ト
  ラック当りのセクター数」というものは存在しません。 (セクター数の共通な
  トラックをまとめて "ノッチ" と呼びます)

  目で見てわかる例として、3.5インチの 128MB MO と 230MB 以上の MO があり
  ます。 MO はセクタの境界が目で見えます。注意深くシャッターを開けて見て
  みると、 128MB MO は扇型に溝がありノッチは見られませんが、230MB 以上の
  MO は外側にいく程トラック当たりのセクタ数は多くなり、ノッチが見られま
  す。 230MB以上のMOはこうすることで大容量化を計っているのです。 # な
  お、シースルーなMOならシャッターを開けなくてもわかります。

  したがって「HDD のジオメトリー」の単位として使用される「トラック当りの
  セクター数」には、すくなくとも SCSI ディスクの場合、物理的な意味との対
  応は一般的に存在せず、単にマザーボードの BIOS がもつ仕様に合わせるため
  だけに使用されています。

  また IDE ディスクでもかなり以前 (504MB の壁が話題になっていた頃 ?) か
  ら、ディスクの内周と外周でセクター数が異なることは珍しくないようです。
  (ディスク自体の構造は IDE でも SCSI でもまったく同じだったりする場合も
  あることをある人から指摘して頂きました。)

  2.  ディスクアクセス

  さて HDD へのアクセスでは、セクター単位での読み書きが基本になります。
  複数のディスク面から構成される一般的なドライブでは、どの面にある、どの
  トラックの、何番目のセクターかを指定することが必要です。

  2.1.  3 次元 (3D) アドレス / CHS (シリンダー、ヘッド、セクター)

  トラック当りのセクター数がすべてのトラックについて共通な HDD の場合に
  は、どのトラックかを指定するシリンダー番号、どのディスク面かを指定する
  ヘッド番号、そして何番目のセクターかを指定するセクター番号の 3 つを組
  み合わせて 3 次元 (3D) アドレスとしてセクター位置を指定するという方法
  が自然でした。

  これは標準 IDE インターフェイスが使用するシリンダー番号:16bit, ヘッド
  番号:4bit, セクター番号:8bit の計 28bit によってセクター位置を指定する
  方法に結びついています。この 28bit により指定された各セクターが
  512byte のサイズだとすれば、アクセス可能なディスク容量は 512=2^9 より
  28+9=37bit -> 2^37=128GB となります。

  ただし、もともとの BIOS の仕様ではシリンダー番号指定に 10bit、ヘッド番
  号指定に 4bit、セクター番号指定に 1〜63 を使うようになっており、IDE の
  仕様とビット数の割り当てが異なっています。このために両方で共通に使える
  ビット数はシリンダー、ヘッド、セクターに対してそれぞれ 10bit, 4bit,
  6bit の合計 20bit (しかもセクター番号は 6bit = 64 ではなく、ひとつ少な
  い 63 までしか使えない) となり、アクセス可能なディスク容量は
  (2^14)*63*512/(1024*1024)=504MB となってしまいます。これが (もうかなり
  前のことになってしまいますが) 有名な「504MB の壁」です。

  2.2.  ジオメトリ変換: ("LARGE")

  この「壁」を回避するために、BIOS のメニューで "LARGE" と表示されるジオ
  メトリ変換方法と「LBA」という方法が利用されています。

  「"LARGE"」とは、ディスク (IDE コントローラ) とのやり取りでは E-IDE の
  仕様に従って 16bit および 4bit で表現されるシリンダー番号、ヘッド番号
  を使い、一方 INT13h を経由した OS とのやり取りではもともとの BIOS 仕様
  に従った 10bit および 8bit で表現されるシリンダー番号、ヘッド番号を使
  う、という方法です (セクター番号はBIOS 仕様に合わせて 1〜63 を共通に使
  います)。

  具体的にはディスクの持つジオメトリー情報をもとに、シリンダ数を 2 で
  割ってヘッド数に 2 をかける手順を繰り返し、シリンダ数が 1023 以下にな
  るか、あるいはヘッド数が 128 以上 になるまで続けるか、あるいはヘッド数
  を 255 として「シリンダ数×ヘッド数」で求めた全セクター数をこの 255 で
  割ってシリンダ数を求めます。そしてこの手順で求めたシリンダ数、ヘッド数
  によるジオメトリ (L-CHS) を INT13h を経由した OS とのやり取りで使いま
  す。この方法によれば、アクセス可能なディスク容量は
  1023*255*63*512/1024/1024/1024=7.8GB となります。これがここしばらく話
  題になることの多かった「7.8GB (or 8GB) の壁」です。

  2.3.  ジオメトリ変換: LBA (Logical Block Addressing)

  (注: 以前 LBA を "Linear Block Addressing" と書いていたのですが、それ
  は誤用だという指摘を受けました。自分でも調べてみましたが、どうも今まで
  誤解していたようなので訂正しておきます。情報提供、ありがとうございまし
  た。)

  一方、セクター数がトラックによって異なる HDD の場合には、 3D アドレス
  を使用するより、むしろすべてのセクターに対して通し番号を付け、セクター
  位置を一次元の (線形 = リニアな) 番号によって管理したほうが、効率上も
  わかり易さでもより良いと考えられます。この「すべてのセクターに通し番号
  を付け、その番号によってセクター位置を指定する」方法は "LBA" と呼ばれ
  ており、すべての SCSI ディスクコントローラ、および 504MB 以上の大容量
  ディスクに対応した IDE コントローラの多くはこの方法によってディスクに
  アクセスすることができます。このセクター番号はパーティションテーブル内
  では 32bit によって表現され、セクターサイズ 512bytes を前提とすればア
  クセス可能なディスク容量は 32+9=41bit -> 2^41=2TB (テラバイト) となり
  ます。

  ただし、OS やブートローダでは依然として従来の BIOS 仕様に従った 10bit
  および 8bit で表現されるシリンダー番号、ヘッド番号を使う、という方法で
  アクセスするものが多いため、LBA によるリニアアドレスはディスクコントロ
  ーラとのやり取りでのみ利用され、INT13h を経由した OS とのやり取りでは
  つい最近まで上記の "LARGE" で説明した手順によって求めた CHS ジオメトリ
  ーを使います。従ってアクセス可能なディスク容量は先程と同じく 7.8GB と
  なります。

  2.4.  BIOS Extended (INT13h AH=4xh)

  最近では IBM と MS により、INT13h AH=42h (Extended READ) や INT13h
  AH=43h (Extended WRITE) などの規格が提唱され、OS が INT13h BIOS コール
  を経由して直接「リニアアドレス」を利用できるようになってきています。

  Linux カーネルのように起動後は BIOS を経由せず、直接ディスクコントロー
  ラにアクセスする OS では、以前から「カーネルが起動してしまえば」7.8GB
  の壁を気にすることなくディスクを利用できましたが、新らしい BIOS call
  を使えば BIOS 経由でディスクにアクセスする OS であっても「7.8GB の壁」
  を超えてディスクを利用することができるようになったわけです。

  ただし、この BIOS call を実際に使っているソフトウェアはまだ数が少な
  く、またドライブのほうで対応していない場合もあるようです。特に起動に使
  うブートローダでこれに対応しているのは Free なものでは GRUB か extipl
  (extipl では sample としてこのためのコードが含まれています) くらいしか
  私は知りません。Linux の起動用に使われることの多い LILO は version 21
  以前は対応していません。LILO Version 22 では対応するためのコードが入っ
  たようです。("edd" option)

  また、既存のパーティションを縮小するために利用されている FIPS はまだ
  v2.0 でも LBA BIOS コールには対応していないようです。このため、HDD 上
  の 8GB を越える領域に対して現状の FIPS を使うとデータを破壊する結果を
  招くと予想されます。

  2.5.  不具合のある BIOS

  「E-IDE 対応」なはずのマザーボードには、時期によって対応可能なシリンダ
  ー数の上限が異なるものがあるようです。本来なら IDE の仕様上限である
  65536 シリンダーまで対応しているべきと思うのですが、以前聞いた話では
  ディスクコントローラの問い合わせに対してドライブ側が答えるシリンダー数
  が 4096 以上になると暴走するという欠陥品的な代物の BIOS もあり、そのよ
  うな場合の対策として BIOS からの問合せに対してドライブが答えるシリンダ
  ー数を実際より少なく見せかける設定のためのジャンパーが用意されている
  HDD もあるようです。

  ところが Linux を使う場合には、このような不自然なジャンパー設定がか
  えって邪魔になって、せっかく使えるはずの LBA アクセスが使えなくなる場
  合もあるので要注意です。一方ごく最近にはシリンダー数が 16bit (65535)
  を超えるような巨大なディスクもあるようで、こういう場合にはカーネルに
  パッチを当てないとうまく扱えないという話もあります。「BIOS Extended
  Read/Write」によるアクセスが普及して、CHS アドレスを使ってアクセスしな
  くてもすむようになれば、こういう問題も解消されるだろうと思われます。

  2.6.  BIOS で変換できない場合

  もっと以前の「E-IDE 対応」ですらない BIOS を持つマザーボードでは、ドラ
  イブの称するシリンダー数を 1024 で割った余りのシリンダー数しか認識しな
  いという例が多かったようです。このため、シリンダー数 1100 程度のドライ
  ブだと BIOS の認識する容量が数10MB 程度しか無くて困ってしまうという話
  題がけっこうありました。

  で、そういう場合の対策としては手動で BIOS に HDD のシリンダー数を 1023
  だとして設定してしまって、とりあえず 504MB までは正常に BIOS から認識
  できるようにしておき、はみ出す部分は Linux の (起動用には使えないので)
  データ領域として使うということがわりと一般的だったと思います。

  3.  パーティションについて

  ハードディスクを使う場合、いくつかの理由から複数の領域に分割して利用す
  ることが多くあります。この分割した領域を「パーティション」と呼びます。

  (MO の場合にはパーティションに分割せずディスク全体をまるごとデータ領域
  として使う場合もあります)

  Linux システムでは通常 "/" (ルート) ファイルシステム用のパーティション
  とスワップ用のパーティションのすくなくとも 2 つのパーティションを使用
  します。また "/home" ファイルシステムとしてユーザーのデータ領域を別の
  パーティションに分離することは、バックアップやシステム情報の保存などに
  有効となります。

  LDP/JF の Partitin-HOWTO の「2. ともあれパーティションとは？」や Disk-
  HOWTO などにパーティション分割の方法についての説明などがあります。

  ところでパーティションには、「基本 (primary)」、「拡張 (extended)」、
  「論理 (logical)」の区別があります。ここでは、そのそれぞれの違いについ
  て説明してみます。

  3.1.  基本領域 (primary partition)

  「基本領域」というのは最初に定義された形式です。この「基本領域」を定義
  する「パーティションテーブル」はハードディスクの先頭 512 byte (最初の
  セクタ) の最後のほう 64bytes (最後に 0xAA55 の 2bytes がくるの
  で、447バイト目から - 510バイト目まで) に収まるように定義されていて、
  かつ１つの「基本領域」を定義するために 16バイトが必要なため、「基本領
  域」はディスク全体で最大 4 個までしか作成できません。

  この 16bytes の中身 (ひとつの「基本領域」を定義する構造体) は以下のよ
  うになっています。 (この部分は LDP/JF の large-disk-mini-HOWTO より引
  用)

     struct partition {
             char active;    /* 0x80: bootable, 0: not bootable */
             char begin[3];  /* CHS for first sector */
             char type;
             char end[3];    /* CHS for last sector */
             int start;      /* 32 bit sector number (counting from 0) */
             int length;     /* 32 bit number of sectors */
     };

  ここで、 CHS は Cylinder/Head/Sector の略です。また active は起動可能
  な領域であるかどうかを示すフラッグで、 type はそのパーティションの種類
  を示す ID (Linux の Ext2fs なら 0x83) です。begin[3] と end[3] は CHS
  アドレスによるパーティションの開始位置と終了位置、また start と length
  は LBA アクセスのためのセクター番号によるパーティションの開始位置とサ
  イズです。 (/余談)

  PC が生まれた頃はたぶんこれで問題無かったのでしょうけれど、だんだんと
  ハードディスクの容量が増えてくると、もっとたくさんのパーティションを使
  いたくなります。「拡張」と「論理」はこの要望に応えるために、最初の形式
  を拡張したものです。

  3.2.  拡張領域 (extended partition)

  「拡張」領域とはその中に「論理」領域を収めた基本領域です。しごくあたり
  まえの説明ですが、単にそれだけです。「拡張」領域の場所や大きさ、パー
  ティション ID などは「基本」と同じくハードディスクの先頭 512bytes (こ
  れをマスターブートレコード、MBR と呼ぶ) 内のパーティションテーブルに記
  録されます。

  3.3.  論理領域 (logical partition)

  「論理」領域は「基本」や「拡張」と異なり、そのサイズや位置などの情報は
  MBR に記録されません。では、どこに記録されているのか ?

  (余談) 実はこれ、私は最近ようやく知って面白いと思ったのですが、以前か
  ら AT 互換機に詳しい方には当然のことなのかもしれません。 (/余談)

  実は、「論理」領域は「親亀の上に子亀、そのまた上に孫亀」といった感じの
  連鎖構造になっています。

  図で書くと、こんな感じ (等幅フォントで見てください _o_)

  1. 「拡張」領域内にひとつの「論理」領域

     大元の「拡張領域」の中に「先頭トラック」に相当するサイズのスペース
     (その中に「準」パーティションテーブルがある) と、それに続いて論理領
     域が含まれています。

      |拡張領域全体
      |----------------------------------------------------
      |先頭トラック|論理領域

  2. 「拡張」領域内にふたつの「論理」領域

     大元の「拡張領域」の中に「先頭トラック」に相当するサイズのスペース
     (その中に「準」パーティションテーブルがある) と、それに続いて最初の
     論理領域、そしてさらに次の「準」拡張領域が含まれています。

     次の「準」拡張領域の内部は上記の「拡張領域内にひとつの論理領域」と
     同じです。

      |拡張領域全体
      |----------------------------------------------------
      |先頭トラック|論理領域|「準」拡張領域

                         |「準」拡張領域
                         |--------------------------------
                         |先頭トラック|2 番目の論理領域

  3. 「拡張」領域内に 3 つの「論理」領域

     大元の「拡張領域」の中に「先頭トラック」に相当するサイズのスペース
     (その中に「準」パーティションテーブルがある) と、それに続いて最初の
     論理領域、そしてさらに次の「準」拡張領域が含まれています。これは上
     記の「拡張領域内にふたつの論理領域」と同じです。

     次の「準」拡張領域の内部も「拡張領域内にふたつの論理領域」と同じで
     す。

     3 番目の「準」拡張領域の内部は上記の「拡張領域内にひとつの論理領
     域」と同じです。

      |拡張領域全体
      |-----------------------------------------
      |先頭トラック|論理領域|「準」拡張領域

                 |「準」拡張領域
                 |------------------------------------------------------
                 |先頭トラック|2 番目の論理領域|2 番目の「準」拡張領域

                            |2 番目の「準」拡張領域
                            |------------------------------------
                            |先頭トラック|3 番目の論理領域

  「拡張」領域の先頭セクター (512 bytes) には、その領域内に存在する「論
  理」領域と、その次の「準」拡張領域の位置とサイズを記録した「準」パー
  ティションテーブル (512bytes のうちの 447 - 510 bytes, 計 64bytes の領
  域) が存在します。

  「準」拡張領域という名前は、この文書で便宜的に付けた名前です。この領域
  の構造は大元の拡張領域とまったく同じで、ただその全体が別の (「準」) 拡
  張領域に含まれるという点だけが違います。

  「準」パーティションテーブルの形式は MBR にあるディスク全体のパーティ
  ションテーブルとほぼ同じ (ただし、セクターアドレスの計算方法にちょっと
  注意が必要) です。

  4.  おわりに

  4.1.  お願い

  ここまで、とりあえず書けた部分だけでまとめてみましたが、まだまだ不足し
  ている情報があるはずです。「これも追加して欲しい」という意見をお持ちの
  方は是非教えて下さい。よろしくお願いします。

  4.2.  謝辞

  この文書は LDP/JF の large-disk-mini-HOWTO やその他の参考文献から得ら
  れた情報をまとめたものです。Linux ユーザーの役に立つ文書を数多く集積
  し、世界に発信している LDP と JF のみなさんに感謝します。また、この
  「ハードディスクドライブの基礎知識」について、以下の方々から有益なフィ
  ードバックを頂きました。ここに感謝の表します。

  1999 10/06 修正: ``セクター''および ``ディスクアクセス''の文章をおくじ
  さんからの指摘を参考に修正しました。

  1999 12/5 追加: ``セクター''にある MO の例は飯塚さんからの情報提供によ
  ります。

  4.3.  この文書の配布について

   copyrighted (c) 1999 Taketoshi Sano

  この文書は GNU パブリックライセンス (GPL) バージョン 2 かそれ以降の条
  件、あるいは標準的な Linux ドキュメントプロジェクト (LDP) の条件に基づ
  いた配布ならば自由にしていただいてかまいません。これらのライセンスはこ
  のドキュメントが入手できるようなサイトから入手できます。LDP の条件は
  (翻訳をのぞく) いかなる修正も許可していません。修正されたバージョンは
  GPL の基でのみ配布されるものとすることが可能です。

