作业 2——驱动 UART¶
- 截止日期: 2023 年 4 月 30 日,23:00
- 此作业为个人完成
作业目标¶
- 巩固设备驱动的知识
- 阅读硬件文档并在文档中追踪所需功能
- 使用中断;在中断上下文中使用非阻塞函数
- 使用缓冲区;同步
- 带参数的内核模块
任务描述¶
编写一个内核模块,实现串口 (UART16550) 的驱动程序。该设备驱动程序必须支持计算机中的两个标准串口, COM1 和 COM2 (0x3f8 和 0x2f8,实际上是两个串口的整个 8 地址范围 0x3f8-0x3ff 和 0x2f8-0x2ff)。除了标准例程 (open, read, write, close) 外,驱动程序还必须支持使用 ioctl 操作 (UART16550_IOCTL_SET_LINE) 更改通信参数。
驱动程序必须使用中断来进行接收和发送,以减少延迟和 CPU 使用时间。 read 和 write 调用也必须是阻塞的。 不符合这些要求的作业将不予考虑。 建议你为驱动程序中每个串行端口的读取例程使用一个缓冲区,并为写入例程使用另一个缓冲区。
当用户空间发起读取操作时,如果内核的读缓冲区为空,没有数据可读,那么阻塞读调用将会等待,直到 至少 有一个字节被读取。同样,当用户空间发起写入操作时,如果内核的写缓冲区已满,没有空间可写,那么阻塞写调用也将会等待,直到 至少 有一个字节被写入。
实现细节¶
该驱动程序以名为 uart16550.ko 的内核模块形式实现。
该驱动程序是字符设备驱动,会根据传递给加载模块的参数,提供不同的功能操作。
- major 参数指定设备必须注册的主设备号。
- option 参数指定驱动程序的工作方式:
- OPTION_BOTH:还会注册 COM1 和 COM2,主设备号由 major 参数给出,次设备号为 0(对应 COM1)和 1(对应 COM2);
- OPTION_COM1:仅注册 COM1,主设备号为 major,次设备号为 0。
- OPTION_COM2:仅注册 COM2,主设备号为 major,次设备号为 1。
- 如果你不熟悉如何在 Linux 中传递参数,请参阅 tldp。
- 默认值为 major=42 和 option=OPTION_BOTH。
COM1 关联的中断号为 4 (IRQ_COM1),COM2 关联的中断号为 3 (IRQ_COM2)
需要使用 header 中的定义来进行特殊操作。
在实现读/写例程时,可以参考大写/小写字符设备驱动程序的 示例;唯一的区别是你需要使用两个缓冲区,一个用于读取,另一个用于写入。
可以使用 kfifo 作为缓冲区。
不需要使用延迟函数从端口读取/写入数据(可以在中断上下文中完成所有操作)。
需要在读/写例程与中断处理例程之间进行同步,以使例程成为阻塞例程;建议使用 等待队列进行同步。
为了使作业正常工作,必须禁用 默认串口驱动程序:
cat /proc/ioports | grep serial 可以检测到默认驱动程序是否存在于定义 COM1 和 COM2 的区域。
为了停用它,必须重新编译内核,可以将串口驱动程序设置为模块,或者完全停用它(虚拟机上已经进行了这个修改)。
- Device Drivers -> Character devices -> Serial driver -> 8250/16550 and compatible serial support.
快速开始¶
你必须从 src 目录中的代码模板开始实现作业。模板中只有一个名为 uart16550.h 的头文件。你需要提供其余的实现。你可以添加任意数量的 *.c 源文件和额外的 *.h 头文件。你还应该提供一个名为 uart16550.ko 的 Kbuild 文件来编译内核模块。请按照 作业仓库 的 README.md 文件 中的说明进行操作。
提示¶
要想增加获得最高分的机会,请阅读并遵循 Linux 内核中描述的 编码风格规范。
此外,使用以下静态分析工具来验证代码:
- checkpatch.pl
$ linux/scripts/checkpatch.pl --no-tree --terse -f /path/to/your/list.c
- sparse
$ sudo apt-get install sparse
$ cd linux
$ make C=2 /path/to/your/list.c
- cppcheck
$ sudo apt-get install cppcheck
$ cppcheck /path/to/your/list.c
扣分规则¶
有关作业扣分的信息可以在“基本说明页面 <https://ocw.cs.pub.ro/courses/so2/teme/general>`__ 上找到。
在特殊情况下(作业通过了测试但不符合要求),以及如果作业未全部通过测试,成绩可能会降低得更多。
提交作业¶
作业将由 vmchecker-next 基础设施自动评分。提交作业将在 moodle 的 课程页面 上与相关作业相关联。你可以在 仓库 的 README.md 文件 中找到提交详细信息。