Linux启动第一集 之世界最有名的一个函数名

首先看一下内核中最有名气的一个函数(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*段都在一块连续的内存中

Linux启动第一集 之世界最有名的一个函数名


                         (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---

文章与封面台词无关:)


上一篇:速读-张量流处理器(TSP)


下一篇:解决IAR编译出现Warning[25]: Label 'xxx' is defined pubweak in a section implicitly declared root