首先看一下内核中最有名气的一个函数(top1):
asmlinkage __visible void __init start_kernel(void)
第一个函数出来就有三个知识点,派头确实很大。
asmlinkage:
确保所有的参数都是栈传递。
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
#define CPP_ASMLINKAGE
#endif
#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif
include/linux/linkage.h
#ifdef CONFIG_X86_32
#define asmlinkage
CPP_ASMLINKAGE __attribute__((regparm(0)))
arch/x86/include/asm/linkage.h
__visible :
告诉优化器(optimizer)其它人会调用这个函数或者变量。
通过git可以查看此标识符引入的时候作者是怎么说的
git show
9a858dc7cebce01a7bb616bebb85087fa2b40871
+#if __GNUC_MINOR__ >= 6
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+#endif
include/linux/compiler-gcc4.h
commit 9a858dc7cebce01a7bb616bebb85087fa2b40871
Author: Andi Kleen <ak@linux.intel.com>
Date: Mon Sep 17 14:09:15 2012 -0700
compiler.h: add __visible
gcc 4.6+ has support for a externally_visible attribute that
prevents the optimizer from optimizing unused symbols
away. Add a __visible macro to use it with that compiler
version or later.
This is used (at least) by the "Link Time Optimization" patchset
__init
表明代码(text)和数据仅仅在初始化的时候需要。
1. 定义
#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)
#define __initconst __constsection(.init.rodata)
#define __exitdata __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)
(include/linux/init.h)
#ifndef __cold
#define __cold __attribute__((__cold__))
#endif
(include/linux/compiler-gcc4.h)
#ifndef __section
# define __section(S) __attribute__ ((__section__(#S)))
#endif
...
#define notrace __attribute__((no_instrument_function))
(include/linux/compiler.h)
2.init*段都在一块连续的内存中
(arch/x86/kernel/vmlinux.lds.S)
3. 她们都将被释放(释放的函数从kernel_init进入)
void free_initmem(void)
{
free_init_pages("unused kernel",
(unsigned long)(&__init_begin),
(unsigned long)(&__init_end));
}
(arch/x86/mm/init.c)
---The End---
文章与封面台词无关:)