.mod.c 是什么文件
我們可以為代碼清單4.1的模板編寫一個簡單的Makefile:
obj-m := hello.o
并使用如下命令編譯Hello World模塊:
?????? make -C /usr/src/linux-2.6.15.5/ M=/driver_study/ modules
?????? 如果當前處于模塊所在的目錄,則以下命令與上述命令同等:
???????? make –C /usr/src/linux-2.6.15.5 M=$(pwd) modules
?????? 其中-C后指定的是Linux內核源代碼的目錄,而M=后指定的是hello.c和Makefile所在的目錄,編譯結果如下:
[root@localhost driver_study]# make -C /usr/src/linux-2.6.15.5/ M=/driver_study/ modules
make: Entering directory `/usr/src/linux-2.6.15.5'
CC [M] /driver_study/hello.o
/driver_study/hello.c:18:35: warning: no newline at end of file
Building modules, stage 2.
MODPOST
CC????? /driver_study/hello.mod.o
LD [M] /driver_study/hello.ko
make: Leaving directory `/usr/src/linux-2.6.15.5'
從中可以看出,編譯過程中,經(jīng)歷了這樣的步驟:先進入Linux內核所在的目錄,并編譯出hello.o文件,運行MODPOST會生成臨時的hello.mod.c文件,而后根據(jù)此文件編譯出hello.mod.o,之后連接hello.o和hello.mod.o文件得到模塊目標文件hello.ko,最后離開Linux內核所在的目錄。
?????? 中間生成的hello.mod.c文件的源代碼如代碼清單4.7所示。
代碼清單4.7 模塊編譯時生成的.mod.c文件
1 ?? #include <linux/module.h>
2 ?? #include <linux/vermagic.h>
3 ?? #include <linux/compiler.h>
4 ??
5 ?? MODULE_INFO(vermagic, VERMAGIC_STRING);
6 ??
7 ?? struct module __this_module
8 ?? __attribute__((section(".gnu.linkonce.this_module"))) = {
9 ?? .name = KBUILD_MODNAME,
10??? .init = init_module,
11??? #ifdef CONFIG_MODULE_UNLOAD
12??? .exit = cleanup_module,
13??? #endif
14??? };
16??? static const char __module_depends[]
17??? __attribute_used__
18??? __attribute__((section(".modinfo"))) =
19??? "depends=";
hello.mod.o產(chǎn)生了ELF(Linux所采用的可執(zhí)行/可連接的文件格式)的2個節(jié),即modinfo和.gun.linkonce.this_module。
如果一個模塊包括多個.c文件(如file1.c、file2.c),則應該以如下方式編寫Makefile:
obj-m := modulename.o
modulename-objs := file1.o file2.o???
-----------------------------------------------------------------
http://blog.csdn.net/zhaokugua/archive/2007/11/02/1862500.aspx
4.9模塊的編譯
----------------------------------------------------------------------
2.4內核中,模塊的編譯只需內核源碼頭文件;需要在包含linux/modules.h之前定義MODULE;編譯、連接后生成的內核模塊后綴為.o。
2.6內核中,模塊的編譯需要配置過的內核源碼;編譯、連接后生成的內核模塊后綴為.ko;編譯過程首先會到內核源碼目錄下,讀取頂層的Makefile文件,然后再返回模塊源碼所在目錄。
清單2:2.4 內核模塊的Makefile模板
| #Makefile2.4 KVER=$(shell uname -r) KDIR=/lib/modules/$(KVER)/build OBJS=mymodule.o CFLAGS=-D__KERNEL__ -I$(KDIR)/include -DMODULE -D__KERNEL_SYSCALLS__ -DEXPORT_SYMTAB-O2 -fomit-frame-pointer -Wall -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h all: $(OBJS) mymodule.o: file1.o file2.old -r -o $@ $^ clean:rm -f *.o |
在2.4 內核下,內核模塊的Makefile與普通用戶程序的Makefile在結構和語法上都相同,但是必須在CFLAGS中定義-D__KERNEL__- DMODULE,指定內核頭文件目錄-I$(KDIR)/include。有一點需注意,之所以在CFLAGS中定義變量,而不是在模塊源碼文件中定義,一方面這些預定義變量可以被模塊中所有源碼文件可見,另一方面等價于將這些預定義變量定義在源碼文件的起始位置。在模塊編譯中,對于這些全局的預定義變量,一般在CFLAGS中定義。
清單3:2.6 內核模塊的Makefile模板
| # Makefile2.6 ifneq ($(KERNELRELEASE),) #kbuild syntax. dependency relationshsip of files and target modules are listed here. mymodule-objs := file1.o file2.o obj-m := mymodule.o else PWD := $(shell pwd) KVER ?= $(shell uname -r) KDIR := /lib/modules/$(KVER)/build all:$(MAKE) -C $(KDIR) M=$(PWD) clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions endif |
KERNELRELEASE是在內核源碼的頂層Makefile中定義的一個變量,在第一次讀取執(zhí)行此Makefile時, KERNELRELEASE沒有被定義,所以make將讀取執(zhí)行else之后的內容。如果make的目標是clean,直接執(zhí)行clean操作,然后結束。當make的目標為all時,-C $(KDIR) 指明跳轉到內核源碼目錄下讀取那里的Makefile;M=$(PWD) 表明然后返回到當前目錄繼續(xù)讀入、執(zhí)行當前的Makefile。當從內核源碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啟動去解析kbuild語法的語句,make將繼續(xù)讀取else之前的內容。else之前的內容為kbuild語法的語句, 指明模塊源碼中各文件的依賴關系,以及要生成的目標模塊名。mymodule-objs := file1.o file2.o表示mymoudule.o 由file1.o與file2.o 連接生成。obj-m := mymodule.o表示編譯連接后將生成mymodule.o模塊。
補充一點,"$(MAKE) -C $(KDIR) M=$(PWD)"與"$(MAKE) -C $(KDIR) SUBDIRS =$(PWD)"的作用是等效的,后者是較老的使用方法。推薦使用M而不是SUBDIRS,前者更明確。
通過以上比較可以看到,從Makefile編寫來看,在2.6內核下,內核模塊編譯不必定義復雜的CFLAGS,而且模塊中各文件依賴關系的表示簡潔清晰。
清單4: 可同時在2.4 與 2.6 內核下工作的Makefile
總結
以上是生活随笔為你收集整理的.mod.c 是什么文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bbb 烧写脚本分析
- 下一篇: bbb u-boot mmc总线初始