您的位置:首页 > 运维架构 > Linux

[Linux driver] Hello world编译过程解析

2011-11-25 11:33 267 查看
虽然系统提供的makefile很智能地将hello.c最终编译成了hello.ko,但是我还是想知道系统的makefile到底干了些什么。

首先看编译驱动的目录,编译后多个四个文件:hello.ko, hello.mod.c, hello.mod.o, hello.o

hello.mod.c是一个C程序的源文件,查看其内容,似乎仅仅只是定义了两个全局的结构体变量。

我猜想:这个文件其实是驱动的版本信息,编译后的这些信息就好像元数据一样附加到ELF文件的.TEXT段,然后加载驱动的框架可以读取这些信息。原理应该是WINDOWS下的那种rc文件一样。

光看生成的文件还不够,修改了一下Makefile,把具体的执行信息都打印出来:

obj-m := hello.o

KERNEL_DIR := /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

all:

make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules -n

clean:

rm *.o *.ko

在调用系统提供的makefile的时候,加上-n的参数。-n是指执行命令的时候将命令打印出来,但并不真正的执行。

修改好后执行make,果然打印了许许多多的命令出来。认真看产生的命令,发现居然在源码目录下创建了一个隐藏文件,有意思,于是执行:ll -a,将所有文件显示出来:

编译驱动后,不仅仅只多了四个文件,其实还产生了一个隐藏目录(.tmp_versions)和三个隐藏的文本文件(.hello.ko.cmd, .hello.mod.o.cmd, .hello.o.cmd)。

查看三个隐藏文件的内容,终于明白了系统的makefile执行的流程:

1、建立隐藏文件夹.tmp_versions,作为编译过程中的临时文件夹;

2、使用脚本程序,根据hello.c生成hello.mod.chello.mod.c其实是驱动需要的元数据;

3、使用GCC编译hello.mod.c,生成hello.mod.o,将编译的命令参数行写到 .hello.mod.o

4、使用GCC编译hello.c,生成hello.o,将编译的命令参数行写到 .hello.o.cmd

5、使用ld链接器链接hello.mod.o和hello.o,生成hello.ko,将命令参数行写到.hello.ko.cmd

6、删除中间生成的临时文件

下面是make的执行过程:

make -C /lib/modules/2.6.28-11-generic/build M=/home/ldd3/helloworld -n

make[1]: Entering directory `/usr/src/linux-headers-2.6.28-11-generic'

mkdir -p /home/ldd3/helloworld/.tmp_versions ; rm -f /home/ldd3/helloworld/.tmp_versions/*

test -e /usr/src/linux-headers-2.6.28-11-generic/Module.symvers || ( \

echo; \

echo " WARNING: Symbol version dump /usr/src/linux-headers-2.6.28-11-generic/Module.symvers"; \

echo " is missing; modules will have no dependencies and modversions."; \

echo )

make -f scripts/Makefile.build obj=/home/ldd3/helloworld

{ echo /home/ldd3/helloworld/hello.ko; echo /home/ldd3/helloworld/hello.o; } > /home/ldd3/helloworld/.tmp_versions/hello.mod

(cat /dev/null; echo kernel//home/ldd3/helloworld/hello.ko;) > /home/ldd3/helloworld/modules.order

:

echo ' Building modules, stage 2.';

make -f /usr/src/linux-headers-2.6.28-11-generic/scripts/Makefile.modpost

echo ' MODPOST 1 modules'; scripts/mod/modpost -m -a -i /usr/src/linux-headers-2.6.28-11-generic/Module.symvers -I /home/ldd3/helloworld/Module.symvers -o

/home/ldd3/helloworld/Module.symvers -S -K /usr/src/linux-headers-2.6.28-11-generic/Module.markers -M /home/ldd3/helloworld/Module.markers -w -s /home/ld

d3/helloworld/hello.o

set -e; echo ' CC /home/ldd3/helloworld/hello.mod.o'; gcc -Wp,-MD,/home/ldd3/helloworld/.hello.mod.o.d -nostdinc -isystem /usr/lib/gcc/i486-linux-gn

u/4.3.3/include -D__KERNEL__ -Iinclude -I/usr/src/linux-headers-2.6.28-11-generic/arch/x86/include -include include/linux/autoconf.h -Iubuntu/include -Wa

ll -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -O2 -m32 -msoft-float -mregparm=3 -freg

-struct-return -mpreferred-stack-boundary=2 -march=i586 -mtune=generic -Wa,-mtune=generic32 -ffreestanding -pipe -Wno-sign-compare -fno-asynchronous-unwind-

tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iarch/x86/include/asm/mach-default -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -

Wdeclaration-after-statement -Wno-pointer-sign -fwrapv -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(hello.mod)" -D"KBUILD_MODNAME=KBUILD_STR(hello)"

-DMODULE -c -o /home/ldd3/helloworld/hello.mod.o /home/ldd3/helloworld/hello.mod.c; scripts/basic/fixdep /home/ldd3/helloworld/.hello.mod.o.d /home/ldd3/h

elloworld/hello.mod.o 'gcc -Wp,-MD,/home/ldd3/helloworld/.hello.mod.o.d -nostdinc -isystem /usr/lib/gcc/i486-linux-gnu/4.3.3/include -D__KERNEL__ -Iinclud

e -I/usr/src/linux-headers-2.6.28-11-generic/arch/x86/include -include include/linux/autoconf.h -Iubuntu/include -Wall -Wundef -Wstrict-prototypes -Wno-tr

igraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -O2 -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-bound

ary=2 -march=i586 -mtune=generic -Wa,-mtune=generic32 -ffreestanding -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mn

o-3dnow -Iarch/x86/include/asm/mach-default -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -Wdeclaration-after-statement -Wno-poin

ter-sign -fwrapv -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(hello.mod)" -D"KBUILD_MODNAME=KBUILD_STR(hello)" -DMODULE -c -o /home/ldd3/helloworl

d/hello.mod.o /home/ldd3/helloworld/hello.mod.c' > /home/ldd3/helloworld/.hello.mod.o.tmp; rm -f /home/ldd3/helloworld/.hello.mod.o.d; mv -f /home/ldd3/hell

oworld/.hello.mod.o.tmp /home/ldd3/helloworld/.hello.mod.o.cmd

set -e; echo ' LD [M] /home/ldd3/helloworld/hello.ko'; ld -r -m elf_i386 --build-id -o /home/ldd3/helloworld/hello.ko /home/ldd3/helloworld/hello.o /hom

e/ldd3/helloworld/hello.mod.o; echo 'cmd_/home/ldd3/helloworld/hello.ko := ld -r -m elf_i386 --build-id -o /home/ldd3/helloworld/hello.ko /home/ldd3/hellow

orld/hello.o /home/ldd3/helloworld/hello.mod.o' > /home/ldd3/helloworld/.hello.ko.cmd

make[1]: Leaving directory `/usr/src/linux-headers-2.6.28-11-generic'
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: