新聞中心

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

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

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

代碼在代碼中有什么呢?

本文引用地址:http://butianyuan.cn/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

當代碼編譯成模塊時,會定義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)閉