Linux 驱动学习静态加载与动态加载详解

1、静态加载和动态加载

静态加载:静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用。静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译和下载内核,效率较低。若采用静态加载的驱动较多,会导致内核容量很大,浪费存储空间;

动态加载:动态加载利用了Linux的module特性,可以在系统启动后用insmod命令添加模块(.ko),在不需要的时候用rmmod命令卸载模块,采用这种动态加载的方式便于驱动程序的调试,同时可以针对产品的功能需求,进行内核的裁剪,将不需要的驱动去除,大大减小了内核的存储容量。是在编译内核的时候,就编译进内核,开机后会自动加载;

动态加载一般是设备驱动程序,设备驱动里面会使用到内核驱动,比如使用交叉编译或官网下载的一个在linux系统下工作的设备驱动,因为是针对Linux系统而制作的,它知道内核支持的基本驱动,比如I2C、SPI、等操作硬件的驱动,协议驱动提供了标准的操作硬件的协议函数,而这个设备驱动里面正是调用了内核协议驱动工作。

动态加载是将驱动编译成模块,使用insmod命令加载。
加到启动脚本里让其开机自动加载,算是一种技巧,不是标准的方法

区别:

比较:静态加载一般用于基础功能的驱动,反正都是迟早是要加载的,编译进内核效率更高;动态加载一般用于扩展功能的驱动,这个设备可能需要加载这个驱动也可能不需要加载这个驱动,这就要根据情况去加载和卸载驱动,比如:支持热插拔功能的设备。

补充:驱动代码是单独编译还是直接编译进内核,可以在配置内核是通过make menuconfig进行选择;也可以将驱动代码独立出来,自己编写Makefile编译成ko文件;

2、驱动编写之静态编译

https://wiki.t-firefly.com/zh_CN/ROC-RK3588S-PC/linux_compile.html该目录网站有详细下载SDK的教程

1)新建驱动源码目录

如图所示,找到要编译平台的内核源码位置,也就是本次编译的对象RK3588_SDK

然后进入到、kernel/drivers/***,本次是要编译加密的文件,所以要放入到/kernel/drivers/crypto文件夹中。新增一个mod208文件夹,将官方或者自己编写的驱动文件放入到该新建的文件夹中

2)编写、修改Makefile

在新添加的目录下编写Makefile

例如:

# Makefile for the Linux device tree

obj-$(CONFIG_CHRDEVBASE) += chrdevbase.o   

# CONFIG_CHRDEVBASE :为宏定义,格式CONFIG_xxx,对应三态

而本次mod208的makefile如下:

obj-$(CONFIG_CRYPTO_DEV_MOD208) := mod208.o

mod208-objs := m208_helper.o mod208_api.o mod208_i2c.o mod208_module.o

目录新建,则需要在上一级Makefile进行修改:

3)编写、修改Kconfig

在新建目录下编写Kconfig文件,编写时删除注释

例子:

 menu "Chr Driver"             // 开始,菜单名,可自定义,一般格式:xxx Driver

config CHRDEVBASE // config xxx, 注意是 xxx 不是 config_xxx,省略了前缀"CONFIG_"

tristate "ChrDevBase Driver" //

default n // 默认状态 n

---help---

This is the driver for Chr Driver // 帮助信息

endmenu // 结束

本次编写的Kconfig如下:

config CRYPTO_DEV_MOD208

tristate "Support for MODSEMI mod208 authentication devices."

depends on I2C

help

  This option enables the driver for mod208 hardware authentication devices

  To compile this driver as a module, choose M here.

若目录是新建,则需修改上一级 Kconfig,添加如下代码(若不是新建则不需添加),添加新建目录编译路径

4)配置menuconfig图形化界面

1、进入图像化界面,两个方式

make ARCH=arm menuconfig  /* 方式一 */

make menuconfig     /* 方式二 */

本次使用的是第二种,make menuconfig

2 路径选择路线(Enter建),找到编写的驱动

Device Drivers —> … Package(KLSP) —> chr Driver —> <>ChrDevBase Driver

本次是在Cryptographic API --> Hardware crypto devices选择

3 对编写的驱动进行配置

按 空格键 进行状态切换

* : 编译进内核

n : 不被编译

m : 编译成模块

4 退出保存,生成 .config 文件

5 查看 .config 文件是否有对应的驱动菜单

5)配置dts

设备树是Linux内核的一个重要组成部分,描述系统中所有硬件设备和配置信息,DTS文件包含系统硬件信息,包括CPU,内存和外设等,Linux内核启动时会自动加载DTS文件,将硬件信息映射到内核中

设备树:为了解决嵌入式系统中硬件设备数量变化、不同的硬件配置等问题而设计的一种数据结构,它用于描述硬件设备的寻址、中断、时钟、电源等信息,让内核能够正确识别硬件,管理设备资源。

开始支持使用设备树,这样做的意义重大,可以实现驱动代码与设备的硬件信息相互的隔离,减少了代码中的耦合性。通过设备树对硬件信息的抽象,驱动代码只要负责处理逻辑,而关于设备的具体信息存放到设备树文件中,这样,如果只是硬件接口信息的变化而没有驱动逻辑的变化,开发者只需要修改设备树文件信息,不需要改写驱动代码

设备树由一系列被命名的节点(Node)和属性(Property)组成,而节点本身可包含子节点。在设备树中,可描述的信息包括:

CPU的数量和类别。

内存基地址和大小。

总线和桥。

外设连接。

中断控制器和中断使用情况。

GPIO控制器和GPIO使用情况。

时钟控制器和时钟使用情况。

基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备。

一般在Linux源码中存在大量的dts文件,对于 arm 架构可以在arch/arm/boot/dts找到相应的dts,另外mips则在arch/mips/boot/dts,powerpc在arch/powerpc/boot/dts。

执行./build.sh的时候刚出现几个的配置参数中可以看出目标文件

TARGET_ARCH=arm64

TARGET_PLATFORM=rk3588

TARGET_UBOOT_CONFIG=rk3588

TARGET_SPL_CONFIG=

TARGET_KERNEL_CONFIG=rockchip_linux_defconfig

TARGET_KERNEL_DTS=roc-rk3588s-pc-mipi101-M101014-BE45-A1

在这里表示**.dsti和**.dst文件的区别,dsti文件是公共的信息,会被dst包含进去

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值