读《深入Linux设备驱动程序内核机制》

怎么读到这本书的


去年做了一个ZNS SSD的项目,但是主要验证测试都是基于dnvme驱动的。考虑到跟客户的环境可能有偏差,另外dnvme不适合拿来测试存储软件栈,需要在nvme驱动里面实现这个指令集。我作为多年纸上谈兵的linux爱好者,主动抗了这个任务。临阵磨刀找书看:《Linux Device Drivers》虽然经典,但是已经很久没有更新了。有人推荐了这本书,索性就看呗。

感想


看到作者的前言中对本书的定位时,有点想换书了:这本书不是手把手教你写驱动的,而是教给你驱动为什么要写成那个样子,内核提供的各种机制应该怎样取舍。这就像是在policy vs mechanism中,本书重点放在了解释mechanism。转念一想,把机制弄懂了,也不枉磨刀不误砍柴工了。索性就把书看完了。

印象最深的是,本书开篇便用的大篇幅讲module是怎么被加载进内核的:ko文件的结构是什么,内核怎么读这个文件,各个分段都加载到什么地方,符号表是怎么解析的,导出的符号是怎么在内核中处理的,如此等等。对比下大多数驱动的书中对加载module的描述,仅仅是说“modprobe比insmod好用,因为它会帮你解决依赖”。本书“不知道要高到哪里去了”。

可能有人要问了,你读了这大几百页书,不还是modprobe吗?没错。但是,假设某一天你需要写一个比modprobe还好用的工具,这几百页书不就没白读吗?万一真有这一天呢o( ̄︶ ̄)o

说点失望的地方:这本书对block层的讲解里面,虽然覆盖了大量的代码,然而对核心架构的描述有些模糊。当然有可能是我的重点关注在block层上,而本书篇幅所限吧。

备忘


  • GCC别名:__attribute__((alias(#fn_name)))
  • 用nm查看模块的符号表
  • struct file中的private_data用来保存和传递驱动自定义的数据。比如在nvme里面可以存namespace结构。
  • RCU
    • 读者加锁,在临界区中引用数据
    • 写者用自己的新数据去覆盖老数据。但是需要等到老数据没有reference后,所以这里要设置一个callback。
  • irq_thread机制:将中断处理工作放到一个kthread中来做。
  • kobject_uevent: 这个函数实现了将内核中发生的事件通知到用户空间。
  • __must_check: 这个qualifier很有用啊,强制caller来检查返回值。
  • vm_area_struct: 这个结构代表了一段连续的虚拟内存空间,相当于《The Design of the UNIX Operating System》中的region。
  • SetPageReserved: 用这个函数来把物理页面pin住。
  • 访问硬件的地址时,可以用读写屏障来保证顺序。
  • GDB:
    • finish命令:跑完当前函数,并打印退栈信息。
    • @操作符:可用于查看内存addr@len
    • WARN_ON(): 不触发panic,只是打印栈信息。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容