1. 情景分析法必须确立一个情景,此情景满足以下条件:

#    a.满足自己的学习目标
#   b.该情景内的代码,应该只能被执行1次.譬如,分析usb进行数据传输的过程. 那么在执行该情景前,应该将
#   所以的USB设备拔出, 或者将它们对应的驱动取消执行.
#   再譬如, 要分析kmalloc()的执行过程, 那么我应该在该kmalloc第一次被执行处,加上一句while(1), 防止后续又
#   有kmalloc()被执行.
#   c.若该情景需要用户应用, 譬如应用获取按键事件等. 所要执行的应用程序应尽量得到其源码, 或者自行编写或搜索相关例程.
#   拥有源码后, 就可以将不必要的代码删除, 减少关联驱动的阅读.

2. 情景分析法实践流程:

#   a. 由上至下的代码简化. 由上至下,即由应用程序=>驱动框架=>硬件驱动.
#   应用程序的一句ioctl(), 可能涉及驱动的几百个函数的执行. 若是我们能先尽量地简化应用程序,或驱动框架,会大大地
#   减少代码阅读量.
#   b. 批量添加函数名打印. 根据打印, 可以一一对被执行的函数进行简化. 具体添加打印方法,见
#   https://blog.csdn.net/weixin_45154862/article/details/127192739
#   c. 集合所有被简化的函数, 进行代码分析.

3. 细节说明之 函数简化:

#   去掉判断语句,循环语句, 宏定义的语句, 总之去掉所以需要我们进行分析判断, 耗费脑力的代码.
#   而最终简化的结果是, 我们可以无需依靠打印,开发板的运行输出, 便可以靠阅读代码,知道代码的执行流程.

#   函数简化的范围: 我们分析的是驱动代码, 其他非该驱动框架或驱动的代码无需简化分析. 譬如kmalloc.
#   一般,范围会限制在该驱动框架或驱动所在文件夹内.

#  z. 直接删除函数
#  在对某个函数进行简化前, 我们可以试着将该函数删除, 会有30%的概率,情景依旧正常执行!
#  这样的结果是喜闻乐见的,因为一个函数,可能会嵌套几十个函数, 那么我们就可以少简化几十个函数,
#  少分析几十个函数. 大大地减少工作量.
#  因此简化前,请先执行此步骤.

#   a. 保留副本
#   需要简化的函数, 应保留其副本(函数原文件处,复制一份,并重命令), 方便代码分析时回看.
#   而我们的简化工作就直接在原函数进行.

#   b. 独立函数的执行.
#   若某函数被执行了多次, 且每次的执行, 执行流程的不同.可以将该函数的代码复制多份, 并重命名,
#   以独立每次函数的执行. 这样,简化工作就在其函数副本内执行, 这区别于步骤a. 每一个函数的副本,
#   若想它们被执行, 需要在头文件添加声明, 将会增加工作量. 这也就是步骤a直接修改原函数,而非副本函数的理由.
#   譬如:
#   处理前:
    test();
    test();
    test();
#    处理后:
    test1();
    test2();
    test3();

#   c. 去掉所有的判断语句的分支, 仅保留被执行的代码,及其判断条件.
#   譬如:
#    简化前:
    void test(int a,int b)
    {
        int c;

if(a>9) {
            xxxx; /* 被执行 */
        } else if (b<9) {
            xxxx;
        }
    }
#   简化后
    void test(int a,int b)
    {
        int c;

if(a>9) {
            xxxx; /* 被执行 */
        }
    }

#   d. 去掉循环
#   譬如:
#   简化前
    i=0;
    while(i<get_count()){
        set_index(i);
        i++;
    }
#   简化后
    /* get_count()的返回值为3 */
    i=0;
    set_index(i);
    i=1;
    set_index(i);
    i=2;
    set_index(i);
#   这时, set_index()函数被执行了多次.可以使用b步骤进行处理.

#   e. 去掉宏定义
#   譬如:
#   简化前:
#   xxx.h
#define TEST(a,b) a>b:3?4
    xxx.c
    TEST(5,6);
#简化后:
    xxx.c
    5>6:3?4
    
#  f. 删除指针赋值语句
#  太多的指针变量, 使得结构体间的关系错综复杂.但其实许多的指针,在当前情景内,是不被使用的,
#  将它们删除, 可以减少代码分析时的工作量. 不仅是指针, 含有队列的入队,出队等语句, 也可删除的
#  都尽量删除.

4. 细节说明之 代码分析

# a. 集合所有简化后的,需要被执行的, 该驱动相关的, 函数到一个文件内. 依据函数的嵌套关系,将函数源码补充完全.
#     主要目的是方便分析, 和进行代码标注.
#     譬如:
    int test(void)
    {
        get_index();
        void get_index(void)
        {
            set_type(c);
            void set_type(struct type a)
            {
                g_type = a;
            }
        }
    }

# b. 结构体成员关系标注
#   使用<tagx> 指示 某一操作的对象,以及操作过程.
#   对象或成员处注有<tagx>, 操作处也注有 <tagx>, 可以实现跳转,通过手动搜索<tagx>.
#    譬如, 这里的<tagx> 可以记录该成员在何处被分配内存, 或被赋值.
    struct machine {
        struct tv b;
    };
    struct machine a;
        -> struct tv *b; <tag3>

int machine_type_create(struct machine *mac)
    {
        mac->b = kmalloc(); <tag3>
    }
#    <point to objx> 意为此指针指向objx, <objx> 在objx 处有标注.
#   譬如一下, <point to obj6> 表明b成员指向sony_tv. 而<tag5> 标注此赋值是在何处进行的.
    strct machine a;
        ->struc tv *b; <point to obj6> <tag5>

struct tv sony_tv; <obj6>

int get_tv(struct machine *mac)
    {
        mac->b = &sony_tv; <tag5>
    }
#    <add to listx> 意为将此list_head加入 listx, <listx> 在链表头处有标注.

#https://gitee.com/suiren/usb2hdmi/blob/master/drm_read.c
#drm_read.c一文,是完全使用本文的代码阅读方法, 而获得的驱动阅读总结, 也可作为参考.

linux驱动源码阅读之情景分析法实践指南相关推荐

  1. [Linux] USB-Storage驱动 源码阅读笔记(一)

    USB-Storage驱动 源码阅读笔记--从USB子系统开始 最近在研究U盘的驱动,遇到很多难以理解的问题,虽然之前也参考过一些很不错的书籍如:<USB那些事>,但最终还是觉得下载一份最 ...

  2. r8169驱动源码阅读记录

    r8169驱动源码阅读记录 初始化 发包 收包 源码地址:linux-4.19.90\drivers\net\ethernet\realtek\r8169.c 源码阅读环境:Windows 搭建 op ...

  3. 【转载】ubuntu下linux内核源码阅读工具和调试方法总结

    http://blog.chinaunix.net/space.php?uid=20940095&do=blog&cuid=2377369 一 linux内核源码阅读工具 window ...

  4. Linux内核源码阅读以及工具(转)

    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)

  5. Linux内核学习(五):linux kernel源码结构以及makefile分析

    Linux内核学习(五):linux kernel源码结构以及makefile分析 前面我们知道了linux内核镜像的生成.加载以及加载工具uboot. 这里我们来看看linux内核的源码的宏观东西, ...

  6. 米尔科技 Z-turn XC7Z010 Linux驱动源码路径

    米尔科技 Z-turn XC7Z010 Linux驱动源码路径 网址:http://www.myir-tech.com/bbs/thread-6999-1-1.html Z-turn XC7Z010 ...

  7. Linux内核源码阅读以及工具详解

    接上篇Linux内核源码下载方法 这篇总结了如何利用source insight对Linux内核代码进行阅读和学习(资料来源于网络) 随着linux的逐步普及,现在有不少人对于Linux的安装及设置已 ...

  8. java collection源码_jdk源码阅读Collection实例分析

    jdk源码阅读Collection详解 见过一句夸张的话,叫做"没有阅读过jdk源码的人不算学过java".从今天起开始精读源码.而适合精读的源码无非就是java.io,.util ...

  9. linux实现自己的write函数,Linux 内核源码阅读 - write 系统调用的实现

    最近在看write系统调用的实现,虽然还有一下细节不是很清楚,但是大致的实现机理还是有一定的理解了.总结如下: 这里假设最普通的情况,不考虑Direct IO 的情况.从全家的高度看,要往一个文件中写 ...

最新文章

  1. MongoDB性能测试代码
  2. BFC(Box Formatting Context)的原理
  3. matlab GUI figure置右上角
  4. python困难_Python开发总感觉困难重重,可能是你没用上这些开发工具
  5. 大剑无锋之如何查看一个java进程的堆内存使用情况(jps,jstack,jmap)【面试推荐】
  6. ps的初级教程:去痘痘-庞姿姿
  7. 英语3500词(二) your dream lover主题 (2022.1.14)
  8. 牛客网SQL实战二刷 | Day1
  9. 5-2本题要求对两个整数a和b,输出其中较大的数。
  10. Squid+MRTG实现完善的缓存代理和http服务加速代理
  11. IT小盆友:注意20种习惯最耗元气
  12. 导出excel文件后,显示文件损坏
  13. 计算机导论二进制小数乘法,二进制计算
  14. [整理]几个好的嵌入式linux学习网站和博客
  15. css中的auto属性
  16. 开发原生的 Google 眼镜应用 【已翻译100%】(1/2)
  17. iPhone X下界面满屏展示
  18. java程序设计教程试题_java程序设计试题库.doc
  19. 服务器额定功率和实际功率_商业服务器解决方案,提高功率和效率
  20. 开课啦!图观™应用编辑器 零基础入门课(第一讲)

热门文章

  1. asp.net中HTML控件和web控件的简单理解
  2. offsetLeft深入研究
  3. 在Ubuntu上装CLPACK,并跑出ELSDc的代码
  4. 二线城市的JAVA工程师,从一二线城市回到三四线城市的工程师们,是否可以分享一下你们现在的工作与状态?...
  5. 成事的百条铁律(21-40)
  6. 成考大专要英语和计算机吗,成人高考都需要考英语吗
  7. Excel写保护怎么破解
  8. c#获取本地ip地址网关子网掩码_详细介绍winformC#获得Mac地址,IP地址,子网掩码,默认网关的代码实例(图)...
  9. 黄聪:Fiddler对安卓应用手机抓包图文教程
  10. 群雄逐鹿 百家争鸣 | 华云数据荣获2021信创“大比武”总决赛全国第二名