嵌入式开发记录-day16 驱动开发-linux最小驱动开发、Makefile、U盘挂载

1、配置Makefile编译环境

  1、拷贝linux内核文件iTop4412_Kernel_3.0_20200410.tar.gz到/home/topeet/下,并解压 tar -zvxf  iTop4412_Kernel_3.0_20200410.tar.gz

  2、cd iTop4412_Kernel_3.0

  3、修改Makefile文件 vim Makefile,将

    ARCH ?= arm

    CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-

  4、配置内核,由于使用的是iTOP-4412的板子,所以在目录下/home/topeet/iTop4412_Kernel_3.0/arch/arm/configs/找到iTop-4412_defconfig文件

  5、将iTop-4412_defconfig文件拷贝到根目录/topeet/iTop4412_Kernel_3.0/下

cp iTop-4412_defconfig /topeet/iTop4412_Kernel_3.0/

mv iTop-4412_defconfig .config  // 重命名.config 文件 有可能拷错了内核版本,可以再尝试下,或者将正确的内核拷贝过去,再试试

make menuconfig  // 执行命令

// 执行make menuconfig 有可能出错,提示如下

root@liu-virtual:/home/topeet/iTop4412_Kernel_3.0# make menuconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
*** 
*** Install ncurses (ncurses-devel) and try again.
*** 
make[1]: *** [scripts/kconfig/dochecklxdialog] 错误 1
make: *** [menuconfig] 错误 2

// 缺少库文件

sudo apt-get install libncurses5-dev 

make menuconfig  // 再次执行  

//弹出窗口,使.config文件生效,可以不用做修改,

// 直接退出,但是必须执行,.config 与之前发生变化

  6、编译内核

  linux内核版本大于3,所以执行make

make // 执行make命令,等待一段时间

  有可能出错,提示

drivers/misc/inv_mpu/mpuirq.c:256: error: expected ')' before 'KBUILD_MODNAME'
drivers/misc/inv_mpu/mpuirq.c:256: error: 'KBUILD_MODNAME' undeclared here (not in a function)
drivers/misc/inv_mpu/mpuirq.c:256: error: expected ',' or ';' before string constant
make[3]: *** [drivers/misc/inv_mpu/mpuirq.o] 错误 1
make[2]: *** [drivers/misc/inv_mpu] 错误 2
make[1]: *** [drivers/misc] 错误 2
make: *** [drivers] 错误 2

gedit mpuirq.c  // 打开文件将256行注释掉,重新执行,还有警告但是,没有错,正常执行完毕;猜测应该mpu模块的驱动用不了;

  7、安装内核

make modules_install   // 安装模块
make install                 // 安装内核

// 修改timeout 开机时候选择启动内核
gedit boot/grub/grub.cfg
// 将set timeout = 0,0改为5 

  8、然后重启reboot

详细配置请看大佬 https://blog.csdn.net/crazycoder8848/article/details/44131735

--------------------------------------------由于上面太折腾了,所以换了讯为已经弄好的Ubuntu镜像,但是还是下了好久------------------------------------

2、最简linux驱动

 mini_linux_module.c

 1 #include <linux/module.h>
 2 #include <linux/init.h>
 3 
 4 //2、 必须遵循GPL协议
 5 // 没有linux版本限制、且开源
 6 MODULE_LICENSE("Dual BSD/GPL"); 
 7 // 声明作者可有可无 
 8 MODULE_AUTHOR("TOPEET");
 9 
10 // 3、
11 static int hello_init(void)
12 {
13     // KERN_EMERG表示终端无论是什么权限 都可以打印出来后面字符串
14     // 七种打印方式,调试的时候可能会用到
15     printk(KERN_EMERG "HELLO WORLD enter!\n");
16     return 0;
17 }
18 static void hello_exit(void)
19 {
20     printk(KERN_EMERG "HELLO WORLD exit!\n");
21 }
22 
23 //1、 入口函数module_nint
24 module_init(hello_init);
25 module_exit(hello_exit);

3、编写Makefile文件

#!/bin/bash
#通知编译器我们要编译模块的哪些源码
#这里是编译Mhello.c这个文件编译成中间文件Mhello.o
obj-m += Mhello.o 

#源码目录变量,这里用户需要根据实际情况选择路径
#作者是将Linux的源码拷贝到目录/home/topeet/下并解压的
KDIR := /home/topeet/Andord/iTop4412_Kernel_3.0

#当前目录变量
PWD ?= $(shell pwd)

#make命名默认寻找第一个目标
#make -C: 指定内核源码所在的目录。
#$(KDIR)Linux源码目录,作者这里指的是/home/topeet/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
# M: 指定Makefile和源文键Mhello.c所在的目录 #modules要执行的操作 all: make -C $(KDIR) M=$(PWD) modules // 这里的空格一定要使用linux下的Tab键 #make clean执行的操作是删除后缀为o的文件 clean: rm -rf *.o // // 这里的空格一定要使用linux下的Tab键

4、编译模块

make  // 执行make命令

  

  执行make后,进入Linux内核所在的源码目录,编译出Mhello.o,再运行MODPOST生成临时的Mhello.mod.c,再根据这个文件生成Mhello.mod.o文件,最后再链接

  Mhello.o和Mhello.mod.o生成Mhello.ko文件。

  其中生成的Mhello.mod.c产生了Linux可执行、可连接的ELF文件的第二个节点信息。

5、验证

  将生成的mini_linux_module.ko文件拷贝到U盘中,在开发板上运行;

mount /dev/sda1 /mnt/disk   // 挂载U盘
insmod  /mnt/disk/mini_linux_module.ko   // 加载模块
lsmod   // 查看模块第一种方法
cat /proc/modules   // 查看运行模块第二种方法

rmmod mini_linux_module.ko     // 卸载模块,卸载模块不需要添加路径,否则有可能无反应,而卸载失败

--------------------------剩下的仅供参考----------------------------------

 

6、关于rmmod模块无法卸载问题总结

  rmmod mini_linux_module.ko 执行无法找到某些文件,根据提示,添加文件即可;

  rmmod mini_linux_module.ko命令执行,提示没有某些文件,根据提示,添加也可以;

  rmmod mini_linux_module.ko命令执行成功,但是没有打印退出消息,但是没有报错,lsmod查看模块还在,

  rmmod mini_linux_module.ko执行失败原因总结

  执行时,不要加U盘路径 rmmod /mnt/disk/mini_linux_module.ko

    进入Ul盘里面执行:rmmod mini_linux_module.ko 不要加后缀ko,执行rmmod mini_linux_module

  若提示需要添加文件3.0.15类似文件,使用uname -r 查看 xxx

  mkd /lib/modules/xxx

  执行结果:

[root@iTOP-4412]# insmod /mnt/disk/mini_linux_module.ko 
[ 421.102380] HELLO WORLD enter!
[root@iTOP-4412]# lsmod
mini_linux_module 700 0 - Live 0xbf008000
[root@iTOP-4412]# rmmod mini_linux_module 
[ 431.513047] HELLO WORLD exit!

  7、加载模块:

insmod mini_linux_module.ko   // 加载模块
lsmod       // 查看模块
rmmod mini_linux_module   // 卸载模块

 8、需要注意:.config

  linux中使用.config来确认哪些模块驱动代码编译进内核,可以使用基于文本菜单的配置界面make menuconfig来配置.config文件,是否需要将设备驱动,编译进内核中,然后再make zImage,生成相应的内核镜像文件;

  字符设备一般在Character device驱动中; 

9、linux内核裁剪

  make menuconfig配置模块的三种属性:

    <> 不编译状态;

    <M> 对应的部分编译成模块

    <*> 将对应的代码编译进内核

   vim  driver/char/Kconfig

   找到LEDS注册的驱动代码(/LEDS ),仿照LEDS 代码,增加HELLO_CTL模块

config HELLO_CTL
        tristate "Enable HELLO config"
        default y
        help
          Enable HELLO config

//bool :只可以编译或者不编译
// tristate 可以编译进内核,或者不编译进内核,也可以编译成模块

  make menuconfig // 在里面找打HELLO_CTL模块,选择<M>编译成模块,可以查看.config文件变化;

10、在make menuconfig中,取消LEDS驱动编译进内核,声称zImage镜像,烧写进来,查看LEDS驱动是否存在,并查看HELLO_RTL 模块

11、Makefile 、Kconfig、.config三者之间关系

   在执行make menuconfig后,执行当前目录下的scripts脚本scripts   Kconfig,在这里Kconfig是该脚本的输入文件,那么.config就是该脚本的输入文件。

  这有点类似去饭店吃饭一样,Kconfig是饭店的菜单,我们可以选择或者不选择这个菜(也就是编译或者不编译进内核,或者编译成模块),选择好了后,服务员记

录了我们点的菜的菜单(这个菜单就是.config),饭店根据这份菜单做出一大堆饭菜(在编译时,内核根据每一级的.config文件编译出一个定义好的新内核)。

 

12、Linux内核编译

  在Linux内核源码根目录下,执行make zImage,在arch/arm/boot目录下生成,zImage镜像文件。

  为什么会生成镜像文件在这个目录下?

    因为在这个目录下的Makefile文件中定义了,在当前目录生成zImage目标文件,虽然在其他路径下makefile也有目标文件,但都是中间临时的目标文件。

 

 

 

posted @ 2020-06-27 12:22  笑不出花的旦旦  阅读(401)  评论(0)    收藏  举报