- 博客(56)
- 收藏
- 关注
原创 从零开始理解Linux中断架构(25)中断运行全景实例
前面我们基本理解了软中断处理的基本框架,为了对中断调用有一个全景的直观感受,我们在网卡驱动程序的中断函数dump_stack,观看一下各种情况下的软中断调用call Stack的情况。(1)ksoftirqd处理软中断的情况(2)irq_exit退出时处理软中断的场景,就是那个小尾巴(3)__local_bh_enable_ip执行软中断的场景(4)NAPI模式驱动全貌(网卡驱动)该图中,我们可以看到网卡驱动是如何使用软中断来处理网络数据包的,通过该图对于中断处理也有个全方位的理解。
2023-08-12 19:29:25
289
原创 从零开始理解Linux中断架构(24)软中断核心函数__do_softirq
处理软中断期间时还会进入新的硬中断,从而带进新的软中断需要处理,如果同一中断频繁产生,系统会在local_softirq_pending()上的同一未决标志上重复置位,这里会造成软中断丢失。让in_interrupt检查条件为真,进入软中断处理临界区,后面进来的处理请求,需要检查in_interrupt(),从而达到禁止本cpu上的软中断嵌套的目的。__do_softirq可能是要挂在irq_exit小尾巴上跑的,还需要尽快的退出异常处理流程,避免让系统老是回不到应用态执行应用线程。
2023-08-04 22:05:12
343
原创 从零开始理解Linux中断架构(23)中断运行临界区和占先调度
只需要判断in_interrupt(),看看这个中断运行临界区是否被占领,如果已经被占领了,说明前一个软中断处理处于被打断状态,后面的就不进去了,就可以保证__do_softirq()不会在同一Core嵌套调用。前面的中断临界区相关的函数:in_interrupt,in_irq等都使用到了preempt_count,这个preempt到底是个什么东西呢?in_interrupt在驱动中使用频率最高的函数了,in_interrupt()就是指示Core是否正在中断处理中,包含了硬中断,软中断运行临界区。
2023-07-29 09:46:35
883
原创 从零开始理解Linux中断架构(22)软中断处理框架
内核专门为软中断建立了内核线程(ksoftirqd)来处理软中断事务。在 smpboot.c中,设计一个hotplug thread线程框架,集中管理boot_threads的启动。软中断的内核处理线程ksoftirqd就只依托这个线程框架建立的。软中断处理线程的代码都在kernel/softirq.c,在内核初始化时(kenel_init),spawn_ksoftirqd根据softirq_threads描述,为每个CPU建立ksoftirqd/x软中断线程。
2023-07-24 22:53:52
155
原创 从零开始理解Linux中断架构(21)软中断之基本理念
在Linux内核中,软中断是一种在内核空间中执行的中断处理方式,与硬件中断不同,软中断不是由硬件设备触发的,而是由内核软件产生的。在内核中,软中断被用于执行一些高优先级的任务,如网络数据包处理、定时器处理等。
2023-07-22 14:34:35
71
原创 从零开始理解Linux中断架构(20)--关于二级中断控制-链式chained Handler
上级中断控制器链接的中断源(irq=17)handler_irq已经被EINT的中断控制器驱动改写成mtk_eint_irq_handler,而不再是原来的handle_fasteio_irq。链式(chained)级联方式里,上级中断控制器链接的中断源handler_irq是由当前的二级中断控制器驱动提供,irq_data.chip任然是上级的中断控制器chip对象,这就表明,中断开关和应答还是通过上级中断控制器进行。这个是典型的N->1的连接方式。他的连接也是一样,分为1->N的模式和1->1的模式。
2023-07-16 17:31:25
230
原创 从零开始理解Linux中断架构(19)--中断线程化irq_thread
handler主中断处理例程,运行hard_irq 流程上。所谓的中断线程化就是设备注册的主handler也会运行在内核线程上,此时的中断的irqaction->handler指向了irq_default_primary_handler,他不会做任何处理,只是以IRQ_WAKE_THREAD返回,以便后续代码唤醒对应的irq_thread线程。编译时如果定义了CONFIG_IRQ_FORCED_THREADING,参数irqflags不包含IRQF_NO_THREAD中断Action都将强制线程化处理。
2023-07-15 10:21:31
493
原创 从零开始理解Linux中断架构(18)--中断流处理
④在全局中段描述符树irq_desc_tree中找的77对应的中断描述符:irq_desc[77]。kernel初始化中断控制器(gic v3)时,调用set_handle_irq(gic_handle_irq),将gic_handle_irq赋予handle_arch_irq,为中断处理进入C语言第一跳建立了跳板。handler代表的是主Handler,运行在硬中断流程上,thread_fn代表的是要创建的中断线程的入口函数,thread_fn如果不为NULL,系统会创建一个内核线程来处理该中断。
2023-07-08 16:38:57
268
原创 从零开始理解Linux中断架构(17)--设备中断处理函数
现在达到了最后一步,给中断源安装上设备层级的中断处理函数,这个是每个具体设备驱动需要做的核心工作,每个device probe 时,驱动程序会初始本设备的寄存器和使用@manage.c注册设备自己相关的中断处理函数。设备中断处理函数的运行位置如下图的红色箭头所指的地方,我们就从宏观上的理解到了设备级中断处理函数的运行位置:dev specific handler指示的位置。
2023-07-06 21:19:46
234
原创 从零开始理解Linux中断架构(16)--Linux中断映射
linux系统中维护的全局allocated_irqs,从allocated_irqs的低位到高位查询第一个连续N个空闲的位作为软件中断号,每一位代表该位序号对应的软件中断号是否已经分配。系统会调用bitmap_find_next_zero_area() 从allocated_irqs中找到第一个空闲位 start作为软件中断号。of_irq_parse_one会将dts中的中断信息进行解析,并建立如上图的逻辑关系。irq_desc_tree利用irq作为key来存储irq_desc对象,节点动态生成。
2023-07-04 21:06:24
650
原创 从零开始理解Linux中断架构(15)--Linux GIC控制初始化
GICv3要求Core处理完中断后,必须通知中断控制器中断处理完成,以便GIC维护中断状态机。GICv3架构将中断的完成分为2个阶段:Priority Drop和Deactivation。(1)
2023-07-03 20:46:32
268
原创 从零开始理解Linux中断架构(14)--Linux硬中断管理设计理念
将中断控制硬件控制抽象统一的中断控制器抽象结构,把中断处理系统框架设计成通用框架,让中断处理过程设计成跟体系结构无关,跟中断控制器无关的运行框架,以便系统新添加中断控制器支持时,只需要填写irq_chip.结构这类chip-level specific 的相关工作。不同种类和厂家的中断控制器的访问是不同的,为了隐藏这些差异,Linux内核抽象化了中断控制器操作,定义了统一的中断控制器描述符,每种中断控制器自定义各种操作函数,来隐藏操作细节。中断域还需要管理中断控制器级联时,中断处理链条的传递。
2023-07-02 17:29:02
263
原创 从零开始理解Linux中断架构(13)--Linux中断域
由于计算机系统日益复杂,外设中断数量不断增加,系统可能同时需要多个中断控制器进行级联,中断源需要统一管理,面对这样的状况,Linux对各种中断控制器进行抽象,对如何进行硬件中断号到IRQ number映射关系上进行进一步抽象出通用与设备无关的架构,通用中断处理代码中就有了irq domain的出现。对于每个中断控制器都可以连接若干个外设的中断请求,中断控制器会对连接其上的中断源进行编号,这个编号(1,2,3,...N)仅在中断控制器仅限制在本范围内。
2023-06-28 22:43:34
209
原创 从零开始理解Linux中断架构(12)--硬中断之中断控制器(GICV3)
Inactive中断未被触发Pending(待处理)中断已经被硬件触发,GIC回将IAR寄存器中相应的位置1,但cpu还没有应答中断,在这个阶段称为Pending。Active(处理中)CPU已经应答(acknowledge)了该中断请求,并且正在处理中前一个中断已经响应了,同一中断源又触发了中断,后一个中断进入pending状态ICv3中断控制器状态切换过程如下:①中断源没有被触发的时候,处于初始的"
2023-06-27 21:17:12
492
原创 从零开始理解Linux中断架构(11)---中断屏蔽与开启
当PE发起AArch64执行状态的一个异常,所有的PSTATE中断自动屏蔽。这意味着此后的中断是禁用的。如果软件是支持嵌套的异常,例如,允许一个更高的优先级中断打断处理一个低优先级的来源,那么需要中断处理程序显式地开启中断。(3)在内核态发生的el1_irq有有占先任务调度的情况,当前任务被调度前打开中断。我们前面的阶段介绍了中断程序的外围工作,外围工作保证在硬中断处理阶段中断是关闭的,“至于中断处理阶段到底打开了中断没有,还的看看具体的设备级中断处理函数个性行为。中断被屏蔽“区只是从外围的角度去看的,
2023-06-27 18:12:17
206
原创 从零开始理解Linux中断架构(10)---上下文切换长征路
#10线程需要被调度到#15,pre=#10,next=#15,el0_sync_10执行schedule,将执行流切到了el0_irq_15,此时栈指针SP_EL1指向了#15系统堆栈,el0_irq_15开始执行收尾工作。15#被挂起,中断上下文(pt_regs)存在它的内核栈底部,与他对应的执行流el0_irq_15挂在switch point上,返回信息存储在15#任务的cpu_context上。10#进程为用户态当前运行,SP_EL1指向它的内核栈底部,SP_EL0指向应用程序堆栈。
2023-06-26 20:35:55
255
原创 从零开始理解Linux中断架构(9)---异常执行流与调度
线程的管理在内核中有显式的管理实体(task_struct object),但是对于el0_irq,el0_sync,el1_irq,el1_sync这类handler就没有显式的管理,如下图的el1_irq,代码看起来比较好理解,但是深入了解后,会发现在这函数里经历了很多的堆栈切换,但是el1_irq的存续并没有一个专门的内存结构去存储他的状态,被当成了当前线程的延伸段去处理,把上下文存储在了当前任务的cpu_conext,这就会造成理解的困难。如果需要调度,调度器会选择下一个进程,并且进行进程的切换。
2023-06-26 19:53:20
806
原创 从零开始理解Linux中断架构(8)---执行上下文之CPU上下文
实际上这里使用了一个隐含的事实:Linux所有的任务切换都是在内核中__switch_to函数中进行的,当前任务通过__switch_to->cpu_switch_to切换到(next)。这个过程相对于__switch_to来讲相当于从cpu_switch_to子函数调用返回,不管调度出去多久,寄存器被修改了多少,从__switch_to层面看就是觉得cpu_switch_to执行的时间变成有点长,只是要求这里只需要cpu_switch_to遵循。跟__switch_to是否进行了任务切换一点关系都没有。
2023-06-25 16:24:11
326
原创 从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文
当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是,除了时间流逝外,原来运行的程序应该毫无感知。具体到Armv8架构,中断上下文要保存就是X0-X30。X30是LR寄存器。Armv8在exception发起后,PE做了一些前提工作:(1) CPU core感知到异常发生,生成一个目标异常等级(2) 把PSTATE寄存器里的值保存到对应目标异常等级的SPSR_ELx寄存器便于恢复时使用。
2023-06-24 17:13:29
694
原创 从零开始理解Linux中断架构(6)---Linux执行上下文
上面图中上帝视角的PC指针已经不是应用小“我“看到的那样在“小我逻辑连续“下转移,存在着很多大跳转的情况,这些大跳转早已脱离了下一条指令是“我”决定的条件,打破了小我的逻辑连续,跑到了“他“的逻辑地盘上去了,而这个大转移是操作系统这个“大我“的执行逻辑。PC指针被俘获体现出的本地性,让应用程序的执行逻辑产生了“我"(this)的感觉:CPU在忠实的执行我的代码,我决定了PC的下一条指令,各个运算的结果跟我的设计一致,我掌控了这一切。<对应>PC小跳转(顺序执行,无条件转移,条件转移,函数调用,函数返回)
2023-06-23 19:13:34
271
原创 从零开始理解Linux中断架构(5)--EL跃迁与Linux用户/内核态
这个就是Linux从内核态进入用户态最为本质的代码,最为底层的逻辑。如果先不考虑内存虚拟空间的切换概念,Linux内核态到用户态的切换,其实就是这么的简单。对比一下 图5-1, 图5-2标注红色的部分,就是这么简单的切换模型,完成了linux内核态到用户态的转换。svc支撑起了整个的系统调用让系统从用户态陷入内核态,eret支撑起了从内核态切入用户态的工作。有了前面的基本概念,我们来看看linux是如何包装使用这个最为简单的模型的,让系统从内核态->用户态的函数叫ret_to_user。
2023-06-22 15:22:11
636
原创 从零开始理解Linux中断架构(4)--学习几条ARM汇编指令
因为entry.S是使用汇编指令编写的。我们需要学习几条汇编,以便能够看懂entry.S来消除很多的底层疑惑。这里只需要理解基本的约定和寻址格式和几条常用的指令,达到能够读懂代码的目的就够了。
2023-06-18 21:56:15
309
原创 从零开始理解Linux中断架构(3)--Armv8体系架构
首先让我们带着问题进入到armv8架构的学习中。linux中断代码分为两部分entry.S @arch\arm64\kernel\entry.S汇编部分和C代码后续处理。汇编代码中处理最为低级的部分,设置硬件中断向量表,保持当前上下文,切换中断堆栈等任务,这是就如我们嵌入式系统看到那样。@arch\arm64\kernel\entry.S中对于中断向量表(vectors)的定义如下:一开始我也是看不懂这些代表什么,如果要彻底理解这张表,需要知道一点点ARMV8系统架构中的一些基本知识。PE,
2023-06-15 22:06:49
1611
1
原创 从零开始理解Linux中断架构(2)-朴素的中断管理设计理念
不破除这些迷障,就达不到对系统的深刻理解,中断系统和CPU体系架构息息相关,我们AX3000 WIFI路由器使用的平台是MTK7981,基带是Arm Cortex-a53,系统架构是ArmV8。纯逻辑是跨越系统和应用的,不管对于应用程序员还是系统程序员,逻辑推导是基本的工具,设计原型是基本的出发点。在这个多任务情况下,如果允许抢占(preempt),中断程序执行完毕后,就不一定回到原来的那个任务,这里有一个调度点(schedule),系统会根据任务的优先级和任务等待情况来决定挑选那个任务出来运行。
2023-06-14 21:39:57
395
原创 从零开始理解Linux中断架构(1)-前言
前段时间在转行手撸WIFI路由器,搞wifi路由器需要理解网络驱动程序,以太网卡驱动程序,无线WIFI驱动程序,而网卡驱动的关键路径就在中断程序中,需要了解NIC设备驱动程序如何收发数据,为了彻底的知道数据包是如何二层传递上来的,又需要了解一点Linux中断系统。第一次看到这张表是无感的,大概能够看懂的就是那个中断次数,因为不停的cat,这个数值会一直不停的增加。第一列是逻辑中断号,第二三列是中断次数,第四列是中断控制器的名字,第五列是硬件中断号,第六列 中断类型,第七列是 中断源关联设备。
2023-06-14 14:45:03
715
原创 一个程序员眼中的团队原型思考(3)---- 个体的孤独和团队的力量
团队感想之四:团队是谁,团队是谁的? 经常会看到团队管理者要求每个团队成员应该从全局利益出发,有全局的眼光,团队不是管理者,而是大家,团队不是管理者的,而是大家的。但是从实际的效果上来看,这个强调是起不到作用的,物理归属上明明就是股东的,不是大家的。谈团队是谁的,实际上是谈的对团队的拥有问题,成员对于团队的拥有问题是不用质疑的,当然是老板的。 团队的利益点和个人的利益点不是息息相关的吗?团队的效能提高了,个体收益和满足感也就提高了,这是每个团队成员都能够明确的道理,但是
2010-07-25 22:03:00
12990
60
原创 一个程序员眼中的团队原型思考(2)---个体的孤独和团队的力量
团队感想之三:团队亚文化漩涡的暗力量表征 在团队合作过程中,经常会出现这样的情况,抱怨声声,流言四起,还冷不丁的出现一支冷箭,让人措手不及而受伤倒地,这个现象该如何从整体上去解读?抱怨和冷箭的实质是什么?它们的动力结构是什么?暗箭和抱怨是团队运作过程中人性所致吗? 抱怨是团队运行不顺畅的产物,流言是团队运行不和谐的产物,暗箭是团队派别斗争的产物。抱怨,流言和暗箭只是团队暗力量的外部表征。抱怨是明的,流言则是半明半暗的,而暗枪则是全暗的。 抱怨是团队个体
2010-07-25 21:55:00
10609
6
原创 一个程序员眼中的团队原型思考(1)-个体的孤独和团队的力量
写程序太久了,这大概是中了“原型”的毒了,我对事物的理解都喜欢从最简单的原理开始,喜欢从最为本质的地方开始。只有这样我才能更为深刻的理解新事物。但是带来的问题就是事物的本质不是那么容易搞清楚的,于是就只有半途而废,所以对很多新事物都没有理解就挂掉了。参加拓展训练,感触颇深。鲜活的团队力量让我改变了原来的一些想法,于是乎有如下的思考。 团队感想之一:团队精神的自然属性 只有个体不能完成目标任务时,才会激发团队精神。如果某任务单个体就可以顺利完成,就无需要团队了。原始社会时,我们的老
2010-07-25 21:41:00
23883
53
原创 Android核心分析(28)-----Android GDI之Surface&Canvas
Surface&Canvas Canvas为在画布的意思。Android上层的作图几乎都通过Canvas实例来完成,其实Canvas更多是一种接口的包装。drawPaints ,drawPoints,drawRect,drawBitmap ... 1 Canvas与Surface之间本质关系 对于本节,我们不去研究Skia图形引擎本身,我们需要了解的我们的所做的图形到底放置到了那个地方,并且这个Canvas如何与Surface连接在一起的。 Canvas(Java)在C++
2010-06-14 22:05:00
38610
37
原创 Android核心分析(27)-----Android GDI 之SurfaceFlinger之动态结构示意图
SurfaceFlinger对象建立过程示意 1 SurfaceSession的建立 客户端请求建立Surface时,首先在要与SurfaceFlinger建立一个Session,然后再Session上建立一个Connection通过概念返回Bclient对象。WindowManagerService在添加第一个窗口前会检查SurfaceSession是否建立,如何没有建立,将会新建立一个实例来代表与SurfaceFlinger的一个连接。 new SurfaceSession()@wi
2010-06-14 22:02:00
36249
12
原创 Android核心分析(26)-----Android GDI之SurfaceFlinger
Android GDI之SurfaceFlinger SurfaceFinger按英文翻译过来就是Surface投递者。SufaceFlinger的构成并不是太复杂,复杂的是他的客户端建构。SufaceFlinger主要功能是: 1) 将Layers (Surfaces) 内容的刷新到屏幕上 2) 维持Layer的Zorder序列,并对Layer最终输出做出裁剪计算。 3) 响应Client要求,创建Layer与客户端的Surface建立连接 4) 接收Client要求,修改Layer属性(输出大
2010-06-14 20:31:00
66466
27
原创 Android核心分析(25)------Android GDI之共享缓冲区机制
Androird GDI之共享缓冲区机制 1 native_handle_t对private_handle_t 的包裹 private_handle_t是gralloc.so使用的本地缓冲区私有的数据结构,而Native_handle_t是上层抽象的可以在进程间传递的数据结构。在客户端是如何还原所传递的数据结构呢?首先看看native_handle_t对private_handle_t的抽象包装。 numFds= sNumFds=1; numInts= sNumInt
2010-06-14 16:29:00
33479
13
原创 Android核心分析(24)-----Android GDI之显示缓冲管理
Android GDI之屏幕设备管理-动态链接库 万丈高楼从地起,从最根源的硬件帧缓冲区开始。我们知道显示FrameBuffer在系统中就是一段内存,GDI的工作就是把需要输出的内容放入到该段内存的某个位置。我们从基本的点(像素点)和基本的缓冲区操作开始。 1 基本知识 1.1点的格式 对于不同的LCD来讲,FrameBuffer的二进制格式不一样,并且可以分为两部分: 1)点的格式:通常将Depth,即表示多少位表示一个点。 1位表示一个点
2010-06-14 13:36:00
43227
24
原创 Android核心分析(23)-----Andoird GDI之基本原理及其总体框架
Android GDI基本框架 在Android中所涉及的概念和代码最多,最繁杂的就是GDI相关的代码了。但是本质从抽象上来讲,这么多的代码和框架就干了一件事情:对显示缓冲区的操作和管理。 GDI主要管理图形图像的输出,从整体方向上来看,GDI可以被认为是一个物理屏幕使用的管理器。因为在实际的产品中,我们需要在物理屏幕上输出不同的窗口,而每个窗口认为自己独占屏幕的使用,对所有窗口输出,应用程序不会关心物理屏幕是否被别的窗口占用,而只是关心自己在本窗口的输出,至于输出是否能在屏幕上看见,则
2010-06-13 22:49:00
36130
18
原创 Android核心分析(22)-----Android应用框架之Activity
3 Activity设计框架 3.1 外特性空间的Activity 我们先来看看,Android应用开发人员接触的外特性空间中的Activity,对于AMS来讲,这个Activity就是客服端的Activity。应用程序员在建立Android应用时,构建Activity的子类就是Andoid外特性空间展现的接口。我们可以从下面的简单的例子描述看看Activity,到底如何
2010-05-24 23:32:00
39103
32
原创 Android核心分析(21)----Android应用框架之AndroidApplication
Android Application Android提供给开发程序员的概念空间中Application只是一个松散的表征概念,没有多少实质上的表征。在Android实际空间中看不到实际意义上的应用程序的概念,即使有一个叫Application的类,这个也就是个应用程序上下文状态,是一个极度弱化的概念。Application只是一个空间范畴的概念,Application就是Activit
2010-05-24 23:31:00
77919
36
原创 Android核心分析(20)----Android应用程序框架之无边界设计意图
Android应用程序框架 1 无边界设计理念 Android的应用框架的外特性空间的描述在SDK文档(http://androidappdocs.appspot.com/guide/topics/fundamentals.html#acttask)有十分清楚的描述,Android应用的基本概念,组件生命周期等等有详细的描述。在外特性空间中,Android提供了Activit
2010-05-23 22:06:00
30732
27
原创 Android核心分析(19)----电话系统之GSMCallTacker
Android电话系统之GSMCallTracker 通话连接管理 GSMCallTracker在本质上是一个Handler。 GSMCallTracker是Android的通话管理层。GSMCallTracker建立了ConnectionList来管理现行的通话连接,并向上层提供电话调用接口。 在GSMCallTracker中维护着通话列表:connections。顺序记录了
2010-05-14 23:15:00
31354
6
原创 Android核心分析(18)-----Android电话系统之RIL-Java
Android RIL-Java RIL-Java在本质上就是一个RIL代理,起到一个转发的作用,是Android Java概念空间中的电话系统的起点。在RIL-D的分析中,我们知道RILD建立了一个侦听套接口,等待RIL-Java的连接。一旦连接成功,RIL-JAVA就可发起一个请求,并等待应答,并将结构发送到目标处理对象。在RIL-Java中,这个请求称为RILRequest。为
2010-05-14 23:07:00
57096
26
原创 Android核心分析(17) ------电话系统之rilD
Android电话系统之-rild Rild是Init进程启动的一个本地服务,这个本地服务并没有使用Binder之类的通讯手段,而是采用了socket通讯这种方式。RIL(Radio Interface Layer) Android给出了一个ril实现框架。由于Android开发者使用的Modem是不一样的,各种指令格式,初始化序列都可能不一样,GSM和CDMA就差别更大了,所以为了消除这些差
2010-05-10 22:41:00
63081
40
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人