前言

  • 以野火i.M 6U为例

1. 开发环境搭建

驱动运行条件:

  • 设备驱动是具有独立功能的程序,它可以被单独编译,但不能独立运行, 在运行时它被链接到内核作为内核的一部分在内核空间运行。
  • 因此想要我们写的内核模块在某个版本的内核上运行, 那么就必须在该内核版本上编译它,如果我们编译的内核与我们运行的内核具备不相同的特性,设备驱动则可能无法运行。

驱动简要编译步骤:

  • 首先我们需要知道内核版本,并准备好该版本的内核源码,使用交叉编译工具编译内核源码。
  • 其次,依赖编译的内核源码编译我们的驱动模块以及设备树文件。
  • 最终将驱动模块和设备树拷贝到开发板上运行。

1.1 环境准备

1.1.1 安装工具

在编译源码前需要准备好交叉编译环境,安装必要的依赖和工具,如:

  • gcc-arm-linux-gnueabihf 交叉编译器
  • bison 语法分析器
  • flex 词法分析器
  • libssl-dev OpenSSL 通用库
  • lzop LZO压缩库的压缩软件

参考命令:

  • sudo apt install make gcc-arm-linux-gnueabihf gcc bison flex libssl-dev dpkg-dev lzop

1.1.2 编译内核

编译好内核,有以下两个用途:

  • 制作系统镜像,烧录至开发板
  • 保留一份在开发环境的系统中,用于辅助驱动开发
1.1.2.1 获取内核源码

若内核已经烧写至开发板上,则可以通过命令 uname -a 查看内核版本。

*

知道内核版本后可在其官网上下载其内核源码,如并章节以版本为 Linux npi 4.1.9.71-imx-r1 为例,可在gitee或github上下载(野火官方提供)

  • 命令:git clone https://gitee.com/Embedfire/ebf-buster-linux.git
1.1.2.2 编译内核

编译内核的步骤过程根据不同官方提供的脚步和Makefile不一样而不同。以下为野火的i.M 6U编译linux内核例程。

单独新建一个工作目录,将其内核源码放在该目录下,切换到内核源码目录,找到 make_deb.sh 脚本,修改里面的配置参数,如内核编译位置等等。修改好配置参数后,只需要执行脚本即可编译内核。(其它内核可以参考该脚本,也可以自己手写一个编译脚本)

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:编译文件进行打包。

1.2 内核驱动模块编译和加载

hello 例程可以去 李柱明的gitee clone: demo_code_for_mystudy/linux/driverTest/helloModule

1.2.1 hello 例程分析

这只是一个模块例程,不含驱动部分

必须内容可分为以下几点:

  • 入口函数
  • 出口函数
  • 协议

hello_module.c

/** @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");

1.2.2 和内核源码一起编译

1.2.3 加载内核驱动模块

编译好得到的内核驱动模块 xx.ko 可以通过多种方式拷贝到 ARM 板上,如NFS网络文件系统、SCP命令得到。

挂载方法可以参考李柱明博客园NFS篇章。

1.3 设备树编译和加载

设备树是在 Linux3.x 才引入的,用于描述一个硬件平台的板级细节。

本系列笔记的驱动例程如无特殊说明,都是依赖于设备树的。

下面简略演示设备树的编译和加载,具体原理由具体篇章说明。

1.3.1 设备树编译

1.3.1.1 使用内核中的dtc根据编译

编译后的内核会自动生成 dtc 工具。其路径是:内核/scripts/dtc/dtc。

编译命令:内核构建目录/scripts/dtc/dtc -I dts -O dtb -o xxx.dtbo xxx.dts

  • 意为编译 dts 为 dtb
1.3.1.2 在内核源码中编译(推荐)

编译内核时都会自动编译设备树,此时,只需要把设备树源文件放到规定位置即可,设备树源文件、编译生成的设备树文件及我们所用到的设备树文件都会存放在 内核源码/arch/arm/boot/dts 里面。但是,编译内核耗时长,所以,推荐只编译设备树,方法如下:

  • 两条命令都在内核源码顶层路径下执行(其实就是利用顶层Makefile):

    • 如果在内核源码中执行了 make distclean ,则必须执行第一条命令来生成默认的配置文件。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig
make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
1.3.1.3 加载设备树

替换设备树的方法:

  • 第一种:设备树是编译到内核中的,所以,重新编译内核,重新制作镜像即可。(麻烦,不推荐)
  • 第二种:将编译好的设备树或设备树插件替换到开发板里面的。(推荐)
  • 第三种:将编译好的设备树放到开发板中,**/boot/dtbs/xxx/,修改boot启动参数。(推荐)

查看是否加载成功:

  • 进入 /proc/device-tree 目录下查看已加载的设备节点,看看有没有改动。

1.4 设备树插件的编译和加载

Linux4.4 以后引入了动态设备树,设备树插件被动态的加载到系统中,供内核识别。

设备树插件一般用于只修改添加部分硬件信息。如只添加 RGB 灯的硬件信息,就只需要编译 RGB 灯的 .dts 文件为 .dtbo 即可。

编译设备树插件的时候,无需重新编译整个设备树插件,只需要编译修改的部分即可。

1.4.1 单独使用dtc工具编译

设备树和设备树插件都是使用 DTC 编译工具编译。

设备树编译后得到的是 .dtb 文件;

而设备树插件编译后得到的是 .dtbo 文件。

使用野火提供的一键式编译工具:

  • 地址:git clone https://gitee.com/Embedfire/ebf-linux-dtoverlays.git
  • 要编译的设备树插件源文件放在 ebf-linux-dtoverlays/overlays/ebf 目录下, 然后回到编译工具的根目录 ebf-linux-dtoverlays/ 执行“make”即可。
  • 生成的.dtbo位于 ~/ebf-linux-dtoverlays/output 目录下。
  • 需要注意的是,如果你在执行“make”后出现报错,可以尝试先卸载device-tree-compiler(卸载命令为:“sudo apt-get autoremove device-tree-compiler”), 重新安装,然后在“ebf-linux-dtoverlays/basic/fixdep文件的权限, 修改权限命令为:“chmod 777 scripts/basic/fixdep”。

1.4.2 内核dtc工具编译设备树插件

编译设备树插件和编译设备树类似,这里使用内核中的dtc工具编译编译设备树插件。

编译命令:内核构建目录/scripts/dtc/dtc -I dts -O dtb -o xxx.dtbo xxx.dts

  • 意为编译 dts 为 dtbo

1.4.3 加载设备树插件

先拷贝设备树插件文件到开发板上。

1.4.3.1 使用 echo 命令加载

先在 /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。

1.4.3.2 uboot 加载

不同的板子可能不支持。

修改环境变量文件即可,进入/boot目录下 修改 vim uEnv.txt

参考:

【linux】驱动-1-环境准备的更多相关文章

  1. s3c6410 Linux 驱动开发环境搭建

    s3c6410 Linux 驱动开发环境搭建 -- 既然你是做Linux开发的,你还用虚拟机? 非常多人都在win下做开发,于是SD_writer.exe之类的烧写工具"大行其道" ...

  2. Linux下搭建Android NDK , Linux 驱动开发环境

    Eclispe Luna(4.4):http://www.eclipse.org/downloads/ CDT :http://www.eclipse.org/cdt/downloads.php AD ...

  3. Linux设备驱动开发环境的搭建(转)

    经过两周的摸索,终于对Linux设备驱动开发有了个初步的认识,下面对Linux设备驱动开发环境的搭建做个小结,以方便自己以后查询,同时也能给同道的初学者一点帮助. 刚接触Linux设备驱动时,初学者往 ...

  4. Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...

  5. Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...

  6. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  7. 【转】linux驱动开发的经典书籍

    原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...

  8. linux驱动系列之makefile

    在linux环境下做嵌入式无论是编写应用程序还是驱动程序等等,都需要用make来进行程序的编译,就需要学会自己编写Makefile.Makefile主要的作用有3点:1.决定编译哪些文件 2.怎样编译 ...

  9. linux驱动面试题2

    1.什么是GPIO? general purpose input/output GPIO是相对于芯片本身而言的,如某个管脚是芯片的GPIO脚,则该脚可作为输入或输出高或低电平使用,当然某个脚具有复用的 ...

  10. 树莓派linux驱动学习之hello world

    最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...

随机推荐

  1. sql 手注 语法

    mysql中的information_schema 结构用来存储数据库系统信息 information_schema 结构中这几个表存储的信息,在注射中可以用到的几个表.  | SCHEMATA ―― ...

  2. Apple 反人类的设计的产品组合

    Apple 反人类的设计的产品组合 Apple shit design macbook pro 2018 + beats solo3 MBP 的耳机孔在电脑右边, betas 的耳机孔在左边, 组合起 ...

  3. how to using js to realize notes feature on the website

    how to using js to realize notes feature on the website js & notes demos https://medium.com/brow ...

  4. svg editor

    svg editor https://c.runoob.com/more/svgeditor/ xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访 ...

  5. 200万枚SPC空投来袭,这样的薅羊毛活动你确定不参加吗?

    在过去的2020年,币圈真的是很火爆,很多人在参与数字货币交易或DeFi挖矿中赚到了大钱.但是转眼到了2021年,DeFi进入了下半场,区块链市场也进入了新的阶段,那么区块链的下一个爆点是什么呢?很多 ...

  6. NGK项目与其他项目相比有哪些优势?

    一个项目运行这么久,难免不被其他项目比来比去.NGK项目之所以能被很多人关注,是因为NGK具有独特的优势,NGK具有很高的性能,在智能合约上有多种应用,而且NGK具有独特的跨链技术.转账没有手续费,在 ...

  7. 知名金融媒体采访行业大咖,多方推动BGV茁壮成长

    近来,多家知名金融媒体如纽约金融时报.伦敦金融时报等采访NGK官方代表洛索斯夫,以及美国当地行业大咖马库斯等人. 受访的NGK官方代币洛索斯夫回答道,近期官方将会推出NGK的书籍<NGK公链底层 ...

  8. C语言数据类型思维导图

  9. 处理XML数据应用实践

    摘要:GaussDB(DWS)支持XML数据类型及丰富的XML解析函数,可实现关系数据和XML数据的映射管理功能. XML概述 XML是可扩展的标识语言(eXtensible Markup Langu ...

  10. Spring Cloud基础

    1.网站架构演变过程 传统架构(单点应用SSM或SSH)→分布式架构(项目拆分)→SOA架构(面向服务架构)→微服务架构 2.微服务概述 2.1SOA架构 面向服务的架构(SOA)是一个组件模型,它将 ...