热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

19年linux驱动笔记

1.管道(pipe)是一种用来连接两个进程的虚拟文件,当进程A欲向进程B发送数据时,它把管道文件视作输出文件,向其中写数据,

1.管道(pipe)是一种用来连接两个进程的虚拟文件,当进程A欲向进程B发送数据时,它把管道文件视作输出文件,向其中写数据,进程B则可将管道文件视作输入文件,从中读数据。于是,进程A和B之间的通信很像普通文件的读写。

2.MINIX中进程的存储空间分为三部分:正文段(即代码段),数据段(即变量),和堆栈段。

3.MINIX中一个简单的系统调用getpid返回调用进程的进程标识号,注意在调用fork时,只有父进程能够获得子进程的进程标识号。如果子进程要得到自己的进程表示号,它必须使用getpid。

4.内核启动流程:先走head.S的汇编流程,这里有个depress_kernel接口,它负责内核的自解压。解压完然后跳到start kernel这个C语言函数接口,这个里面大部分都是一些初始化,最后会有个rest_init()接口,这里面是剩余的初始化。rest_init()里有个try_to_run_init_process("sbin/init")接口,这个就是去运行1号进程(1号进程就是进程ID号PID为1的进程),运行init进程后,start kernel这个函数就不再返回了。如果找不到"sbin/init",内核会去/etc等目录下寻找init进程,都没有就return了。

5.驱动是以模块加载到内核中的,写好一个驱动模块后不能用gcc或者交叉编译来编译,而是要用以后该模块加载到的内核的编译系统来编译(如果要加载到本机的Linux系统中使用,则编译进的内核目录为:lib/modules/$(shell uname -r)/build,下图就是编译模块到本地Linux内核中的makefile,切记不是编译到目标机的内核,Linux系统移植时如果需要编译驱动模块则要换成目标机的内核路径)。如果编译好的内核是要load到arm中运行,则提前在内核的Makefile中修改编译用交叉编译就可以了。编译内核时命令为make uImage,编译设备树时命令为make dtbs,编译模块(驱动)时命令为make modules。

6.驱动模块分为driver和device两个部分,driver.c需要自己去编写,device既可以通过device.c去编写,也可以通过设备树文件添加子节点去设计

7.为了实现进程模型。操作系统维持着一张表格(一个结构数组),即进程表(process table)。每个进程占用一个进程表项。该表项包含了进程的状态、它的程序计数器、栈指针、内存分配状态、打开文件状态、计费和调度信息,以及其他在由运行态转到就绪态必须保存的信息,只有这样才能使进程随后被再次启动,就像从未被中断过一样。

8.在传统进程中,每个进程中只存在一条控制线索和一个程序计数器。但在现代操作系统中,提供了对单个进程中多条控制线索的支持。这些控制线索被称为线程(threads),有时候也称为轻量进程(lightweight processes)。

9.线程间共享数据好处是调度起来只需要加载各自线程的栈信息就可以了,优化了调度。但是坏处也是线程共享许多数据结构导致的。若一个线程关闭一个文件而另一个线程正在读该文件,将有什么后果?假设一个线程注意到内存不够并开始申请更多的内存,但此时发生线程切换,新运行的线程也注意到这个问题并再次申请内存。那么这里是申请一次呢,还是两次呢?

10.进程是通过时钟中断进行调度的,临界区是控制进程同步的方式,但是当进程A进入到临界区后发生时钟中断,进程B切换到运行态也进入到该临界区是非常危险的。这里有两种方式可以防止这种情况发生:(1)当进程A进入到临界区后需要关中断,时钟中断也会被关闭。(2)锁机制。

11.1Gbps意思是1G bits/per secont。根据等量关系1GB/s=8Gbps=8Gbit/s.

12.I/O设备可以粗略的分为两类:块设备和字符设备.

13.设备树解析过程:.dts文件经过编译后变成.dtb文件传给内核,内核解析.dtb文件将每个设备树节点总结为device_node结构体,然后再解析为platform_device资源;platform_device再和platform_driver匹配。

14.如下是设备树中的属性转为device_node结构体中的成员变量:

15.设备树编译解析过程:dts----->dtb------>device_node------>platform_device:一般情况下所有的设备树节点都会转化为一个device_node,包括根节点;但是不是所有的device_node都会转化为platform_device,比如根节点就不会,chosen节点也不会,还有在注册总线和设备时,会对dts节点的状态作一个判断,如果节点里面的status属性没有被定义,或者status属性被定义了并且值被设为“ok”或者“okay”,其他情况则不被注册到系统中。一般情况下只有根节点下面的子节点才会有platform_device结构体,比如下图的i2c节点会有一个platform_device结构体,但是at24c02这个节点不会转换为platform_device结构体,而是交给i2c驱动的probe函数去处理。但是这个规定不是死的,有些节点的compatible属性如果包含"simple-bus"字符串,则也会转换为platform_device结构体的。simple-bus表示简单的内存映射总线,表示cpu能够直接访问到。

16.platform_device和platform_driver匹配使用platform_match接口,比较就是比较name等字符串,下面一共有4个比较项,只要有一项比较成功,则返回1,然后调用platform_driver的probe函数。韦东山的设备树视频的第三章:platform_device和platform_driver的匹配,这一小节详细介绍了下面4种匹配过程。

17.uboot会把dtb文件传给内核,并且在内存上占一块空间,这块空间不会被占用,系统上电后我们可以去查看这块内存区域。可以通过/sys/firmware/fdt查看,可以使用命令:hexdump -C fdt去打印这里面的内容,这个里面是原始的dtb内容。在fdt同级目录有个devicetree目录,/sys/firmware/devicetree/base这里面的文件对应根节点的属性和子节点,子节点是目录存在形式。如果属性是字符串,可以使用cat去查看内容。

18.GPIO复用的dts配置时,如果有下面打印不要认为内核没有对qcom,rx-gpio进行解析,先看看配置的节点中有没有pinctrl-names属性,这2中配置的方式是一样的。

19.当中断发生时,cpu会跳到某个地址运行中断处理函数,这些中断处理函数的地址是连续排列的,这就是中断向量表。这些中断处理函数要:保护现场,调用函数,恢复现场。

20.一个中断控制器只能控制32种中断,这32种中断信息存放在irq_desc[]数组中(韦东山的Linux设备树详解对中断讲解的非常详细,以后细看)。

21.设备树中对设备配置中断时,需要指定2个内容,第一就是需要指定中断控制器是哪个(interrupt-parent属性);第二就是指定是该中断控制器中第几个中断(interrupts属性)。interrupt属性中有时会有2个参数,或者更多,这是因为比如有些中断不需要指定触发方式,这些参数的个数都是中断控制器来决定的。在设备树中搜索interrupt-controller就可以数出来当前系统有多少个中断控制器。有interrupt-controller这个属性的节点代表的便是中断控制器,中断控制器中#interrupt-cells属性的值表示它下一级的设备需要多少个32位的数据来描述某一个中断。比如我们数出来了当前系统设备树中有3个中断控制器,那么这3个中断控制器之间的关系是怎么样的呢?如下图,gpg和gpf是第一个中断控制器下面的子节点,所以gpg和gpf这2个中断控制器要想第一个中断控制器发送中断信息。

22.设备树的interrupt-extended属性(中断扩展属性)。比如说某块板子有4个按键(都可以产生按键中断),就可以用该属性描述设备树。其中第一个指定中断控制器,后面参数的个数由该中断控制器的#interrupt-cells来指定。intc控制器需要4个参数描述中断,第一个指定中断控制器,第二个指定主控制器,第三个指定子控制器,第四个指定中断号,第五个指定触发方式(上升沿,下降沿,双边沿,高电平,低电平)。该属性具体解释看韦东山的设备树视频的第五章第五小节。

 

23.I2C驱动程序分为:I2C总线驱动程序I2C设备驱动程序。I2C总线驱动程序负责识别设备和提供读写接口,这个驱动程序内核中是有自带的。

24.字符设备驱动程序框架:应用层接口open,read,write;驱动层提供drv_open,drv_read,drv_write;再下面就是硬件层了。怎么构造驱动层接口呢,我们实现file_operations结构体就可以了,我们辛辛苦苦构造出来的驱动层的file_operations怎么用呢,我们告诉内核就可以了,怎么告诉内核呢,通过register_chrdev函数(这个可以简单的想象为它把file_operations结构体放到内核里面的某个数组,放到数组里的哪一项呢?放到主设备号下标那),那么谁来调用这个register_chrdev函数呢,我们在驱动的入口函数里调用这个注册函数。这就是字符设备驱动程序框架,非常简单。

25.config文件中宏的作用,比如CONFIG_MMC=y的作用就是执行对应Makefile时,看要不要将相应的目录编译进内核,如下:

 


推荐阅读
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • 【并发编程】全面解析 Java 内存模型,一篇文章带你彻底掌握
    本文深入解析了 Java 内存模型(JMM),从基础概念到高级特性进行全面讲解,帮助读者彻底掌握 JMM 的核心原理和应用技巧。通过详细分析内存可见性、原子性和有序性等问题,结合实际代码示例,使开发者能够更好地理解和优化多线程并发程序。 ... [详细]
  • Java 8 引入了 Stream API,这一新特性极大地增强了集合数据的处理能力。通过 Stream API,开发者可以更加高效、简洁地进行集合数据的遍历、过滤和转换操作。本文将详细解析 Stream API 的核心概念和常见用法,帮助读者更好地理解和应用这一强大的工具。 ... [详细]
  • 本书详细介绍了在最新Linux 4.0内核环境下进行Java与Linux设备驱动开发的全面指南。内容涵盖设备驱动的基本概念、开发环境的搭建、操作系统对设备驱动的影响以及具体开发步骤和技巧。通过丰富的实例和深入的技术解析,帮助读者掌握设备驱动开发的核心技术和最佳实践。 ... [详细]
  • 如何使用 net.sf.extjwnl.data.Word 类及其代码示例详解 ... [详细]
  • 如何在Spark数据排序过程中有效避免内存溢出(OOM)问题
    本文深入探讨了在使用Spark进行数据排序时如何有效预防内存溢出(OOM)问题。通过具体的代码示例,详细阐述了优化策略和技术手段,为读者在实际工作中遇到类似问题提供了宝贵的参考和指导。 ... [详细]
  • 计算 n 叉树中各节点子树的叶节点数量分析 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
  • 全面解析Java虚拟机:内存模型深度剖析 ... [详细]
  • 在处理大规模并发请求时,传统的多线程或多进程模型往往无法有效解决性能瓶颈问题。尽管它们在处理小规模任务时能提升效率,但在高并发场景下,系统资源的过度消耗和上下文切换的开销会显著降低整体性能。相比之下,Python 的 `asyncio` 模块通过协程提供了一种轻量级且高效的并发解决方案。本文将深入解析 `asyncio` 模块的原理及其在实际应用中的优化技巧,帮助开发者更好地利用协程技术提升程序性能。 ... [详细]
  • MongoDB Aggregates.group() 方法详解与编程实例 ... [详细]
  • 深入解析零拷贝技术(Zerocopy)及其应用优势
    零拷贝技术(Zero-copy)是Netty框架中的一个关键特性,其核心在于减少数据在操作系统内核与用户空间之间的传输次数。通过避免不必要的内存复制操作,零拷贝显著提高了数据传输的效率和性能。本文将深入探讨零拷贝的工作原理及其在实际应用中的优势,包括降低CPU负载、减少内存带宽消耗以及提高系统吞吐量等方面。 ... [详细]
  • 本文详细介绍了HDFS的基础知识及其数据读写机制。首先,文章阐述了HDFS的架构,包括其核心组件及其角色和功能。特别地,对NameNode进行了深入解析,指出其主要负责在内存中存储元数据、目录结构以及文件块的映射关系,并通过持久化方案确保数据的可靠性和高可用性。此外,还探讨了DataNode的角色及其在数据存储和读取过程中的关键作用。 ... [详细]
  • voc生成xml 代码
    目录 lxmlwindows安装 读取示例 可视化 生成示例 上面是代码,下面有调用示例 api调用代码,其实只有几行:这个生成代码也很简 ... [详细]
author-avatar
咬__唇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有