关于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)