Chinaunix

标题: 学习Linux内核和驱动开发有终南捷径吗?欢迎来辩! [打印本页]

作者: shenlanyouyu    时间: 2015-08-15 11:09
标题: 学习Linux内核和驱动开发有终南捷径吗?欢迎来辩!
获奖名单已公布:http://bbs.chinaunix.net/thread-4188427-1-1.html

话题背景
      这是一个连阅读都被碎片化的时代,在这样一个时代,人们趋向于激进、浮躁。内心的不安宁使我们极难静下心来研究什么。许许多多的Linux工程师,他们的简历书写着“精通”Linux内核,有多年的工作经验,而他们的“精通”却只是把某个寄存器从0改成1,从1改成0的不断重复;许许多多的Linux工程师终日埋头苦干,敲打着自己的机器和电路板,却从未冷静下来思考,并不断重构和升华自己的知识体系。
      Linux内核的版本更新达上千个,代码规模不断增长,平均每个版本的新增代码有4万行左右。在源代码的10个主要子目录中,驱动程序的代码量呈线性增长趋势。Linux各个子系统之间的关系错综复杂,系统整体规模和复杂性分别呈超线性和接近线性增长趋势,drivers和arch等模块的快速变化是引起系统复杂性增加的主因。设备驱动程序是连接计算机软件和硬件的纽带和桥梁,开发者在嵌入式操作系统的开发移植过程中,有将近70%~80%的精力都用在了驱动程序的开发与调试方面。这就对设备驱动程序开发人员提出了极高的要求。开发者不仅要同时具备软件和硬件的知识和经验,而且还要不断地学习、更新自己,以便跟上嵌入式系统日新月异的发展。在代码量最多的驱动程序中,有什么规律可循?最根本的又是什么?学习Linux内核和驱动开发有捷径吗?欢迎大家参与讨论,分享Linux内核和驱动开发的经验。


讨论话题
从以下话题中任选一个或多个话题参与讨论,这次讨论的话题内容不限于下面罗列的话题。
1. 分享Linux内核学习和驱动开发的经验。
2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。
4. 您深入研究过Linux设备驱动模型,关注过Linux内核驱动的设计思想吗?
5. Android系统是基于Linux内核的,传统的Linux驱动开发和Android驱动开发有什么区别?


讨论时间
2015-08-17至2015-09-15


活动奖励
活动结束后将选取4名讨论精彩的童鞋,每人赠送一本《Linux设备驱动开发详解:基于最新的Linux 4.0内核》图书作为奖励。


奖品简介
   
作者: 宋宝华   
丛书名: 电子与嵌入式系统设计丛书
出版社:机械工业出版社
出版日期:2015 年8月
开本:16开
版次:1-1


内容简介:
     历时8年,三次重构,内窖愈加炉火纯青。全部代码更新至全新的Linux4.0版本。全面讲解ARM Linux新版本内核架构,如设备树等。不仅仅注重知识和程序的讲解,更注重程序的思想、演变、架构和算法。
      本书首先介绍Linux设备驱动的基础。第1章简要地介绍了设备驱动,并从无操作系统的设备驱动引出了Linux操作系统下的设备驱动,介绍了本书所基于的开发环境。第2章系统地讲解了Linux驱动工程师应该掌握的硬件知识,为工程师打下Linux驱动编程的硬件基础,详细介绍了各种类型的CPU、存储器和常见的外设,并阐述了硬件时序分析方法和数据手册阅读方法。第3章将Linux设备驱动放在Linux 2.6内核背景中进行讲解,说明Linux内核的编程方法。由于驱动编程也在内核编程的范畴,因此,这一章实质是为编写Linux设备驱动打下软件基础。
      其次,讲解Linux设备驱动编程的基础理论、字符设备驱动及设备驱动设计中涉及的并发控制、同步等问题。第4、5章分别讲解Linux内核模块和Linux设备文件系统;第6~9章以虚拟设备globalmem和globalfifo为主线,逐步给其添加高级控制功能;第10、11章分别阐述Linux驱动编程中所涉及的中断和定时器、内核和I/O操作处理方法。
      接着,剖析复杂设备驱动的体系结构以及块设备、网络设备驱动。该篇讲解了设备与驱动的分离、主机控制器驱动与外设驱动的分离,并以大量实例(如input、tty、LCD、platform、I2C、SPI、USB等)来佐证。其中第12章和第17章遥相呼应,力图全面地展示驱动的架构。Linux有100多个驱动子系统,逐个讲解和学习都是不现实的,授人以鱼不如授人以渔,因此我们将更多的焦点放在了架构讲解方面,以便读者可以举一反三。


样章试读:
文前.pdf (1.46 MB, 下载次数: 209)
1-3z.txt (114.01 KB, 下载次数: 132)

shupi.jpg (33.22 KB, 下载次数: 382)

shupi.jpg

作者: dreamice    时间: 2015-08-17 15:31
支持
作者: niao5929    时间: 2015-08-17 16:37
先支持意向,等想好了再写讨论内容,不过我个人理解LINUX内核很像进化中的生命体,同时它的模块化理念非常高级,每一个层次都在不断的进化和完善,同时不会影响全局的使用。
作者: heguangwu    时间: 2015-08-18 09:05
没深入搞过,乱谈一番:
1. 分享Linux内核学习和驱动开发的经验。
    驱动开发其实有一定的模式,主要是要了解硬件的特性以及如何对接到驱动的函数中,还有就是要适应内核编程的环境以及调试的方法

2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
    难点就是后面的调试

3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。
    每一个子系统都巨大无比,没那个能力去完全搞明白  

4. 您深入研究过Linux设备驱动模型,关注过Linux内核驱动的设计思想吗?
    个人理解设计思想就是回调函数,给一个API让你注册,后面通过注册ID找到对应的回调函数进行处理

5. Android系统是基于Linux内核的,传统的Linux驱动开发和Android驱动开发有什么区别?
    Android的驱动就是要对C语言再进行一层包装,采用类似JNI/JNA机制向Android上层提供Java的API,这样厂商可以决定驱动的主要部分在C还是Java实现
作者: niao5929    时间: 2015-08-18 20:45
本帖最后由 niao5929 于 2015-08-18 20:45 编辑


1. 分享Linux内核学习和驱动开发的经验。
    读代码,编译内核的初级级别,自己没社么经验

2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
    难点就是建模和对底层硬件的深入了解

3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。
    linux 模块化的设计最让人感到方便,这样的设计可以非常方便的进行模块的替换和组装,这也是LINUX非常有应用广度的一个方面。

4. 您深入研究过Linux设备驱动模型,关注过Linux内核驱动的设计思想吗?
   感觉LINUX因为自由和开源的关系,她的进化非常类似与生命的特点。自由开源软件可以承载更多新思想和新技术。Linux内核自4.1开始支持不停机的热升级。这必然涉及到驱动的动态更新问题。这些新特性总是让好奇的我想看个究竟。

5. Android系统是基于Linux内核的,传统的Linux驱动开发和Android驱动开发有什么区别?
    Android总感觉似乎需要用到很多JAVA的技术,而目前JAVA确实已经被ORACLE搞得非常的让人担忧。我觉得程序员或者编程爱好者都应该学习更自由和开放的GO、PYTHON、D等等这些纯的自由开源软件,还是那句话:自由开源软件可以承载更多新思想和新技术。
作者: ilikerome    时间: 2015-08-19 07:35
cool,mark,
不过还是不想做驱动,还是搞搞网络编程吧。
作者: kartorz    时间: 2015-08-19 11:01
本帖最后由 kartorz 于 2015-08-20 09:44 编辑

1. 分享Linux内核学习和驱动开发的经验。

捷径没有,但是有合理的方法。

1)  首先,需要熟悉操作系统的设计与实现,推荐大家看 MINIX作者的那部书,同时把MINIX的kernel代码研读一下。 不然,你不知道操作系统都有哪些模块, 不知道操作系统要做些什么事情,提供什么功能。
      简单地说,操作系统首先要驱动 CPU,然后提供那几大管理(中断,进程,内存),实现一,两百个系统呼叫,提供驱动接口。
      
2)  去intel的官网,找一下 Intel® 64 and IA-32 Architectures Software Developer’s Manual , 了解一下 CPU的架构,工作模式,底层的编码。否则, 你不知道 gdt, ldt,  page table, 实地址,保护模式,timer等中断都是什么东西,为什么操作系统要这样来设置寄存器。
      这块基本上全是汇编语言,对CPU的初始化,寄存器设置,手册上面都有严格的时序要求。 哪些操作需要屏蔽中断,哪些需要在一个指令周期完成等等。

有了上面的基础后,大概知道一个操作系统大概要做些什么事情, 如何驱动底层的 CPU,这个时候阅读 linux的kernel代码,事半功倍。

kernel 分为两个模块:一个是 core : 驱动cpu, 中断,进程,内存几大管理, 提供系统呼叫;   另一个是driver,  驱动设备工作。 linux的driver 都是有架构的,不需要从底层做起。 driver的架构大概就是 char, block, net, video, audio, usb, 等等。 别看操作系统的代码量大,其实,把driver 占了估计 90%的代码量, 这些都是不需要去看的。  driver 框架的设计,也就是 微内核 与 宏内核的区别。

阅读过程中,观其大略即可,主要了解整个结构,以及程序的流程。 如: 系统呼叫的调用, 追一个就可以了。—— 看看,操作系统如何捕捉软中断, 根据中断号,dispatch到相应的服务程序,如何 保存现场, 完成后,又回到用户态。 系统呼叫调用,核心 就是 dispatch的流程。 追完一支系统呼叫,其它的大概就知道怎么回事了。  driver 也就一样的, 找个简单的驱动看看, 从驱动层一直到驱动的架构,流程清楚就可以了。 如 char 设备驱动, 追一下 register 以后, 驱动框架如何 把该设备放入 list,当有用户请求的时候,它又如何 查找到 相应的设备,调用 相应的操作函数。 一路下来,流程大概知道就可以了。

不建议阅读, 毛德操的 linux内核源码分析 之类的书, 会让读者一头雾水。 正确的方法应该是, 先了解相应的背景知识后,再来阅读源码。 举个例子,你想了解 ext4的文件系统驱动代码,首先你得去查资料,搞清楚 ext4文件系统是怎么回事,再来阅读代码。 之前,推荐初学者 先 阅读 操作系统设计实现, intel的编程手册,就是这个道理。 只有了解了背景,再阅读源码时,一切都 迎刃而解了。 不推荐 毛德操的书也是个道理,书里面告诉你,代码一会跳到这里,一会又call back到注册的函数,一会又调用了什么,只见树木,而不见森林。


作者: shenlanyouyu    时间: 2015-08-19 13:26
回复 7# kartorz


    分享有干货,感谢分享。
作者: openspace    时间: 2015-08-19 14:28
回复 1# shenlanyouyu


临时想起一些说一下吧:


1. 分享Linux内核学习和驱动开发的经验。

内核学习

Linux 内核功能越来越完善,如果没有充裕的时间,深入内核并不是很现实。所以建议先读一本内核的书,
第一遍是读,会读的很迷糊;之后反省一下,然后再浏览一下;可以想象一个 OS 是如何运行的,这样可以不
陷入 Linux 内核的细节;最后可以深入自己感兴趣或者需要的那一子系统

        推荐 《Linux Kernel Development》

即便是子系统,也是很庞大的。一个省力的方式是网上搜一些相关的文章,便于快速了解这个子系统的运作;
然后结合代码,形成自己的认知,最后做一下总结。如果仅仅是快速了解某一子系统的运作,可以参考一些早期
代码的注解书籍,再深入的时候看看最新的代码实现

对内核的认知是一个反复的过程,一开始并不完善,可能需要反复纠正。不要陷入这种纠错中;而是以后继续
使用和学习过程中,发现了没有弄清楚的地方再深入,毕竟 Linux 内核是不断变化的

还有一个很好的方式是,从系统调用入手,现在这方面的数据不少,而且对系统调用的语义都有讲解,这样可以
间接了解 Linux 系统的一些概念。对系统调用熟悉了,可以根据系统调用的执行过程,来大体了解内核的一个
运作过程;但是跟踪系统调用的时候要注意抓主线,现在内核系统很复杂,一些 code path 上可能会涉及多个
子系统,可以从名字上猜测它们是干什么的,不需要深入,否则会发现精力完全被分散掉了

学习 Linux 内核,一个很重要的是抽象的能力,所谓的抽象这里仅仅是指分清接口和接口的实现。因为 Linux
内核子系统很多,有很多子系统相互渗透,这样 code path 看上去很复杂。阅读代码的时候,为了排除干扰,
需要分清哪些是自己需要看的,哪些是其它子系统的接口,对于其它子系统的接口,先当作它们功能完善不会
出问题好了,这样可以关注重点;打个比方,一个应用程序的代码可能量很大,比如一个 apache 项目,它
包含很多组件,有时候阅读代码的时候会看到不同组件的 API,深入看相关组件实现并不现实,这时候分清主次
对于代码的阅读就很有帮助了,总不能看到了 malloc 就要先把它的实现弄清楚吧,系统调用多者呢

推荐书籍
        OReilly.Linux.System.Programming.2nd.Edition
        The.Linux.Programming.Interface


驱动开发

一直围绕服务器做,接触的比较多的是网卡驱动。最开始想着从上到下,好好学习协议栈,后来发现内容太多,
进展太慢。后来参考一些驱动开发方面的书籍,把驱动独立开,使用内核提供的接口,就类似写应用的时候很多
情况下只需要了解系统接口和库函数的原型描述而不需要继续深入一样。这样把自己从内核复杂的实现细节中解
放出来,可以重点看网卡的特性部分;之后可以再深入了解设备的运作过程,比如网卡的收发包在协议栈中的
位置和运作

个人感觉如果工作中能接触驱动开发最好,否则很多情况下,有的设备并不常见,比如 Infiniband 卡

现在民用设备越来越广泛,可以选择自己感兴趣而手头又容易有的设备进行研究,比如无线网卡、wifi 等
驱动开发,一定要先专注一个设备,从头到尾熟悉一遍,然后总结驱动开发是怎样的、驱动是如何关联到系统中
的、Linux 采用什么样的分层模式来提供对多种多样设备的支持,如类似 VFS 一样的抽象分层

推荐
        linux device driver, 3rd edition
        Linux设备驱动开发详解



2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?

Linux 内核对各种设备的驱动开发提供了完善的框架支持,对应某个驱动,把对外的接口弄清楚就可以了。打个
比方,一个设备可能在不同的 OS 上需要支持,比如 FreeBSD/Windows 等,每个 OS 都有自己定义的接口,
设备的驱动定义好与这些 OS 接口的连接,剩下的就是设备本身的特性管理以及驱动接口中对设备管理函数的调
用了,比如寄存器访问、配置管理、缓冲区管理、数据收发等,比较重要的中断和同步的控制,要避免数据处理的
时候的死锁。

比如网卡驱动,基本的要求是提供内核需要的接口,这样网卡驱动才能挂接到系统中,剩下的就是接口需要调用
网卡驱动的内部函数,来对网卡进行控制、数据收发和管理等

Linux 支持的设备种类繁多,不可能所有都掌握,某一子系统也只能是熟悉,因为同类设备还有许多自由的特性。
写驱动的步骤可以概括为:
        1) 阅读设备规范,对设备的运行机理有所了解
           为了减少干扰,不考虑要支持的 OS,独立与 OS 考虑基本的功能如何实现
        2) 参考同类设备在 Linux 内核中的驱动架构
        3) 提供基本的 Linux 设备驱动接口和实现设备的基本功能,比如网卡收发小数据量
        4) 在性能上逐步提示,比如网卡传输的数据量加大、中断及时处理、避免死锁等
        5) 对边界条件进行完善,网卡上就是对一些特殊大小的数据包传输完善等
        6) 对设备进行更高级控制的支持,比如网卡支持 ethtool 等工具
        7) 反复调试、改进和优化



3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。

        每一个子系统都巨大无比,而且涉及各种硬件规范,很难去搞明白所有。只能是遇到问题的时候,
        能对某一部分深入下去。之前了解过 SCSI 的架构,最上层的抽象,中间层的桥梁,最底层的设备
        驱动控制
        如果仅仅是做 driver 的工作,可以把精力放在设备特性上,Linux 内核部分只需要了解驱动
        接口和同步、内存管理等基本功能



4. 您深入研究过Linux设备驱动模型,关注过Linux内核驱动的设计思想吗?

        Linux 设备驱动模型是从分类的角度来看待设备,分类是多维的,所以 /sys 下也是多个目录
        另外,设备驱动模型给出了系统中设备布局信息,比如根据总线地址可以定位对应的设备目录等

        Linux 内核驱动可以都是遵循一个逐层抽象的架构:
                最上层的抽象层便于系统软件的访问,
                中间层的实现硬件协议细节,同时提供上下两层连接的接口,
                对于最下层的 driver 来说就是要定义底层驱动要实现的接口和实际的设备控制
        由于 Linux 内核各类驱动的框架支持,driver 可以更加关注设备本身的特性
       


5. Android系统是基于Linux内核的,传统的Linux驱动开发和Android驱动开发有什么区别?

        传统的 Linux 内核驱动开发,只需要定义好 Linux 需要的驱动接口就好了,之后
        专注与设备本身的特性
        而 Android 驱动开发,需要将设备操作接口继续封装,提供上层使用的 Java API;
        driver 部分可以使用 C 代码,一些更复杂的操作可以用 Java 实现,然后 driver
        提供对复杂操作的接口支持
        一个很重要的方面是功能的分离定义,比如哪些是 driver 实现的,哪些是上层实现的,
        它们之间的接口是怎样的,定义好这些,就可以按照传统 driver 的实现方式来做了;
        从某种程度上,可以看作是传统 driver 跟相关 tools 转换成了 Android driver
        和上层 Java 接口



作者: lyl19    时间: 2015-08-19 18:43
本帖最后由 lyl19 于 2015-08-19 18:44 编辑

回复 1# shenlanyouyu

我觉得设备驱动 开发对kernel的掌握还算是次要的,最重要的是对arch, 以及硬件的理解。
印象中发生了太多的case, 与arch相关的,比如说memory barrier,都要花比较大的气力解决。
而与硬件相关的,比如说DMA hung之类的,中断不触发之类的,这个时候,单纯从软件来很难解决,一般都是WAR,比如复位啥的。但如果有机会去读到硬件的RTL, 这个时候你对这类的问题将不再是恐惧,而是心里会有数。

所以个人认为,设备驱动的编写绝不是单纯软件的事情,必须要熟悉该设备的RTL,如果你能够得到的话。





   
作者: 流氓无产者    时间: 2015-08-20 09:35
其实和app没啥区别
重点两个
机制和实现
机制大概就是说的所谓模型,逻辑上来说,我们要完成的事物,如何表达成机器的流程
实现就是具体到某个类型某种硬件,该如何去读取控制它的状态和流程

抽象的思想比细节的实现更重要
现实中却往往卡在某个实现上
作者: zymh_zy    时间: 2015-08-20 09:38
迫于生计,没法静下心来研究Linux内核和驱动开发这么深入的东西 。。。。
作者: niao5929    时间: 2015-08-20 10:31
linux kernel 4.0之后的 hotpath很高级的样子。很想了解她的细节和具体实现技术。呵呵。以后LINUX系统是不是可以长生啦
作者: jimopt    时间: 2015-08-21 10:50
2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?

个人的经历是:
07年小本毕业,读研期间基本都在用MATLAB和VC写一些小程序。毕业后当了5年的码农,看过不少代码,也写过不少代码。一直做的嵌入式开发,但是可能待大型企业的缘故,直到现在这第三份工作才有机会接触到linux驱动或者说linux内核的部分。然后时隔多年又开始频繁浏览这个论坛。
现在让我最痛苦的是什么呢?驱动代码的风格!奇怪吗?
我是一个clean code的拥趸,当我看到驱动代码中那一堆堆的简写,一条条的下划线,好几屏才能翻完的超大函数,随处可见成套出现的宏定义等等时,我的心简直是奔溃的~~~
这些年下来纯码农技术而言,一直修炼的方向是如何“把代码写得可以像优美的文章一样精巧”。我不会允许自己的函数超过200行(拆分一下函数OK?),不会允许一个函数有超过10的复杂度(拆分一下函数OK?),不会允许一个编译宏在函数内反复出现(拆分一下函数OK?重要的事情说3遍)不会允许代码到处都是struct,几乎不会允许写注释。linux内核代码颠覆了这一切。
随便举几个例子:
if (a && b || c && d)  何苦让看的人再去理解一遍这个复杂的判断, if(ThisIsMyWantedCondition) + inline bool ThisIsMyWantedCondition()的组合才是我期望看到的代码。
struct net_device一遍遍出现在代码中,就不能typedef一下,去掉那个struct让代码看起来简略一点吗?
nlmsghdr是啥?写成netlinkMessageHeader并不会让你的程序变大变慢哪怕一点点,却会让看了人担惊受怕,这是什么鬼?

好看的代码绝对不会影响代码的效率,却绝对赢促进开发的效率。尤其是你在一个团队中工作的时候。大家花多长时间去理解前人写的代码?在一声“哦~~原来是这个意思啊”之后大家看完之后有顺手把它改成你终于理解出来的“文章”吗?
linux的历史太长,内核的代码改动得太多,但是代码风格居然看不到一丝演进的迹象。芯片商提供的驱动源码居然还是要求把变量声明写在遥远的北方的原始C语言风格。

解决办法?前人栽树,后人乘凉。这句话在软件行业并不那么适用。前人挖坑,后人扫雷或许更为贴切。
当我们在抱怨别人写得代码不够好的时候,是否有心把他的代码改改好呢?这才是进步的关键。

作者: Vinge    时间: 2015-08-21 15:09
1. 分享Linux内核学习和驱动开发的经验。
LINUX内核刚开始用,作为工作中的人觉得还是带着项目目的来学习是最快的。以前一直想学LINUX,断断续续看了些书,就是没有入到门。后来工作需要了,弄了个开发板,3个月就把过去几年没有玩明白的东西全玩明白了。
无它,唯手熟已(当然,还算不上“熟”,只是比起以前的自己熟多了)。

2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
其实linux驱动真做起来了也不见得就是难,说它难是因为面对庞大的代码库,和N多的子系统架构和调用,你不知从何下手好。这点还是推荐跟着<设备驱动程序>从易到难深入,或者跟着伟东山的免费视频来玩(宋老师别敲我)。
最后,一定要动手写,动手操作。同样的代码,copy一遍和敲一遍理解程度绝对不是一个档次的。

其他几个我还不敢说些啥。lol
作者: shenlanyouyu    时间: 2015-08-21 15:58
回复 15# Vinge
赞同。驱动开发只是理论学习,很难掌握,理论联系实践才能快速掌握。

   
作者: shenlanyouyu    时间: 2015-08-21 23:43
回复 14# jimopt

的确Linux内核自有一套编码规范,不是驼峰编码规则。
习惯了驼峰编码规则,再来看Linux内核中的带下划线的函数命名是非常不习惯的。

   
作者: shenlanyouyu    时间: 2015-08-21 23:48
回复 9# openspace

Android中引入了HAL层,kernel层的driver完成的工作更简单了,很多业务逻辑封装到HAL来实现。
   
作者: sithui    时间: 2015-08-24 00:21
1. 分享Linux内核学习和驱动开发的经验。
学校内核更多的是要去理解整个Linux的框架,所以一定要从宏观切入,从顶向下,从大到小,从巨到细。
驱动只是linux内核的一部分,只有明白了基本的概念之后才能理解驱动中用到的技术和api的意义。
刚开始不可能所有的都弄的很懂很细,有些东西可以暂时跳过, 一定要先从整体上把握Linux内核的结构,然后理解一些基本概念,再去看驱动。
一般驱动是面向具体功能的,比如一个芯片的驱动,如触摸屏驱动,它向下连接的是不同的触屏芯片,向上连接的是linux的input系统。它的功能就是把输入的物理信号转换成input系统能识别的输入信号。然后再去看为了实现这些功能,驱动是如何与芯片互动的,又是如何遵循字符设备驱动框架的,等等。再慢慢去看一些复杂的驱动框架如USB, ALSA, V4L2等。

2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
Linux驱动开发其实是比较好入门的,看看ldd这一系列的书基本上写个字符驱动没有什么问题,难点在于把知识融汇起来去解决实际问题以及在复杂的驱动架构中去解决问题。这两个问题需要开发者对于linux框架和基本接口很熟悉,同时思考问题有大局观,同时也能考虑到细节实现上。

3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。
推荐驱动子系统的学习步骤是从最简单的入手,如ldd中的虚拟驱动,再到简单的字符设备驱动如ts驱动、再到一些总线驱动如I2C的EEPROM等,再到USB、ALSA、V4L2等结构复杂的。

作者: fezh    时间: 2015-08-26 14:57
上一本:设备驱动开发详解第2版还没看完呢,问问宋老师是不是可以以旧换新?
作者: ckf513728912    时间: 2015-08-27 14:31
回复 7# kartorz


    谢谢您的分享
作者: shenlanyouyu    时间: 2015-08-28 09:03
本帖最后由 shenlanyouyu 于 2015-08-30 10:42 编辑

“以旧换新”这个服务还没有呢,家电行业倒有
作者: axlrose    时间: 2015-08-31 15:46
本帖最后由 axlrose 于 2015-09-04 14:32 编辑

这本书终于出来了,太棒了,家里书架上还放着第一版,看到之前宋老师的BLOG上本书介绍,多了好多新内核内容,设备树等都是3.x后才加入的
现在正在用3.14内核,很多时间都花在修改dts设备树上面,这本书里面好多新内容都适用,准备搞本来学习

1. 分享Linux内核学习和驱动开发的经验。
首先是看<linux设备驱动开发> 这书对驱动有个了解,实际开发中需要看当前内核里的子系统的实现,比如i2c, spi的,参考内核现有的示例
可以了解子系统是怎么与实际硬件打交道的,目前都是有很多现成的框架,找一个相近的修改

2. 您觉得Linux驱动开发的难点是什么,有什么好的方法来克服?
主要还是对硬件芯片的熟悉,对具体芯片功能要掌握,比如跟一些纯软件开发人员聊i2c,spi, 他们根本不知道是啥玩意,所以需要先掌握硬件基本知识
然后就是研究具体芯片数据手册,比如RTC pcf8563,需要找datasheet看懂里面的寄存器,然后才有办法去写驱动调试代码,驱动开发需要很多硬件知识
很多时候遇到bug,除了google, 找找patchwork网站上的补丁,官方内核补丁,然后就是自己去读代码分析

3. Linux内核有上百个驱动子系统,你研究过内核各种驱动子系统的共性,层次结构设计吗?分享学习一个Linux内核子系统的经验,例如USB、I2C、HID等driver。
仔细看过i2c和spi的驱动,

4. 您深入研究过Linux设备驱动模型,关注过Linux内核驱动的设计思想吗?
学习过linux的设备驱动模型,里面的设计用到了类似面向对象的思想,引用计数器等,非常巧妙,实现自动内存回收的功能。
其实可以看一下 barebox一个uboot-V2的东东,里面的驱动架构就是一个微型没有OS版的linux设备驱动模型,从学习角度上是很值得看看的


把设备结点通过/sys的目录树来表示,每个节点都可以很方便的通过文件来访问,每次的新节点添加删除都发生uevent事件,给应用层的udev很多处理的机会

5. Android系统是基于Linux内核的,传统的Linux驱动开发和Android驱动开发有什么区别?
区别不大,Android驱动开发是在原有linux kernel中做加法,加入了一些Binder, ashmem,Low Memory Killer, wake lock等
内核驱动开发上大同小异,在JNI层需要给android提供一个 libhardware适配层,也就是跟内核通信的一个统一抽象层 HAL,通过jni给上层的java提供接口,可以让Android App可以操作底层驱动,比较典型的是一个led灯的示例,这个网上能随便搜得到的


PS:
除了构建内核系统外,我现在用buildroot多些,拿来构建rootfs非常方便,之前跟一些嵌入式朋友交流,有的人还不知道这个玩意,使用后发现很棒,全自动化构建,添加软件包自动编译,不需要自己手工./configure , make , install这些麻烦事,构建交叉工具链也非常的方便
另外就是yocto, 现在用freescale芯片的朋友做嵌入式linux应该知道这全自动构建系统,类似gentoo portage
openwrt也是个好东西,以前以为只适用于路由器,其实改造一下,对于不需要使用yocto这种构建GUI型的系统功能的小系统很适用,ubus, uci, netifd, procd, init-hooks等都是很棒的小巧组件




作者: shenlanyouyu    时间: 2015-09-01 22:36
回复 23# axlrose

感谢分享!
   
作者: CN薰様    时间: 2015-09-02 13:05
总感觉这个分类有点奇怪。内核可以说是硬件无关的,除非非说是arm、ppc、mips、x86这样的。而驱动是硬件相关的。mtd、net子系统可以
归结到内核。

因为我本身就是做系统移植,所以总觉得驱动开发应该归结到嵌入式里面,因为当你完成用户的需求的话,就需要在SOC外围扩展各个芯片
那么这就需要对应的驱动;还有一种就不不是特定的通用芯片,比如数据采集类,大部分需要写FPGA、CPLD的逻辑,localbus或者pci(e)接口,
也需要驱动。

这2种情况是不一样的,第一种情况,目前的linux内核基本已经涵盖90%以上的设备驱动,无需自己开发,只是需要按照自己的设计修改地址、中断
参数;第二种情况就需要自己编写对应的设备驱动,很多情况做字符设备就可以解决。

内核我不太关心,驱动的话还是要多多看看芯片手册,诸如一些接口芯片的话只要能对接口协议比如uart、spi、usb的物理传输层协议很熟,基本上
在看内核实现问题也不大。

至于说和外围芯片打交道的驱动,如果带DMA的话,基本上就是准备请求->通过dma传输给外围芯片->外围芯片有数据通过dma传输回cpu->发起中断
->cpu响应中断处理返回数据
大部分是这个模式
其实linux编程相对简单,毕竟框架已经写好了,我们只需要封装底层的初始化、读写函数就可以了
作者: 快乐的土豆    时间: 2015-09-06 17:03
有干货,马克一下表示支持。
作者: cnlnzz01    时间: 2015-09-11 18:13
提示: 作者被禁止或删除 内容自动屏蔽
作者: cnlnzz01    时间: 2015-09-11 18:20
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2