You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

制作GoldOS镜像时mcopy报错‘Cannot initialize ::’求助

自制OS构建问题:mcopy无法识别DOS媒体

我用以下Makefile构建自制操作系统GoldOS:

ASM = nasm

.PHONY: floppyimage kernel bootloader everything

goldos: everything
    qemu-system-i386 -fda build/goldos.img

norun: everything

everything: floppyimage kernel bootloader build

floppyimage: build/goldos.img

build/goldos.img: build bootloader kernel
    dd if=/dev/zero of=build/goldos.img bs=512 count=2880
    mkfs.fat -F 12 -n "GOLDOS" build/goldos.img
    dd if=build/bootloader.bin of=build/goldos.img conv=notrunc
    mcopy -i build/goldos.img build/kernel.bin "::kernel.bin"

bootloader: build/bootloader.bin

build/bootloader.bin: build bootloader/bootloader.asm
    $(ASM) bootloader/bootloader.asm -fbin -obuild/bootloader.bin

kernel: build/kernel.bin

build/kernel.bin: build kernel/kernel.asm
    $(ASM) kernel/kernel.asm -fbin -obuild/kernel.bin

clean:
    rm -r build

build:
    mkdir -p build

执行时出现错误:

dd if=/dev/zero of=build/goldos.img bs=512 count=2880
2880+0 records in
2880+0 records out
1474560 bytes (1.5 MB, 1.4 MiB) copied, 0.00605087 s, 244 MB/s
mkfs.fat -F 12 -n "GOLDOS" build/goldos.img
mkfs.fat 4.2 (2021-01-31)
dd if=build/bootloader.bin of=build/goldos.img conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 5.852e-05 s, 8.7 MB/s
mcopy -i build/goldos.img build/kernel.bin "::kernel.bin"
init :: non DOS media
Cannot initialize '::'
::kernel.bin: Success
make: *** [makefile:18: build/goldos.img] Error 1

bootloader.asm包含引导签名但缺少FAT12 BPB(BIOS参数块),kernel.asm为空。回滚bootloader修改、清理输出文件后问题仍存在。


问题根源

mkfs.fat会在镜像的第一个扇区写入FAT12文件系统的BPB(包含文件系统识别信息),但随后你用dd将自己的bootloader(不含BPB)覆盖了整个第一个扇区,导致文件系统的关键识别数据丢失,mcopy无法识别这是合法的DOS媒体。

解决方案

方法1:给Bootloader添加FAT12 BPB

在bootloader.asm最开头添加符合1.44MB软盘的FAT12 BPB,确保参数和镜像匹配:

; FAT12 Boot Parameter Block (BPB)
jmp short start
nop

OEMIdentifier     db 'GOLDOS  '   ; 8字节OEM标识
BytesPerSector    dw 512          ; 每个扇区字节数
SectorsPerCluster db 1            ; 每簇扇区数
ReservedSectors   dw 1            ; 保留扇区数(包含引导扇区)
FATCount          db 2            ; FAT表数量
RootDirEntries    dw 224          ; 根目录条目数
TotalSectors      dw 2880         ; 总扇区数(1.44MB软盘)
MediaType         db 0xF0         ; 媒体类型(1.44MB软盘)
SectorsPerFAT     dw 9            ; 每个FAT表扇区数
SectorsPerTrack   dw 18           ; 每磁道扇区数
Heads             dw 2            ; 磁头数
HiddenSectors     dd 0            ; 隐藏扇区数
TotalSectorsBig   dd 0            ; 大扇区数(当TotalSectors<65536时为0)

; 扩展BPB
DriveNumber       db 0x00         ; 驱动器号(0x00=软盘)
Reserved          db 0            ; 保留
BootSignature     db 0x29         ; 扩展BPB签名
VolumeID          dd 0xDEADBEEF   ; 卷ID
VolumeLabel       db 'GOLDOS    ' ; 11字节卷标
FileSystem        db 'FAT12   '   ; 8字节文件系统类型

[org 0x7c00]
[bits 16]

start:
    ; 原bootloader代码...

然后调整Makefile的镜像构建步骤,改用mtools的mformat格式化(兼容性更好):

build/goldos.img: build bootloader kernel
    dd if=/dev/zero of=build/goldos.img bs=512 count=2880
    dd if=build/bootloader.bin of=build/goldos.img conv=notrunc
    mformat -i build/goldos.img -f 1440 -v GOLDOS ::
    mcopy -i build/goldos.img build/kernel.bin "::kernel.bin"

方法2:保留mkfs.fat生成的BPB

如果不想修改bootloader的BPB,可以只写入bootloader代码部分,不覆盖mkfs.fat生成的BPB:

  1. 修改bootloader.asm的org地址,跳过BPB区域(BPB约62字节):
    [org 0x7c00 + 62]
    [bits 16]
    
    start:
        ; 原bootloader代码...
    
  2. 调整Makefile的写入步骤,只把bootloader写入到扇区偏移62字节处:
    build/goldos.img: build bootloader kernel
        dd if=/dev/zero of=build/goldos.img bs=512 count=2880
        mkfs.fat -F 12 -n "GOLDOS" build/goldos.img
        dd if=build/bootloader.bin of=build/goldos.img bs=1 seek=62 conv=notrunc
        mcopy -i build/goldos.img build/kernel.bin "::kernel.bin"
    

额外检查

  • 执行make clean彻底清理build目录,避免旧文件残留
  • 确保mtools版本为最新,避免兼容性问题

内容的提问来源于stack exchange,提问作者Golden Star

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:44:54