共计 1814 个字符,预计需要花费 5 分钟才能阅读完成。
“我以前始终想不明确:为什么我一个小小散户竟能左右整个股市?不论之前涨势如许疯狂,我一买入它必然上涨!我一卖出它就上涨。我一空仓大盘疯涨,我一满仓大盘狂泻。手握百亿资金的庄家们竟死死盯着我手里这几万块钱不放。这到底是为啥?”
A 股让我琢磨不透,然而在计算机里,中断和过程也是让人琢磨不透?比方某个微信群里探讨问题:在非抢占 Linux 内核中,为啥中断产生在内核态的时候不去抢占?
这个问题显著就是中断和过程之间的那些扯不分明的事件。为啥在 Linux 2.4 内核里没有实现中断抢占呢?其实大家都是从当初 Linux 4.x 内核的眼光来看老版本的内核。要晓得 LInux 内核也是 90 后哟,它诞生于 91 年,当初才 27 岁。
对于中断和过程之间那些事,笨叔感觉如下几个问题挺有意思
中断产生时候,ARM 处理器到底帮你做了那些事件?
[大家能够见《奔跑吧 Linux 内核》第 618~ 625 页]
-
如果中断产生在内核态,它的中断上下文 到底寄存在什么中央?有那些寄存器须要存?或者说那些寄存器是主演,那些寄存器其实是主角?
[参考第 625 页这个图] 这个问题,大家须要搞清楚,IRQ 栈和 SVC 栈到底存了些啥东东,那些寄存器是必须的,也就是配角,没有它不行。那些寄存器其实跑龙套的,有没有不伤大雅。
3. 如果中断产生在用户态,它在中断解决实现之后,它是怎么返回到用户空间?[这个问题,大家能够去看汇编,这个在《奔跑吧》里没有去详细分析这个__irq_usr 这个汇编函数,这个函数不简单,大家能够本人去浏览]
- 假如时钟的 tick 中断来了,而且它产生在用户空间,硬件中断实现之后,查看当初须要调度,那么调度到下一个过程 next 运行,假如这个 next 过程也是用户过程,那么这个 next 过程到底从什么中央开始执行?
[这个问题,其实很有意思,假如 A 用户过程在 B 这个中央,产生了中断,之后,又产生了调度。那如果一段时间之后,A 过程又被调度回来,它是不是从 B 这个中央开始执行呢?
要搞清楚这个问题,大家能够看《奔跑吧 linux 内核》第 369~374 页的形容,也能够参考这个图。其实关键点是在 switch_to 函数的实现和了解上 ]。
switch_to() 函数如果简略的总结的话,其实两条语句就够了。如上面:
cpu_switch_to:
stmia r0!, {r4 - sl, fp, sp, lr} @store regs on stack
ldmia r1, {r4 - sl, fp, sp, pc} @load all regs saved previously
假如 r0 指向 prev 过程的 cpu_context 数据结构,r1 指向 next 的 cpu_context 数据结构。
第一条汇编把 prev 过程的 sp 和 lr 寄存器保留到 r0 指向的 cpu_context 里,而后把 next 过程中 cpu_context 里的 sp 和 lr 寄存器装载在 CPU 硬件的寄存器里,就这么简略实现了 过程上下文切换。实现切换之后,next 过程就从 ldmia 这条指令下一条指令开始运行了,真的哟,真的开始运行了。。。
小明纳闷的说:笨叔,我怎么能验证你说的鬼话呢?
笨叔:其实很简略,你用笨叔的“O0”内核来 debug 单步一下,你能够在 switch_to 函数里设置断点,而后察看 prev 和 next 过程的 cpu_context 外面的 lr 都装了啥值,
小明:唷,好方法,我就去试试
笨叔:同时能够能够把 prev 和 next 的 sp 栈打印进去看看哟
小明:好嘞,笨叔
cpu_context 是啥什么鬼,小伙伴能够看第 342 页的 copy_thread() 函数里,过程第一次被创立的时候 cpu_context 里到底装了什么葫芦。
预计有小伙伴对 pt_regs 和 cpu_context 这两个数据结构玩意搞糊涂了吧,其实如果,你把这两个数据结构的用意和用处想明确了,上述这个问题都不是问题。pt_regs 是保留以后过程产生中断或者异样或者零碎调用等状况的时候 CPU 的上下文,它是寄居在过程内核栈的顶部。而 cpu_context 算是 PCB 的外围保留成员,PCB 是啥?不是电路板,是过程外围管制块。cpu_context 只是用来保留过程切换时候的 CPU 状态,其实就是 SP 和 LR 有用,他们俩个是配角。
明天笨叔废话一大堆,呵呵。笨叔弱弱问一句,我的中断来了,A 股的“底”到底到木有?欢送小伙伴在评论区留言,到“底”来了没?
最初,大家记得关注笨叔的书和配套视频,《奔跑吧 linux 内核》,笨叔出品,笨笨的滋味,总有你想要的!