驱动运行条件:html
驱动简要编译步骤:linux
在编译源码前须要准备好交叉编译环境,安装必要的依赖和工具,如:git
参考命令:github
sudo apt install make gcc-arm-linux-gnueabihf gcc bison flex libssl-dev dpkg-dev lzop
编译好内核,有如下两个用途:vim
若内核已经烧写至开发板上,则能够经过命令 uname -a
查看内核版本。
*
知道内核版本后可在其官网上下载其内核源码,如并章节以版本为 Linux npi 4.1.9.71-imx-r1 为例,可在gitee或github上下载(野火官方提供)网络
git clone https://gitee.com/Embedfire/ebf-buster-linux.git
编译内核的步骤过程根据不一样官方提供的脚步和Makefile不同而不一样。如下为野火的i.M 6U编译linux内核例程。
单独新建一个工做目录,将其内核源码放在该目录下,切换到内核源码目录,找到 make_deb.sh 脚本,修改里面的配置参数,如内核编译位置等等。修改好配置参数后,只须要执行脚本便可编译内核。(其它内核能够参考该脚本,也能够本身手写一个编译脚本)ionic
deb_distro=bionic DISTRO=stable build_opts="-j 6" build_opts="${build_opts} O=build_image/build" build_opts="${build_opts} ARCH=arm" build_opts="${build_opts} KBUILD_DEBARCH=${DEBARCH}" build_opts="${build_opts} LOCALVERSION=-imx-r1" build_opts="${build_opts} KDEB_CHANGELOG_DIST=${deb_distro}" build_opts="${build_opts} KDEB_PKGVERSION=1${DISTRO}" build_opts="${build_opts} CROSS_COMPILE=arm-linux-gnueabihf-" build_opts="${build_opts} KDEB_SOURCENAME=linux-upstream" make ${build_opts} npi_v7_defconfig make ${build_opts} make ${build_opts} bindeb-pkg
O=build_image/build
:指定编译好的内核放置的位置。ARCH=arm
:目标是 ARM 体系结构内核。KBUILD_DEBARCH=${DEBARCH}
:对于deb-pkg目标,容许覆盖deb-pkg部署的常规启发式。LOCALVERSION=-imx-r1
:使用内核配置选项 "LOCALVERSION" 为常规内核版本附加一个惟一的后缀。KDEB_CHANGELOG_DIST=${deb_distro}
:KDEB_PKGVERSION=1${DISTRO}
:版本信息。CROSS_COMPILE=arm-linux-gnueabihf-
:指定交叉编译器。KDEB_SOURCENAME=linux-upstream
:KDEB_SOURCENAME make变量仅控制已打包的源tarball的名称,并不影响bind -pkg和deb-pkg输出的.deb包名称。make ${build_opts} npi_v7_defconfig
:生成配置文件。make ${build_opts} bindeb-pkg
:编译文件进行打包。hello 例程能够去 李柱明的gitee clone: demo_code_for_mystudy/linux/driverTest/helloModule函数
这只是一个模块例程,不含驱动部分
必须内容可分为如下几点:工具
hello_module.cflex
/** @file hello_module.c * @brief 简要说明 * @details 详细说明 * @author lzm * @date 2021-02-21 18:08:07 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * ********************************************************** * @LOG 修改日志: ********************************************************** */ #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> // 入口函数:安装驱动时调用的函数 static int __init hello_init(void) { printk(KERN_EMERG "[ KERN_EMERG ] Hello Module Init\n"); printk( "[ default ] Hello Module Init\n"); return 0; } // 出口函数:卸载驱动时调用的函数 static void __exit hello_exit(void) { printk("[ default ] Hello Module Exit\n"); } module_init(hello_init); module_exit(hello_exit); //MODULE_LICENSE("GPL2"); MODULE_AUTHOR("embedfire "); MODULE_DESCRIPTION("hello world module"); MODULE_ALIAS("test_module");
编译好获得的内核驱动模块 xx.ko 能够经过多种方式拷贝到 ARM 板上,如NFS网络文件系统、SCP命令获得。
挂载方法能够参考李柱明博客园NFS篇章。
设备树是在 Linux3.x 才引入的,用于描述一个硬件平台的板级细节。
本系列笔记的驱动例程如无特殊说明,都是依赖于设备树的。
下面简略演示设备树的编译和加载,具体原理由具体篇章说明。
编译后的内核会自动生成 dtc 工具。其路径是:内核/scripts/dtc/dtc。
编译命令:内核构建目录/scripts/dtc/dtc -I dts -O dtb -o xxx.dtbo xxx.dts
编译内核时都会自动编译设备树,此时,只须要把设备树源文件放到规定位置便可,设备树源文件、编译生成的设备树文件及咱们所用到的设备树文件都会存放在 内核源码/arch/arm/boot/dts 里面。可是,编译内核耗时长,因此,推荐只编译设备树,方法以下:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
替换设备树的方法:
查看是否加载成功:
Linux4.4 之后引入了动态设备树,设备树插件被动态的加载到系统中,供内核识别。
设备树插件通常用于只修改添加部分硬件信息。如只添加 RGB 灯的硬件信息,就只须要编译 RGB 灯的 .dts 文件为 .dtbo 便可。
编译设备树插件的时候,无需从新编译整个设备树插件,只须要编译修改的部分便可。
设备树和设备树插件都是使用 DTC 编译工具编译。
设备树编译后获得的是 .dtb 文件;
而设备树插件编译后获得的是 .dtbo 文件。
使用野火提供的一键式编译工具:
编译设备树插件和编译设备树相似,这里使用内核中的dtc工具编译编译设备树插件。
编译命令:内核构建目录/scripts/dtc/dtc -I dts -O dtb -o xxx.dtbo xxx.dts
先拷贝设备树插件文件到开发板上。
先在 /sys/kernel/config/device-tree/overlays/下建立一个新目录,名字自定义。
而后将 dtbo 固件 echo 到 path 属性文件中或将 dtbo 的内容 cat 到 dtbo 属性文件中。
echo xxx.dtbo >/sys/kernel/config/device-tree/overlays/xxx/path # 或 cat xxx.dtbo >/sys/kernel/config/device-tree/overlays/xxx/dtbo
删除设备插件:rmdir /sys/kernel/config/device-tree/overlays/xxx
。
不一样的板子可能不支持。
修改环境变量文件便可,进入/boot目录下 修改 vim uEnv.txt