如何将Zeal 8-bit OS移植到新硬件?完整移植指南与避坑清单
【免费下载链接】Zeal-8-bit-OSAn Operating System for Z80 computers, written in assembly项目地址: https://gitcode.com/gh_mirrors/ze/Zeal-8-bit-OS
Zeal 8-bit OS 是一个完全用 Z80 汇编语言编写、专为 8 位计算机设计的轻量级操作系统。很多复古电脑爱好者和自制硬件玩家都想把它跑在自己的 Z80 机器上,却不知道从何下手。这篇Zeal 8-bit OS 移植指南将带你从零开始,一步步把内核、驱动和启动流程迁移到新硬件上,并附上社区踩过的真实坑位清单,帮你少走弯路。整个内核代码不到 8KB,移植的核心不是改内核,而是写驱动、配内存、改链接脚本。
移植前必读:先搞清楚你的硬件属于哪种模式 🧭
Zeal 8-bit OS 提供两种内核运行模式,移植前必须先判断你的硬件属于哪一种,这决定了后续所有工作方向。
MMU 模式:需要 4 个可切换的 16KB 虚拟页
内核依赖 MMU(内存管理单元),将 Z80 的 64KB 地址空间划分为 4 个 16KB 虚拟页:
- Page 0(0x0000–0x3FFF):存放内核代码,绝对禁止切换,内核二进制不能超过 16KB;
- Page 1(0x4000–0x7FFF):用户程序加载并执行的区域,程序从这里开始链接;
- Page 2:用户程序的扩展 RAM;
- Page 3:内核与驱动的数据区,系统调用时会被临时换回。
如果内存映射细节还不清楚,建议先阅读项目文档 memory-mapping.md,它把四种页的职责和切换时机讲得很透彻。
no-MMU 模式:无内存管理器的兼容方案
没有 MMU/Memory Mapper 的机器(如 TRS-80 Model I)也不用灰心,内核提供了 no-MMU 模式:ROM 放在前 16KB(0x0000–0x3FFF),其余 48KB 最好是 RAM。你需要在配置中指定两个关键地址:
KERNEL_STACK_ADDR:内核栈底;KERNEL_RAM_START:内核 RAM 起始地址,建议至少预留 3KB(当前内核 BSS 约 1KB)。
最快移植方法:五步把 Zeal 8-bit OS 跑起来 🚀
官方支持的 supported-targets.md 明确给出了移植流程,核心就五步,跟着做就行。
第一步:在 Kconfig 中登记你的目标硬件
打开仓库根目录的 Kconfig 文件,仿照现有条目(zeal8bit、trs80、agon)添加config TARGET和config COMPILATION_TARGET选项。这一步的作用是让内核构建系统认识你的硬件。
第二步:创建 target 目录与 unit.mk 构建文件
在target/下新建一个目录,目录名必须与 Kconfig 中TARGET选项的值完全一致。目录内创建unit.mk,通过四个 make 变量声明构建内容:
SRCS:需要汇编的源码文件(驱动是必须的);INCLUDES:头文件目录;PRECMD:内核构建前执行的命令(如生成 romdisk);POSTCMD:内核构建完成后执行的命令(如拼接最终 ROM 镜像)。
参考现有目标的unit.mk,很快就能照猫画虎写出来。
第三步:实现目标驱动并注册到 VFS
驱动本质是一个包含名字和 8 个例程地址(init、read、write、open、close、seek、ioctl、deinit)的结构,放在DRV_VECTORS段中。驱动之间的依赖必须在编译期解决,比如驱动 A 依赖 B,B 的结构就必须排在 A 前面。驱动注册与初始化细节可以查阅 drivers.md,里面给出了完整的汇编示例。
第四步:编写 mmu_h.asm 适配内存
MMU 模式下,内核会包含一个mmu_h.asm文件来操作内存映射。你需要参考target/zeal8bit/include/mmu_h.asm的写法,把页切换、地址翻译等底层操作映射到你的硬件实现上。
第五步:配置启动磁盘与 stdout 输出
移植能否成功"跑起来",最后看两件事:
- 至少有一个磁盘驱动能挂载包含
init.bin的文件系统(内核启动时会加载并执行它,路径由CONFIG_KERNEL_INIT_EXECUTABLE配置,默认A:/init.bin); - 至少有一个驱动注册为标准输出(调用
zos_vfs_set_stdout),否则连开机横幅都看不到。
避坑清单:老手也容易翻车的 5 个坑 ⚠️
坑 1:Page 0 被换页导致内核崩溃
MMU 模式下第一页存放内核代码,任何情况下都不能切换。如果用户程序执行期间发生换页再触发 syscall,会直接未定义行为。务必在驱动和链接脚本里把内核段固定在第一页。
坑 2:用户程序参数指向 Page 3 引发冲突
系统调用时内核会把 RAM 页映射到 Page 3。如果用户程序参数恰好指向这一页,内核会把该页重映射到 Page 2,并自动把指针减去 16KB。理解这个机制,才能避免驱动写参数时地址错乱。
坑 3:中断处理里乱用备用寄存器
Z80 的备用寄存器(AF'、BC' 等)只允许在中断处理程序中使用。普通驱动代码若必须使用,记得di禁用中断,用完再ei恢复,且不要假设备用寄存器的值在两次中断之间保持不变。寄存器使用规则详见 kernel.md。
坑 4:内核 RAM 预留不足
no-MMU 模式下,内核 BSS 段、驱动数据、内核栈都挤在KERNEL_RAM_START到KERNEL_STACK_ADDR之间。BSS 约 1KB,栈建议 1KB,整体至少留 3KB 才够稳妥,否则驱动一加载就爆内存。
坑 5:romdisk 与 init.bin 拼装顺序错误
构建顺序是:先编译init.bin→ 打包成 romdisk → 再拼接内核镜像。参考现有配置(如 configs/zeal8bit/os.conf)的CONFIG_ROMDISK_OFFSET_PAGES等选项,确保最终二进制能正确烧录到 ROM/NOR Flash。
实战案例:三个移植参考对象 💡
想快速上手,最聪明的做法是研究官方已有的三个移植目标:
- Zeal 8-bit Computer(MMU 模式):最完整,支持 UART、视频文本模式、PS/2 键盘、SD 卡与 CompactFlash,配置文件在 configs/zeal8bit/os.conf;
- TRS-80 Model I(no-MMU 模式):最简单的移植范例,只实现了一个文本模式视频驱动,配置见 configs/trs80/os.conf;
- Agon Light(no-MMU 模式):基于 eZ80,功能接近完整,支持彩色文本、VBLANK 定时中断、ROMDISK 只读挂载,配置见 configs/agon/os.conf。
最后的建议:从小而美的移植开始 🎯
别一上来就追求功能齐全。官方对移植的最低要求是:能显示开机横幅。先跑通最小闭环(内核 + 视频驱动 + 磁盘驱动 + init.bin),再逐步加键盘、文件系统、更多外设驱动。
另外记住:用户程序的入口地址默认为 0x4000(可由KERNEL_INIT_EXECUTABLE_ADDR配置),运行时通过 DE/BC 寄存器接收参数(DE 指向参数字符串,BC 为长度),这些 ABI 约定在 user-space.md 中有完整说明,移植驱动和测试程序时都用得上。
如果你的机器内存布局符合要求,那就动手吧——克隆仓库后,打开 Kconfig 开始你的第一次 Zeal 8-bit OS 移植之旅。祝你一次点亮,跑出属于自己的开机横幅!🎉
【免费下载链接】Zeal-8-bit-OSAn Operating System for Z80 computers, written in assembly项目地址: https://gitcode.com/gh_mirrors/ze/Zeal-8-bit-OS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考