array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 【转】Linux 内核常见宏定义 - 爱码网

Linux 内核常见宏定义

 

  我们在阅读Linux内核是,常见到这些宏 __init, __initdata, __initfunc(), asmlinkage, ENTRY(), FASTCALL()等等。它们定义在 /include/linux/init.h 和 /include/linux/linkage.h 以及其他一些.h 文件中。

  1. __init

      位置:/include/linux/init.h

      定义: #define __init   __attribute__ ((__section__ (".init.text")))

      注释:这个标志符和函数声明放在一起,表示gcc编译器在编译时,需要把这个函数放在.text.init Section 中,而这个Section 在内核完成初始化之后,就会被释放掉。

  举例:asmlinkage void __init star_kerne(void) { ... }

 

  2. __initdata

  位置:/include/linux/init.h

  定义:#define __initdata __attribute__ ((__section__ (".init.data")))

  注释:这个标志符和变量声明放在一起,表示gcc编译器在编译时,需要把这个变量放在.data.init Section中,而这个Section 在内核完成初始化之后,会释放掉。

  举例:static struct kernel_param raw_params[] __initdata ={ ... }

 

  3. __initfunc()

  位置:/include/asm-i386/init.h

  定义:#define __initfunc(__arginit) \      __arginit __init; \      __arginit

  注释:__initfunc() 是一个自定义宏,用来定义一个 __init 函数,在Linux-2.4中已被__init宏所取代。

  举例:__initfunc (void mem_init(unsigned long start_mem, unsigned long end_mem)) { ... }

 

  4. asmlinkage

  位置:/include/linux/linkage.h

  定义:#define asmlinkage CPP_ASMLINKAGE  __attribute__((regparm(0)))

  注释:这个标志符和函数声明放在一起,带regparm(0)的属性声明告诉gcc编译器,该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈传递参数,你定义的 c 函数时要在函数前加上宏asmlinkage。

  举例:asmlinkage void __init start_kernel(void) { ... }

 

  5.ENTRY()

  位置:/include/linux/linkage.h

  定义:#define ENTRY(name) \                 .globl name; \                 ALIGN; \                 name:

  注释:将name 声明为全局,对齐,并定义为标号。

  举例:     

   ENTRY(swapper_pg_dir)
 
  .long 0x00102007
 
  .fill __USER_PGD_PTRS-1,4,0
 
 <span style="color: rgb(0, 0, 255);"> /* default: 767 entries */
</span>
  .long 0x00102007
 
<span style="color: rgb(0, 0, 255);">  /* default: 255 entries */
</span>
  .fill __KERNEL_PGD_PTRS-1,4,0
 
等价于
 
  .globl swapper_pg_dir
 
  .align 16,0x90
 
<span style="color: rgb(0, 0, 255);">  /* if i486 */
</span>
  swapper_pg_dir:
 
  .long 0x00102007
 
  .fill __USER_PGD_PTRS-1,4,0
 
<span style="color: rgb(0, 0, 255);">  /* default: 767 entries */
</span>
  .long 0x00102007
 
<span style="color: rgb(0, 0, 255);">  /* default: 255 entries */
</span>
  .fill __KERNEL_PGD_PTRS-1,4,0

  

  6. FASTCALL ()

  位置:/include/linux/kernel.h

  定义:#define FASTCALL(x)  x  __attribute__((regparm(3)))

  注释:这个标志符和函数声明放在一起,带regparm(3)的属性声明告诉gcc编译器,这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

  举例:extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next))

  这个例子中,prev将通过eax,next通过edx传递。

 

 

  7. __sched

  位置:/include/linux/sched.h

  定义:/* Attach to any functions which should be ignored in wchan output. */      #define __sched  __attribute__((__section__(".sched.text")))

  我们在阅读Linux内核是,常见到这些宏 __init, __initdata, __initfunc(), asmlinkage, ENTRY(), FASTCALL()等等。它们定义在 /include/linux/init.h 和 /include/linux/linkage.h 以及其他一些.h 文件中。

  1. __init

      位置:/include/linux/init.h

      定义: #define __init   __attribute__ ((__section__ (".init.text")))

      注释:这个标志符和函数声明放在一起,表示gcc编译器在编译时,需要把这个函数放在.text.init Section 中,而这个Section 在内核完成初始化之后,就会被释放掉。

  举例:asmlinkage void __init star_kerne(void) { ... }

 

  2. __initdata

  位置:/include/linux/init.h

  定义:#define __initdata __attribute__ ((__section__ (".init.data")))

  注释:这个标志符和变量声明放在一起,表示gcc编译器在编译时,需要把这个变量放在.data.init Section中,而这个Section 在内核完成初始化之后,会释放掉。

  举例:static struct kernel_param raw_params[] __initdata ={ ... }

 

  3. __initfunc()

  位置:/include/asm-i386/init.h

  定义:#define __initfunc(__arginit) \      __arginit __init; \      __arginit

  注释:__initfunc() 是一个自定义宏,用来定义一个 __init 函数,在Linux-2.4中已被__init宏所取代。

  举例:__initfunc (void mem_init(unsigned long start_mem, unsigned long end_mem)) { ... }

 

  4. asmlinkage

  位置:/include/linux/linkage.h

  定义:#define asmlinkage CPP_ASMLINKAGE  __attribute__((regparm(0)))

  注释:这个标志符和函数声明放在一起,带regparm(0)的属性声明告诉gcc编译器,该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈传递参数,你定义的 c 函数时要在函数前加上宏asmlinkage。

  举例:asmlinkage void __init start_kernel(void) { ... }

 

  5.ENTRY()

  位置:/include/linux/linkage.h

  定义:#define ENTRY(name) \                 .globl name; \                 ALIGN; \                 name:

  注释:将name 声明为全局,对齐,并定义为标号。

  举例:     

   ENTRY(swapper_pg_dir)
 
  .long 0x00102007
 
  .fill __USER_PGD_PTRS-1,4,0
 
 <span style="color: rgb(0, 0, 255);"> /* default: 767 entries */
</span>
  .long 0x00102007
 
<span style="color: rgb(0, 0, 255);">  /* default: 255 entries */
</span>
  .fill __KERNEL_PGD_PTRS-1,4,0
 
等价于
 
  .globl swapper_pg_dir
 
  .align 16,0x90
 
<span style="color: rgb(0, 0, 255);">  /* if i486 */
</span>
  swapper_pg_dir:
 
  .long 0x00102007
 
  .fill __USER_PGD_PTRS-1,4,0
 
<span style="color: rgb(0, 0, 255);">  /* default: 767 entries */
</span>
  .long 0x00102007
 
<span style="color: rgb(0, 0, 255);">  /* default: 255 entries */
</span>
  .fill __KERNEL_PGD_PTRS-1,4,0

  

  6. FASTCALL ()

  位置:/include/linux/kernel.h

  定义:#define FASTCALL(x)  x  __attribute__((regparm(3)))

  注释:这个标志符和函数声明放在一起,带regparm(3)的属性声明告诉gcc编译器,这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

  举例:extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next))

  这个例子中,prev将通过eax,next通过edx传递。

 

 

  7. __sched

  位置:/include/linux/sched.h

  定义:/* Attach to any functions which should be ignored in wchan output. */      #define __sched  __attribute__((__section__(".sched.text")))

相关文章: