PC-98x1/disk/区画情報

PC-98x1/disk/区画情報

ネタ元

disktut: DISKに関する資料 第2稿
undoc1: UNDOCUMENTED 9801/9821 Vol.1 BIOS・割り込み編 (書籍) ISBN4-8443-4642-3
undoc2: UNDOCUMENTED 9801/9821 Vol.2
GRUB98: http://www.kmc.gr.jp/proj/linux98/arch/i386/boot/grub98/ (20030409 ver)

(20150123めも) (lib)parted のディスクタイプ "pc98" ってほんとに PC-98x1 系のことだと最近気づいた。あとで詳しく確認しよう… → http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/labels/pc98.c

留意点

  • BIOS からみたセクタサイズ - 256/512/1024 バイト(2048 もあったっけ?)
  • Win98(Win2000 も?)から区画情報のフォーマットが変わったとかいう話を聞いたような気がする。 どっかに資料があるんだろうか…。
  • HDD のセクタ番号は 0 から始まる。 FDD は 1 から。 (つまりフロッピーディスクとそれ以外のデバイスとでは、CHS⇔LBA の変換式が異なる)

ハードディスクのジオメトリを得る

基本的には DISK BIOS の新SENSE(int 1Bh, AH=84h)を使う、ってことでいいんでしょうか。

int 1Bh, ah=84h 新SENSE

入力

レジスタ 内容
AH 84h
AL DA/UA
8xh (SASI/ESDI/IDE)
Axh (SCSI)

出力

レジスタ 内容
CF 0 正常終了、もしくは新SENSE コマンドが未サポート
1 エラー
AH bit7-4 ステータス
bit3-0 デバイス容量 (legacy SASI)
0000 5MB
0001 10MB
0011 20MB
0100 40MB
BX セクタ長(バイト単位)
CX シリンダ数 -1 (undoc1)
DH ヘッド数
DL シリンダ当たりのセクタ数

undoc1 によると、SENSE および新SENSE で AH に返される容量値は、テクニカルリファレンスの記載値とは異なるらしい。

AH bit3-0 SENSE
(テクニカルリファレンス)
SENSE
(undoc1)
新SENSE
(undoc1)
SASI ISR DTx2-x0
(参考)
0000 5M
0001 10M
0010 15M
0011 20M
0100 40M 25M 20M
0101 40M 25M
0110 40M
0111 40M 未接続
1001 100M
(ESDI)
1111 80M以上
(IDE)

古めの SASI BIOS では新SENSE コマンドがサポートされていない場合がある。 (ちなみに PC-9800 シリーズのテクニカルデータブックには「コマンドに該当しないコードが指定された場合は正常終了(CF=0)する」という記述がある。つまり未サポートコマンドは完全スルー) このときは SENSE コマンド(AH=04h)を使い、AH の bit3-0 で返された容量に対応するジオメトリを自前で用意する必要がある。

ディスク容量 シリンダ ヘッド セクタ数
(1セクタ 256byte)
セクタ数
(1セクタ 512byte)
5MB 153 4 33 17
10MB 310 4 33 17
20MB
(ハーフハイト)
615 4 33 17
40MB 615 8 33 17

セクタサイズが 256bytes か 512bytes かはシステムメモリ 0000:0481h の bit1-0(undoc2:memsys.txt)で知ることができるようだ。→ 一概に決め付けないほうがいい、かな…

SASI BIOS が新SENSE コマンドに対応している場合、システムメモリ 0000:0480h の bit7 がセットされる――と undoc2:memsys.txt には書いてあった。 でも説明をよく読むと、「セットされていなくても実はサポートされている」というケースが多々報告されている。

(あらかじめ BX あたりに 0 とか叩き込んでおいてから)とりあえず新SENSE コマンドを発行してみて、レジスタに妥当とおもわれる値が返ってこなかった場合だけ「超ふるい SASI」とみなすのが無難ですかねえ…。

関連情報

システムメモリ 0000:0460〜047Fh
SCSI 機器のパラメータテーブル (undoc2:memsys.txt、"PC-98 in FreeBSD source" など)

区画情報の判定 (IPL)

ディスク全体用 IPL(シリンダ 0、ヘッド 0、セクタ 0 にある、いわゆる MBR)の、

  • オフセット 04h から 4 バイトが "IPL1"
  • セクタ最後の 2 バイト(セクタサイズ 256 と 512 でオフセット値が異なる)が 55h, AAh

で、拡張フォーマットかどうか一応判定できる。
「標準フォーマット」(セクタサイズ 256 バイトで容量 20M バイト以下の場合、初期化時にフォーマットを選ぶことができる)の IPL にも "IPL1" が書き込まれているため、これだけで判定することはできない。

区画情報(拡張フォーマット)

シリンダ 0、ヘッド 0、セクタ 1 に収められている。
区画情報は1区画あたり 32 バイト。 したがって、セクタサイズが 512 バイトのデバイスでは最大 16 個の区画情報が格納できる。 セクタサイズ 256 バイトの場合は最大 8 個。

以下の表はほぼ disktut からの引用。

offset size name description
00h byte boot ブート可/不可
bit7 が 1 なら何かしら起動可能なシステムが入っていて、0 なら単なるデータ領域ということらしい。 その他の部分の扱いは、区画の種類によってケースバイケース。
01h byte syss 区画種別、アクティブ/スリープ
bit7 が 1 ならその区画はアクティブ、0 ならスリープ、ということらしい。 その他の部分は区画の種類をあらわすようだ。
02h word sysy 不明(0000h)
04h byte IPLs IPL の物理セクタ番号
05h byte IPLh IPL の物理ヘッド番号
06h word IPLc IPL の物理シリンダ番号
08h byte vostas 領域先頭の物理セクタ番号
09h byte vostah 領域先頭の物理ヘッド番号
0Ah word vostac 領域先頭の物理シリンダ番号
0Ch byte voends (領域終端の物理セクタ番号)
0Dh byte voendh (領域終端の物理ヘッド番号)
0Eh word voendc 領域終端の物理シリンダ番号
10h 16bytes sysm 領域名 の ASCII 文字列
  • ふつう、IPL の位置と領域先頭位置は同じになる。
  • 領域終端シリンダは、その区画のいちばん最後にあるシリンダ表す(「次の領域の先頭」ではない)。 したがって、1シリンダ分の領域を確保した場合、vostac と voendc は同じ値になる。
  • てゆうかセクタ番号(vostas, voends)とヘッド番号(vostah, voendh)って使ってんの? (0 以外の値いれたらやばくね?)
  • 領域名が 16 文字未満の場合、あまった部分にはスペース (20h) が詰められるようだ。

先頭2バイト(boot, syss)はむしろ1ワードとみなしちゃったほうがいいのかも。

区画の種別(disktut + GRUB98/shared_src/pc_slich.h から補填)
※ syss の bit7 はとりあえず 0 とみなしている。 boot の bit7 も(FreeBSD と PC-UX 以外では)とりあえず 0 とみなしている。

syss (syss:boot) OS
00h 未使用領域
01h (01:2xh ) MS-DOS (FAT12)
04h (04:00h) PC-UX スワップ領域
04h (04:90h) PC-UX システム領域
06h N88-BASIC
11h (11:2xh) MS-DOS (DOS 3 FAT16)
21h (21:2xh) MS-DOS (DOS 5 FAT16)
44h (44:94h) FreeBSD, NetBSD/pc98
61h (61:2xh) Windows FAT32
62h (62:20h) Linux/98 (EXT2/SWAP)
  • NEC 版 MS-DOS の format /H コマンドを使った場合、大きさ 10M バイトまでの領域は syss が 01h になるようだ。11M バイト以上を指定すると 11h になる(下記「DOS3.3 拡張フォーマット」の項も参照)。
  • 同様に、129M 以上の領域を作成すると syss は 21h になる。11〜128M までは 11h。DOS 3.x は 21h の領域に対応していない(DOS 3.3 付属の format でマップを見ると領域が「他のOS」という表記になる)。たぶん総セクタ数が 65536 以上の領域はこっちを使うんだと思う。 EPSON の DOS 4.0 がこのへんをどう扱っていたのか、ちょっと気になる。
  • MS-DOS 区画の boot (2xh) の下位 4bit は 1 から 0fh までの値をとる(disktut によると「FORMAT.EXE で領域をブート可能にした順に 1 から F まで」だそうです)。ブートしない DOS 領域は 0 (20h) のようだ。
  • Linux/98 区画は bootable なら EXT2、bootable じゃなければスワップ領域とみなすらしい(GRUB98)。
  • todo: HPFS (OS/2) と NTFS(WinNT/2000) の区画 ID を調べよう。
  • todo: その他の OS の区画情報を大募集中。 たしか Netware とか PANIX とかあったような。 あと CP/M86 とか CP/M68K とかもハードディスク使えたよね?(実はまったく知らない)

セクタ長と区画サイズに関する補項

IBM PC 系だと「1セクタ = 512bytes」の対応が(少なくとも FD と HD では)ハードウェアから OS までほぼ一貫しているが、PC-98 系はこのへんが少しややこしくなっており、

  • ハードウェア的な物理セクタ長
  • BIOS から見た(物理)セクタ長
  • MS-DOS などの OS から見た論理セクタ(レコード)長

がそれぞれ異なっていることがある。

DOS3.3 拡張フォーマット

なぜかテクニカルデータブックの「ハードウェア編」のほうに SCSI ディスクのパーティションに関する情報が載っていた。



 SCSI インターフェイスで制御される固定ディスクは、拡張フォーマットでフォーマットされ、4つのアクティブなパーティションの確保が可能である。 また、パーティションの最大領域は 128M バイトである。

DOS 3.3 拡張フォーマットで確保した区画の状態

区画容量 FAT サイズ 論理セクタサイズ
10M 以下 FAT12 1024
65M 未満 FAT16 1024
65M 以上 FAT16 2048

つまりアレだ、DOS 3.x でそこそこデカめのハードディスクを活用するために、論理セクタサイズをでっかくしてるわけだ…ちなみに(起動)ドライブの論理セクタがデカいと、MS-DOS のディスクバッファ(BUFFERS= で指定するアレ)のサイズもその分だけデカくなる。 つまりセクタサイズがでかいとメモリが圧迫される。