向内核模块中添加新功能

一、向内核添加新功能

1.1 静态加载法:

即新功能源码与内核其它代码一起编译进uImage文件内

  1. 新功能源码与Linux内核源码在同一目录结构下

  2. 给新功能代码配置Kconfig

    #进入要添加的新功能的同级目录,这里用添加一个名为MY_HELLO的驱动做演示
     
    #cd到linux源码中driver文件下的char文件中,修改其Kconfig文件,
    vim Kconfig
    
    #在其中可以发现他们长的都差不多,我们在里面添加如下内容,在内容中解析每个都是什么意思
    config MY_HELLO //添加新功能MY_HELLO
    
        tristate "This is a hello test" //tristate表示这个功能可以动态加载,如果禁止动态加载的话就将其替换为bool即可
    
        help //对添加功能的解释,具体现象都在下方使用命令make menuconfig后
            This is a test for kernel new function
    
  3. 给新功能代码改写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. 命令行界面太小(太矮或太窄或字体太大了),只需将界面最大化后执行即可

向内核模块中添加新功能_第1张图片

 

向内核模块中添加新功能_第2张图片

向内核模块中添加新功能_第3张图片

向内核模块中添加新功能_第4张图片 

 

  ​5.回到linux源码最上层执行 make uImage,生成的uImage就是添加完新功能的文件了,就可以将其使用tftp传输到开发板上进行测试

2.动态加载法:

即新功能源码与内核其它源码不一起编译,而是独立编译成内核的插件(被称为内核模块)文件.ko

1、新功能源码与Linux内核源码在同一目录结构下时:

  1. 给新功能代码配置Kconfig

  2. 给新功能代码改写Makefile

  3. make menuconfig 界面里将新功能对应的那项选择成

  4. make uImage

  5. 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) modules

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

clean:
	rm -rf  *.o  *.ko  .*.cmd  *.mod.*  modules.order  Module.symvers   .tmp_versions

else
CONFIG_MODULE_SIG=n
obj-m += myhello.o //因为我们的功能源码为myhello.c,所以这里是myhello.o

endif

我们在源码所在文件夹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命令查看打印信息

你可能感兴趣的:(linux,驱动)