蜗窝科技

关于Linux各种上下文的理解

蜗窝讨论区存档 · Linux kernel技术问答 · 楼主 electrlife · 2016-11-30 · 2 帖

本文是原「蜗窝讨论区」的历史存档(2016-11-30),来自版块「Linux kernel技术问答」,共 2 帖。讨论区已停止服务,此处仅供查阅。

electrlife · 2016-11-30 18:02

在 /memory_management/mm-init-1.html#4940贴子上有网友提出了如下问题?

>> Hello,linuxer >> 请教一个问题,可能对你比较简单,但是我百思不得其解 >> Linux中的各个驱动是在进程的上下文里面执行的吗,如果是,在哪个进程

个人觉得这是个很好的问题,想了想似乎我也不能很好去回答这个问题,因此在这里提出来希望各位大侠们来解惑!

下面是我从另一个角度去理解(以下全部是个人出于对程序的理解而得出的猜测):

对于“上下文”这个词,我觉得需要理解清楚,“上下文”应该源于context这个词,我的理解是指一段程序运行时所处的相应的系统状态。 因为这种系统的状态影响着程序的各种行为方式。比如中断context不可以blocking。因此可以分为以下几种,但这种划分方式也是不严格的,依赖于具体的软硬件系统结构: 1. 进程context 2. 中断context 以上两种context应该存在于所有的体系中(如有例外,请各位补充:)),对于linux而言,似乎又多了个“内核context”。但对于Linux是否还存在其它的 context,我不得而知,各位高手们补充!

对于内核也只不过是一堆函数的集合,每个函数也需要相应的stack,这些函数运行时也会遇到blocking,因此也需要相应的空间去保存 其运行的上下文(context 后面以此词代替)。这些函数依据调用者可以简单分为以下几种: 1. 在内核空间有很多内核thread,那运行在这些线程的函数毋庸置疑会保存在相应线程的context中。 2. 中断程序,这个毫无疑问运行在中断context 3. 系统调用,用户空间的程序会调用来运行内核空间的相应的函数,如:processA-->open-->sys_open, 此时sys_open运行在内核空间 因此系统应该提供相应的专门的stack空间供sys_open使用(系统如何提供这样的stack?)。如果此时sys_open由于资源缺乏而pending了,显然此时我们需要保存其相应的stack及CPU registers,那保存到哪里呢,我觉得应该保存到相应的process对应的stack上(或许保存到该process相关联的某个空间,因为从安全的角度考虑,内核的stack保存在process stack上毕竟不太放心),也即本例中的processA。简化整个调用过程如下: processA-->open-->sys_open-->SVC xxx-->(保存相应的registers,切换到相应的stack,返回并执行相应的system call:do_sysopen)-->pending(保存此时的stack及registers到相应的processA某个空间)

从上面的描述可以认为sys_open运行在内核context。

类比驱动程序的执行,也可以简单认为驱动是一些函数,也会因为调用者的不同而不同。 如:在中断中调用则运行在中断的context,也可能运行在内核thread中。 当然也可能运行在系统调用里,那相应的情景就如上所述!

思考: 1. 驱动程序如果被内核thread调用,其stack应该是由该thread提供,是不是意味着可以定义很大的变量在其stack,因为thread的stack我理解是可依据需求自动扩大的。

  1. 驱动程序如果被系统调用中被调用,那其运行context不是在process的context,我的理解其stack是系统分配的固定大小,因此此驱动函数定义局部变量时需要格外注意其大小。

以上是我个人的理解,请不吝赐教!

jack · 2016-12-01 18:19

对于系统调用,每一个进程调用,那么系统调用自然运行在当前进程的内核空间,这么说主要是因为调用并没有切换地址空间,仅仅是切换了内核栈,而内核栈就是当前进程的内核栈。如果遇到pending,保存应该也是保存在这个栈中。 对于中断context,看怎么理解了,其和进程context还有些区别,个人感觉中断context只是标记当前在处理中断,防止中断重入,至于使用的栈和寄存器等,还要考虑到当时运行级别以及中断表中对应的门类型。个人理解