Linux入门教程:Linux内核编译中的九个技巧

关于Linux的内核编译有不少系统管理员都不知道如何去处理。其实就像平时的Linux系统管理一样Linux内核编译也有技巧可以掌握。在本文中我们就向大家介绍下Linux内核编译九个技巧。

1.构建泛型宏 (。/linux/include/linux/kernel.h)

#define min(x, y) ({ \

typeof(x) _min1 = (x); \

typeof(y) _min2 = (y); \

(void) (&_min1 == &_min2); \

_min1 《 _min2 ? _min1 : _min2; })

大家看了就明白是什么意思了。但是我还有几点疑问:

(1)(void) (&_min1 == &_min2);这行代码是用来干什么的?

(2)为什么{}的外面要加(),不加的时候编译是不通过的,具体是什么原因?

2. 范围的扩展

(1) switch 语句

switch(a)

{

case 1 。.. 3:

printf(“fafadsf”);

break;

case 4 。.. 8:

printf(“dsafaf”);

break;

}

(2)数组的初始化 int widths[] = { [0 。.. 9] = 1, [10 。.. 99] = 2, [100] = 3 };以上部分内核中用的很多。

3 .零长度的数组

struct iso_block_store {

atomic_t refcount;

size_t data_size;

quadlet_t data[0];

};

这允许结构中的元素引用结构实例后面紧接着的内存。在需要数量可变的数组成员时,这个特性很有用应用实例:

struct iso_block_store * p =(void *)malloc(sizeof(struct iso_block_store) + data_size);

4. 获得函数的返回地址

如下面的代码所示,__builtin_return_address 接收一个称为 level 的参数。这个参数定义希望获取返回地址的调用堆栈级别。例如,如果指定 level 为 0,那么就是请求当前函数的返回地址。如果指定 level 为 1,那么就是请求进行调用的函数的返回地址,依此类推。

void * __builtin_turn_address( unsigned int level );

在下面的示例中(见 。/linux/kernel/softirq.c),local_bh_disable 函数在本地处理器上禁用软中断,从而禁止在当前处理器上运行 softirqs、tasklets 和 bottom halves。使用 __builtin_return_address 捕捉返回地址,以便在以后进行跟踪时使用这个地址。

void local_bh_disable(void){ __local_bh_disable((unsigned long)__builtin_return_address(0));}

5 .常量检测

在编译时,可以使用 GCC 提供的一个内置函数判断一个值是否是常量。这种信息非常有价值,因为可以构造出能够通过常量叠算(constant folding)优化的表达式。__builtin_constant_p 函数用来检测常量。

__builtin_constant_p 的原型如下所示。注意,__builtin_constant_p 并不能检测出所有常量,因为 GCC 不容易证明某些值是否是常量。

int __builtin_constant_p( exp )

Linux 相当频繁地使用常量检测。在清单 3 所示的示例中(见 。/linux/include/linux/log2.h),使用常量检测优化 roundup_pow_of_two 宏。如果发现表达式是常量,那么就使用可以优化的常量表达式。如果表达式不是常量,就调用另一个宏函数把值向上取整到 2 的幂。

#define roundup_pow_of_two(n) \

( \

__builtin_constant_p(n) ? ( \

(n == 1) ? 1 : \

(1UL 《《 (ilog2((n) - 1) + 1)) \

) : \

__roundup_pow_of_two(n) \

6. 函数属性

GCC 提供许多函数级属性,可以通过它们向编译器提供更多数据,帮助编译器执行优化。本节描述与功能相关联的一些属性。

属性通过其他符号定义指定了别名。

# define __inline__ __inline__ __attribute__((always_inline))

# define __deprecated __attribute__((deprecated))

# define __attribute_used__ __attribute__((__used__))

# define __attribute_const__ __attribute__((__const__))

# define __must_check __attribute__((warn_unused_result))

定义是 GCC 中可用的一些函数属性。它们也是在 Linux 内核中最有用的函数属性。下面解释如何使用这些属性:

always_inline 让 GCC 以内联方式处理指定的函数,无论是否启用了优化。

deprecated 指出函数已经被废弃,不应该再使用。如果试图使用已经废弃的函数,就会收到警告。还可以对类型和变量应用这个属性,促使开发人员尽可能少使用它们。

__used__ 告诉编译器无论 GCC 是否发现这个函数的调用实例,都要使用这个函数。这对于从汇编代码中调用 C 函数有帮助。

__const__ 告诉编译器某个函数是无状态的(也就是说,它使用传递给它的参数生成要返回的结果)。

warn_unused_result 让编译器检查所有调用者是否都检查函数的结果。这确保调用者适当地检验函数结果,从而能够适当地处理错误。

下面是在 Linux 内核中使用这些属性的示例。deprecated 示例来自与体系结构无关的内核(。/linux/kernel/resource.c),const 示例来自 IA64 内核源代码(。/linux/arch/ia64/kernel/unwind.c)。

int __deprecated __check_region(struct resource

*parent, unsigned long start, unsigned long n)

static enum unw_register_index __attribute_const__

decode_abreg(unsigned char abreg, int memory)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/25024.html