首次编译Kernel模块的经历

今天在电脑的ubuntu上首次按照别人博客的说明编译Kernel的最简单的Hello world模块配置。

先把参考的博客地址列出来,感谢先烈的辛苦劳动:

:http://blog.csdn.net/fudan_abc/article/details/5380511


过程一,Makefile的理解

先说文章1的makefile,我将的makefile修改如下,主要是去掉了前面的#if判断

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules modules_install clean

这个代码段的理解是在我运行make之后才自己体会的,

$(make)就是make,而make -c $(KERNELDIR) 就是跳到$(KERNELDIR) 所在的目录

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
这个意思是找到当前系统所在的内核的位置,并进入build文件夹,对于我的ubuntu来说是这个路径: /lib/modules/2.6.32-45-generic/build

总的意思就是执行:

1)跳到/lib/modules/2.6.32-45-generic/build目录中

2)然后执行make  M=/home/host/workspace/module modules

所以真实起作用的应该是/lib/modules/2.6.32-45-generic/build目录下的Makefile文件


过程二,错误调试

很遗憾是没有出现我想要的直接编译通过的结果(参考文章也说不一定会通过)

错误代码如下(只摘录了一部分):

make -C /lib/modules/2.6.32-45-generic/build M=/home/host/workspace/module modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-45-generic'
  CC [M]  /home/host/workspace/module/main.o
In file included from include/linux/prefetch.h:14:0,
                 from include/linux/list.h:6,
                 from include/linux/module.h:9,
                 from /home/shot/workspace/module/main.c:2:
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/processor.h:110:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
In file included from include/linux/irqflags.h:57:0,
                 from /usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:61,
                 from include/linux/list.h:7,
                 from include/linux/module.h:9,
                 from /home/host/workspace/module/main.c:2:
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/irqflags.h:11:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
In file included from include/linux/list.h:7:0,
                 from include/linux/module.h:9,
                 from /home/host/workspace/module/main.c:2:
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:111:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:117:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:121:35: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h: In function ‘__xchg’:
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:247:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:254:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
In file included from include/linux/list.h:7:0,
                 from include/linux/module.h:9,
                 from /home/host/workspace/module/main.c:2:
usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h: At top level:
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:322:5: warning: "__LINUX_ARM_ARCH__" is not defined [-Wundef]
/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:325:2: error: #error "SMP is not supported on this platform"
In file included from include/linux/module.h:9:0,
                 from /home/host/workspace/module/main.c:2:
这下惨了,一堆问题。
拿出以前定位问题的经验,warning不管,先找error

/usr/src/linux-headers-2.6.32-45-generic/arch/arm/include/asm/system.h:325:2: error: #error "SMP is not supported on this platform"
这个是说明平台不支持SMP。我记得好像SMP是多核之类的玩意。

然后我注意到这个文件时在arm目录下,我楞住了,我现在运行的是自己PC机器上的ubuntu,明明是Intel的CPU,怎么引用的ARM的头文件。

怎么办?外事不决问google。很快答案就出来了。

由于我在这个PC机器上改过.bashrc文件,加入了ARCH=arm, CROSS_COMPLIE=arm-none-linux-两个变量,导致我gcc的时候就自动找到了以ARM架构为首的相关文件。

为了验证我打开了/lib/modules/2.6.32-45-generic/build目录下的Makefile文件,找到对应的$(CC)变量设置的行

# Make variables (CC, etc...)

AS              = $(CROSS_COMPILE)as
LD              = $(CROSS_COMPILE)ld
CC              = $(CROSS_COMPILE)gcc
CPP             = $(CC) -E
AR              = $(CROSS_COMPILE)ar
NM              = $(CROSS_COMPILE)nm
STRIP           = $(CROSS_COMPILE)strip
OBJCOPY         = $(CROSS_COMPILE)objcopy
OBJDUMP         = $(CROSS_COMPILE)objdump
变量$(CC)引用了CROSS_COMPILE这个变量,故此不是我要的在Intel下的gnu gcc,而是arm相关的gcc
关于ARCH这个变量也在这里使用

# Architecture as present in compile.h
UTS_MACHINE     := $(ARCH)
真相终于大白,不能在Intel的机器上使用ARM的东东啊,水火不容。

该我还是会改的,我在module目录下的Makefile中加入了这两句

CROSS_COMPILE = 
ARCH = x86
告诉makefile要使用x86架构,不需要指定交叉编译器,就是默认的gcc编译就可以,果然成功了

host@cifae-cdLinux:~/workspace/module$ make
make -C /lib/modules/2.6.32-45-generic/build M=/home/host/workspace/module modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-45-generic'
  CC [M]  /home/host/workspace/module/main.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/host/workspace/module/main.mod.o
  LD [M]  /home/host/workspace/module/main.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-45-generic'

过程三,遗留的问题

还有一个地方没有搞清楚,就是博客中写道的makefile这句话

modules_install:
	$(MAKE) -C $(KDIR) M=$(PWD) modules_install
我运行make modules_install是返回错误的

host@cifae-cdLinux:~/workspace/module$ make modules_install
make -C /lib/modules/2.6.32-45-generic/build M=/home/host/workspace/module modules_install
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-45-generic'
mkdir: cannot create directory `/lib/modules/2.6.32.60+drm33.26/extra': Permission denied
make[1]: *** [_emodinst_] Error 1
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-45-generic'
make: *** [modules_install] Error 2
这个问题就留着以后解决吧!





你可能感兴趣的:(嵌入式研发)