查看Linux内核源码技巧的记录

时间:2021-03-23 12:28:09

一、关于Linux内核启动流程

      参见文章《Linux内核启动流程笔记》。


二、关于数据结构

1.  双向循环链表

     参见总结《Linux中List.h文件分析和应用》。

2.  哈希表


三、关于驱动程序的分析

      基于4412-linux3.5平台,以I2C接口的触摸屏驱动为例子。

1.   找驱动程序源文件

      触摸屏肯定属于输入子系统,所以在drivers\input\touchscreen目录下肯定能找到其驱动程序;  然后把触摸屏电源和地短接一下,串口终端就会打印什么ft5x06 err,所以断定drivers\input\touchscreen目录下下的ft5x06_ts.c文件为当前使用触摸屏的驱动程序。

2.   在Linux内核中找到对于配置项

      在上面找到文件名的情况下, 终端中输入命令grep "ft5x06_ts" -R *  找到如下一行:

                  drivers/input/touchscreen/Makefile:obj-$(CONFIG_TOUCHSCREEN_FT5X0X)     += ft5x06_ts.o


      由此可见,当变量CONFIG_TOUCHSCREEN_FT5X0X为y或m时,ft5x06_ts文件会被编译。


      在内核源码目录中执行make  menuconfig,按”/“表示搜索。输入CONFIG_TOUCHSCREEN_FT5X0X,出现如下信息:

  | Symbol: TOUCHSCREEN_FT5X0X_SINGLE [=n]                                                            
  | Type  : boolean                                                                                   
  | Prompt: Disable MULTI-Touch Mode                                                                  
  |   Defined at drivers/input/touchscreen/Kconfig:324                                                
  |   Depends on: !S390 && !UML && INPUT [=y] && INPUT_TOUCHSCREEN [=y] && TOUCHSCREEN_FT5X0X [=y]    
  |   Location:                                                                                       
  |     -> Device Drivers                                                                             
  |       -> Input device support                                                                     
  |         -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])                     
  |           -> Touchscreens (INPUT_TOUCHSCREEN [=y])                                                
  |             -> FocalTech ft5x0x TouchScreen driver (TOUCHSCREEN_FT5X0X [=y])

        从上述信息中可知,只要FocalTech ft5x0x TouchScreen driver选项被配置,相应Makefile中CONFIG_TOUCHSCREEN_FT5X0X变量的值就为y,ft5x06_ts.就会被编译近内核。上述信息中Defined at drivers/input/touchscreen/Kconfig:324 表示在Kconfig文件中定义的位置,一般在Kconfig中都是CONFIG   TOUCHSCREEN_FT5X0X的字样。


        注意,有时分析是上述流程的逆过程,也就是用配置选项CONFIG_TOUCHSCREEN_FT5X0X找到驱动源文件ft5x06_ts.c


3.   驱动结构的分析

      分析子系统源码,一般从入口函数开始分析。在ft5x06_ts.c源码文件中,由module_init(ft5x0x_ts_init);可知入口函数为ft5x0x_ts_init,在ft5x0x_ts_init函数中调用i2c_add_driver函数注册i2c_driver,对应的i2c_driver结构体为ft5x0x_ts_driver,在ft5x0x_ts_driver结构体id_table成员中name为ft5x0x_ts。

      通过上面的分析,再结合bus-dev-drv模型,在bus总线的dev链表中必将找到对应的一个i2c_client结构(i2c_board_info的type成员值为ft5x0x_ts),所以在终端中输入命令:

grep "ft5x0x_ts" -R * 后,找到如下信息:

      arch/arm/mach-exynos/mach-tiny4412.c:           I2C_BOARD_INFO("ft5x0x_ts", (0x70 >> 1)),

      从上述信息中可以知道在mach-tiny4412.c文件中肯定能找到dev(如果是I2c设备,就是i2c_client)的注册过程。通过内核文档可知,i2c_client的注册过程有4中方法,查看mach-tiny4412.c源码文件发现使用了第一中方法。

      这种方法是线调用i2c_register_board_info函数把i2c_board_info结构体放入__i2c_board_list链表,后面在某个地方会调用i2c_register_adapter函数,此函数中会调用i2c_scan_static_board_info函数,此函数就会使用到__i2c_board_list链表,具体做法就是调用i2c_new_device函数把链表中的每个成员构造成一个i2c_client。

      由此可见,这种方法必须在 i2c_register_adapter 之前 i2c_register_board_info,所以不适合动态加载insmod。如果要想动态加载,可以使用直接创建设备的方法,即直接i2c_new_device方法。不管哪种方法,最终都会调用i2c_driver结构体的成员函数probe,在里面进行设备驱动的设计,由于是触摸屏,将使用输入子系统。