新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > kbuild系統(tǒng)-編譯到內(nèi)核和編譯成模塊的區(qū)別

        kbuild系統(tǒng)-編譯到內(nèi)核和編譯成模塊的區(qū)別

        作者: 時間:2012-07-30 來源:網(wǎng)絡(luò) 收藏

        代碼在代碼中有什么呢?

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

        的代碼中看是一樣的。入口函數(shù)都是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

        當(dāng)代碼編譯成模塊時,會定義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的一部分

        執(zhí)行順序:

        start_kernel->rest_init

        啟動后在rest_init中會創(chuàng)建init內(nèi)核線程

        init->do_basic_setup->do_initcalls

        do_initcalls中會把.initcall.init中的函數(shù)依次執(zhí)行一遍

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

        ...

        (*call)();

        ...

        }

        于是執(zhí)行了module_init(fn)函數(shù)



        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 益阳市| 墨江| 武隆县| 阿克陶县| 鹤壁市| 哈尔滨市| 石门县| 黄陵县| 正定县| 罗田县| 阳春市| 桑植县| 菏泽市| 新余市| 秦皇岛市| 如东县| 富川| 兰坪| 永福县| 德惠市| 陵水| 安化县| 车致| 稻城县| 抚顺市| 清水县| 太湖县| 高阳县| 全州县| 白城市| 双牌县| 赞皇县| 厦门市| 象州县| 当雄县| 清涧县| 呈贡县| 江达县| 什邡市| 江津市| 宜宾县|