一、向内核添加新功能
1.1 静态加载法:
即新功能源码与内核其它代码一起编译进uImage文件内
-
新功能源码与Linux内核源码在同一目录结构下
-
给新功能代码配置Kconfig
#进入要添加的新功能的同级目录,这里用添加一个名为MY_HELLO的驱动做演示#cd到linux源码中driver文件下的char文件中,修改其Kconfig文件, vim Kconfig #在其中可以发现他们长的都差不多,我们在里面添加如下内容,在内容中解析每个都是什么意思 config MY_HELLO //添加新功能MY_HELLOtristate "This is a hello test" //tristate表示这个功能可以动态加载,如果禁止动态加载的话就将其替换为bool即可help //对添加功能的解释,具体现象都在下方使用命令make menuconfig后This is a test for kernel new function
-
给新功能代码改写Makefile
#cd进入添加功能源码的同级目录,并修改其makefile#拷贝一行,粘贴在下一行,修改成: obj-$(CONFIG_MY_HELLO) += myhello.o //注意最后的文件是对应源码的.o文件,前方的CONFIG_后对应的是实现功能的名字,我们的源码是myhello.c,添加的功能叫做MY_HELLO
4.make menuconfig 界面里将新功能对应的那项选择成<*>
在命令行输入 make menuconfig后会出现如下界面,然后按步骤执行即可 :
#make menuconfig如果出错,一般是两个原因:
#1. libncurses5-dev没安装
#2. 命令行界面太小(太矮或太窄或字体太大了),只需将界面最大化后执行即可
5.回到linux源码最上层执行 make uImage,生成的uImage就是添加完新功能的文件了,就可以将其使用tftp传输到开发板上进行测试
2.动态加载法:
即新功能源码与内核其它源码不一起编译,而是独立编译成内核的插件(被称为内核模块)文件.ko
1、新功能源码与Linux内核源码在同一目录结构下时:
-
给新功能代码配置Kconfig
-
给新功能代码改写Makefile
-
make menuconfig 界面里将新功能对应的那项选择成<M>
-
make uImage
-
make modules
make modules会在新功能源码的同级目录下生成相应的同名.ko文件(生成的ko文件只适用于开发板linux)
注意此命令执行前,开发板的内核源码已被编译,上面三个make都是在源码的最顶层执行的,配置Kconfig和Makefile则是在要添加的目录下执行的
2、新功能源码与Linux内核源码不在同一目录结构下时
这里就需要一个makefile将其与内核连接起来,代码如下:
ifeq ($(KERNELRELEASE),)
#这里可以选择是编译为x86格式的.ko文件还是arm下的.ko文件
ifeq ($(ARCH),arm)
#此为linux源码的绝对路径
KERNELDIR ?= /home/linux/linux_4422/kernel/linux-3.14
#此为根目录挂载的路径
ROOTFS ?= /opt/4412/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules INSTALL_MOD_PATH=$(ROOTFS) modules_installclean:rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versionselse
CONFIG_MODULE_SIG=n
obj-m += myhello.o //因为我们的功能源码为myhello.c,所以这里是myhello.oendif
我们在源码所在文件夹make后会生成x86下的.ko文件,使用 make ARCH=arm 则会生成arm下的.ko文件。
主机ubuntu下使用ko文件
sudo insmod ./???.ko #此处为内核模块文件名,将内核模块插入正在执行的内核中运行 ----- 相当于安装插件 lsmod #查看已被插入的内核模块有哪些,显示的是插入内核后的模块名 sudo rmmod ??? #,此处为插入内核后的模块名,此时将已被插入的内核模块从内核中移除 ----- 相当于卸载插件 sudo dmesg -C #清除内核已打印的信息 dmesg #查看内核的打印信息
开发板Linux下使用ko文件
#先将生成的ko文件拷贝到/opt/4412/rootfs目录下: cp ????/???.ko /opt/4412/rootfs #在串口终端界面开发板Linux命令行下执行 insmod ./???.ko #将内核模块插入正在执行的内核中运行 ----- 相当于安装插件 lsmod #查看已被插入的内核模块有哪些 rmmod ??? #将已被插入的内核模块从内核中移除 ----- 相当于卸载插件 内核随时打印信息,我们可以在串口终端界面随时看到打印信息,不需要dmesg命令查看打印信息