Chinaunix首页 | 论坛 | 博客
  • 博客访问: 82145
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-23 11:54
个人简介

让思想和双脚带我去梦的远方

文章分类

全部博文(13)

文章存档

2015年(7)

2014年(6)

我的朋友

分类: 嵌入式

2014-12-22 11:23:58

内核编译宏
  • __attribute__     
    __attribute__(section),__attribute__是关键字,是gcc的C语言扩展,它可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。用来修饰函数时,可以使你把代码放在image的不同段,如:
    void f(void) __attribute__((section(“new_section”)));
    函数f()将被放到只读new_section段中,而不是.text中。
    __attribute((regparm(0))),告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。
    __attribute((regparm(3))),告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。
    gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器, 缺省使用寄存器,假如想通过堆栈传递,定义的c函数时要在函数前加上宏asmlinkage。

  • asmlinkage
    在看内核源代码start_kernel函数时,第一个遇到的疑问是asmlinkage,原来asmlinkage是一个宏,在不同的cpu体系结构中对应不同的定义,多数的cpu体系结构都没有对此宏做相应扩展。在x86体系里,它定义在文件include/arch/x86/include/asm/linkage.h中,具体如下:

点击(此处)折叠或打开

  1. #ifdef CONFIG_X86_32
  2. #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))
    
    这个定义表示被asmlinkage这个宏修饰的函数在x86体系结构中通过堆栈传递参数。
    其中CPP_ASMLINKAGE也是一个宏,定义在include/linux/linkage.h头文件中,具体为:

点击(此处)折叠或打开

  1. #ifdef __cplusplus
  2. #define CPP_ASMLINKAGE extern "C"
  3. #else
  4. #define CPP_ASMLINKAGE
  5. #endif
    
     “C”是用来实现C++和C的混合编程,而__cplusplus是C++语言固定的宏,用于判断是不是用C++语言写的程序。
    总的来说,asmlinkage是个宏,使用它是为了保持参数在stack中,因为从汇编语言到C语言代码参数的传递是通过stack的,它也可能从stack中得到一些不需要的参数,asmlinkage将要解析那些参数。


  • __init
     __init是一个宏定义,定义在arch/um/include/shared/init.h文件中,具体如:

点击(此处)折叠或打开

  1. #define __init        __section(.init.text)
  2. #define __initdata    __section(.init.data)
  3. #define __exitdata    __section(.exit.data)
  4. #define __exit_call   __used __section(.exitcall.exit

    这个标志符和函数声明放在一起,它表示gcc编译器在编译的时候需要把这个函数放在.init.text中,而这个section在内核完成初始化之后会被释放掉。其中__section字段和__init定义在同一个文件中,定义如下:

点击(此处)折叠或打开

  1. #ifndef __KERNEL__
  2. #ifndef __section
  3. # define __section(S) __attribute__ ((__section__(#S)))
  4. #endif

  • register
    register可以用来修饰变量,表示寄存器变量,只能用于整型和字符变量,表示变量被存储在CPU的寄存器中,而不像普通变量被存储在内存中,这样可 以提高运算速度,它常用于在同一变量名频繁出现的地方,且它只适用于局部变量和函数的形式参数,它属于auto型变量,不能作为全局变量

  • EXPORT_SYMBOL
    若内核函数或变量要被内核模块调用,则必须使用EXPORT_SYMBOL宏进行处理,作用之一是将该符号连接到二进制文件的各个__ksymtab_xx_xx section,内核加载模块时,会先确认该模块调用的各内核函数是否已export,也就是说EXPORT_SYMBOL可以将一个函数或变量以符号的方式导出给其他模块使用。
阅读(6649) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~