
本文概述
字符设备驱动是Linux驱动开发的入门基础,也是嵌入式Linux面试的必考点。本文以面试问答形式,从驱动框架、设备号、file_operations、模块加载流程、用户空间交互到常见调试技巧,系统梳理字符设备驱动开发的完整知识体系。
核心要点速览
字符设备按字节流读写,用file_operations结构体定义操作接口
主设备号匹配驱动,次设备号区分具体设备实例
module_init/module_exit是驱动模块的入口出口
cdev结构体代表一个字符设备,通过cdev_add注册到内核
用户空间通过设备文件(/dev/xxx)访问字符设备驱动
面试真题
面试官问:请描述一下Linux字符设备驱动的开发步骤。你写过字符设备驱动吗?实现了哪些接口?
面试官考察点
字符设备驱动是Linux驱动的基础题型,面试官想看候选人有没有真正写过驱动,而不是只背概念。考察要点包括:是否理解设备号机制、是否熟悉file_operations各成员、是否知道cdev注册流程、是否了解用户空间如何与驱动交互、是否有实际的调试经验。
核心对话:字符设备驱动知识点详解
面试官可能追问的问题
区别有三点:一是用户空间地址可能无效(未映射),copy_from_user会做地址检查;二是如果触发缺页,copy_from_user能正确处理缺页异常而不是Oops;三是有权限检查,防止非法访问。直接在内核中用memcpy访问用户空间指针,遇到无效地址会直接panic。
mknod是手动创建设备文件,需要知道主从设备号,静态创建,设备拔掉了文件还在。udev是用户空间设备管理守护进程,内核检测到设备插入时通过netlink通知udev,udev自动根据规则创建/dev下的设备文件,设备拔掉自动删除。现代Linux系统都用udev(或systemd-udevd)管理设备节点。
主要手段有:自旋锁(spinlock)用于短时间临界区、中断上下文;互斥锁(mutex)用于可能睡眠的临界区;原子操作(atomic_t)用于简单的计数和标志位;信号量(semaphore)用于有资源计数的场景。选型原则:不睡眠用自旋锁,可能睡眠用互斥锁。同时要注意死锁预防。
最基础的是printk打印日志,配合dmesg查看;复杂点用动态调试(dynamic debug)控制哪些pr_debug输出;还可以用proc文件系统或debugfs导出内部状态;应用层可以用strace跟踪系统调用;内核级调试用kgdb单步调试;oops时根据栈回溯定位问题位置。
容易失分的表达
"驱动直接读写用户空间指针就行"——不了解copy_to/from_user的必要性
把cdev和device搞混,说不清cdev_add和device_create的区别
"主设备号是设备的编号"——概念模糊,不知道匹配驱动这个核心作用
说不出模块加载过程,只知道insmod会加载
面试前准备动作
手写一遍最简字符设备驱动框架,包含module_init、file_operations、cdev注册
整理字符设备、块设备、网络设备三种驱动类型的对比
准备一个你实际写过的字符设备驱动案例,说清实现了哪些功能和遇到的问题
理解内核空间与用户空间的区别,以及为什么不能直接访问用户空间指针
核心关键词
Linux字符设备驱动、file_operations、cdev注册、设备号主设备号次设备号、copy_to_user、copy_from_user、module_init、insmod、设备节点、嵌入式Linux面试












