您的位置:首页 > 运维架构 > Linux

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

2016-01-20 15:54 489 查看
一、关于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。如果要想动态加载,可以使用直接创建设备的方法,即直接[b]i2c_new_device方法。[/b]不管哪种方法,最终都会调用i2c_driver结构体的成员函数probe,在里面进行设备驱动的设计,由于是触摸屏,将使用输入子系统。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: