M-book

求上得中, 求中得下, 求下得无!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

随笔分类 -  Kernel

摘要:在讨论全局变量之前我们先要明白几个基本的概念:1. 编译单元(模块): 在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ERROR), 因为它不像编译错误那样可以给出你程序错误的具体位置,你常常对这种错误感到懊恼,但是如果你经常使用gcc,makefile等工具在linux或者嵌 入式下做开发工作的话,那么你可能非常的理解编译与连接的区别!当在VC这样的开发工具上编写完代码,点击编译按钮准备生成exe文件时,VC其实做了两 步工作,第一步,将每个.cpp(.c)和相应.h文件编译成obj文件;第二步,将工程中所有的obj文件进 阅读全文

posted @ 2011-10-12 15:51 M-book 阅读(1930) 评论(0) 推荐(0)

摘要:volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。用volatile关键字声明的变量i每一次被访问时,执行部件都会从i相应的内存单元中取出i的值。没有用volatile关键字声明的变量i在被访问的时候可能直接从cpu的寄存器中取值(因为之前i被访问过,也就是说之前就从内存中取出i的值保存到某个寄存器中),之所以直接从寄存器中取值,而不去内存中取值,是因为编译器优化代码的结果(访问cpu寄存器比访问ram快的多)。以上两种情况的区别在于被编译成汇编代码之后,两者是不一样的。之所以这样做是因为变量i可能会经常变化,保证对特殊地址的稳定访问。=====以下 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(210) 评论(0) 推荐(1)

摘要:在大型C语言项目工程或者linux内核中我们都会经常见到两个FASTCALL和armlinkage两个标识符(修饰符),那么它们各有什么不同呢?今天就给大家共同分享一下自己的心得.大家都知道在标准C系中函数的形参在实际传入参数的时候会涉及到参数存放的问题,那么这些参数存放在哪里呢? 有一定理论基础的朋友一定会肯定地回答:这些函数参数和函数内部局部变量一起被分配到了函数的局部堆栈中,真的是这样吗?其实还有例外的情况:首 先作为linux操作系统,它不一定就只运行在X86平台下面,还有其他平台例如ARM,PPC,达芬奇等等,所以在不同的处理器结构上不能保证都是通过 局部栈传递参数的,可能此时就有朋 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(224) 评论(0) 推荐(0)

摘要:linux i386 kernel中:#define fastcall __attribute__((regparm(3)))#define asmlinkage __attribute__((regparm(0))) 函数定义前加宏asmlinkage ,表示这些函数通过堆栈而不是通过寄存器传递参数。 宏asmlinkage定义如下:#define asmlinkage __attribute__((regparm(0))).gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(256) 评论(0) 推荐(0)

摘要:在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。(1)先来介绍它的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。下面是a.c的内容char a = 'A'; // global variablevoid msg(){printf("Hello\n");}下面是main.c的内容int main(void){extern char a; // extern variable m 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(239) 评论(0) 推荐(0)

摘要:1.内存屏障(memory barrier) #define set_mb(var, value) do { var = value; mb(); } while (0) #define mb() __asm__ __volatile__ ("" : : : "memory")1)set_mb(),mb(),barrier()函数追踪到底,就是__asm__ __volatile__("":::"memory"),而这行代码就是内存屏障。 2)__asm__用于指示编译器在此插入汇编语句 3)__volatile_ 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(827) 评论(0) 推荐(1)

摘要:推荐 volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有 volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触发,所以经常会写出这样的程序: short flag; void test() { do1(); while(flag==0); do2(); } 这段程序等待内存变量flag的值变为1(怀疑此处是0,有点疑问,)之后才运行do2()。变量flag的值由 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(193) 评论(0) 推荐(0)

摘要:typedef在C中真是一个神奇的东西,没有点事例真是很难理解:(回头看看那超烂的大学C教程,很多地方没写清楚,遇到问题时看不懂代码。u-boot中有这么一段代码。/*这里定义了一个新的数据类型init_fnc_t,*这个数据类型是参数为空,返回值为int的函数。*/typedef int (init_fnc_t) (void);/*init_sequence是一个指针数组,指向的是init_fnc_t类型的函数*/init_fnc_t *init_sequence[] = {cpu_init, /* basic cpu dependent setup */board_init, /* bas 阅读全文

posted @ 2011-08-28 22:55 M-book 阅读(226) 评论(0) 推荐(0)

摘要:1、typedef int (init_fnc_t) (void);表示定义init_fnc_t为函数类型,该函数返回int型,无参数。而“init_fnc_t *init_sequence[]={cpu_init, board_init }”表示用init_fnc_t(函数类型)去定义一个一维指针数组,数组中的元素都是指针变量,而且都是指向函数的指针,这些函数返回值都是int型,无参数的。更明朗的说就是数组中的每个元素是用来存放函数入口首地址的。2、int (*init_fnc_t) (void);表示定义一个函数指针(返回值为int型,无参数的函数指针,存放的是函数的首地址),typede 阅读全文

posted @ 2011-08-28 22:55 M-book 阅读(954) 评论(0) 推荐(0)

摘要:摘要: 在学习linux内核代码及一些开源软件的源码(如:DirectFB),经常可以看到有关__attribute__的相关使用。本文结合自己的学习经历,较为详细的介绍了__attribute__相关语法及其使用。GNU C的一大特色(却不被初学者所知)就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__书写特征是:__attribute__前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__a 阅读全文

posted @ 2011-08-27 17:59 M-book 阅读(299) 评论(0) 推荐(0)

摘要:From http://hi.baidu.com/cygnusnow/blog/item/8b82000f871fcf2f6159f3de.htmlGNU C的一大特色(却不被初学者所知)就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__书写特征是:__attribute__前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数。__attribute__语法格式为:__ 阅读全文

posted @ 2011-08-27 16:45 M-book 阅读(203) 评论(0) 推荐(0)

摘要:Android、X windows、qt等众多应用对于linux系统中键盘、鼠标、触摸屏等输入设备的支持都通过、或越来越倾向于标准的input输入子系统。 因为input子系统已经完成了字符驱动的文件操作接口,所以编写驱动的核心工作是完成input系统留出的接口,工作量不大。但如果你想更灵活的应用它,就需要好好的分析下input子系统了。 一、input输入子系统框架 下图是input输入子系统框架,输入子系统由输入子系统核心层( Input Core ),驱动层和事件处理层(Event Handler)三部份组成。一个输入事件,如鼠标移动,键盘按键按下,joystick的移动等等通过 in. 阅读全文

posted @ 2011-08-26 18:18 M-book 阅读(427) 评论(0) 推荐(0)

摘要:Eric Fang 2010-02-04--------------------------------------------------------------本站分析linux内核源码,版本号为2.6.32.3转载请注明出处:http://ericfang.cublog.cn/--------------------------------------------------------------接上一篇文章继续分析。三.input_event事件的处理事件的处理的接口函数为input_event,在\linux\input.h中还定义了、 input_report_key、input 阅读全文

posted @ 2011-08-24 16:15 M-book 阅读(903) 评论(0) 推荐(0)

摘要:Eric Fang 2010-02-03--------------------------------------------------------------本站分析linux内核源码,版本号为2.6.32.3转载请注明出处:http://ericfang.cublog.cn/--------------------------------------------------------------接上一篇文章继续分析。二.Input handler的注册在Input device的注册中存在下列疑问:1, 匹配dev和handler时,input_handler_list上的handl 阅读全文

posted @ 2011-08-24 16:03 M-book 阅读(487) 评论(0) 推荐(0)

摘要:Eric Fang 2010-02-03--------------------------------------------------------------本站分析linux内核源码,版本号为2.6.32.3转载请注明出处:http://ericfang.cublog.cn/--------------------------------------------------------------在前面键盘驱动的分析中已经接触到了输入子系统,本文将结合键盘驱动,系统分析输入子系统。回想一下,在设备驱动匹配成功时,创建了一个input_dev并注册到输入子系统;在键盘中断处理例程中向输入 阅读全文

posted @ 2011-08-24 15:55 M-book 阅读(701) 评论(0) 推荐(0)

摘要:由于linux还不是一个实时的操作系统,因此如果需要更高精度,或者更精确的定时的话,可能就需要打一些实时的补丁,或者用商用版的实时linux,. 这里内的定时器最小间隔也就是1个tick. 这里还有一个要注意的,我这里的分析并没有分析内核新的hrt 定时器.这个定时器是Monta Vista加入到内核的一个高精度的定时器的实现. 先来看几个相关的数据结构. ///这个是一个最主要的数据结构,表示一个完整的定时器级联表 Java代码 structtvec_base{ ///自旋锁 spinlock_tlock; ///表示由本地cpu正在处理的定时器链表 structtimer_list*run 阅读全文

posted @ 2011-08-24 15:23 M-book 阅读(701) 评论(0) 推荐(0)

摘要:LINUX内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 <linux/timer.h> 和 kernel/timer.c 文件中。被调度的函数肯定是异步执行的,它类似于一种“软件中断”,而且是处于非进程的上下文中,所以调度函数必须遵守以下规则:1) 没有 current 指针、不允许访问用户空间。因为没有进程上下文,相关代码和被中断的进程没有任何联系。2) 不能执行休眠(或可能引起休眠的函数)和调度。3) 任何被访问的数据结构都应该针对并发访问进行保护,以防止竞争条件。内核定时器的调度函数运行过一次后就不会再被运行了(相当于自 阅读全文

posted @ 2011-08-24 15:20 M-book 阅读(325) 评论(0) 推荐(0)

摘要:Linux per_cpu机制的详解 针对IA64体系结构 在Linux操作系统中,特别是针对SMP或者NUMA架构的多CPU系统的时候,描述每个CPU的私有数据的时候,Linux操作系统提供了per_cpu机制。 per_cpu机制就是让每个CPU都有自己的私有数据段,便于保护与访问。 通过宏DEFINE_PER_CPU,定义这种私有数据,只不过这种私有数据放在特定的数据段中。 #define DEFINE_PER_CPU(type, name) \ __attribute__((__section__(".data.percpu"))) \ PER_CPU_ATTRIB 阅读全文

posted @ 2011-08-24 15:18 M-book 阅读(5029) 评论(0) 推荐(0)

摘要:3.5.2 网路超时重传 对于 TCP 协议而言,如果某次发送完数据包后,并超过一定的时间间隔还没有收到这次发送数据包的 ACK 时, TCP 协议规定要重新发送这个数据包。 在 Linux2.6.25 的内核中,这种数据的重新发送使用软件时钟来完成。这个软件时钟保存在面向连接的套接字(对应内核中 inet_connection_sock 结构)中。对这个域的初始在函数 tcp_init_xmit_timers 中,如清单3-15 清单3-15 函数 tcp_init_xmit_timers 、函数 inet_csk_init_xmit_timers 和函数 setup_timervoid t 阅读全文

posted @ 2011-08-24 15:17 M-book 阅读(491) 评论(0) 推荐(0)

摘要:函数首先获得到本地 CPU 的 base 。然后检测如果 jiffies 注: hrtimer_run_pending() 函数是高精度时钟的处理。本文暂没有涉及高精度时钟相关的内容。 大于等于 timer_jiffies ,说明可能已经有软件时钟到期了,此 时就要进行软件时钟的处理,调用函数 __run_timers 进行处 理。如果 jiffies 小于 timer_jiffies ,表明没有软件时钟到期, 则不用对软件时钟进行处理。函数返回。 接下来看一下函数 __run_timers 都作了些什么,如清单3-9 清单3-9 __run_timers函数static inline voi 阅读全文

posted @ 2011-08-24 15:15 M-book 阅读(400) 评论(0) 推荐(0)