--- nono/vm/ufs.cpp 2026/04/29 17:04:50 1.1 +++ nono/vm/ufs.cpp 2026/04/29 17:05:43 1.1.1.5 @@ -4,7 +4,9 @@ // Licensed under nono-license.txt // -// UFS +// +// UFS 読み込み +// #include "ufs.h" #include "ffs_dir.h" @@ -31,7 +33,7 @@ Filesys::~Filesys() // 成功すれば true を返す。 // 失敗すれば errstr にエラーメッセージをセットして false を返す。 bool -Filesys::Mount(SCSIHD *hd_, uint32 start, uint32 size) +Filesys::Mount(SCSIDisk *hd_, uint32 start, uint32 size) { hd = hd_; part_start = start; @@ -62,7 +64,7 @@ Filesys::Mount(SCSIHD *hd_, uint32 start // スーパーブロックの構造は の struct fs 参照。 // スーパーブロックを読む (ここはまだ PeekBlock() は使えない) - hd->PeekImage(&fs0, part_start * 512 + 8192, sizeof(fs0)); + hd->Peek(&fs0, part_start * 512 + 8192, sizeof(fs0)); // 読み込んだスーパーブロックはゲストエンディアン(BE) なので // 使う前に (もう面倒なのでほぼ全部) ホストエンディアンにしておく。 // ヘッダに定義してあるマクロをそのまま使いたいからだけど、正気かなこれ。 @@ -157,6 +159,27 @@ Filesys::Mount(SCSIHD *hd_, uint32 start // マジック if (fs->fs_magic != FS_UFS1_MAGIC) { + // マジックが違った場合、どう違うか分かる分には表示したい。 + + if (fs->fs_magic == FS_UFS1_MAGIC_SWAPPED) { + errstr = "Byte-swapped FFSv1 not supported"; + return false; + } + + // FFSv2。マジックフィールドで v1/v2 を区別できるのにそもそも + // スーパーブロックの位置が違う…。 + struct fs fs2; + hd->Peek(&fs2, part_start * 512 + 65536, sizeof(fs2)); + if (fs2.fs_magic == FS_UFS2_MAGIC) { + errstr = "FFSv2 not supported"; + return false; + } + if (fs2.fs_magic == FS_UFS2_MAGIC_SWAPPED) { + errstr = "FFSv2 (and byte-swapped) not supported"; + return false; + } + + // どれでもなければとりあえず生値を表示 errstr = string_format("Bad superblock magic 0x%08x (!= 0x%08x)", fs->fs_magic, FS_UFS1_MAGIC); return false; @@ -320,7 +343,7 @@ Filesys::OpenFile(inodefile& file, const break; default: - __unreachable(); + VMPANIC("corrupted state=%d", (int)state); } } // 通常ファイルに到達 @@ -493,7 +516,7 @@ Filesys::PeekBlock(void *buf, uint32 b, { // FFS_FSBTODB(fs, b) がブロック番号 b をセクタ番号に変換する。 uint32 sector = part_start + FFS_FSBTODB(fs, b); - hd->PeekImage(buf, sector * 512, len); + hd->Peek(buf, sector * 512, len); } @@ -525,12 +548,11 @@ inodefile::FindFile(const std::string& n // ようだ。 const char *dp = (const char *)(data.data()); const char *dend = dp + data.size(); - uint32 file_ino; uint16 reclen; for (; dp < dend; dp += reclen) { const struct direct *d = (const struct direct *)dp; - file_ino = be32toh(d->d_fileno); + uint32 file_ino = be32toh(d->d_fileno); reclen = be16toh(d->d_reclen); std::string str = string_format("ino=%u reclen=%u name=|%s|",