s3c6410 LCD驱动的分析过程——定位相关源代码

时间:2023-02-08 12:21:49

本文主要讲述了在拿到一套硬件和相关的内核源代码时,怎样找到特定驱动的源代码相关的文件。

首先,linux的驱动可以通过make menuconfig命令来进行配置,通过该命令,我们可以大概了解到这套内核所含了哪些可用的源代码。

因此我们可以通过这个命令,来查看源代码中包含什么驱动。初步定位驱动程序的位置。以下讲述一下我在没有其它资料的前提下怎么查找s3c6410芯片LCD相关驱动代码的位置的过程(假设你想换一下LCD屏,要改一下该驱动的各种信号的时序和分辨率):
1、执行make menuconfig
执行命令后,查看各个选择,找一下跟LCD有关的选项发现选项如下:
Device Drivers
|_Graphics support
  |_*Support for frame bufferdevices
  |_*S3C Framebuffer Support
  |_Select LCD Type(4.3 i...800x480)
关键就是这个Select LCD Type这里,里面可以选择很多类型,有7寸的800X480的,有10寸的等等。找到这里以后,我们要找出这个配置项会让内核在编译时做什么东东。


2、查看源代码目录的driver/KConfig文件(关于KConfig的格式可以自己上网查一下,《Linux驱动开发入门与实践》P89页也有讲述),通过大概的查看与分析,定位到"driver/video/KConfig"文件。然后在该文件中用“查找”的方法,找一下自己关心的配置项的配置信息(比如我们可以查一下Select LCD Type)。这时我们会发现找不到这个关键字。那么我们可以再试一下找这个配置项附近的一些其它配置项,如它上两行的“Support for frame buffer”选项。
找这些其它的配置项是为了大概定位到我们所需的配置项的位置。大概定位以后,我们再往下查找一下附近的"source"关键字,看以下引入了哪些文件。我们需要看的配置项有可能就在这些文件里。通过这个方式,我找到了我关心的配置项“Select LCD Type”的内容在"driver/video/samsung/KConfig"文件中。


3、定位到我们的配置项后,我们把这个配置项声明的宏定义给记录下来。例如:以下这些是我们关心的配置项的部份内容:

config FB_S3C_EXT
tristate "S3C Framebuffer Support (eXtended)"
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
depends on FB && (ARCH_S3C64XX || ARCH_S5P64XX || ARCH_S5PC1XX)


default y if VIDEO_SAMSUNG
---help---
TBA


choice
depends on FB_S3C_EXT
prompt "Select LCD Type"
default FB_S3C_EXT_TFT480272


config FB_S3C_EXT_TFT480272
boolean "4.3 inch 480x272 TFT LCD"
select TOUCHSCREEN_IF
help
 4.3 inch 480x272 TFT LCD


config FB_S3C_EXT_TFT800480
boolean "7 inch 800x480 TFT LCD - A70"
select TOUCHSCREEN_IF
help
 7 inch 800x480 TFT LCD


config FB_S3C_EXT_S70T800480
boolean "7 inch 800x480 TFT LCD - S70"
select TOUCHSCREEN_IF
help
 7 inch 800x480 TFT LCD


config FB_S3C_EXT_W50I800480
boolean "5 inch 800x480 TFT LCD - W50i"
select TOUCHSCREEN_IF
help
 5 inch 800x480 TFT LCD


config FB_S3C_EXT_T240320
boolean "3.5 inch 240X320 Toppoly LCD"
select TOUCHSCREEN_IF
help
 3.5 inch 240X320 Toppoly LCD


这里的"FB_S3C_EXT"和"FB_S3C_EXT_TFT_LCD类型"是会影响内核的宏定义,我们要把它记下来然后进入下一步的分析。



4、查看与KConfig文件同一目录下的makefile。查找“obj+宏定义=...”,这样可以了解到,选择了这此配置项以后会增加哪些文件到内核。然后我们就可以重点分析这些源代码了。我们查看Makefile里的内容不多,关键点是这几句:
obj-$(CONFIG_FB_S3C_EXT)+= s3cfb.o
obj-$(CONFIG_FB_S3C_EXT) += s3cfb_spi.o
obj-$(CONFIG_PLAT_S3C64XX) += s3cfb_fimd4x.o
……
#以下这些跟分辨率有关的都在同一个文件里
obj-$(CONFIG_FB_S3C_EXT_TFT480272) += s3c_mini6410.o
obj-$(CONFIG_FB_S3C_EXT_TFT800480) += s3c_mini6410.o
obj-$(CONFIG_FB_S3C_EXT_S70T800480) += s3c_mini6410.o
……


从这里开始,我们已经找到了跟LCD有关的所有代码的位置。
下面我们开始分析一下这些文个把中关键代码的位置,讲述一下我的分析过程:
我们发现不管是4寸的屏幕还是7寸的屏幕,即使它们的分辨率不同,内核都是包含了同一个文件“s3c_mini6410.c”于是我猜想:与屏幕时序和分辨率有关的参数应该是放在s3c_mini6410.h这个头文件中,用条件编译的方式进行处理。结果打开该文件,确实如此,以下是s3c_mini6410.h部份代码片段:


#if defined(CONFIG_FB_S3C_EXT_TFT480272)


#define S3CFB_LCD_TYPE "N43"
#define S3CFB_VBP (0x03)/* back porch */
#define S3CFB_VFP (0x02)/* front porch */
#define S3CFB_VSW (0x02)/* vsync width */
#define S3CFB_HBP (0x2d)/* back porch */
#define S3CFB_HFP (0x04)/* front porch */
#define S3CFB_HSW (0x06)/* hsync width */


#define S3CFB_HRES 480/* horizon pixel  x resolition */
#define S3CFB_VRES 272/* line cnt       y resolution */


#define S3CFB_CLKVAL 11
#define S3CFB_VIDCON1 (S3C_VIDCON1_IVCLK_RISE_EDGE)


//------------------------------------------------------------------------------
#elif defined(CONFIG_FB_S3C_EXT_TFT800480)


#define S3CFB_LCD_TYPE "A70"
#define S3CFB_VBP (0x1d)/* back porch */
#define S3CFB_VFP (0x11)/* front porch */
#define S3CFB_VSW (0x18)/* vsync width */
#define S3CFB_HBP (0x28)/* back porch */
#define S3CFB_HFP (0x28)/* front porch */
#define S3CFB_HSW (0x30)/* hsync width */


#define S3CFB_HRES 800/* horizon pixel  x resolition */
#define S3CFB_VRES 480/* line cnt       y resolution */


#define S3CFB_CLKVAL 3/* ~33.25 MHz */
#define S3CFB_VIDCON1 (S3C_VIDCON1_IHSYNC_INVERT | S3C_VIDCON1_IVSYNC_INVERT)


//------------------------------------------------------------------------------
#elif defined(CONFIG_FB_S3C_EXT_S70T800480)
…………
……
#endif


下一步,我们再分析一下上面定义这些宏的作用,我的分析过程是这样的:
1、打开s3c_mini6410.c,查找一下这些宏哪里用到,结果发现上面的这些宏都是“s3cfb_set_fimd_info”函数里被用到了。这些函数利用这些宏设置了一个s3cfb_fimd的外部变量。到这一步存在几个疑问:
a)这个变量的声明在哪里?
b)这个变量的定义在哪里(它的完整结构是怎么样的)?
2、抱着第一点的疑问,我们查看s3c_mini6410.c 引用的头文件,一个一个进行重点分析,我找到“s3cfb.h”中,定义了s3cfb_fimd_info_t结构。并且声明了一个外部变量:
extern s3cfb_fimd_info_t s3cfb_fimd;
于是我再查看了一下,s3cfb.c看看该文件中有没有真正地定义这个s3cfb_fimd变量,结果发现s3cfb.c文件中没有这个变量。
3、打不到文件,我们再回头想一下makefile文件中,包含了哪些特定的文件——还有"s3cfb_fimd4x.c"呢。我打开该文件,确实找到了这个变量的定义。


以上说这些实际没有涉及太多的技术相关的信息,主要是讲述了一下,当我的源代码没有相关的文档相关的技持时,怎么去分析和修改相关的驱动源代码。现在定位到这些代码以后就可以进行重点分析里面的函数的功能了。