求教怎么学习linux内核驱动

author author     2023-02-15     624

关键词:

1.首先要了解为什么要学习内核?下图已表明,如果要从事驱动开发或系统研究,就要学习内核。

2.内核的知识就像下面的绳结一样,一环扣一环,我们要解开它们,就必须要先找到线头也就是内核中的函数接口。初学阶段,我们一般不深入的研究内核代码,会使用内核的接口函数就不错了。

3.下面提供了如何学习这些内核函数的方法,就像解绳子一样

4.学习内核的四步法则,思维导图的设计尤为重要,这也是能否学习好内核的关键

5.语言基础也需要扎实,所以需要把C语言巩固巩固
参考技术A 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 接口

学习笔记——《linux设备驱动程序(第三版)》linux设备模型:内核添加删除设备驱动程序(代码片段)

文章目录1.前言2.准备工作2.1.概念2.2.具体总线、设备、驱动结构体说明2.3.注册总线3.添加设备3.1.STEP1——发现设备并创建设备结构structXXX_dev3.2.STEP2——初始化设备结构3.3.STEP3——注册设备4.删除设备5.添加驱动程序6.删除驱动程... 查看详情

linux内核源码如何学习?

1.学习主线linux内核源码大而全,一个人,即使再聪明、再有精力,也不可能完全看完、看懂所有的linux内核源码。一口君建议按照以下主线进行深入研究:linux驱动架构linux网络子系统linux内核启动过程linux内存管理机制linux调度... 查看详情

驱动学学之驱动学习的准备工作

1:驱动开发的准备工作(1)正常运行linux系统的开发板。要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的。(2)内核源码树,其实就是一个经过了配置编译之后的内核源码。这里使用的是九鼎官方提供的kener,因为... 查看详情

字符设备驱动体验,字符设备驱动学习

                字符设备驱动学习  在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码。因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块。一、编译安装字符设备驱动程... 查看详情

学习linux底层驱动开发有啥经典的参考书?

...常用命令=>linux系统编程=>内核开发阅读内核源码其中学习linux常用命令时就要学会自己编译内核,优化系统,调整参数安装和常用命令书太多了,找本稍微详细点的就ok,其间需要学会正则表达式系统编程推荐《高级unix环境... 查看详情

为什么要学习linux内核,如何学习?

1.为什么要学习Linux内核大多数程序员可能一辈子都没有机会从事 Linux 内核开发,也可能不会去从事Linux驱动开发的工作,那么为什么我们仍然需要学习 Linux 内核?Linux 的源码和架构都是开放的,我们可以从中... 查看详情

linux下写的sd驱动,android怎么调用?

通过jNI,java可以调用底层的c++代码。参考技术ASD驱动是和内核连在一起的,可以说是内核的一部分,Android的开发工具是eclipse不能直接调内核。要用sorceInsight修改内核,编译后运行Linux系统,这样来调。 参考技术Bopen后,使用。 查看详情

(todo)linux内核:设备驱动模型sysfs与kobject基类(代码片段)

(todo)Linux内核:设备驱动模型(0)sysfs与kobject背景学习Linux设备驱动模型时,对kobject不太理解。因此,学习了一下。现在我知道了:kobj/kset是如何作为统一设备模型的基础,以及到底提供了哪些功能。以后我们就知道,在具... 查看详情

linux内核模块开发怎么进行单元测试

usb_register_notify,你当前的系统中运行的内核缺少这个函数定义,你这个因为你要安装的模块,并没有在这个你运行的这个系统中编译生成,而是拿别的机器,或者别人的模块安装在你当前的机器上,不提倡。有源码的话,在你... 查看详情

ubuntusystem-config-kickstart怎么编译

...成功编译出helloworld模块驱动。1、首先确定本机linux版本怎么查看Linux的内核kernel版本?\'uname\'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用\'uname\'参数可以查看当前服务器内核运行的各个状态。#unam... 查看详情

linux内核该如何学习?linux内核源码该怎么读?

Linux内核该如何学习?linux内核源码该怎么读?专注后台服务器开发,包括C/C++,Linux,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8Sÿ... 查看详情

添加自己的驱动程序到linux内核(详解)

...添加驱动到内核的步骤,于是趁着这个机会,展开有关的学习。 Target   :hi3531dLinux     :Linux-3.18 步骤在自己喜欢的位置创建一个目录(前提是这个目录下面存在Kconfig以及Makefile)为了方便演示,我们这... 查看详情

浅淡个人学习嵌入式linux过程

...首先要会用Linux,知道Linux是如何操作,继而才能了解Linux怎么调用系统底层驱动的。  当时的我只是知道Linux是独立于Windows的另一个操作系统。 查看详情

我的内核学习笔记12:linuxi2c-gpio驱动应用实例(代码片段)

linux内核的i2c-gpio是使用GPIO模拟I2C协议的驱动,只需要配置2根GPIO即可使用。Linux的I2C子系统比较复杂,笔者暂时还没有研究。本着“实用”的目的,介绍一下如何使用这个驱动及一些注意事项。一、概述Linux内核很多... 查看详情

openharmony内核学习[1]--单独编译openharmony标准系统内核(代码片段)

内核是操作系统的核心,学习掌握OpenHarmony内核对于开发人员至关重要。笔者整理学习OpenHarmony标准系统内核笔记如下:阅读本文大约需要15分钟。(目录)OpenHarmony标准系统内核OpenHarmony标准系统类设备(参考内存≥128MiB),OpenHarmo... 查看详情

linux学习资料整理

Linux免费学习资料整理linux基础(系列课程)快速上手linuxLinux网络经典案例Linux网络高并发技术之epolllinux之C语言内存管理Linux网络聊天室设计Linux开发调试技巧linux高级Linux中网络通信协议分析GUI开发Linux中POLL机制高并发编... 查看详情

如何编译一个linux下的驱动模块

...成功编译出helloworld模块驱动。1、首先确定本机linux版本怎么查看Linux的内核kernel版本?'uname'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用'uname'参数可以查看当前服务器内核运行的各个... 查看详情

《linux内核设计与实现》学习笔记——中断中断处理程序

中断和中断处理程序中断随时可能产生,打断CPU的执行,CPU转而处理中断。不同的设备对应的中断不同,每个中断都通过一个唯一的数字标志。这些中断值称为中断请求(IRQ)线,每个irq线关联一个数值。中断处理程序响应中断... 查看详情