container_of

定义:

/**

 * container_of - cast a member of a structure out to the containing structure

 * @ptr:the pointer to the member.

 * @type:the type of the container struct this is embedded in.

 * @member:the name of the member within the struct.

 *

 */

#define container_of(ptr, type, member) ({\

const typeof(((type *)0)->member) * __mptr = (ptr);\

(type *)((char *)__mptr - offsetof(type, member)); })

#endif

 

第一步:

      Const typeof (((type *)0->member) * __mptr=(ptr)

         Struct list_head *__mptr=ptr

第二步:

       (type *)(char *)__mptr -offsetof(type,menber)

        0x***-offset

第三步:offsetof(type,member)

             ((TYPE *)0)->MEMBER

                  &(TYPE *)0)->MENBER

(TYPE *)0 这是一个强制类型转换,把0地址强制类型转换成一个指针,这个指针指向一个TYPE类型的结构体变量。 (实际上这个结构体变量可能不存在,但是只要我不去解引用这个指针就不会出错)。

((TYPE *)0)->MEMBER (TYPE *)0是一个TYPE类型结构体变量的指针,通过指针指针来访问这个结构体变量的member元素


&((TYPE *)0)->MEMBER  等效于&(((TYPE *)0)->MEMBER),意义就是得到member元素的地址。但是因为整个结构体变量的首地址是0,

 

 

 

 

 

内核定时器

时钟中断

HZ:常数决定了时钟发生的频率

Tick:发生时间中断的时间间隔tick=1/HZ

Jiffies:核心变数,

struct timer_list

{

unsigned long expires;超时时间

void *function)(unsigned long0)处理函数

unsigned long data;内核调用超时处理函数时传递给它的参数

 

}

静态初始化

TIMER_INITALIZER(_function,_expires,_data)

DEFINE_TIME(_name,_function,_expires,_data);

_name 待定义的内核定时器变量名称

Void init_timer(struct timer_list *timer);

 

修改定时器

wKiom1g6MEviN7l2AACB4QttqMw102.png-wh_50

 

 

 

init_timer(time)初始化定时器,传地址

#define BARK_TIMER  5

#deifne BARK_DATA  100

Xxx.expires = jiffies+HZ*BARK_TIMER;//BARK_TIMER=5五秒

Xxx.function=xxxxxx

Xxxx.data=BARK_DATA;

Add_timer(&xxxxx

 

del_timer()

 

 

 

 

2系统调用

 ANSI C fopen(标准c的库函数)

UNIX C  open (系统调用)

 

 

用户态的程序一般情况是不能访问内核态的资源,只有通过中断或者系统调用才能从用户态进入内核态

 

 

2.6.35366个内核系统调用为应用程序服务。

系统调用的原理:

应用程序首先使用适当的值填充寄存器,然后调用一个特殊的指令,跳转到内核某个固定的位置,内核根据应用程序所填充的固定值来找到相应的函数执行。

适当的值:arch/arm/asm/unistd.h

调用特殊指令 arm->SWI(软中断)

              X86  0x80

固定位置:在arm体系中,应用程序跳转到entry-conmmon ->vector_swi ->会用到sys_call_table(calls.S)

 

 

用户空间编程 fd=openaa.txt...

            5->寄存器  

             SWI

      ____________________

            vector_swi

                 sys_call_table[5]

                       sys_open  

                             SYSCALL_DEFINR3  拼接   

 

1)添加新的内核函数

   vim arch/arm/kernel/sys_arm.c

   Asmlinkage int sys_add(int x,int y)

   {

        printk(entry sys_add!\n);

        Return x+y;

}

2)更新头文件 arch/arm/include/asm/unistd.h

      #define __NR_add    (__NR_SYSCALL_BASE+366)

  3)更新系统调用表(calls.S

CALL(sys_add)

 最后make下即可