仮想CD機能付きポータブルHDD HD-PSGU2で遊ぶ
はじめに
さて、皆様は仮想CDドライブ機能付きポータブルHDDというものをご存じでしょうか。
DistroHopperな方やベータ版OSをいち早く試したい方、廃品業者から仕入れたPCにOSを入れて売りさばくのが趣味の方は既にお持ちかと思いますが、光学メディアのイメージファイルを入れておくと、USB CD/DVDドライブとして振舞ってくれる便利な道具です。
代表的なものには、ioddやZALMAN製のケース単体で売っていて好きなHDDを入れて使うもの、BUFFALOやIODATA製のユーティリティが内蔵されたもの、似たような仕組みのものとしてはLTEモデムやモバイルルーターのドライバが入っていないときに自動でロードされるドライバCDも、広義の外付けの仮想CDドライブの範囲に含まれるでしょう。

私もZALMAN ZM-VE200を持っていて便利に使っているのですが、ギーク・オタクというのは便利なものを持つと予備が欲しくなってしまう生き物でして、つい魔が差してBUFFALO HD-PSGU2の「ケースだけ」を買ってしまったのでした。それが内蔵HDDの先頭をコピーしないと仮想CD機能は使えない、FAT32上にある(つまり4GBまでの)isoファイルしかマウントできないという、いわくつきのものであることを知っているにもかかわらず…
お散歩してみる
お散歩するって言ったって、肝心のHDDがありませんので、フリマに出てくるのを虎視眈々と待ち、ディスク入りのものを入手。この時点ですでに試合に負けて勝負にも負けているのですが、気にせず続けましょう。一通り説明書通りに動作することを確かめてから、HDDを取り出します。

HDD単体でPCに接続し、先頭を256MiBほどダンプしたものをHD-PSGU2.BINとしましょう。
HDDを換装した方の情報によると、先頭512256セクタまでがユーティリティエリアで不可視となっており、その次のセクタからがHDDとして認識するとのことでしたので、まずはそれを確認してみます。
$ hexdump -C -s 262275072 -n 512 HD-PSGU2.BIN
0fa20000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0fa201b0 00 00 00 00 00 00 00 00 ce 2c 8d 2f 00 00 00 20 |.........,./... |
0fa201c0 21 00 0c fe ff ff 00 08 00 00 80 72 f1 0d 00 00 |!..........r....|
0fa201d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0fa201f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
0fa20200
ビンゴ。MBRのパーティションテーブルがいました。
ここからCDとして認識される容量250MiBを引くと、131072バイト。とりあえず先頭から見て行ってみましょう。
$ hexdump -C -n 131072 HD-PSGU2.BIN
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001e00 00 00 00 00 00 00 00 00 50 31 00 0c 00 d1 07 00 |........P1......|
00001e10 88 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001e20 00 01 00 00 00 d0 07 00 0f 05 02 00 5c 13 00 00 |............\...|
00001e30 42 55 46 46 41 4c 4f 20 56 69 72 74 75 61 6c 2d |BUFFALO Virtual-|
00001e40 43 44 28 75 74 69 6c 29 30 32 30 30 02 02 00 01 |CD(util)0200....|
00001e50 00 21 03 00 00 00 00 00 00 00 00 00 00 00 00 00 |.!..............|
00001e60 42 55 46 46 41 4c 4f 20 56 69 72 74 75 61 6c 2d |BUFFALO Virtual-|
00001e70 43 44 28 75 73 65 72 29 30 32 30 30 ff 0f 00 00 |CD(user)0200....|
00001e80 44 41 54 41 20 20 20 20 20 20 20 10 53 59 53 54 |DATA .SYST|
00001e90 45 4d 20 20 42 49 4e 20 00 00 00 00 00 00 00 00 |EM BIN ........|
00001ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00020000
ここにしかデータはいませんが、あなたが泉に落とした斧ですという雰囲気を醸し出しています。
ジーっと見てたら、どこが大事かはわかりましたね!あとはエンディアンをひっくり返して答え合わせです。
| オフセット | データ | Hex | Dec | 意味 |
|---|---|---|---|---|
| 1e0c | 00 d1 07 00 | 7D100h | 512256 | 先頭の不可視領域(セクタ) |
| 1e20 | 00 01 00 00 | 100h | 256 | ユーティリティCD-ROM領域のオフセット(セクタ) |
| 1e24 | 00 d0 07 00 | 7D000h | 512000 | ユーティリティCD-ROM領域のサイズ(セクタ) |
この値を書き換えれば、HDD上の任意の領域をユーティリティCD-ROMのかわりにマウントできそうです。
完成
250GBのHDDの末尾に確保するとして、こうしましょう。
| オフセット | データ | Hex | Dec | 意味 |
|---|---|---|---|---|
| 1e0c | 00 04 00 00 | 400h | 1024 | 先頭の不可視領域(セクタ) |
| 1e20 | 00 10 23 1c | 1C231000h | 472059904 | CD-ROM領域のオフセット(セクタ) |
| 1e24 | 70 49 f9 00 | f94970h | 16337264 | CD-ROM領域のサイズ(セクタ) |
設定データはこうなります。
$ hexdump -C HD-PSG250U2_end.BIN
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001e00 00 00 00 00 00 00 00 00 50 31 00 0c 00 04 00 00 |........P1......|
00001e10 88 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001e20 00 10 23 1c 70 49 f9 00 0f 05 02 00 5c 13 00 00 |..#.pI......\...|
00001e30 42 55 46 46 41 4c 4f 20 56 69 72 74 75 61 6c 2d |BUFFALO Virtual-|
00001e40 43 44 28 75 74 69 6c 29 30 32 30 30 02 02 00 01 |CD(util)0200....|
00001e50 00 21 03 00 00 00 00 00 00 00 00 00 00 00 00 00 |.!..............|
00001e60 42 55 46 46 41 4c 4f 20 56 69 72 74 75 61 6c 2d |BUFFALO Virtual-|
00001e70 43 44 28 75 73 65 72 29 30 32 30 30 ff 0f 00 00 |CD(user)0200....|
00001e80 44 41 54 41 20 20 20 20 20 20 20 10 53 59 53 54 |DATA .SYST|
00001e90 45 4d 20 20 42 49 4e 20 00 00 00 00 00 00 00 00 |EM BIN ........|
00001ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002000
これをHDDの先頭に書き込んで……目的のイメージファイルもddで流し込みます。
できました。5.7GBほどあるWindows11 2024H2のイメージがマウントされています。ここに内蔵ユーティリティ以外が表示される想定はないでしょうから、文字がはみ出しちゃって埋もれていますね。

イメージ領域は必ずしも不可視領域内になくても良いため、HDDの末尾に領域と一致するようにパーティションを作成し隠し属性をつけておき、パーティションにisoイメージをddでコピーして入れ替えるといった運用にすることで、イメージを入れ替える際に分解してHDDを繋ぎかえる必要はなくなります。
$ sudo parted /dev/sdd
(parted) mkpart primary fat32 472058880s -1s
(parted) set 3 hidden on
パーティションテーブルで指定するセクタ番号は、HDD上の絶対セクタより不可視領域として設定したセクタ数分オフセットしていることに注意しましょう。

おまけ
中身入りのHDDを入手できた方は、一応ユーティリティ領域も切り出してしておきましょう。
$ dd if=HD-PSGU2.BIN of=HD-PSGU2.iso bs=131072 skip=1 count=2000
ユーティリティは、MobileLaunch.exeが常駐し、そこからドライブ2割り当てツールであるVCDUTK.exeを呼び出す仕組みとなっていますが、VCDUTL.exeはそのまま実行しても機能してくれません。
常駐させずに使いたいときは、HDDの先頭に確保したFAT32領域に配置したうえで、バッチファイルから
%~d0¥DATA¥VCDUTL¥VCDUTL.exe /SETUP:%~d0¥DATA¥SYSTEM.BIN /IMAGE:"%~d0¥DATA¥CD images"
などと呼んであげると起動してくれます。これらのツールはスイッチが1の位置の時しか動作しませんので、¥DATA¥SYSTEM.BINを直接書き換えたほうが早いかもしれません。
$ hexdump -C SYSTEM.BIN
00000000 00 00 00 00 50 32 58 02 01 00 00 00 00 00 00 00 |....P2X.........|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000030 44 41 54 41 20 20 20 20 20 20 20 10 43 44 49 4d |DATA .CDIM|
00000040 41 47 7e 31 20 20 20 10 44 45 42 49 41 4e 7e 32 |AG~1 .DEBIAN~2|
00000050 49 53 4f 20 00 00 00 00 00 00 00 00 00 00 00 00 |ISO ............|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
SYSTEM.BINの中身は、マウントするイメージファイルのSFNのパスが書いてあるだけです。これがわかれば2番目の仮想CDドライブもユーティリティなしでマウントできそうですね!
2番目の仮想CDドライブはオフセット指定ではなく、ファームウェアがFAT32を解釈して動作しているようです。
オフセット06hにある58 02 は600秒で省電力に入るという設定のようです。デフォルトは00 00(無効?)
物足りない方へ
HD-PSGU2に使用されているJmicronのSATA-USBブリッジ、中のマイクロコントローラーはi8051らしいですよ……
Discussion