Kernel - 拳不离手、曲不离口 - Speak with your code, my friend, not your word.

[玩转kernel系列]中断

ARM里的中断通常是指IRQFIQ,以IRQ来讲,ARMIRQ的处理过程大概是这样:  

外部设备遇到某一事件发出一个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对应的代码

 

继续阅读

[玩转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 <stdio.h>
#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