前言
继续驱动学习小结。字符设备驱动是驱动架构的基础。
字符设备驱动
字符设备的关键数据结构有cdev、file_operations
cdev描述了一个字符设备的信息。file_operations描述了驱动提供给虚拟文件系统的接口。
1 | struct cdev { |
内核提供了对cdev进行操作的接口,主要功能如下:
- cdev_init 关联cdev和file_operations结构
- cdev_alloc 申请一个cdev结构空间
- cdev_add, cdev_del 往系统添加/删除一个cdev描述的字符设备, 一般分别在驱动probe, remove中调用。
- cdev_put 字符模块驱动的解引用, 引用一般在访问接口内部实现。
设备号的申请释放
在调用cdev_add 前,需要调用register_chrdev_region或者alloc_chrdev_region向系统申请设备号。register_chrdev_region是已知主设备号时调用, alloc_chrdev_region则是不提供主设备号,由系统自动分配。
1 | /** |
文件操作
文件操作提供几个接口,主要实现如下的功能:
- llseek 设置文件当前位置
- read 读取文件数据
- write 写入文件数据
- unlocked_ioctl 非读写操作,对应fcntl, ioctl等的接口
- mmap 将设备内存映射到进程空间
- open 打开文件
- poll 询问设备是否可以被非阻塞的读写
- aio_read, aio_write 异步读写操作
读写文件传入的地址都是用户空间的地址,用户空间不能直接访问内核的内存,需要通过copy_from_user, copy_to_user函数来实现数据的复制。在这两个函数中,会判断传入的地址是否是用户空间,防止随意改写了内核空间导致出现不可预料的错误。
在具体的实现中,在open接口中会把设备对应的cdev指针设置到file文件对应的私有数据private_data成员上,这样在其他接口中,可以很方便的从file指针获取到对应的cdev空间,从而访问相应的空间。
用户空间调用
加载驱动模块后,对应的/proce/devices就可以看到对应的设备。这个时候需要手动在/dev目录下,使用mknod创建一个文件跟设备关联起来。
1 | mknod /dev/globalmem c 230 0 # 创建字符设备文件 对应主设备号230, 次设备号 0 |
然后使用echo xxx >
更多
字符设备主要就是一个cdev和file_operation结构。通过申请好设备号,然后注册到系统,手动创建文件关联设备,然后就可以在用户空间访问到驱动接口了。
其他
这周项目组来了几个应届的新人,安排每个老同事带一个新人,结成个师徒关系吧,还宣布带新人也要占工作的40%绩效。说实话,项目组里的基本都是新人,除了两个呆了有一年以上的,其他的老同事也基本上是今年社招入职的,大部分都是跨领域的,有的也只是工作经验吧,也都是在学习的阶段。
嗯,这算是我第二次带新人了,上一次是好多年前了。参照某为的新人试用期机制,以及这几个月我工作的心得,给安排了一些学习要点和minitask,先让他自己看了一周,动手学习并完成给定的任务,并及时输出总结文档。
现在发现的一个最主要问题就是缺少主动沟通,很少提问,需要我这边主动找他才有反馈。要求每天反馈的日报,也没有严格执行,要求整理总结文档也没有。本来担心他日报没啥写的,就让他晚上九点前给日报的,这周五的日报就没发了,相应的进度也有些慢,看来还是压力没有给到位,没有紧迫感,执行力不强。
也许我对新人的期望高了一些,需要转变一下策略,得主动先给他讲一下再安排任务,直接给任务的话,他也不及时沟通确认任务,问一下都是明白了,做起来却不是一回事。
00后都出来工作了,我们这些老骨头也要加强学习了,各方面都得加强。
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。
博客地址: https://fishmwei.github.io
掘金主页: https://juejin.cn/user/2084329776486919