上周我在整理一台老实验机的时候,要找一个小分区放启动镜像。系统是新的,可我鬼使神差打开磁盘工具列表,往下翻到 mkfs.minix 那一条,旁边一个刚转运维的同事问:现在还有人用这个命令格式化磁盘吗?这问题问得很好。ext4、XFS、Btrfs 随便挑一个都更现代,但 Minix 文件系统以及 mkfs.minix 这条命令,并没有完全从 Linux 生态里消失。它在某些小分区、旧设备兼容、文件系统原理学习场景里,仍然是最顺手的工具之一。
这篇文章我不会只把 mkfs.minix 的参数草草抄一遍。我想用它配合一块真实 U 盘,把从分区、格式化、挂载、验证到问题排查的完整过程走一遍,同时说清楚这条老命令背后的文件系统布局、版本差异和使用边界。内容不排斥新手,运维和做嵌入式的朋友看完可以直接在测试环境抄作业;对文件系统内部结构感兴趣的人,也能从后面的超级块观察里找到一点思路。
1. 一条老命令:mkfs.minix该怎么定位
1.1 它从哪来,为什么Linux还留着
Minix 文件系统来自一个为教学目的开发的操作系统。1987 年这个系统发布时,作者把核心源码写进了教材附录,很多学生都是抱着那本厚书一边读一边敲代码。Linux 诞生前后,开发环境同样跑在 Minix 上,早期的 Linux 内核直接沿用了 Minix 文件系统来管理磁盘。所以你会看到两个“活化石”一直保留到今天:一个是内核里的 minix 文件系统驱动,另一个就是 util-linux 工具箱里的 mkfs.minix。
后来内核社区陆续做出了 ext、ext2 等更强大的文件系统,才逐渐把 Minix 文件系统从日常使用中替换掉。但因为它超级简单,没有复杂日志,没有 B+树目录,没有任何“智能”设计,反而让它变成一个特别适合学习磁盘布局的样本。内核维护者也没有把这段支持和工具删除,一直放在 util-linux 里。
很多新人在 ls /sbin/mkfs* 时会看到这么一串带 mkfs. 前缀的文件:mkfs.ext2、mkfs.ext4、mkfs.xfs、mkfs.fat、mkfs.minix。而 mkfs.minix 正是那一堆“现代选手”里最朴素的一个。它不是用来替代谁的,更像是一把留给特殊场景的小号螺丝刀。
1.2 什么场景下你会想起它
我从实际使用倒推,下面几类情况最值得把它捡起来:
- 做一个超小的启动分区或镜像。比如要给某个嵌入式设备做 32MB、64MB 的独立分区,Minix 文件系统造成的额外开销非常小,结构简单到可以手工推算。
- 需要兼容比较老的系统或内核。极老的内核不一定认识 ext4,但对 Minix v1、v2 往往天生支持。
- 学习文件系统原理。Minix 文件系统的超级块、inode 位图、块位图、数据区布局非常清晰,可以拿着十六进制工具逐个字节看。
- 测试场景里不想引入现代文件系统的“自动行为”。例如有些场景要排除日志、延迟分配等干扰,只验证最基本的读写逻辑。
注意,这些场景都有一个共同点:分区都很小。mkfs.minix 从来不是为了格式化一个几百 GB 的硬盘准备的。如果你手里是 2TB 企业盘,请把命令关上,去用 mkfs.ext4 或 mkfs.xfs;如果你只是想找块小盘做实验,或者要在镜像文件里预先放一个极简文件系统,那就可以继续往下看。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实操前把磁盘和设备理清楚
2.1 用 lsblk 和设备分区确认目标盘
磁盘操作的底线是先确认设备名,这一步做错了,数据就没了。我找了一块 2GB 的旧 U 盘做实验,插上机器后先执行 lsblk:
bash复制lsblk -o NAME,SIZE,TYPE,TRAN,MOUNTPOINTS
输出里会出现类似下面的一行:
text复制sdb 2G disk usb
我确认它是 sdb 而不是系统盘的 sda。判断依据不能只靠“应该不会错”,我会再看一眼盘符对应的厂商和型号。lsblk 看不到的话,可以用:
bash复制lsblk -o NAME,SIZE,MODEL,TRAN
这样能看清是不是 U 盘。接着用 lsblk -f /dev/sdb 看当前盘上是否已有分区和文件系统签名。旧 U 盘往往残留着其他分区表信息,后面格式化前我会处理掉。
一个我非常推荐的习惯是:在执行任何写操作前,把你的目标设备用一行命令固化下来。
bash复制lsblk /dev/sdb
只要这个输出没有出现 sda、nvme0n1 这种系统盘名字,再往后操作时才安心。
2.2 安装/检查 mkfs.minix 所在工具包
mkfs.minix 不是独立软件包,它来自 util-linux。大多数 Linux 发行版默认已经安装 util-linux,因为 mount、fdisk、hwclock 这些基础命令也在同一个包里。但个别精简系统、容器镜像或从源码编译的嵌入式环境里可能没有。
需要确认就先查路径:
bash复制which mkfs.minix
如果没输出,再查包管理器。Debian/Ubuntu 系可以用:
bash复制dpkg -S /sbin/mkfs.minix
# 或者直接用 apt-file 查
apt-file search bin/mkfs.minix
RHEL/CentOS/Fedora 系常见路径:
bash复制rpm -qf /usr/sbin/mkfs.minix
因为工具属于 util-linux,真缺这个命令时直接安装 util-linux 通常就能解决:
bash复制sudo apt install util-linux
# 或
sudo dnf install util-linux
有一个小坑值得提一下:某些发行版把 mkfs.minix 放在 /usr/sbin,而普通用户的 PATH 不包含 /usr/sbin。你输入 mkfs.minix 提示 command not found,但 sudo mkfs.minix 却能执行,因为 sudo 的 secure_path 里包含了 /usr/sbin。先 ls -l /usr/sbin/mkfs.minix 看一眼,比直接怀疑包没装更靠谱。
2.3 在空闲U盘上创建测试分区
我在这块 2GB U 盘上不留整个盘,只划出一小块 64MB 左右的空间给 Minix 文件系统。为什么划小一点?后面章节会详细说,核心是 Minix 文件系统不适合现代大分区,64MB 已经足够验证所有特性。
先调用 fdisk:
bash复制sudo fdisk /dev/sdb
进入交互界面后依次输入:
text复制g # 这里如果盘里已有旧分区表,先新建 GPT 分区表
n # 新分区
1 # 分区号
2048 # 起始扇区,采用默认对齐
+64M # 分区大小
t # 改类型
0c # 或直接填 Microsoft basic data,其实对流程影响不大
p # 查看分区表
w # 写盘并退出
如果你更习惯传统 MBR,那 fdisk 里新建 MBR 分区表也可以。Minix 是个文件系统,和分区表类型没有强绑定关系,GPT 或 MBR 都能承载,我选择 GPT 只是因为新机器更常用。
分区创建完成后,Linux 通常会自动刷新分区表。如果没识别出新的 /dev/sdb1,可以手动执行:
bash复制sudo partprobe /dev/sdb
此时分区已经就绪,我不急着格式化。先抹掉旧分区表或旧文件系统留下的签名,防止 blkid 或后续挂载误判:
bash复制sudo wipefs -a /dev/sdb1
wipefs 只清理设备头部的文件系统/分区表魔术签名,不会全盘清零,所以对旧盘来说是个安全又高效的动作。
3. mkfs.minix命令参数逐项讲透,并完成格式化
3.1 参数速查表与两个特殊“版本陷阱”
先看一下 mkfs.minix 最基本的语法:
text复制mkfs.minix [options] device [size-in-blocks]
把常用参数整理出来:
| 参数 | 含义 | 实操提醒 |
|---|---|---|
-c |
格式化前先检查坏块 | 对老旧 U 盘可能非常慢,建议只在怀疑盘体损坏时用 |
-l <file> |
从坏块列表文件读取坏块并标记 | 通常由 badblocks 命令生成,普通场合用不到 |
-n <namelen> |
设置最大文件名长度,只接受 14 或 30 | 默认 30,兼容老系统可能要用 14 |
-i <count> |
显式指定 inode 数量 | 不指定时工具会按分区大小估算 |
-v |
创建第二版 Minix 文件系统(v2) | 注意:小写 v 不是 verbose |
-V |
打印程序版本并退出 | 大写 V 才是显示版本,别和小写 v 弄混 |
size-in-blocks |
只使用设备指定块数 | 一般不用手填 |
这里有两个非常容易翻车的点,必须先说。
第一,-v 绝对不是“啰嗦模式”。很多习惯用 mkdir -v、cp -v 的朋友,看到 mkfs.minix -v 想当然以为会打印更多过程信息,结果却不是。小写 -v 是让工具创建 Minix 文件系统版本 2(version 2)。这个版本在旧工具里通常不默认启用,默认创建的往往是版本 1。一旦你加了 -v,超级块里的魔数就会变、inode 结构也会不同,老内核/老驱动可能认不出来。
第二,大写 -V 是很多命令通用的“显示版本号并退出”。想看工具版本时用 -V,想在实操里创建一个版本 2 的 Minix 文件系统,必须用小写 -v。这两个参数代表了完全不同的动作,写脚本时落错一个会导致后续行为天差地别。
3.2 第一次格式化:命令行完整走一遍
我的目标分区是 /dev/sdb1,大小为 64MB。直接执行:
bash复制sudo mkfs.minix -v /dev/sdb1
为了让你看到实际效果,我给一份示例输出,不同 util-linux 版本打印格式会有差异,但核心信息一致:
text复制mkfs.minix: 1024 blocks, 128 inodes
mkfs.minix: blocksize=1024
是不是非常朴素?这就是 Minix 文件系统的风格。输出里两块重要信息:分区被划分出的块数量,以及工具计算出的 inode 数量。然后没有任何花哨的动画或提示,命令就结束了。
如果你想把整块 /dev/sdb1 里的一部分空间拿出来格式化,而不是用整个分区,可以在命令末尾加块数。例如只用前 4096 个块,每块默认 1024 字节,约 4MB:
bash复制sudo mkfs.minix -v /dev/sdb1 4096
这个方法在制作定长镜像时很有用。不过日常用整个分区更多,块数参数可以留作扩展知识。
格式化完以后,先不急着挂载,用 file 命令确认文件系统识别结果:
bash复制sudo file -s /dev/sdb1
如果是版本 2,你会看到输出里带 Minix filesystem、v2、30 char names 之类的字样。如果是版本 1,识别结果会是另一套字眼。这一步能立刻验证你是否真的把文件系统写进去了,也能避免后面挂载时出现“unknown filesystem type"这种尴尬。
3.3 挂载、读写验证与卸载
让 Linux 认出 Minix 文件系统不光靠用户态命令,还要看内核是否支持。先查一下当前内核支持情况:
bash复制grep minix /proc/filesystems
如果这里没有 minix,先加载内核模块:
bash复制sudo modprobe minix
在大多数发行版上,模块叫 minix.ko;某些内核把 Minix 支持直接编译进了内核,那 /proc/filesystems 里就会直接出现 minix,不需要加载。看不到时就用 modprobe minix 试,不要慌。
然后创建挂载点并挂载:
bash复制sudo mkdir -p /mnt/minix
sudo mount -t minix /dev/sdb1 /mnt/minix
df -hT /mnt/minix
df 输出里文件系统类型那一列会直接显示 minix。挂载成功后再写入几个测试文件:
bash复制echo "hello minix" | sudo tee /mnt/minix/hello.txt
sudo mkdir /mnt/minix/docs
sudo cp /mnt/minix/hello.txt /mnt/minix/docs/
sync
sync 很重要。Minix 文件系统没有日志,数据还在页缓存里时直接拔盘或重启,大概率会丢。养成写完就 sync 的习惯,再往下走。
查看目录内容:
bash复制ls -la /mnt/minix/
ls -la /mnt/minix/docs/
确认数据都写进去以后,卸载:
bash复制sudo umount /mnt/minix
卸载完不着急结束,再挂载一次,验证数据仍在:
bash复制sudo mount -t minix /dev/sdb1 /mnt/minix
cat /mnt/minix/hello.txt
cat /mnt/minix/docs/hello.txt
到这里,一个完整的 mkfs.minix 格式化实验已经闭环:分区 -> 格式化 -> 加载模块 -> 挂载 -> 写入 -> 卸载 -> 重挂载 -> 读回。如果后面不想保留这块分区,可以用 wipefs -a /dev/sdb1 清掉签名,或者直接用 fdisk 删除分区。
4. 不是所有地方都适合Minix:容量、命名与适用边界
4.1 极简设计带来的取舍
先明确一件事:Minix 文件系统为了简单牺牲了很多现代文件系统的能力。它没有日志,没有 extents,没有目录索引树,结构基本上是“一张纸就能画出来的布局”:磁盘最开始是引导块,然后是超级块,超级块里记录 inode 位图、块位图和数据区位置。
这种设计的好处是占用空间小、驱动代码容易读。坏处也很明显:一旦在写操作中间断电,没有日志帮忙回放,文件系统状态只能停留在“写到一半”的某个点。你可以用 fsck.minix 扫描修复,但它不会有 ext4 那种强大的自愈体验。
因此,Minix 文件系统适合存放不常变的小文件,比如启动镜像的内核、initramfs、配置文件;不适合作为日常数据盘。如果有人拿它存数据库,那不是命令不好使,是选型错了。
我在实测中还发现,Minix 对“大量小文件”的目录遍历能力很弱。目录项是线性存储的,文件一多,查找需要从头扫到尾,性能会明显下降。这正好反过来说明,它适合文件数量斤斤计较的场景,比如一个只存三五个文件的引导分区。
4.2 版本决定兼容边界:v1、v2与v3
Minix 文件系统本身有多个版本,但用户态 mkfs.minix 一般只负责创建版本 1 和版本 2。默认不指定 -v 时,很多 util-linux 版本生成 v1;指定 -v 后生成 v2。两者的差异集中在 inode 结构、魔数和容量上限上,文件名长度规则也不同。
Linux 内核里的 minix 文件系统驱动比较宽容,它同时能识别 v1、v2,后来还加入了 v3 的支持。但“内核能识别”不等于“util-linux 的 mkfs.minix 能创建”。很多人在网上看到 Minix 3 文件系统的新特性,回头想用 mkfs.minix 格式化一个 v3,结果工具压根不支持。
Minix 3 文件系统通常由 MINIX 3 系统自带的 mkfs 工具创建,不是 Linux 包里的 mkfs.minix。也就是说,你手上这条命令的真实能力上限是“创建 v2”。做完一个 v2 文件系统后,如果拿到极老的设备上挂载失败,也不要惊讶,那时候可能需要用不带 -v 的 v1 格式。
还有一个容量上的限制需要强调。Minix 文件系统诞生年代太早,不是为 GB 级分区设计的。我用一颗 2GB U 盘时,也只划出 64MB 给小分区。如果你习惯性把整个 U 盘直接 mkfs.minix /dev/sdb1,某些版本会直接拒绝,某些版本会写出一个内核不认的畸形文件系统。所以这条命令的最佳伴侣是 fdisk,先把分区缩小到 64MB 或甚至更小。
默认文件名最大长度是 30 个字符,老模式可选 14 个字符。对现代命名习惯来说 30 个字符简直是折磨。我在实验时复制一个长文件名文件过去,直接报错。如果你要格式化的分区会放用户文件,请优先考虑 vfat 或 ext4;只有像启动分区这种文件名自己说了算的场景,才适合 Minix。
4.3 不想占真盘?用loop镜像做实验
读到这里,如果你手头没有空闲 U 盘,又不想在生产服务器上乱试,我强烈建议用回环设备(loop device)做实验。这个办法可以让你不碰任何真实硬盘就把整个流程跑通,最适合练习。
先在当前用户目录生成一个 32MB 的空文件镜像:
bash复制dd if=/dev/zero of=~/minix.img bs=1M count=32
然后对镜像文件执行 mkfs.minix:
bash复制mkfs.minix -v ~/minix.img
注意,这里的“设备”参数直接指向普通文件,mkfs.minix 会把它当作块设备处理并写入文件系统结构。再挂载:
bash复制mkdir -p ~/mnt/minix
sudo mount -o loop ~/minix.img ~/mnt/minix
-o loop 会自动分配一个 /dev/loop0 之类的回环设备,内核看到这个回环设备后,再按 minix 类型解析。后面读写、卸载操作和真实 U 盘完全一致。
用镜像实验的好处很多:删掉镜像文件就相当于把整块“U盘”格式化,不需要担心分区表误写;调试时可以随时复制一份镜像做备份;还能通过 file ~/minix.img 快速看文件系统签名。我后来做文件系统实验时基本都是这个流程,效率比找真实盘高得多。
5. 实际运维中遇到的挂载与识别问题
5.1 问题速查表
这里把我在真实环境里碰到的现象和排查思路整理成一张表,遇到问题先对号入座。
| 现场现象 | 大概率原因 | 处理建议 |
|---|---|---|
mkfs.minix: command not found |
util-linux 未安装或 /usr/sbin 不在 PATH |
使用完整路径 /usr/sbin/mkfs.minix,缺少则安装 util-linux |
mount: unknown filesystem type 'minix' |
内核模块未加载或内核未编译支持 | sudo modprobe minix;仍失败则检查内核配置 |
mount: wrong fs type, bad option, bad superblock |
设备里不是 Minix 文件系统,有旧签名残留 | wipefs -a /dev/sdb1 后重新格式化 |
| 挂载后只能读不能写 | 文件系统版本过旧或挂载时带了 ro |
检查 mount 选项;格式化时用 -v 创建 v2 |
No space left on device |
分区太小或 inode 数被占满 | df -i 查看 inode;重新规划分区大小 |
| 格式化时提示 block 太多、inode 不合理 | Minix 不适合大分区 | 把分区缩小到 64MB 级别再试 |
fsck.minix 扫描出大量错误 |
非正常断电导致 | 先在镜像盘上练习,重要数据不要放在 Minix 分区 |
注意,第一行里“命令没找到”还有一个隐蔽可能:不是没有工具,而是 /usr/sbin 不在普通用户 PATH 里。用 sudo 后若正常,就不是包缺失的问题。
5.2 三个容易翻车的细节
下面这些坑都是教训换来的,单独拎出来说。
第一个坑是 -v 和 -V 看错。刚开始接触 mkfs.minix 时,我想看详细日志,敲了一个小写 v,结果它创建了版本 2 的 Minix 文件系统。当时没意识到,还纳闷输出怎么这么少。后来拿到一台只支持 v1 的旧内核环境里挂载,直接报 bad magic。排查了半天,才发现自己天天都在用 -v。从此我写脚本时会在注释里写明:小写 v 表示 version 2,不是 verbose;要看版本号请用大写 V。
第二个坑是格式化前没有清理旧签名。U 盘以前做过启动盘,里面可能残留 vfat、ext4 甚至 LUKS 的签名。mkfs.minix 会把自己需要写的部分覆盖掉,但有些旧签名残留位置交叉,会让 blkid 识别出错误结果。现在我在所有格式化操作前都会执行:
bash复制sudo wipefs -a /dev/sdb1
sudo partprobe /dev/sdb
有条件的话再用 lsblk -f /dev/sdb1 确认输出里已经没有任何文件系统类型。这一步能省去后面挂载时的大量困惑。
第三个坑是试图直接格式化整块 /dev/sdb,而不是分区 /dev/sdb1。这样做不是完全不可行,因为老式工具确实允许对整块盘建立文件系统。问题在于,如果你以后想把这块 U 盘重新分区,必须先消除盘首的文件系统签名,还要面对某些系统只识别分区、不识别整盘文件系统的麻烦。最安全的实践永远是:先建分区,再格式化分区。
5.3 fsck.minix与坏块处理
Minix 文件系统的配套检查工具是 fsck.minix,它同样来自 util-linux。实验过程中如果你模拟过掉电、或者直接强制拔盘,再次挂载前可以扫一遍:
bash复制sudo fsck.minix /dev/sdb1
这个工具不采用交互式修复的“一路 yes/no”
