制作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:
- 修改bootloader.asm的org地址,跳过BPB区域(BPB约62字节):
[org 0x7c00 + 62] [bits 16] start: ; 原bootloader代码... - 调整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
相关产品推荐
相关产品推荐

