[Arm Linux]交叉编译一个驱动为模块

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 https://blog.csdn.net/wangyijieonline/article/details/83996189

最近在搞Linux驱动,出现了很多问题,做一个记录吧。

问题1:编译模块的准备

编译一个模块需要准备以下部分的工具:
<1> 完整可编译并运行到板子上的内核源码,要注意一定要和编内核时使用的完全一样的内核,如果不对编译时可能不会报错,但会在insmod时发生version magic报错。
<2> 交叉编译工具链要准备好,各种交叉编译工具链,常见的有
aarch64-linux-gnu-
arm-linux-gnueabi-
arm-none-eabi
区别见另一篇博客[嵌入式Linux]–arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf、gnueabi区别
<3> 还可能碰见openssl之类的error,自行百度安装相应的库就可以

问题2:内核的准备工作

上边说到要准备好内核源码,这里又有一个问题,是否需要按照板子的实际情况将内核源码进行修改,答案是不需要,但是需要make menuconfig生成一个.config文件和make 编译一次,此外需要修改最顶层的根目录Makefile,将ARCH和CROSS_COMPILE修改
ARCH := arm64
CROSS_COMPILE := aarch64-linux-gnu-

问题3:模块的最基本组成部分

下面是一个最简单的HelloWorld模块程序:

//hello.c文件
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <asm/io.h>         //含有iomap函数iounmap函数
 #include <asm/uaccess.h>    //含有copy_from_user函数
 #include <linux/device.h>   //含有类相关的处理函数
  
  int init_hello_module(void)
  {
     printk("***************Start***************\n");
     printk("Hello World Init! \n");
      return 0;
  }
  
  void exit_hello_module(void)
  {
     printk("***************End***************\n");
     printk("Hello World Exit! \n");
  }

 module_init(init_hello_module);
 module_exit(exit_hello_module);
 
 MODULE_LICENSE("Dual BSD/GPL");//一般放到最后
#Makefile文件
CROSS_COMPILE:= aarch64-linux-gnu-
ARCH:= arm64
CC:= $(CROSS_COMPILE)gcc
LD:= $(CROSS_COMPILE)ld 
obj-m := leddriver.o 

KERNELDIR = /home/linux-4.9.88

PWD := $(shell pwd) 

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

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

clean:
	rm -f *.o
	rm -f *.symvers
	rm -f *.order
	rm -f *.ko
	rm -f *.mod.c

猜你喜欢

转载自blog.csdn.net/wangyijieonline/article/details/83996189
今日推荐