firmware linux 原理_Firmware加载原理分析 | 学步园
Firmware
加载原理分析
前言
前段时间移植
wifi
驱动到
android
的内核上,发现
firmware
的加载始终出错,问了几个人,都不是很了解,没办法,只好自己研究一下。
原理分析
从本质上来说,
firmware
需要做的事情包括两件:
1,
通知用户态程序,我需要下载
firmware
了;
2,
用户态程序把用户态的数据
copy
到内核层;
3,
内核把内核态的数据写到设备上,比如
wifi
模块里;
其中第三步应该不难,关键是看看,
linux
里面是如何实现第一、二步的;
实现机制
简单的说,它的机制分成以下几部分:
1,
通过一定的方式,通知用户态程序,比如
init
程序,如图所示:
显然是通过
kobject_uevent
的方式通知的应用层,它的机制我有空再详细解释,简单的说,就是往一个
socket
广播一个消息,只需要在应用层打开
socket
监听
NETLINK_KOBJECT_UEVENT
组的消息,就可以收到了。
用户态的
init
是如何做的?
可以看到
init
程序打开了一个
socket
,然后绑定它,最后通过
select
来监听
socket
上来的数据,最后调用
handle_device_fd
来处理收到的消息;当内核发送一个
KOBJ_ADD
的消息上来的时候,经过过滤,判断是否是
firmware
要被加载的消息,然后调用
handle_firmware_event
来处理;
2,
用户态的数据如何下载到内核;
本质上它是内核创建了两个文件,一个文件
A
用来标志下载的开始和结束,另外一个文件
B
用来接收用户层传下来的数据,当用户态的程序往
A
文件写入
1
的时候,标志用户态程序已经往里面写程序来,而往里面写入
0
的时候,就标志下载成功结束,如果写入
-1
就表示下载失败了;下面看看这两个文件是如何被创建的
,
以及数据是如何写到内核的,请看图:
这个图基本上就是两个文件被创立的过程,以及当这两个文件被用户态程序访问的时候将要被调用的函数,比如对于标志文件,如果往里面写入数据,将会触发函数
firmware_loading_store
函数,如果往
bin
文件里面写入数据将会触发
bin
文件类型的
write
函数;
用户态写数据的过程大约是这样的:当用户态收到
KOBJ_ADD
消息的时候最终将会调用
handle_firmware_event
的函数;
它的过程就是:
a,
先往标志文件里面写
1
;
b,
从用户空间读取数据;
c,
往内核创建的文件里面写数据;
d,
如果成功写入
0
,否则写入
-1
;
下面看看内核是如何接受这些文件的,前面提到内核创建了一个
bin
文件,用来接收用户态的数据,下面看看这个过程:
对于
SYSFS_KOBJ_BIN_ATTR
属性的文件,在
inode
初始化的时候,将会被赋予
bin_fops
的文件操作函数集,于是当上层调用
write
的时候,将会走到内核的
bin_fops.write
函数;这个函数干的事情很简单,就是把用户态的数据
copyright
到
bb->buffer
,而
bb->buffer
其实是在
open
的时候分配的空间,这样的话,就实现了用户态的数据到内核的
copy
;过程是不是完了?
还有一个步骤,这个
bb->buffer
本身是如何与
wifi
驱动交互的呢?这只是一个中间层,它的数据必须要写到
wifi
的驱动才应该算完整,而这一步其实就是通过
flush_write
来完成的,下面看看这个过程:
这里可以清楚的看到,
flush_write
做的事情就是把
bb->buffer
的内容
copy
到
wifi driver
分配的空间
fw->data
里面去了,至此,用户态的数据已经完整的写到了
wifi
的
driver
空间了;
3,
内核态的数据到
wifi
模块
这个就比较简单了,通过函数
sdio_writesb
利用
sdio
总线把数据写到模块里面去了;
总结
Firmware
的加载主要是利用了
uevent
的通讯机制实现用户态和内核态的交互,另外还涉及了
sys
文件系统里的文件创建
,
我加载
wifi firmware
始终出错的原因是
android
的文件系统要求把
wifi
的
firmware helper
放到
/etc/firmware
里面,而把真正的
firmware sd8686.bin
放到
/etc/firmware/mrvl
里面,估计是
marvel
修改后的结果,结论就是,这个设计真丑;
备注
作者
:wylhistory;
联系方式
:wylhistory@gmail.com
firmware linux 原理_Firmware加载原理分析 | 学步园相关推荐
- JPA/hibernate懒加载原理分析及JSON格式API反序列化时连环触发懒加载问题的解决
什么是懒加载 JPA是java持久层的API,也就是java官方提供的一个ORM框架,Spring data jpa是spring基于hibernate开发的一个JPA框架.Spring data j ...
- Tomcat:应用加载原理分析
前情回顾 上一篇文章主要了解了一下Tomcat启动入口,以及初步的分析了Tomcat的启动流程,下面我们将会解密Tomcat应用部署的实际流程. 一.直观对比 虽然前面已经说了那么多关于Tomcat的 ...
- 浅析Android字体加载原理
浅析Android字体加载原理 前言 之前在处理系统字体问题的时候,可借鉴的资料很少,遇到了很多坑,不得不了解Android字体加载原理,现抽空写一篇总结,来加深自己对这块的理解. 内容 概述 And ...
- 【Docker镜像文件加载原理生产中重新制作并提交镜像文件案例演示】
一.知识回顾 之前的内容都帮你整理好了,在这里哟! [0.Docker相关目录文章整理,可自行查看,包含多节内容] [1.Docker详细安装部署&阿里镜像地址配置] [2.Docker架构& ...
- 【Docker篇】Docker镜像加载原理,UnionFS(联合文件系统),镜像Commit
文章目录 Docker镜像 1. 镜像是什么 2.Docker镜像加载原理 2.1 UnionFS(联合文件系统) 2.2 Docker镜像加载原理 3. 分层理解 3.1 引申理解 4. 镜像Com ...
- spring bean加载原理
简单的分析了一下spring bean的加载原理,属于个人的理解,源码比这个要复杂的多: spring的配置文件applicationContext.xml的内容如下: <?xml versio ...
- 深度剖析React懒加载原理
目录 代码分割 React的懒加载 import() 原理 React.lazy 原理 Suspense 原理 参考 1.代码分割 (1)为什么要进行代码分割? 现在前端项目基本都采用打包技术,比如 ...
- Android 进阶——MultiDex分包与动态加载原理剖析
一.为什么要进行Dex分包 Android下单个Dex文件存在65535函数数量的限制,而一个功能稍微复杂点的APP很容易超过这个限制,为此,我们引入了Dex分包,将一个App所有class分别打包为 ...
- Android MultiDex 分包及加载原理
彻底了解 65536 方法数超限的问题根源,与官方的 MultiDex 方案原理. Problem 日常开发中,一旦项目变的庞大起来,很容易遇到如下的编译错误: trouble writing out ...
- 内嵌WEB服务器加载原理
内嵌WEB服务器加载原理 理解里面的tomcat是如何启动的 Startup.bat Server.start() 1,概述 我们在使用springboot项目的时候并没有使用外部的tomcat,那么 ...
最新文章
- Ajax---根据id从数据库查找对应的省份名称
- 2012最炙手可热的10项IT技术——相对应的技术书
- java 树的层次遍历_Java遍历树的层级 - osc_jegm3yg5的个人空间 - OSCHINA - 中文开源技术交流社区...
- linux鼠标触摸屏应用程序,在Ubuntu环境下实现插入鼠标自动关闭触摸板
- ack是什么,如何使用Ack机制,如何关闭Ack机制,基本实现,STORM的消息容错机制,Ack机制
- python分布式爬虫系统_如何构建一个分布式爬虫:理论篇
- Java 学习笔记(121208)
- 1092 最好吃的月饼 (20分)
- [推荐]查看Json输出的*最方便*的方法 (转)
- C语言编程题:完美的素数
- 企业手机装配线平衡改善研究
- php 实现网站克隆,自己写的php curl库实现整站克隆功能
- 手机屏幕什么计算机,手机屏幕和电脑屏幕的区别
- 周五送码 | MS08067实验室攻防平台
- Visual Studio安装以及增加工具集C盘占用问题
- Python_爬虫_猫眼电影网电影预告片批量下载
- excel锁定单元格不能修改_EXCEL/WPS如何保护特定的数据不被更改?
- 那些表面光鲜的成功人士背后
- Win10_64位系统安装CUDA、CUDDN、深度学习平台Paddle 、PaddleX安装总结
- XAMPP/PHPnow/phpStudy安装使用对比