内核compiler.h的学习

直接上代码就可以了,所以的学习都在注释当中呢!

#ifndef __LINUX_COMPILER_H
#define __LINUX_COMPILER_H

#ifndef __ASSEMBLY__

//如果宏定义了__CHECKER__
//详细学习一个Sparse
#ifdef __CHECKER__

/**
 * 这个使用来修饰一个变量的,这个变量必须是非解除参考的,no
 * dereference的,即这个变量必须是有效的,而且变量所在的
 * 地址空间必须是1,即用户程序所使用的。
 * 程序空间分成3部分,0表示normal space,即普通地址空间,
 * 对于内核代码讲,就是内核空间,1表示用户地址空间
 * 2表示设备地址映射空间,如硬件设备的寄存器在内核
 * 里所映射的地址空间
 *
 */
# define __user     __attribute__((noderef, address_space(1)))

//默认的是内核地址空间
# define __kernel   /* default address space */

//变量可以为空
# define __safe     __attribute__((safe))

//变量可以进行强制转换
# define __force    __attribute__((force))

//参数类型必须与实际参数类型一致
# define __nocast   __attribute__((nocast))

//指针地址在设备地址空间
# define __iomem    __attribute__((noderef, address_space(2)))

//参数x,在执行前引用计数必须为0,执行后,引用计数必须为1
# define __acquires(x)  __attribute__((context(0,1)))

//参数x,在执行前引用计数必须为1,执行后,必须为0
# define __releases(x)  __attribute__((context(1,0)))

//参数x的引用计数在执行后+1
# define __acquire(x)   __context__(1)

//参数x的引用计数在执行后-1
# define __release(x)   __context__(-1)

//参数x为0,则返回0;如果参数x不为0,的引用计数+1,并且返回1
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)

//检查用户地址空间指针
extern void __chk_user_ptr(void __user *);

//检查设备地址空间指针
extern void __chk_io_ptr(void __iomem *);

#else

# define __user
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
# define __builtin_warning(x, y...) (1)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x) (x)
#endif

#ifdef __KERNEL__

//__GNUC__ 该宏表示GCC的版本
//可以使用该宏针对不同版本的gcc进行条件编译
#if __GNUC__ > 4
//错误,没有对应版本的compiler-gcc.h文件
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 4
# include <linux/compiler-gcc4.h>
#elif __GNUC__ == 3
# include <linux/compiler-gcc3.h>
#else
//对不起,错误。你的编译器版本太老了或者是不被识别。
# error Sorry, your compiler is too old/not recognized.
#endif

/* Intel compiler defines __GNUC__. So weabove header files here will overwrite implementations
 * coming from above header files here
 * Intel编译器定义了__GNUC__.所以在这里也包含compiler-intel.h头文件。
 */
#ifdef __INTEL_COMPILER
# include <linux/compiler-intel.h>
#endif

/*
 * Generic compiler-dependent macros required for kernel
 * build go below this comment. Actual compiler/compiler version
 * specific implementations come from the above header files
 * 定义likely和unlikely宏
 *
 * 在内核编译的时候,所需要的宏定义在该注释下面。真正的编译器或者是
 * 编译器版本实现在上面的头文件中。
 */

/*
 * __builtin_expect()是有GCC或者是intel编译器提供的实现
 * 提供该实现的目的是为了优化代码,避免过度跳转带来的性能
 * 上的下降。
 * __builtin(!!(x),1)表示x的值为1的可能性比较大
 * __builtin(!!(x),0)表示x的值为0的可能性比较大
 *
 * 例如:
 * int x;
 * if(unlikely(x))
 * {
 *   x += 1;
 * }else{
 *  x -= 1;
 * }
 * 这段代码表示,x为0的可能性较大,也就是说
 * 程序执行else中的代码的可能性比较大,所以在
 * 编译的时候else里面的内容紧跟着上面的代码
 */

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

//优化屏障
//详细了解请看我的博客[《内核Memory Barrier学习》](http://blog.csdn.net/hongbochen1223/article/details/44961487)
/* Optimization barrier */
#ifndef barrier
# define barrier() __memory_barrier()
#endif

#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off)                   \
  ({ unsigned long __ptr;                        __ptr = (unsigned long) (ptr);                 (typeof(ptr)) (__ptr + (off)); })
#endif

#endif /* __KERNEL__ */

#endif /* __ASSEMBLY__ */

#ifdef __KERNEL__
/*
 * Allow us to mark functions as ‘deprecated‘ and have gcc emit a nice
 * warning for each use, in hopes of speeding the functions removal.
 * Usage is:
 *      int __deprecated foo(void)
 *
 *
 * 允许我们标志一个函数为‘过时的‘,并且会使gcc对没一个使用发出合理的警告,
 * 希望能够加快函数的移除。
 * 使用方式:
 *      int __deprecated foo(void)
 */
#ifndef __deprecated
# define __deprecated       /* unimplemented */ //未实现
#endif

#ifdef MODULE
#define __deprecated_for_modules __deprecated
#else
#define __deprecated_for_modules
#endif

#ifndef __must_check
#define __must_check
#endif

/*
 * Allow us to avoid ‘defined but not used‘ warnings on functions and data,
 * as well as force them to be emitted to the assembly file.
 *
 * As of gcc 3.3, static functions that are not marked with attribute((used))
 * may be elided from the assembly file.  As of gcc 3.3, static data not so
 * marked will not be elided, but this may change in a future gcc version.
 *
 * In prior versions of gcc, such functions and data would be emitted, but
 * would be warned about except with attribute((unused)).
 *
 * 允许我们避免在函数和数据中‘定义了但是没有使用’的警告,同时强制他们发送给
 * 汇编文件。
 * 对于编译器gcc 3.3,未被标记上已用属性的静态函数将会被汇编文件忽略。但是对于
 * 编译器gcc 3.3,没有这样标记静态数据将不会被忽略,但是在后续的gcc版本中将会
 * 发生改变。
 * 在更高级的gcc版本中,这样的函数和数据虽然会被传送,但是将会用‘未使用的属性’
 * 来发出异常警告。
 */
#ifndef __attribute_used__
# define __attribute_used__ /* unimplemented */  //未实现
#endif

/*
 * From the GCC manual:
 * 来自GCC手册
 *
 * Many functions have no effects except the return value and their
 * return value depends only on the parameters and/or global
 * variables.  Such a function can be subject to common subexpression
 * elimination and loop optimization just as an arithmetic operator
 * would be.
 * [...]
 * 很多函数除了他们的返回值都是没有影响的,并且他们的返回值仅仅依赖于参数
 * 或者是全局变量。这样的函数将受公共子表达式消除和循环优化支配作为一个算数
 * 运算符。
 */
#ifndef __attribute_pure__
# define __attribute_pure__ /* unimplemented */
#endif

#ifndef noinline
#define noinline
#endif

#ifndef __always_inline
#define __always_inline inline
#endif

#endif /* __KERNEL__ */

/*
 * From the GCC manual:
 * 定义const函数
 * Many functions do not examine any values except their arguments,
 * and have no effects except the return value.  Basically this is
 * just slightly more strict class than the `pure‘ attribute above,
 * since function is not allowed to read global memory.
 *
 * Note that a function that has pointer arguments and examines the
 * data pointed to must _not_ be declared `const‘.  Likewise, a
 * function that calls a non-`const‘ function usually must not be
 * `const‘.  It does not make sense for a `const‘ function to return
 * `void‘.
 */
#ifndef __attribute_const__
# define __attribute_const__    /* unimplemented */
#endif

#endif /* __LINUX_COMPILER_H */
时间: 2024-10-17 22:54:44

内核compiler.h的学习的相关文章

linux内核list.h的学习

这个是学习linux内核的第一篇文章,所有的学习内容都在list.h的注释里面,直接上代码.

LINUX内核分析第四周学习总结——扒开应用系统的三层皮(上)

LINUX内核分析第四周学习总结——扒开应用系统的三层皮(上) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 (一)用户态.内核态和中断处理过程 (二)系统调用概述 系统调用概述和系统调用的三层皮 (三)使用库函数API和C代码中嵌入汇编代码触发同一个系统调用 使用库函数API获取系统当前时间 C代码中嵌入汇编代码的方法(复习) 使用C代码中嵌入汇编代码触发系统调

LINUX内核分析第一周学习总结——计算机是如何工作的

LINUX内核分析第一周学习总结——计算机是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.汇编代码的工作过程 1.实验过程 int a(int x) { return x + 2; } int b(int x) { return a(x); } int main(void) { return b(5) + 1; } 汇编代码如下: 2.代码分析 二.计算机工作的

《信息安全系统设计基础+Linux 内核分析》第一次学习总结

<信息安全系统设计基础+Linux 内核分析>第一次学习总结 教材学习内容总结 学习了<庖丁解牛>的第一章.知道的概念有: 存储程序计算机 = 冯诺依曼计算机,主要思想是:将程序存放在计算机存储器中,然后按存储器中的程序的首地址来执行程序的第一条指令,接下来就是一步一步按照程序中的编写好的指令来一步一步执行,直至程序结束. 冯诺依曼体系结构的要点如下图.底层是:RAM,ROM,运算器(ALU),控制器,寄存器. 由图可知:寄存器是在CPU中的,而RAM,ROM不是在CPU中的,它们

内核bug.h以及GCC内联汇编的学习

所有的学习的内容都在注释当中,我的学习过程是,看到这个代码段之后,将其中需要的只是去大体的学习一遍.争取能够做到理解整体的部分. 下面展示出我的学习的代码: #ifndef _I386_BUG_H #define _I386_BUG_H /* * Tell the user there is some problem. * 告诉用户出现了一些问题 * The offending file and line are encoded after the "officially * undefined

Linux内核中链表的学习

一.自己学习链表 数组的缺点:(1)数据类型一致:(2)数组的长度事先定好,不能灵活更改. 从而引入了链表来解决数组的这些缺点:(1)结构体解决多数据类型(2)链表的组合使得链表的长度可以灵活设置. 基本概念: 头结点: 这个节点是为了便于管理链表的节点,这个节点并不保存数据:虽然和其他节点一样,但是这个头结点是指向首节点的节点. 首节点: 第一个保存有效数据的节. 尾节点: 最后一个保存有效数据的节点 头指针: 头指针是指向头节点的指针. 单链表: 链表节点的数据结构定义: typedef s

linux内核分析第二四学习报告

学生  黎静 课程内容 计算机三大法宝 • 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: • 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: • 中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序. 一.函数调用堆栈 1.堆栈 堆栈式C语言程序运行时必须的一个记录调用路径和参数的空间.包括: 函数调用框架 传递参数 保存返回地址(如eax)

基于tiny4412的Linux内核移植 -- PWM子系统学习(八)

作者信息 作者: 彭东林 邮箱:[email protected] QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4

Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码

陈巧然 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.使用实验楼的虚拟机, 观察只有一个死循环的mykernel与时钟中断的关系 步骤:cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 执行效果如下图 Paste_Image.png 现在查看mymain.c: Paste_Image.png 再查看myin