今天在电脑的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这个问题就留着以后解决吧!