新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > kbuild系統-編譯到內核和編譯成模塊的區別

        kbuild系統-編譯到內核和編譯成模塊的區別

        作者: 時間:2012-07-30 來源:網絡 收藏

        代碼在代碼中有什么呢?

        本文引用地址:http://www.104case.com/article/148697.htm

        的代碼中看是一樣的。入口函數都是MODULE_init(fun),但是代碼中的條件會使宏module_init()在編譯到和編譯成的情況下替換成不同的代碼。

        include/linux/init.h中可知

        #ifndef MODULE

        ...

        #define module_init(x) __initcall(x);

        ...

        #else /* MODULE */

        ...

        /* Each module must use one module_init(), or one no_module_init */

        #define module_init(initfn)

        static inline initcall_t __inittest(void)

        { return initfn; }

        int init_module(void) __attribute__((alias(#initfn)));

        ...

        #endif

        當代碼編譯成模塊時,會定義MODULE宏,否則不會。因為在/usr/src/linux/Makefile中可以看到

        336 MODFLAGS = -DMODULE

        337 CFLAGS_MODULE = $(MODFLAGS)

        338 AFLAGS_MODULE = $(MODFLAGS)

        這兩個變量又被export成為全局變量。所以可以知道,在編譯成模塊時,會有MODULE這個宏。

        由以下代碼可以知道

        #define __initcall(fn) device_initcall(fn)

        #define device_initcall(fn) __define_initcall(6,fn)

        085 #define __define_initcall(level,fn)

        086 static initcall_t __initcall_##fn __attribute_used__

        087 __attribute__((__section__(.initcall level .init))) = fn

        前者實際上是編譯入中的.initcall6.init 這個section

        而在

        arch/i386/kernel/vmlinux.lds.S中可以知道:

        083 __initcall_start = .;

        084 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {

        085 *(.initcall1.init)

        086 *(.initcall2.init)

        087 *(.initcall3.init)

        088 *(.initcall4.init)

        089 *(.initcall5.init)

        090 *(.initcall6.init)

        091 *(.initcall7.init)

        092 }

        093 __initcall_end = .;

        arch/i386/kernel/vmlinux.lds.S

        .initcall6.init是.initcall.init的一部分

        執行順序:

        start_kernel->rest_init

        啟動后在rest_init中會創建init內核線程

        init->do_basic_setup->do_initcalls

        do_initcalls中會把.initcall.init中的函數依次執行一遍

        for (call = __initcall_start; call __initcall_end; call++) {

        ...

        (*call)();

        ...

        }

        于是執行了module_init(fn)函數



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 三台县| 余干县| 辛集市| 城固县| 河西区| 思茅市| 桦甸市| 武威市| 兴国县| 乌什县| 武义县| 闽清县| 施秉县| 玛沁县| 高邑县| 三江| 宜兰县| 观塘区| 台中县| 台南市| 祥云县| 临潭县| 玉龙| 沙洋县| 阳江市| 舒兰市| 瓮安县| 凌云县| 绍兴市| 陕西省| 嘉峪关市| 桂林市| 吉林市| 太康县| 新闻| 延寿县| 洞口县| 九龙坡区| 富蕴县| 阿瓦提县| 榆社县|