《嵌入式驱动(二):驱动编写基本概念》

news/2025/9/26 15:47:34/文章来源:https://www.cnblogs.com/ljbguanli/p/19113631

《嵌入式驱动(二):驱动编写基本概念》

版本号

uboot 2016.03        kernel 4.1.15        busybox 

一、基本概念:

        1. 驱动分类


                1)字符设备驱动:按照单个字符扫描设备信息
                2)块设备驱动:按照块(512字节)扫描设备信息,用于存储设备
                3)网络设备驱动:需要网络协议栈支持TCP/IP、CAN

        2. 驱动编译


                1) 静态编译

                将驱动代码加入到zImage的内核中
                        在合适的内核目录下编写驱动代码 hello.c(/drive/char/)
                        修改Kconfig,新增配置项
                        make menuconfig 选中该配置项
                        对应配置项的CONFIG_XXX 会加入.config文件中‘
                        在驱动代码对应的Makefile中加入编译规则 obj-$(CONFIG_XXX ) += hello.o


                2)动态编译

                将驱动代码以模块的方式编译,动态加入内核或者从内核中去除
                        编写hello.c
                        修改Kconfig,新增配置项
                        通过make menuconfig 选择 M,以模式形式编译
                        对应配置项的CONFIG_XXX 会加入.config文件中 CONFIG_XXX =m
                        在Makefie中 obj-$(CONFIG_XXX ),以模块编译
                        make modules 内核会编译所有模块生成一个.ko驱动文件
                        将驱动文件动态加载到执行的内核中,从内核中去除该驱动模块


二、重点


1. uboot如何编译的?uboot的功能?

        1)解压uboot压缩包,并进入uboot源码目录

tar -zxvf uboot.tar.gz
cd uboot

        2)uboot图形界面是基于ncurses库编写的,所以需要先安装该库

sudo apt-get install libncurses5-dev

        3)编译uboot源码

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean    //清楚原来编译内容,包括.config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig    //用默认配置生成.config,y表示加入编译
make V=0  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16    //编译
ARCH:指定目标硬件架构
CROSS_COMPILE:设置交叉编译工具链
V=0:控制编译输出的详细程度,0表示启动静默/精简输出模式,1表示完整的编译命令,便于调
试。


2. 内核如何编译?如何裁剪?

         编译:

                1) 先利用apt-get工具集下载安装lzop工具(必须保证apt-get源配置,请参考《apt-get源设置》,而且Ubuntu可以上公网,请参考《双网卡网络配置》) 

sudo apt-get install lzop

安装成功,后续可通过该工具生成zImage文件

                2) 将《驱动资料包\源码\内核》内核文件拷贝到Ubuntu系统中,并对文件进行解压缩。

tar -zxvf linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek.tar.gz

                  3)编译内核

cd linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean    //清除旧源
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig    //生成新的.config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig    //微调
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16    //编译
distclean:表示清除之前的编译内容
imx_alientek_emmc_defconfig:将该配置作为内核的.config配置
menuconfig:通过图形界面配置.config
all -j16:通过16核编译代码
ARCH=arm:编译arm32位平台
CROSS_COMPILE=arm-linux-gnueabihf-:设置编译工具链

结果文件主要有2个:
        内核镜像文件:arch/arm/boot/zImage
        设备树文件:arch/arm/boot/dts/imx6ull-alientek-emmc.dtb文件

        裁剪:通过make menuconfig进行微调


3. 根文件系统如何制作?如何自启动?涉及哪些脚本?

        1)将源码拷贝到Ubuntu主机下。(我们可以从busybox官网下载源码,也可以直接使用我下载好的源码,文件在《驱动资料包\工具\busybox》目录下)        

        2)解压文件

tar -vxjf busybox-1.29.0.tar.bz2

        3)修改busybox顶层的Makefile

cd busybox-1.29.0/
vim Makefile

        4) 修改文件中的内容

修改
CROSS_COMPILE ?=
为
CROSS_COMPILE ?= arm-linux-gnueabihf-

修改
ARCH ?= $(SUBARCH)
为
ARCH ?= arm

        5) 配置busybox

make defconfig          //使用默认配置
make menuconfig         //打开图形化配置

        6)通过图形界面配置busybox工具

                配置路径如下:

Location:
-> Settings
-> Build static binary (no shared libs)

Location:
-> Settings
-> vi-style line editing commands

Location:
-> Linux Module Utilities
-> Simplified modutils

Location:
-> Linux System Utilities
-> mdev (16 kb) //确保下面的全部选中,默认都是选中的

           7) 创建一个用来存放生成根文件系统的目录,并编译busybox

mkdir /home/linux/nfs/rootfs                                        //创建存放
根文件系统的目录
make                                                                //编译
make install CONFIG_PREFIX=/home/linux/nfs/rootfs                   //安装
ls -l /home/linux/nfs/rootfs                                        //查看根文
件系统是否创建成功

        8)此时的文件系统还缺少了一些运行的库文件,需要将工具链中的libc库拷贝过去

cd /home/linux/nfs/rootfs
mkdir lib
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/libc/lib/*so* /home/linux/nfs/rootfs/lib/ -d
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/libc/lib/*.a /home/linux/nfs/rootfs/lib/ -d

        9)将符号链接库删除,并拷贝真实的库文件

rm /home/linux/nfs/rootfs/lib/ld-linux-armhf.so.3
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/libc/lib/ld-linux-armhf.so.3 /home/linux/nfs/rootfs/lib

        10)将工具链下的lib库拷贝过去

cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/lib/*so* /home/linux/nfs/rootfs/lib/ -d
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/lib/*.a /home/linux/nfs/rootfs/lib/ -d

        11)将工具链的usr/lib库拷贝过去

mkdir /home/linux/nfs/rootfs/usr/lib -p
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/libc/usr/lib/*so* /home/linux/nfs/rootfs/usr/lib -d
cp ~/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-
gnueabihf/libc/usr/lib/*.a /home/linux/nfs/rootfs/usr/lib -d

        12)进入根目录文件系统查看这两个目录的大小

cd /home/linux/nfs/rootfs
du ./lib ./usr/lib -sh

与上图所示大小一样即为正确。

        13) 创建其余文件夹

mkdir dev
mkdir proc
mkdir mnt
mkdir sys
mkdir tmp
mkdir root
mkdir lib/modules

        14) 我们还需要完善下根我们系统中的配置文件,这些配置文件可以进一步完善Linux系统中的功能

                1. 创建/etc/init.d/rcS文件,并将文件修改为如下内容,该文件是一个shell脚本,Linux内核启动后需要启动的一些服务都可以通过该脚本进行配置

mkdir ~/nfs/rootfs/etc/init.d -p
touch ~/nfs/rootfs/etc/init.d/rcS
vim ~/nfs/rootfs/etc/init.d/rcS

        修改文件内容如下:

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

                2. 修改文件权限

chmod 0777 ~/nfs/rootfs/etc/init.d/rcS

                3. 创建/etc/fstab文件,并将文件修改为如下内容,在rcS脚本中执行mount -a,挂载所有文件系统,就会找到fstab文件,并进行文件挂载。

touch ~/nfs/rootfs/etc/fstab
vim ~/nfs/rootfs/etc/fstab

修改内容如下:

#
proc            /proc           proc    defaults    0       0
tmpfs           /tmp            tmpfs   defaults    0       0
sysfs           /sys            sysfs   defaults    0       0

                4. 创建/etc/inittab文件,该文件指定启动后一些代码的运行方式。

touch ~/nfs/rootfs/etc/inittab
vim ~/nfs/rootfs/etc/inittab

修改文件内容如下:

#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

以上内容的格式为:

<id>:<runlevels>:<action>:<process>
<id>:每个指令的标识符,不能重复。对于busybox而言<id>用来指定启动进程的控制tty,一般
我们将串口或者LCD屏幕设置为控制tty。
<runlevels>:对busybox来说此项说明完成没用
<action>:动作,用于指定<process>可能使用到的动作。如下图所示
<process>:具体的动作,如程序、脚本、命令等。

action动作可配置为如下参数:

        15) 接下来就可以通过nfs挂载测试了。

根文件系统(rootfs)构建工具的实体信息:

busybox:用于生成轻量级、最基本的根文件系统(特点是缺少库、缺少软件);

buildrootyocto:可选择安装某些库、某些软件(用来扩展根文件系统的功能)。

用一张图来表示这个过程

开机自启动:代码写在/etc/init.d/rcS或者/etc/profile

4.总结


5. 内核驱动静态编译和动态编译的区别?

静态编译
将驱动代码直接编译进内核映像(如zImage),成为内核的一部分。驱动随内核启动自动加载,无法单独卸载或更新。适用于核心功能或必须常驻的驱动。

        优点:无需手动加载,性能略高;

        缺点:需重新编译内核才能更新驱动。

        动态编译
将驱动编译为独立模块(.ko文件),可动态加载或卸载。适用于非必需或需频繁调试的驱动。

        优点:灵活性高,便于调试;

        缺点:需手动管理模块依赖。

关键差异

        集成方式:静态编译直接嵌入内核,动态编译生成独立模块。

        维护性:动态编译支持热插拔,静态编译需全内核更新。

        使用场景:核心驱动用静态,可选功能或调试阶段用动态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/918480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一站式电竞平台解决方案:数据、直播、源码,助力业务飞速启航 - 数据服务

我们提供一站式的体育电竞技术、数据与直播服务,助力您快速打造专业级平台。 一、 全面的实时数据与资讯中心 赛程与赛果:覆盖全球主流电竞赛事,数据实时更新。 队伍与选手:详尽的档案资料、数据统计及历史表现。 …

PostgreSQL patroni 高可用 3:patroni 运维

PostgreSQL patroni 高可用 3:patroni 运维PostgreSQL patroni 高可用 3:patroni 运维PostgreSQL ptroni的高可用架构图如下所示,本文完成如下架构图中红色标记内的patroni安装和配置。图片来源于:https://docs.pe…

谷歌站长平台网站建设策划模板

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

nfs故障排查

1. 检查当前 nfsd 线程状态 # 查看当前 nfsd 线程数 cat /proc/net/rpc/nfsd | grep th# 查看 NFS 服务器状态 nfsstat -s# 查看当前 NFS 连接 ss -tnp | grep :20492. 临时增加 nfsd 线程数 # 查看当前线程数(默认通…

业绩亮眼,转型仍有隐忧,若羽臣赴港上市能否实现价值重构? - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

程序员的内容创作利器:深度解析小红书爆款笔记生成提示词

程序员内容创作效率提升指南:深度解析小红书爆款笔记生成AI提示词工程。通过模块化设计、参数化配置和格式化输出,将内容创作效率提升85-90%。包含完整可用提示词代码、技术架构分析、使用场景指南和最佳实践,让技术…

Unigine整合Myra UI Library全纪录(2):渲染

TextureQuadBatcher 由于Unigine没有SpriteBatch类似物,需要手动实现一个。当然用Unigine.Ffp直接来搞也可以,只不过效率就会差一些了。 因为我打算同时用Myra和ImGui.NET,因此这里偷了个懒,去借用Unigine示例里整…

net公司网站开发框架源代码中国网直播

一&#xff0c;基于ANYCAST 设计骨干RP热备1&#xff0c;RP选举说明组播网络RP设置分为动态&#xff0c;静态2种。但和很多网络协议不一样&#xff0c;RP的选择默认是动态优先。也就是在路由器上同时存在动态和静态RP的时候会优选动态&#xff0c;除非定义强制静态优选动态才不…

手机网站 底部菜单一起做网站17杭州女装

我们在开发程序过程中&#xff0c;时常会使用到第三方组件&#xff0c;比如一些通信、UI组件等。常用的引用方法有下面几种。 01 NuGet引用 NuGet是.NET的一个包管理平台&#xff0c;很多开源组件会通过NuGet进行管理和发布。比如我们常用的S7NetPlus等。 从NuGet中引用组件…

服装网站开发方案网站设计博客

一、JQuery是什么&#xff1f; JQuery 是一套JavaScript库&#xff0c; 使用它&#xff0c;可以很方便的进行 JavaScript的编程。比如&#xff1a; 获取页面元素&#xff0c; 修改页面元素的CSS样式等等都可以以很简单的语法完成。节省代码行数和减少开发的时间。 物理上来看就…

元人文AI:为价值创新构筑“舞台”、订立“契约”、预演“未来”

元人文AI:为价值创新构筑“舞台”、订立“契约”、预演“未来” 在人工智能日益深入人类价值腹地的今天,我们面临着一个核心困境:一方面,科技力量要求高效、确定的决策;另一方面,人类价值领域充满难以量化的模糊…

设计一个关于python的if 语句的练习题

当然,以下是一个关于Python中if语句的练习题,旨在帮助理解和应用条件判断: 练习题:天气预测系统 假设你正在开发一个简单的天气预测系统,该系统基于用户输入的温度值来判断并输出相应的天气状况。请编写一个Pytho…

基于CSMA/CA协议的V2X通信MATLAB仿真

基于CSMA/CA协议的V2X通信MATLAB仿真,包含动态车辆移动、信道竞争和性能分析模块: %% MAC协议仿真框架 (CSMA/CA实现) clear; clc;%% 系统参数设置 simTime = 10; % 仿真时间(秒) timeStep = 0.001; % 时间步长…

【招聘专场】想斩获高含金量名企Offer?京东、微芯研究院等企业 软件测试开发岗,虚位以待!

⬆️ 关注霍格沃兹测试学院公众号,回复「面试」,领取测试开发面试真题合集!学社近期有多位同学拿到阿里巴巴、字节跳动、百度、58同城、微博、京东等大厂 Offer 并拿到学社奖学金。关注公众号,回复「面试」获取互联…

练习题:成绩评定系统

当然可以,以下是一个与if语句相关的练习题,它结合了简单的数学计算和条件判断: 练习题:成绩评定系统 假设你正在为一个学校开发一个简单的成绩评定系统。系统需要根据学生输入的分数来判断并输出学生的成绩等级。请…

Day22方法重写

重写首先是对方法的重写,与属性无关,其是在子类中定义与父类的方法名,参数列表,放回值完全相同的非静态方法 因此,重写需要有继承关系的前提下才能调用,子类修饰符的范围可以扩大,但不可以比父类小,而抛出的异…

python调试方法:验证安装路径与路径配置

根据搜索结果和您的环境信息,问题根源已明确:delphivcl模块的安装路径未正确包含在Python的搜索路径中。以下是系统性解决方案: 1️⃣ 验证安装路径与路径配置检查安装位置: pip show delphivcl查看Location字段是…

深入解析:list的学习

深入解析:list的学习2025-09-26 15:31 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

CentOS将软件源修改为国内源

在使用CentOS系统时,yum(Yellowdog Updater Modified)是最常用的包管理工具,无论是安装软件、更新系统还是修复依赖,都离不开它。但CentOS默认的官方yum源服务器位于国外,国内用户在使用时常常会遇到下载速度慢、…

【C++进阶】C++11 的新特性 | lambda | 包装器 - 实践

【C++进阶】C++11 的新特性 | lambda | 包装器 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…