当前位置: 首页 > news >正文

复习总结最终版:Linux驱动

一、bootloader、kernel、rootfs
(一)bootloader概念:一个裸机程序,为kernel启动准备环境并引导kernel启动。
(二)bootloader程序需要做什么?
1.初始化CPU工作模式
2.初始化异常向量表
3.关看门狗(独立的定时器,定时产生复位信号(从头开始执行程序)。
定时投喂(告诉它程序正在正常执行):即在它每次计数快结束时(imx6ull自增),重新给它赋值起始值)
4.初始化时钟
5.关中断
6.关闭Cache(必须关闭D-Cache)
7.关MMU
8.初始化内存和相关设备
9.集成相关协议
10.搬移内核到内存(tftp 0x80800000 zImage)
11.启动内核(bootloader不再控制CPU,CPU的控制权彻底移交给内核)
(三)kernel:操作系统的内核(一个复杂的程序)
1.进程管理
2.内存管理
3.文件管理
4.网络管理
5.设备管理
6.加载(挂载)根文件系统
7.init(最开始的执行的程序:设置环境变量/启动相关服务(shell、userapp))
(四)rootfs:根文件系统,按照一定格式组织一堆文件(操作系统启动后第一个挂载的文件系统,一堆文件的集合)
1.配置文本
2.启动脚本
3.命令(系统程序)
4.用户程序
5.普通文件(mp3、png文本)
二、linux启动流程(U-boot是bootloader的一种,linux领域最主流的就是u-boot)
(一)启动方式分类
1.emmc启动(mfgtool)
①SD卡烧录:烧录工具系统(mfgtool)下载到SD卡,板子选择SD启动,这个烧录系统会自动将完整的启动程序烧录到emmc对应位置
②USB OTG烧录:板子选择下载模式,通过 USB OTG 线连接板和电脑,mfgtool会进行一系列操作最后将系统镜像写入emmc
2.SD卡启动:将启动系统通过 mfgtool下载到SD卡,板子选择SD卡启动
3.SPI NOR Flash启动
3.从网络启动(tftp(简单文件传输协议)和nfs(网络文件系统))
①将U-boot下载到SD卡,运行U-Boot
②配置网络与自动加载(倒计数结束时按enter)
③配置板子的IP地址和服务器IP地址(子网掩码、网关、板子IP、宿主机IP)
setenv、saveenv、reset、help、printenv
④通过TFTP加载内核和设备树到内存
tftp 0x80800000 zImage
tftp 0x83000000 imx6ull.dst
bootz 0x80800000 - 0x83000000
⑤内核启动与挂载nfs:U-Boot 将控制权交给内核,挂载指定目录
(二)内核恐慌:内核运行发生致命错误(跟文件系统挂载失败)
1.解决:setenv bootargs root=/dev/nfs nfsroot=192.168.1.3:/home/linux/imx6/rootfs ip=192.168.1.100 console=ttymxc0,115200 init=/linuxrc
2.root:根文件系统类型
nfsroot:fs根文件系统的位置  远端某ip地址主机下的目录
ip:内核启动阶段使用的ip地址
console:控制台指定为串口0
init:指定init进程(启动的第一个进程)
(三)具体启动流程
1.先执行OCROM(BootROM)的启动程序(通过寻找bootloader,确定启动方式)
2.OCROM:拷贝bootloader程序到内存(RAM)
①学习的移植方式:OCROM的程序中先读取emmc中的HEAD(IVT,DCD)等信息,
根据该信息初始化内存,拷贝bootloader到内存中,执行bootloader。
bootloader首次被加载的内存的低地址处,自己搬移自己到高地址处运行)
②另一种方式:拷贝bootloader的前半部分(最多128KB)到OCRAM中,
boodloader的前半部分将内存初始化好,拷贝自己的后半部分到内存(RAM)中,执行后半部分。
3.uboot(开发板的bootloader)启动到最后阶段时搬移
(如果emmc方式:读取emmc中的kernel到内存中,如果tftp方式:通过tftp下载kernel到内存中)
kernel到内存的0x80800000地址处(搬移dtb文件到内存的0x83000000地址处),向kernel传参,启动内核
4.内核启动到最后阶段,根据bootloader传递的参数加载(挂载的形式:本地及nfs)根文件系统及设置终端(控制台)
5.根文件系统挂载完成后,内核中的init进程退化为用户可见的init进程
init进程加载各种配置、启动各种脚本(程序)、启动shell至此操作系统启动完成,用户可以在shell下运行程序
三、内核编译
(一)官方下载linux kernel源码:4.1.15
(二)将源码拷贝到ubuntu并解压
(三)进去内核源码顶层目录,后续编译所有操作才顶层目录即可
(四)拷贝默认配置 所有默认配置都在arch/arm/configs/目录下
①cp arch/arm/configs/imx_alientek_emmc_defconfig .config
②make imx_alientek_emmc_defconfig
(五)在驱动对应目录下创建.c文件后,修改Makefile和Kconfig
四、驱动框架理解
用户应用层(APP、shell)
|
|发出指令open(/dev/led)、read、write
|
驱动类型层(字符/块/网络)
|
|如何与设备对话
|
硬件连接层(platform/USB/IIC等)
|
|
|
功能子系统(gpio/input/led)
|
|
—————————————————————————
|                        |    
实际硬件层(芯片/电路/引脚)        文件系统层(独立工作、管理数据存储)

(一)用户层:发出指令、接收反馈
(二)驱动类型层(按访问方式分类)
1.字符设备驱动:按顺序,字节流传输数据。read/write,键盘,鼠标(按顺序一个字节一个字节访问)
2.块设备驱动:按块传输、(随机)访问数据。硬盘,U盘,SSD(访问某个文件,不需要先得把前面的访问了才能访问此文件。直接将一整块访问)
3.网络设备驱动:按数据包传输数据。网卡、WI-FI(将数据打包成数据包传输)
(三)硬件连接层(驱动如何找到硬件设备)
1.平台设备(platfrom):直接焊在主板上的。SoC内部的GPIO、I2C控制器
2.PCI/PCIe设备:插在扩展槽上的。独立显卡、高端网卡
3.USB设备:即插即用的外设。U盘、键盘、摄像头
4.其他总线:专用连接方式。I2C、SPI、SDIO设备
(四)功能子系统层(按功能分类,这些子系统提供了标准化的操作接口)
1.GPIO子系统:芯片引脚控制
2.输入子系统:输入设备(键盘、鼠标)
3.LED子系统:LED灯控制
4.帧缓冲子系统:显示屏幕
5.声卡子系统:音频设备
(五)文件系统层(不是硬件驱动,是"数据管家"。文件系统驱动建立在块设备驱动之上,不直接操作硬件)
1.管理数据存储格式
2.提供文件操作接口:文件读写、目录管理
五、Ctags:追踪和查找定义
(一)ctags -R:在顶层目录下创建ctags文件
(二):tag main:查找main函数
(三)ctrl + ]:追踪光标所在的函数定义的地方
(四)ctrl + o:返回上一层
六、驱动程序编总结
(一)设备号:代表一个具体的设备(驱动程序)---无符号32位,但是一般只操作前255位
1.主设备号(高12位):区分设备类型(SPI、IIC)
2.次设备号(低20位):区分同类的不同设备(SPI0、SPI1、SPI2)  
(二)驱动设备的管理(cat /proc/devices)
1.字符设备和块设备都是按照设备号分开独立管理的
2.网络设备按照设备名管理,没有设备号
(三)主要编写步骤(手动实现)
1.根据需求完成open/read/write/close等操作方法
2.向内核注册驱动程序(以内核设备号的方式)
3.建立设备号和设备节点(设备名)之间的对应关系
4.编写新生成的zImage并拷贝到tftp服务目录下
5.重启开发板内核
6.开发板执行mknod /dev/led c 255 0在用户层创建设备号
(四)交叉编译:因为开发板内存不足以提供编译条件,所以在ubuntu编译在开发板运行即可(开发板的根目录挂载的Ubuntu的nfs下)
(五)自动在内核注册设备号和自动在用户层注册设备号
1.杂项设备驱动(字符设备驱动):主设备号  10
2.使用内部函数接口自动注册内核设备号
(六)ioctl(非标准化通信(read/write)时可使用)
1.cmd:命令码,决定操作类型
①.设备类型(8):MAGIC_NUM     //区分不同驱动'k'表示键盘
②.方向(2):读/写
③.数据大小(14)
④.具体命令编号(8)
2.fd:从open中获取
3.arg:可选参数
七、模块化编译(动态加载)
(一)修改Makefile
(二)在Kconfig中配置定义类型为 tristate(三态有 y   n   m)
(三)make menuconfig  选项为M
(四)make modules:模块化编译(编译所有被配置为M的模块)
make //编译所有模块
make zImage   //静态编译内核,只编译配置为y的
(五)会在驱动文件的同层目录下生成xxx.ko的内核模块。拷贝到挂载的目录下
(六)修改设备树
(七)编译make dtbs(.dts-->.dtb),拷贝到tftp目录下
(八)开发板使用.ko
1.insmod  led_misc.ko        //加载到内核
2.lsmod                       //查看module
3.rmmod   led_misc             //从内核移除
八、设备驱动分离理解
(一)四大分离框架
1.软件和硬件分离模型
①硬件相关层(中断处理、时钟配置、寄存器操作)
②硬件无关层(通用逻辑、用户接口、算法实现)
2.子系统分层模型
①应用层接口
②功能子系统
③具体设备驱动
④硬件控制
3.总线-设备-驱动分离模型
①驱动:功能实现(各种APP,微信、支付宝)
②总线:连接标准(应用商店的匹配规则)
③设备:硬件描述(各种品牌的手机,iPhone、华为、小米)
4.设备树与驱动分离
①设备树(硬件描述):串口0在地址0x10000000 、GPIO引脚18连接LED、I2C1总线挂载温度传感器
②驱动程序(通用逻辑):任何串口设备、任何GPIO控制的LED、任何I2C温度传感器
(二)驱动四大优势
1.代码复用
2.维护便捷
3.动态扩展
4.跨平台兼容
(三)从开发者角色看
1.硬件工程师:关注底层寄存器操作(硬件相关层)
2.驱动工程师:关注子系统框架和API(硬件无关层)
3.应用工程师:关注/dev和/sys接口(用户接口)
(四)从开发流程看
1.硬件设计 → 生成设备树描述
2.驱动开发 → 实现子系统接口
3.系统集成 → 设备树与驱动匹配
4.应用开发 → 使用标准设备文件
九、学习的驱动分离思想(属于上面分离框架的3和4)
(一)driver-->platform(bus)-->device
如果驱动和设备匹配(match)成功,注册字符设备驱动(probe),有一方卸载时注销(remove)字符设备驱动
(二)设备树与驱动分离
1.设备树概念
①设备树:描述硬件资源(以开发版为单位)
①.dts:描述板级资源的设备树文件(一般一个开发板对应一个文件)
③.dtsi:描述SOC的设备树文件(类似于.c对应的.h文件
④.h
⑤.dtb:最终编译完成后生成的可加载的设备树文件(类似a.out)
2.设备树操作步骤
①cp arch/arm/boot/dts/imx6ull-alientek-emmc.dts   arch/arm/boot/dts/wwb.dts
②修改arch/arm/boot/dts/Makefile   //新增一行,wwb.dtb(加到对应的SOC下)
③make dtbs           //编译所有的设备树文件
make wwb.dtb        //只编译wwb.dts
3.设备树属性书写原则:通用性高,按照已有书写。未定义则自己书写
4.驱动程序中查找设备节点的函数
①of_find_node_by_path();
②of_property_read_u32_array();
③_property_read_string();
十、中断子系统
(一)中断子系统整体架构
1.硬件层:中断控制器(GIC/PIC)、外设触发中断信号  
2.内核通用框架
①规定所有中断必须分上下半部处理
②提供下半部机制(softirq、tasklet、workqueue)
3.设备驱动层
①上半部:在中断处理函数中快速响应
②下半部:选择一种机制(如workqueue)延迟处理
(二)中断上半部(快进快出不能耗时)
1.识别中断:是谁触发了什么类型的中断
2.清除硬件中断标志(告诉硬件我知道了)
3.简单记录发生了什么(如“按键按下”)
(三)中断下半部(选择处理类型,处理最后交给程序)
1.tasklet(softirq的简化版)
①不能被打断:不能被其他中断打断或者进程调度打断,仅可被硬件中断打断
②不能做耗时操作,不能休眠(阻塞)
③不能被系统调度
2.workqueue(一个普通的内核线程)
①可以被打断也可以被系统调度
②可以做耗时操作,可以休眠(阻塞)
(四)读写锁和自旋锁、原子变量
十一、IIC设备驱动
(一)IIC设备驱动依赖于platfrom驱动
1.IIC设备挂载在platfrom上
2.通过IIC适配器adapter使CPU具备成为IIC主设备的能力
(二)具体设备(dht11)用某个IIC(IIC2)的驱动。依赖于IIC总线。
1.使用IIC2,适配器(函数接口)使得IIC2具有通信能力,可以与硬件和软件交互
2.client(设备树编写(slave_addr))
3.driver驱动编写(read/write)

http://www.dtcms.com/a/473747.html

相关文章:

  • Python全栈(基础篇)——Day09:后端内容(列表生成式+生成器+迭代器+实战演示+每日一题)
  • kanass入门到实战(18) - 如何通过仪表盘,快速直观掌握项目进度及度量
  • seo网站优化工具大全wordpress 百度地图api
  • webstorm 调试时不能连接网页
  • 互助网站建设公司网页制作 主流软件
  • 微信公众号登录wordpress网站安徽城乡建设厅网站证件
  • 用wordpress建公司网站步骤郑州橱柜网站建设
  • StringBuffer和StringBuilder的扩容机制
  • 计数 dp
  • 数据结构 实现二叉搜索树与哈希表
  • 深度解析:使用ZIP流式读取大型PPTX文件的最佳实践
  • 商家运营优化:基于京东API返回值的商品管理策略
  • SpringAI+DeepSeek大模型应用开发自用笔记
  • 220kV变电站电气一次系统设计(论文+CAD图纸)
  • 网站快照诊断qq空间 wordpress
  • sql优化思路
  • LeetCode 分类刷题:92. 反转链表 II
  • 视频背景音乐怎么做mp3下载网站wordpress 密码验证失败
  • 医疗区块链:电子病历的零知识证明实现
  • Redis 核心文件、命令与操作指南
  • 使用 httpsok 给 QNAP NAS 添加阿里云域名的永久免费 HTTPS(SSL)证书
  • AI加持的SEO新纪元:用提示词打造高质量内容生产线
  • Manim环境搭建--FFmpeg环境安装
  • JAVA集合框架详解
  • svn and maven 自动部署shell脚本
  • 电影网站如何做长尾关键词网站建立需要什么技术
  • 网站制作英文版网站肥西县建设局资询网站
  • 腾讯开源80B参数混元图像3.0模型:AI作画正在“拥有大脑”
  • HTTP 的方法和状态码
  • 废品网站怎么做wordpress 评论 顶踩 心 插件