先看Makefile:这种需要在内核的Makefile中添加ARCH 和 CROSS_COMPILE
#ubuntu的内核源码树,如果要编译在ubuntu中安装的模块就打开这2个
#ubuntu的内核源码树,如果要编译在ubuntu中安装的模块就打开这2个
#KERN_VER = 3.13.0-32-generic
#KERN_DIR = /usr#/src/linux-headers-3.13.0-32-generic,ubuntu的内核源码树
KERN_VER = $(shell uname -r)
KERN_DIR = /lib/modules/$(KERN_VER)/build
开发板的linux内核的源码树目录
#KERN_DIR = /home/share/drivers/kernel
obj-m += module_test.o
all:
make -C $(KERN_DIR) M=`pwd` modules
cp:
cp *.ko /root/rootfs/rootfs/drivers -f
.PHONY: clean
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
我们这里看一种全新的,推荐的方式
KERNEL_DIR=/home/wyz/share/kernel_5.10.10/linux-5.10.10
CURDIR=`pwd`
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILE
obj-m := led.o
all:
make -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean cp
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
cp:
sudo cp *.ko /home/wyz/share/tool_server_dir/nfs -rf
我们一行一行的分析:
KERN_VER = $(shell uname -r)
uname -r是linux的一个命令,可以看到内核的版本号,例如我们在ubuntu14.04中输入uname -r得到的是3.13.0-164-generic,这一行的意思是在Makefile中使用shell命令uname -r得到3.13.0-164-generic,然后赋值给KERN_VER 变量,
在Makefile中变量的赋值两边是可以加上空格的,在shell中就不行。
KERN_DIR = /lib/modules/$(KERN_VER)/build
结合第一行的命令,KERN_DIR = /lib/modules/3.13.0-164-generic/build
我们查看一下build是一个软连接,指向:-> /usr/src/linux-headers-3.13.0-164-generic,但是/usr/src/linux-headers-3.13.0-164-generic又是/usr/src/linux-headers-3.13.0-164的软连接。所以最终我们的ubuntu的内核源码树就是:
/usr/src/linux-headers-3.13.0-164
obj-m += module_test.o,这一行就表示我们要将module_test.c文件编译成一个模块。
如果是obj-y += module_test.o就表示我们要将module_test.c文件静态编译链接进zImage中
make -C $(KERN_DIR) M=pwd
modules 这个命令用来实际编译模块,工作原理就是:利用make -C进入到我们指定的内核源码树目录下,然后在源码目录树下借用内核源码中定义的模块编译规则去编译这个模块完成编译。-C
(
K
D
I
R
)
指
明
跳
转
到
内
核
源
码
目
录
下
读
取
那
里
的
M
a
k
e
f
i
l
e
;
M
=
(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=
(KDIR)指明跳转到内核源码目录下读取那里的Makefile;M=(PWD) 选项让该Makefile在构造modules目标之前返回到模块源代码目录并在当前目录生成obj-m指定的xxx.o目标模块。make modules在内核中是编译模块的意义。
总结一下就是:由于obj-m += module_test.o, make -C $(KERN_DIR) modules会进入到内核的源码树目录下,obj-m的值增加了module_test.o,然后make modules,就会生成module_test.ko驱动模块.。 M=pwd
其实是指定在构造modules目标之前返回到模块源代码目录并在当前目录生成obj-m指定的xxx.o目标模块
make -C $(KERN_DIR) M=pwd
modules clean 这个就是和make一样的原理了。