也正是因为Linux内核的唯一性,各个不同发布版本拥有相同的框架。Linux内核是在整个Linux系统的最底层,它负责管理硬件,运行用户程序,并保持系统整体的安全性和完整性。可以说是Linux系统的根和灵魂。图3-1中看到Linux内核还有另一层面的含义。这对于Linux内核同样适用。所以对Linux内核的剖析、学习和研究也不能独立于系统进行,而是要综合考虑应用、内核和硬件等各方面的信息和内容。这样才能更全面、深刻地理解Linux内核。......
2023-11-22
1ᤫ基本中断处理流程
Linux内核的中断处理框架当然要满足之前提到的各种需求。对Linux内核来说,每个中断号都是通过irq_desc进行描述的,可以说irq_desc是中断处理的核心。下面来看看相应的内容:
每个irq_desc是对中断号的抽象描述;而irq_chip是对中断控制器的抽象描述;affinity则是对中断处理在哪些处理器上执行的抽象描述;还有对中断信号的处理方式则是通过han-dle_irq来进行描述;最后需要抽象出来的就是不同设备特别地处理了,这个工作就由action来完成。其他的都是表明相关操作的属性以及和中断在哪个执行实体上运行相关。通过这些抽象结构就可以实现整个中断处理的框架。当然随着Linux内核的演进,这些抽象数据结构的具体形式会有变化(如结构中注释所说),但是要满足中断处理的需求,框架中必然会有物理实体的抽象,这个是不会发生变化的。明白了这些抽象结构表示的物理实体,也就比较容易理解框架的执行过程和逻辑了,图4-27以ARM为例展示了中断处理代码的流程和抽象结构之间的关系。
中断处理的基本操作逻辑就是先获得正确的中断号,然后由相应中断信号处理方式han-dle_irq处理。handle_irq会根据需要,对中断控制器进行操作,以保证中断控制器仍然能够正确地上报中断,另外根据action中的操作完成设备申请的操作逻辑。
2ᤫ中断处理延时操作
下面介绍系统如何解决中断中大数据量时的延时处理问题。图4-28是Linux内核中断处理流程。
图4-27 Linux内核中断处理代码流程和抽象结构的关系
图4-28 Linux内核中断处理流程
从图4-28中可见,Linux内核中断处理分为两部分,分别为hardirq和softirq。hardirq部分决定中断控制器是否能继续上报中断的时间,可以理解为硬件的中断延时时间,中断处理系统将需要进行大量数据处理的工作放到了softirq中进行。这样将完整的中断处理分为两部分进行,既保证了硬件的最小时延又保证了数据的处理。softirq是Linux内核采用的比较老的机制,是对中断数据处理的一种延时操作,也可将其作为延时处理来考虑,相应的介绍有很多,这里就不进行说明了。中断的数据处理部分采用内核线程处理是一种很直接的方式,内核也提供了该方式相应接口request_threaded_irq。通过ps查看任务时,若见到如下信息([irq/中断号-名字]),就说明是中断处理线程。
下面对request_threaded_irq接口进行一下介绍:
request_threaded_irq(unsigned in tirq,irq_handler_t handler,irq_handler_t thread_fn,un-signed long flags,const char * name,void * dev);
●irq———需要申请的中断号。
●handler———中断处理逻辑接口。该接口运行在中断上下文中,只是执行需要快速响应的操作,执行时间尽可能短小,耗时的工作留给线程处理接口。
●thread_fn———如果该参数不为NULL,内核会为该irq创建一个内核线程。当中断发生时,如果handler返回值是IRQ_WAKE_THREAD,内核将会激活中断线程,在中断线程中,thread_fn指向的接口函数将被调用。该接口函数运行在进程上下文中,允许进行阻塞操作。
●flags———控制中断行为的位标志,形式为IRQF_XXXX,例如:IRQF_TRIGGER_RIS-ING、IRQF_TRIGGER_LOW、IRQF_SHARED等。
●name———申请本中断服务的设备名称,同时也作为中断线程的名称。
●dev———作为handler和thread_fn的参数,通常设置为设备的管理实体。
3ᤫ内核提供的通用接口
为了方便开发,内核为访问中断处理框架中抽象的控制结构提供了一些接口函数:
●irq_set_chip(irq,∗chip)/irq_get_chip(irq)———每个中断号irq_chip的操作接口。
●irq_set_handler_data(irq,∗data)/irq_get_handler_data(irq)———每个中断号内中断处理逻辑的私有数据,保存handler所需要的特殊数据,例如中断控制器级联时,进行级联的中断号,用该字段保存下一级中断号的管理实体。
●irq_set_chip_data(irq,∗data)/irq_get_chip_data(irq)———每个中断号内操作中断控制器的私有数据,用于不同的中断控制器管理信息。
●irq_set_irq_type(irq,type)———用于设置中断的触发类型,可选的类型有IRQ_TYPE_EDGE_RISING、IRQ_TYPE_EDGE_FALLING、IRQ_TYPE_EDGE_BOTH、IRQ_TYPE_LEVEL_HIGH、IRQ_TYPE_LEVEL_LOW。
●irq_set_handler(irq,handle)———设置中断处理逻辑,参数handle的类型是irq_flow_handler_t。
●irq_set_chip_and_handler(irq,∗chip,handle)———同时设置中断处理逻辑和中断控制器属性。(www.chuimin.cn)
●irq_set_chained_handler(irq,∗chip,handle)———进行级联的中断号,设置级联的中断处理逻辑,其中会设置标志IRQ_NOREQUEST、IRQ_NOPROBE、IRQ_NOTHREAD。通常用于中断控制器的级联,设置上述三个标志位会使得父控制器的相应中断号不允许被驱动程序申请。
另外内核还提供了一些中断信号处理的方式:
●handle_level_irq。
●handle_edge_irq。
●handle_fasteoi_irq。
●handle_simple_irq。
●handle_percpu_irq。
●handle_edge_eoi_irq。
●handle_bad_irq。
为设备开发提供的中断请求的接口是request_irq和request_threaded_irq。
中断子系统还提供一些接口用于动态申请/扩展中断号(需要配置CONFIG_SPARSE_IRQ),分别如下:
●irq_alloc_desc(node)———申请一个irq,node是对应内存节点的编号。
●irq_alloc_desc_at(at,node)———在指定位置申请一个irq,如果指定位置已经被占用则失败。
●irq_alloc_desc_from(from,node)———从指定位置开始搜索,申请一个irq。
●irq_alloc_descs(irq,from,cnt,node)———申请多个连续的irq编号,从from位置开始搜索。
●irq_free_descs(irq,cnt)———释放irq资源。
这些只是申请函数,要想中断能够正常工作,还需要通过接口对必要的字段进行设置,如irq_set_chip_and_handler_name、irq_set_handler_data、irq_set_chip_data。
中断处理系统还提供了接口,可以方便其他模块查询当前所在的中断处理状态,利于模块做出正确的处理。其接口如下:
●in_irq()———判断当前是否在硬件中断上下文。
●in_softirq()———判断当前是否在软件中断上下文。
●in_interrupt()———判断当前是否进行中断处理,包括在硬件、软件、底半部中断上下文。
这些接口函数是实现具体处理器及设备中断处理的基础,为各种驱动和处理器提供了良好的操作框架。
4ᤫ电源管理相关接口
以上主要是中断处理框架的通用功能。在电源管理方面,中断还是有一定作用的。中断可以作为唤醒系统的信号,使得系统在进入待机时能够被唤醒,而这需要中断控制器的支持。为了实现该功能,系统在中断控制器的抽象实体irq_chip中进行了相关的设计。下面列出了irq_chip中的主要接口:
其中,irq_set_wake是和唤醒相关的功能,主要是打开或关闭相应中断唤醒系统的功能。
内核提供对某个中断进行电源管理唤醒功能的操作接口,接口为int set_irq_wake(un-signed int irq,unsigned int on);
可见内核中断处理框架提供了包括功能、性能和电源管理相关的完整系统方案。
有关深入剖析Linux内核与设备驱动的文章
也正是因为Linux内核的唯一性,各个不同发布版本拥有相同的框架。Linux内核是在整个Linux系统的最底层,它负责管理硬件,运行用户程序,并保持系统整体的安全性和完整性。可以说是Linux系统的根和灵魂。图3-1中看到Linux内核还有另一层面的含义。这对于Linux内核同样适用。所以对Linux内核的剖析、学习和研究也不能独立于系统进行,而是要综合考虑应用、内核和硬件等各方面的信息和内容。这样才能更全面、深刻地理解Linux内核。......
2023-11-22
VFS的实现是以“一切皆是文件”为需求出发点的。要理解VFS的框架首先看一下VFS和系统的静态关系框图,如图5-1所示。从图5-1可见,VFS是用户层的直接接口,是面向用户的服务。图5-1VFS和系统静态关系图在图5-2中每个节点被使用时都会在VFS层中创建dentry,这样可以快速通过文件名进行查找和定位,Linux内核中对dentry的管理组织形式如图5-3所示。以上是系统运行时VFS对文件名的组织管理,这是VFS管理的一个方面。......
2023-11-22
考虑到电源管理的需求涉及处理器和各种设备,一方面是处理器尽可能减少功耗,另一方面是设备尽可能减少功耗。图5-30Linux电源管理各个功能从图5-30可见Linux内核的电源管理功能有与处理器相关的CPUIdle和CPUFreq,也有与设备相关的runtime pm,另外还有与整个系统待机时SLM相关的低功耗电源管理功能。下面分别对这些功能框架进行介绍。具体的驱动同样会在SoC电源管理部分进行讲解。对具体设备的电源管理实现,将在设备驱动中进行详细分析。......
2023-11-22
首先要明确,这里讲述的地址映射框架主要是指内核空间虚拟地址的使用和映射。嵌入式系统通常是采用ARM的处理器,相应的地址映射框架自然就从Linux内核的ARM体系结构入手。图4-19ARM内核地址空间映射关系2.内核中的映射实现和相关的权限管理地址映射的代码框架如图4-20所示。图4-20ARM地址映射代码框架谈到create_mapping的映射,就会涉及体系结构中不同的访问方式和权限。......
2023-11-22
SPI总线框架对这两类设备进行管理,具体的框架如图7-6所示。通常的SPI驱动都是在内核实现并在内核态执行的,所以就不对spidev进行详细的分析。SPI总线框架整体的功能就是这样,接下来看看具体各部分的实现。在SPI总线框架中相应的实体是spi_board_info,内容如下:其中的主要信息是与总线信号相关的属性。......
2023-11-22
整体的frame buffer框架如图6-5所示。了解frame buffer的框架还要先从为用户提供的接口开始。图6-7可变参数中硬件信息的含义固定信息是在frame buffer的操作过程中并不发生变化的。从整体分析,frame buffer的框架很直接,主要就是直接管理实际的设备,而相关的操作与应用层直接相关。......
2023-11-22
DM 3730的I2C控制器框架如图7-4所示。图7-4引自《DM 3730芯片手册》中第2798页的框图。关于DM 3730I2C的驱动部分,主要分析相关初始化和总线传输的操作。由于I2C作为控制和获取状态信息,数据量并不大,而且相关的操作频率并不高,这样在中断中进行相关的处理,对系统的影响并不大。......
2023-11-22
从图3-2中可以理解Linux内核就是将硬件的功能抽象出来,为用户的应用程序提供各种系统服务。与用户相关的属性是与Linux内核中整体安全性相关的,这部分功能通常和硬件具体功能关系不大,而是附加在逻辑功能之上的属性。本书是以嵌入式系统为基础进行说明,所以将重点放在硬件设备的具体功能以及Linux内核在硬件之上的具体实现方面。Linux内核的整体框架如图3-3所示。图3-3清晰地展现了Linux内核的实现层次,以及应用层功能和硬件功能的对应关系。......
2023-11-22
相关推荐