加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_阳江站长网 (https://www.0662zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux加载驱动到内核

发布时间:2022-09-16 16:02:51 所属栏目:Linux 来源:
导读:  linux加载驱动到内核

  原因

  公司项目使用一块运行ubuntu18.04的开发作为开发环境,故需要在其内核中添加相关设备的驱动

  了解

  之前对linux了解较少,仅了解ubuntu是linux系统的一
  linux加载驱动到内核
 
  原因
 
  公司项目使用一块运行ubuntu18.04的开发作为开发环境,故需要在其内核中添加相关设备的驱动
 
  了解
 
  之前对linux了解较少,仅了解ubuntu是linux系统的一种,想必应该差不多,在网上搜索“linux驱动加载”等相关关键词,但出来的攻略都不太好用,毕竟对linux不熟,好多指令及工具都很生疏,用vi指令打开修改文件等;
 
  终于在网络及开发板厂家的帮助下了解到,linux驱动加载可以分为在linux系统运行时加载,或者将驱动加载到内核中,在开发板上电及系统初始化时加载,作为产品而言,不可能在产品投入使用后再手动加载驱动,所以就只能选择将驱动加载到内核中去。很多的信息来源于网络,相关连接我会放在文章末尾。
 
  相关知识
 
  通常我们在windows电脑上使用u盘或者无线网卡等设备时,都需要加载驱动,手动安装驱动程序后,插入设备,电脑即可识别到对应设备,也有些如键盘等设备的驱动通常已经被加载到系统中去,当你开启系统后,就能使用键盘进行输入了(个人猜测,懂意思即可)。
 
  1.在网上了解到通常设备的驱动是一些源码,通过make或者其他指令编译成一个xxxx.ko文件,然后使用insmod或者其他指令加载驱动。
 
  2.在这里我就是用记叙了,此时还没了解将驱动编译进内核是如何操作的,在此之前了解到,编译内核及模块得相关操作,需要先将内核配置下,然后编译内核,生成镜像文件,将编译好的内核及设备树文件更新到相关文件夹下。
 
  继续了解
 
  这样写的有点乱,后续如果实现后再整理下。
 
  1.linux内核是由许多模块构成的,使用者可以选择加载或者卸载某些模块,于是我们可以将设备驱动当做模块给加载到内核中去。
 
  2.先去了解一下Makefile是做什么的?
 
  make是linux下的一个程序,之前说到的编译设备驱动源码用到的应该就是这个程序,makefile相当于make这个程序的配置文件
 
  3.遇到问题了,网上搜到的说Linux的镜像文件是linux的可启动镜像,也就是生成的zImage或者vmlinuz,但是我的开发板的镜像文件却是.img文件
 
  4.之前准备先在开发板上动态加载无线网卡的驱动,奈何在网上找的相关文章都不太好用,不知道是配置问题还是驱动有问题,决定先根据网上的教程写一个简单的驱动吧
 
  开始
 
  1.在linux内核的完整路径,如home/linux3.4下的drivers文件夹下新建文件夹hello,然后在hello文件夹下新建hello.c以及Kconfig和Makefile文件,分别填入以下内容
 
  hello.c
 
  #include  //所有模块都需要的头文件
  #include    // init&exit相关宏
  #include
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("baoli");
  MODULE_DESCRIPTION("hello world module");
  
  static int __init hello_init(void)
  {
        printk(KERN_WARNING "hello world.\n");
        return 0;
  }
  static void __exit hello_exit(void)
  {
        printk(KERN_WARNING "hello exit!\n");
  }
  
  module_init(hello_init);
  module_exit(hello_exit);
  Kconfig
 
  menu "HELLO TEST Driver "
  comment "HELLO TEST Driver Config"
  
  config HELLO
   tristate "hello module test"
   default m
   help
   This is the hello test driver --by baoli.
  
  endmenu
  Makefile
 
  obj-$(CONFIG_HELLO) += hello.o
  以上都是从相关博文中摘抄出来的,经过测试,可以使用
 
  以上文件添加完毕后,修改上一级目录的Kconfig和Makefile,即drivers文件夹下的Kconfig和Makefile,
 
  在Makefile文件的后面添加
 
  obj-$(CONFIG_HELLO) += hello/
  在Kconfig文件的倒数第二行添加
 
  source "drivers/hello/Kconfig"
  原博文中有注:某些内核版本需要同时在arch/arm/Kconfig中添加:source “drivers/hello/Kconfig”
 
  不过我没有尝试。
 
  接下来需要进入配置界面
 
  root@ubuntu:~/work/OK10xx-linux-fs/flexbuild$ flex-builder -c linux:custom -m ls1043ardb -a arm64
  1.选择并进入:Device Drivers选项,可以看到新增 HELLO TEST Driver选项

  2.进入 HELLO TEST Driver选项

  3.可以选择 ,分别为编译成内核模块、编译进内核、不编译。
 
  编译
 
  1)如果选择编译成模块
 
  编译内核过程中,会有如下输出:
 
  LD drivers/hello/built-in.o
 
  CC [M] drivers/hello/hello.o
 
  CC drivers/hello/hello.mod.o
 
  LD [M] drivers/hello/hello.ko
 
  2)如果选择编译进内核
 
  编译内核过程中,会有如下输出:
 
  CC drivers/hello/hello.o
 
  LD drivers/hello/built-in.o
 
  编译完成后,drivers/hello/下新增hello.o和hello.ko,并且/linux-3.4/output/lib/modules/3.4.39/下也会有hello.ko。
 
  编译过内核虽然打印过程有相关输出,但是hello文件夹下却没有hello.o和hello.ko文件,
 
  难道是因为上面标注的内容没有做的原因吗?但是配置中的相关内容是正确的。
 
  简单的驱动
 
  在~/home/forlinx/work/OK10xx-linux-fs/flexbuild/packages/linux/OK10xx-linux-kernel/drivers文件夹下有Kconfig和Makefile文件,新编写的驱动应该也是在上面这个文件夹下。看到网上说把驱动源码编译后会产生.ko文件,但是在drivers文件夹下的驱动文件夹下却没有看到有.ko文件。
 
  经询问开发板厂家技术人员,说是可能已经将.o和.ko文件编译进镜像中linux 驱动,感觉好像哪里不对,先这样试下吧,把生成的镜像刷入到板子中,我这里是将镜像文件及配置文件等放入u盘中,重新启动开发板,经由uboot等程序将镜像刷入系统。看下编写的驱动模块是否出现。
 
  将镜像烧写到开发板中后,使用FTP工具查看开发板ubuntu文件系统(不就是ubuntu系统吗)的根目录下找到lib/modules/4.14.47目录下,并没有发现有hello.ko文件,于是在开发板的终端(通过串口)上输入
 
  root@localhost:~# modprobe hello.ko
 
  这个指令是在正点原子的linux驱动开发手册上看到的,说是比较智能,加载该模块时也会加载该模块所依赖的其他模块,所以就试了下,好像跟什么depmod也有关系,这里先不做了解
 
  但是出现了一下错误
 
  modprobe: FATAL: Module hello.ko not found in directory /lib/modules/4.14.47
 
  显示hello.ko没有在4.14.47文件夹下,但是我在下面的文件夹里发现了这个文件
 
  是时候上波图了
 
  在这里插入图片描述
 
  于是将hello文件夹作为工作目录,开始加载模块
 
  下面是指令的相关操作
 
  以上都是看相关博文和摸索的步骤,看到hello world 和hello exit时感觉不容易啊,终于看到点希望了
 
  然后去搜索
 
  dmesg | tail
 
  这个指令是做啥的,
 
  在网上查到该指令的作用为显示dmesg最近一次的输出,而dmesg的作用为显示开机信息,应该就是开机时显示的模块加载等相关信息了
 
  现在模块应该是已经加载成内核模块了,接下来详细看下新加模块hello的相关文件的原理。
 
  先看下hello文件夹下面的Kconfig 吧
 
  menu "HELLO TEST Driver "
  comment "HELLO TEST Driver Config"
  
  config HELLO
   tristate "hello module test"
   default m
   help
   This is the hello test driver
  
  endmenu
  开始:
 
  先说下Kconfig文件的作用:每个Kconfig分别描述了所属目录源文档相关的内核配置菜单。在内核配置makemenuconfig时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文档中。在内核编译时,主Makefile调用这个.config,就知道了用户的选择(网上抄的,看不太明白)
 
  先看下框架吧
 
  文件整体是由menu以及endmenu包裹起来的
 
  有点难搞,啥意思嘛
 
  要不试试搞一下WIFI驱动,也得学会修改Makefile和Kconfig 文件
 
  这是躲不过去的
 
  网上搜索的wifi模块的驱动也都没有发现Kconfig文件,在1043ubuntu的源码的驱动源码中找到了许多Kconfig文件,有的文件夹内也有Kconfig文件
 
  所以,有两个选择,一个是找到带有Kconfig文件的源码,另一个就是将网上找的驱动源码给修改成可用的源码,这个难度不小。
 
  但是要在网上找现成的驱动源码也是大海捞针啊。
 
  怎么办,先找找看吧

  没找到现成的代码,要修改代码吗?
 
  现在有个问题:网上所下载的驱动源码中都是使用Target platform配置目标平台的方法,而向内核新增驱动的方法都是使用加载文件的方法,哪一种适用于1043,如果是第二种,平台怎么选择,如果是第一种,需要修改Kconfig文件及Makefile这个工作量可就大了
 
  还是说只要能在开发板上用就行了,不用自己移植驱动。

  开发板的技术客服回复如上图,所以要想使用MT7601u这个USB无线网卡,还是需要自己修改驱动源码来适用于1043开发板。
 
  新的发现
 
  在网上又找到了这篇博客,讲的是如何修改驱动源码,使其可以在ARM_linux开发板下工作,
 
  死马当活马医,试试
 
  看这个好像是先在电脑上将模块驱动编译出来,然后将驱动加载到开发板,并不是编译到内核,所以应该不能用,先试试也好
 
  进展
 
  好像网上下载的关于MT7601u的驱动,都是上面发现中的驱动,需要配置编译平台什么的,跟我所需要的不符,如果想要修改的话,难度太大,所以放弃这种方法,改用开发板上自带驱动的wifi模块,虽然自带驱动,但是还是需要在内核配置界面将驱动编译进内核或者编译成内核模块,我使用的是inter5100模块,在配置界面,根据Kconfig文件的关系找到该模块的驱动,并选择编译成内核模块,然后直接编译成镜像烧录进开发板,结果整个系统不正常了,无法通过账号密码登录进文件系统,询问开发板厂家,说是需要配置设备树引脚配置什么的,但还建议先试下编译进内核,看下是否可以。
 
  就先试下吧。
 
  在正点原子的嵌入式linux驱动开发指南上看到,我所下载的MT7601u的驱动好像是platform设备驱动,再了解下。
 

(编辑:应用网_阳江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!