[玩转kernel系列]中断
ARM里的中断通常是指IRQ和FIQ,以IRQ来讲,ARM对IRQ的处理过程大概是这样:
外部设备遇到某一事件发出一个IRQ中断给中断控制器,中断控制器对这个IRQ进行硬件上的处理,把一些信息记在中断控制器的寄存器上,然后中断控制器通过IRQ中断线给ARM发一个信号。ARM收到信号,开始进行以下处理:
(1)将当前状态的cpsr拷贝到IRQ状态的spsr中。
(2)将pc拷贝到IRQ状态的lr中。
(3)屏蔽cpsr中的IRQ位和FIQ位。
(4)跳转入中断向量表的IRQ表项执行(改变pc的值)。
以上都是ARM cpu做的事,不需要程序员插手,程序员编的代码需要接在后面处理。
程序员需要做的是接下来的步骤:
(5) 备份上下文。
e.g.:
sub lr, lr, #4
stmfd sp!, {r0 - r12, lr}
(6)跳入handler。
e.g.:
bl IRQ_Handler
(7):恢复上下文。
e.g.:
ldmfd sp!, {r0 - r12, sp}^
就这么简单!
来看kernel对应的代码
![endif]--> !--[if> ![endif]--> !--[if> ![endif]--> !--[if>
[玩转kernel系列]从今天起,我开一个《玩转kernel》系列,同时期待大家的讨论。
其实我也是刚接触kernel的,在学习过程中的一些心得体会,我想以这种形式写出来,既是对自己学习的一种总结,也为了回馈网络上其他网友对我在学习中的帮助,大家共同学习,共同进步。
介绍一下《玩转kernel》这个系列的样式。所涉及到的硬件平台是ARM。我会将kernel分成若干块来讲,kernel代码量很大,但大体可分为进程管理、存储管理、文件系统、设备驱动以及网络这几个大块,另外还有其他一些东东可以拿出来单独看,比如中断、系统调用等。《玩转kernel》会一块一块来讲,但不会一下子全讲,因为我的能力还有限,另外这不是一个科学的学习方法。我很崇拜c++ primer里的一句话,那就是分而治之、逐步求精。所以这个系列尽量按照这个原则讲。另外基本概念不讲,所以你可能需要一点基础才能看懂,这些基础可以去看大学的课本,我主要还是讲kernel的具体代码实现。
每个专题只有一个总文档(level 1),其他都是不同level的分文档,在总文档里我会把最重要的,最有代表性的代码拿出来讲,而不会讲细节以及运用到的技巧。我的目的,通过总文档,大家可以一览kernel中某个机制的框架,以及代码实现。总文档是一个专题的入口,然后细节以及运用到的技巧会以超链接的方式链到各个分文档中,并且在分文档中也会用到总分的概念。这样的一个专题,就很像一个树,这个树由于本人能力以及时间有限,不会一下子写完,可能会长期处于一个待续的状态。有兴趣的朋友可以经常来看看。好,关于这个系列的具体情况,还要看具体的文章,简单的介绍就讲到这里。
cpu什么时候由执行用户代码转入执行内核代码?
在发生系统调用或者中断的时候。
处理系统调用的那部分内核代码,由于系统调用是在某一个进程中产生的,所以这部分内核代码将工作在“进程上下文”;
处理中断的那部分内核代码,由于中断往往是和外围设备相关,与进程关系不大,所以这部分代码将工作在“中断上下文”。
[存储管理]一个c程序在内存中的映射分为哪几部分?
高地址(3G)
... |
stack |
. . . |
heap |
bss |
data |
rodata |
text |
. . . |
低地址(0)
在用户存储空间,一个c程序的映射可分为6部分,代码段、常量段、数据段、bss段、堆、栈。
其中:
常量主要是指字符串常量;
数据是指函数外定义的、初始化过的变量;
bss是指函数外定义的、未初始化过的变量;
局部变量、子函数返回地址、传给子函数的参数都在栈中分配,方向由高地址向低地址;
动态分配的空间在堆中,方向由低地址向高地址。
运行以下程序,程序各部分在内存中的相对位置一目了然。
#include <malloc.h>
int i = 5, j;
void subfunc(int a)
{
printf("arg:%p\nsubfunc:%p\n",&a, subfunc);
}
int main(void)
{
int tmp = i - 1;
char *p = "abcde";
int a[5];
printf("data:%p\nbss:%p\nautovar:%p\nconst:%p\narray:%p\n",\
&i, &j, &tmp, p, &a[0]);
p = malloc(sizeof(a) / sizeof(a[0]));
for (; tmp >= 0; tmp--)
p[tmp] = a[tmp];
printf("heap:%p\nfunc:%p\n", p, main);
subfunc(tmp);
free(p);
return 0;
}
[文件管理]Almost everything in Unix can be treated as a file.
Qouted from LDD3 page 4.
[设备驱动]linux下各种设备的驱动,共性和个性并存。
...
Each driver is different; as a driver writer, you need to understand your specific device well. But most of the principles and basic techniques are the same for all drivers.
...
--- Quoted from LDD3 page 1