转自:http://blog.csdn.net/dxdxsmy/article/details/8669840

 

前言

前段时间移植 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 修改后的结果,结论就是,这个设计还真行。

From : http://blog.csdn.NET/linweig/article/details/5640697

Firmware 加载原理分析【转】的更多相关文章

  1. PHP-自动加载原理分析

    说起PHP的自动加载,很多同学可能都会想到各种框架的自动加载功能,PHP规范中的PSR0和PSR4原则,Composer的自动加载功能等等,这些都为我们的开发提供了很大的方便. 那么PHP自动加载的前 ...

  2. Spring Boot源码分析-配置文件加载原理

    在Spring Boot源码分析-启动过程中我们进行了启动源码的分析,大致了解了整个Spring Boot的启动过程,具体细节这里不再赘述,感兴趣的同学可以自行阅读.今天让我们继续阅读源码,了解配置文 ...

  3. 从SpringBoot源码分析 配置文件的加载原理和优先级

    本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级     跟入源码之前,先提一个问题:   SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...

  4. javascript图片懒加载与预加载的分析

    javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念.  懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...

  5. JS模块加载器加载原理是怎么样的?

    路人一: 原理一:id即路径 原则.通常我们的入口是这样的: require( [ 'a', 'b' ], callback ) .这里的 'a'.'b' 都是 ModuleId.通过 id 和路径的 ...

  6. 深入解析 composer 的自动加载原理 (转)

    深入解析 composer 的自动加载原理 转自:https://segmentfault.com/a/1190000014948542 前言 PHP 自5.3的版本之后,已经重焕新生,命名空间.性状 ...

  7. iOS 下拉刷新-上拉加载原理

    前言 讲下拉刷新及上拉加载之前先给大家解释UIScrollView的几个属性 contentSize是UIScrollView可以滚动的区域. contentOfinset 苹果官方文档的解释是&qu ...

  8. 老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

      最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者 ...

  9. paip.前端加载时间分析之道优化最佳实践

    paip.前端加载时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的加载,看时间...可以排除编程语言的问题and 数据库.. ## ...

随机推荐

  1. C语言实现两数相加2018-09-23

    /*给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 ...

  2. How To Add Swap Space on Ubuntu 16.04

    Introduction One of the easiest way of increasing the responsiveness of your server and guarding aga ...

  3. Vue源码探究-全局API

    Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...

  4. PHP四种序列化方案

    原文地址:https://t.ti-node.com/thread/... 数据的序列化是一个非常有用的功能,然而目测很多人跟我一样,在刚接触这玩意的时候压根就不理解这货色到底是干啥用的,反正老师说了 ...

  5. TB平台搭建之一

    最近在搭建公司的testbench,主要有一下总结: 1.TB主要有两部分:部分一,软件部分主要用C写的,她的作用是写硬件的驱动(其实就是让核的外围设备可以正常工作或工作到特定的环境上)甚至有可能写整 ...

  6. centos安装并配置MySQL

    一.卸载掉原有mysql [root@xiaoluo ~]# rpm -qa | grep mysql // 这个命令就会查看该操作系统上是否已经安装了mysql数据库 [root@xiaoluo ~ ...

  7. 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记

    https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...

  8. OpenCV中图像的读取,显示与保存

      图像的读取,显示与保存 相关函数:cv2.imread().cv2.imshow().cv2.imwrite() 1.读入图像: 用cv2.imread()函数来读取图像,cv2.imread(路 ...

  9. pycharm-install scipy

    懒得装双系统,所以在win7下用pycharm,python2.7 虽然机子本身是64位,但是安装包的时候,我居然需要下载32位的??迷:) 这次装的是scipy.在pycharm里添加不了,根据网上 ...

  10. SAS描述统计量

    MEANS过程 MEAN过程默认输出的统计量有:观测总数.均值.标准差.最大值和最小值.如果要计算其他统计量或其中的某一些统计量,则可在PROC语句中指定统计量的关键字. BY语句规定了分组变量,要求 ...