老师布置了linux实验作业,本身不打算写了,反正也不交实验报告,但刚好项目也需要,所以就研究了makefile。不过还是要批评自己,怎么能这么的颓废呢?
刚开始做的时候出现了这样的错误,代码如下:
TARGET=helloworld KDIR=/usr/src/linux-headers-4.4.0-72-generic PWD=$(shell pwd) #modules-objs:= **.o #生成模块名所需要的目标文件 obj-m:=$(TARGET).o default: make -C $(KDIR) M=$(PWD) modules _PHONY:install install: insmod $(TARGET).ko _PHONY:uninstall uninstall: rmmod $(TARGET).ko _PHONY:clean clean: -rm *.ko -rm *.o -rm -f Mo* -rm *.mod.* make -C $(KDIR) M=$(PWD) clean
经过研究发现是obj-m:=$(TARGET).o这个地方出了错,o被我写成了O。导致找不到文件。细节问题一定要注意!!!
现在分析一下代码:TARGET=helloworld & obj-m:=$(TARGET).o这两句话是确定要生成的模块
modules-objs :这个变量是说明声称模块modules需要的目标文件 格式要求 <模块名>-objs := <目标文件>
切记:模块的名字不能取与目标文件相同的名字。如在这里模块名不能取成 mymod;
KDIR :这是我们正在运行的操作系统内核编译目录。也就是编译模块需要的环境。
M= :指定我们源文件的位置
PWD :这是当前工作路径$(shell )是make的一个内置函数。用来执行shell命令。
make -C $(KDIR) M=$(PWD) modules
其中-C后指定的是Linux内核源代码的目录,我们需要其中一个目录下的Modules文件,而M=后指定的是helloworld.c和Makefile所在的目录
编译过程中,经历了这样的步骤:先进入Linux内核所在的目录,并编译出helloworld.o文件,运行MODPOST会生成临时的helloworld.mod.c文件,而后根据此文件编译出helloworld.mod.o,之后连接helloworld.o和helloworld.mod.o文件得到模块目标文件helloworld.ko,最后离开Linux内核所在的目录。
使用insmod helloworld.ko 将该Module加入内核中。在这里需要注意的是要用 su 命令切换到root用户,否则会显示如下的错误:insmod: error inserting 'helloworld.ko': -1 Operation not permitted
使用rmmod hello来卸载模块,同样,使用dmesg可以看到打印出的内容。
内核模块的打印信息一般不会打印在终端上。驱动的打印都在内核日志中,我们可以使用dmesg命令查看内核日志信息。dmesg|tail