ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

手写Zeal 8-bit OS设备驱动:从0到1实现键盘与串口驱动的完整教程

手写Zeal 8-bit OS设备驱动:从0到1实现键盘与串口驱动的完整教程 手写Zeal 8-bit OS设备驱动从0到1实现键盘与串口驱动的完整教程【免费下载链接】Zeal-8-bit-OSAn Operating System for Z80 computers, written in assembly项目地址: https://gitcode.com/gh_mirrors/ze/Zeal-8-bit-OSZeal 8-bit OS 是一款专为 Z80 计算机设计的开源操作系统整个内核用汇编语言编写而设备驱动体系正是理解它内部运作的最佳入口。本教程面向新手不要求你熟悉汇编细节只需跟随步骤即可完成键盘驱动与串口驱动从注册到调用的完整开发流程真正搞懂 Zeal 8-bit OS 设备驱动的工作方式。什么是 Zeal 8-bit OS 设备驱动先看驱动结构在 Zeal 8-bit OS 中一个驱动程序本质上是一张函数指针表4 字节的名字 8 个函数地址。内核通过这张表统一调用硬件用户程序则通过 VFS 层访问驱动完全不需要关心底层细节。驱动必须实现的 8 个函数分别是函数作用init开机时初始化硬件返回 0 表示成功read从设备读取数据write向设备写入数据open/close打开 / 关闭设备seek移动读写位置ioctl设置设备参数波特率、输入模式等deinit卸载驱动时清理资源驱动名最长 4 个字符例如SER0串口、KBD0键盘要求全部是字母数字。驱动结构体的完整定义在 drivers_h.asm 中官方驱动文档见 drivers.md。驱动注册的两步走放对位置 返回状态码注册驱动非常简单把上面这张结构体放进名为DRV_VECTORS的 section 即可。开机时内核的驱动管理器会遍历整个 section逐个调用init函数SECTION DRV_VECTORS DEFB SER0 ; 驱动名 DEFW uart_init ; init DEFW uart_read ; read DEFW uart_write ; write DEFW uart_open ; open DEFW uart_close ; close DEFW uart_seek ; seek DEFW uart_ioctl ; ioctl DEFW uart_deinit ; deinit这里有个关键约定如果驱动 A 依赖驱动 BB 的结构体必须放在 A 前面因为依赖关系在编译期就要解析完毕。这个遍历与注册逻辑实现在 drivers.asm 的zos_drivers_init中。init的返回值决定驱动的最终命运返回ERR_SUCCESS0驱动注册成功用户程序可以 open/read/write返回ERR_DRIVER_HIDDEN驱动注册但对外隐藏常用于只给文件系统用的磁盘驱动返回其他错误码注册失败跳过该驱动准备工作获取源码与目录速览动手前先克隆仓库git clone https://gitcode.com/gh_mirrors/ze/Zeal-8-bit-OS项目里与驱动开发最相关的目录kernel/内核本体drivers.asm是驱动管理器target/zeal8bit/Zeal 8-bit 目标机的硬件驱动keyboard.asm与uart.asm是我们的学习样板include/drivers/驱动接口头文件如keyboard_h.asm、video_text_h.asmkernel_headers/sdcc/include/C 语言驱动接口头文件zos_keyboard.h、zos_serial.h实现键盘驱动从裸按键到带缓冲的输入键盘驱动位于target/zeal8bit/keyboard.asm它的核心职责是读取按键 → 处理 → 存入 FIFO 缓冲区 → 供用户程序 read。第一步init 中注册为标准输入keyboard_init只做三件事初始化底层键盘实现PS/2 或并口、清空 FIFO、调用zos_vfs_set_stdin把自己注册为系统默认标准输入。这样 shell 和所有程序都能直接读取键盘无需关心具体硬件。第二步用 ioctl 实现三种输入模式键盘驱动对外只提供一个 ioctl 命令KB_CMD_SET_MODE用于切换输入模式定义见 keyboard_h.asmRAW 模式不做任何处理按下/松开原样上报。比如按下左 Shift 再按 A程序收到0x93左 Shift和0x61小写 aCOOKED 模式默认按键先经过处理再存入缓冲区支持大小写、方向键、退格、Tab 等遇到回车才刷新HALFCOOKED 模式介于两者之间遇到不支持的键会填入缓冲区并返回ERR_SPECIAL_STATE另外还有阻塞/非阻塞读取标志。C 语言下可通过 zos_keyboard.h 直接使用这些常量例如设置原始模式ioctl(fd, KB_CMD_SET_MODE, KB_MODE_RAW | KB_READ_NON_BLOCK);第三步read 返回按键码在 RAW 模式下read 返回的是按键码普通字符直接是 ASCII如a 0x61特殊键使用 0x80~0xFC 的扩展码如KB_LEFT_SHIFT 0x93。松开按键时前面会带一个KB_RELEASED0xFE前缀0x61 [...] 0xFE 0x61 A ... A 已松开实现串口驱动UART 驱动的完整骨架串口驱动target/zeal8bit/uart.asm是另一个经典范例它的init除了初始化波特率外还承担一个重要任务当系统配置了UART 作为标准输出时调用zos_vfs_set_stdout把自己挂到 stdout 上并发送 ANSI 转义序列清屏、设置光标。也就是说串口驱动可以同时扮演显示驱动非常适合没有屏幕的裸机调试场景。串口的 ioctl 命令与键盘完全不同定义在 zos_serial.h包括SERIAL_CMD_SET_ATTR/SERIAL_CMD_GET_ATTR设置/读取属性如 RAW 模式SERIAL_CMD_SET_BAUDRATE/SERIAL_CMD_GET_BAUDRATE设置/读取波特率SERIAL_SET_TIMEOUT/SERIAL_SET_BLOCKING超时与阻塞控制syscall 层如何把参数传递给驱动的 read/write规则与系统调用表完全一致可参考 syscalls.md。如果你想写一个自己的串口小工具romdisk 里的 uart.asm 是现成的用户态参考。编译测试让驱动跑起来Zeal 8-bit OS 使用 Kconfig Makefile 构建。驱动是否作为标准输入/输出由目标机配置决定可在configs/zeal8bit/os.conf等配置文件中调整例如配置CONFIG_TARGET_STDOUT_UART后串口会自动成为标准输出键盘默认注册为标准输入无需额外配置构建整个系统make烧录到模拟器或真机后开机日志会打印类似Driver: SER0 init success的信息这正是zos_drivers_init逐一遍历DRV_VECTORS的成果。之后你在 shell 里输入字符、通过串口收发数据背后都是我们刚刚拆解的那套驱动机制在运转。新手常见问题速查Q驱动名字冲突了怎么办内核会返回ERR_ALREADY_EXIST并跳过该驱动所以命名前先查重SER0、KBD0这类有编号的名字最稳妥。Q我的驱动需要独占硬件不想暴露给用户程序让init返回ERR_DRIVER_HIDDEN即可驱动仍可用但对外隐藏。Q键盘和串口同时注册会不会抢占不会。一个通过zos_vfs_set_stdin成为标准输入一个通过zos_vfs_set_stdout成为标准输出VFS 层各司其职。总结驱动开发其实只有三步回顾全文Zeal 8-bit OS 设备驱动开发可以浓缩为三步实现 8 个函数不用的返回ERR_NOT_SUPPORTED即可把结构体放进DRV_VECTORSsection在init中返回正确的状态码必要时调用zos_vfs_set_stdin/stdout挂载为标准设备掌握了键盘驱动与串口驱动这两个样板你就已经具备了读写 Zeal 8-bit OS 内核驱动代码的能力。下一步不妨尝试阅读 video.asm显示驱动或 compactflash.asm存储驱动把同样的方法论应用到更多硬件上。祝你在 Z80 的世界里玩得开心【免费下载链接】Zeal-8-bit-OSAn Operating System for Z80 computers, written in assembly项目地址: https://gitcode.com/gh_mirrors/ze/Zeal-8-bit-OS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表