首先说这个是个垃圾手机,屏本身都出了坚条。原代码写的时序也不是太稳定。手机是联想A385e。屏在dmesg中看到的是otm8018b_baolongda的国产屏。在目录/sys/devices/virtual/graphics/fb0下:
#cat name 》》msmfb303_80501
#cat modes 》》 U:480x854p-0
#cat virtual_size 》》 480,2566
如下的这些信息是msm8625这个SOC能支持的屏的一些信息与实际的屏无关。用dmesg看的驱动输出的一此信息应当是otm8018b这个屏。因为屏的信息是在代码中写入的,写成什么内核就显示的是什么,所以这些信息与直实有多大关系,主要在程序员。当记为了便与记忆,都会写成真实的,专业做假的不算。
能过对recovery的内核的dmesg的信息分析,屏的接口是mipi接口。如下是dmesg打出的command line
Kernel command line: androidboot.hardware=qcom loglevel=1 vmalloc=200M prim_display=mipi_video_otm8018b_hsd_fwvga androidboot.emmc=true androidboot.serialno=MSM8625QRD5 androidboot.baseband=msm androidboot.mode=recovery fastmmi_mode=0 panel_type=23
“androidboot.hardware=qcom loglevel=1 vmalloc=200M”这个是recovery解包是的内容部分。prim_display=mipi_video_otm8018b_hsd_fwvga这个是我加的,加在打包recovery时。再后面的就是bootloader加的。panel_type=23 这个是联相的程序员加的,用这个初始化调用直接加载屏的驱动。而没用高通的mipi的驱动框加去加载。但是原内核所有驱动,是与高通框加相当的代码是可以用的。
'androidboot.hardware=qcom loglevel=1 vmalloc=200M prim_display=mipi_cmd_otm8018b_baolongda_bt045tn06v00_fwvga'
mipi_cmd_otm8018b_baolongda_bt045tn06v00_fwvga这个是原recovery在用高通自动加载屏驱动时找印出的信息中找到的。框架中,在/arch/arm/arch-msm/下的相当board中定义了prim_display这个的处理,对msm8625这个字符串是直接在代码中定义的,而不是从屏上读回的。这个字符串与屏驱动自动加载代码中的调用相对比,决定用什么驱动。通过这样,在cmmandline中可以选择所用屏幕。或者记bootloader去读屏参数。然后给出字符串。联想原代码没用这些用了个简单的panel_type=23去处理了。
otm8018b这个屏的接口,可以是mipi。也可以是RGB与IIC。这里因为我对mipi的不熟,一开始认为屏的配置还是要用IIC的设置参数的。但实际上,mipi自身定义了命令接口,可以访问屏上的寄存器,并配置它。也就是说,这个mipi的屏,在软件中需要的硬件相信息只有了解它用了mipi接口,接口的数据差分对有几个(1-4),复位reset的GPIO是什么。这三个信息是与电路板相关的。然后就屏的手册,这个在驱动的初始时是必须了解的。电路板信息的中reset的GPIO并不是容易得到的。为了找到这个GPIO,花了相当的时间。用了一些了解系统信息的方法。又猜又试,还好只有一个,记我找到了。
首先,多编译后的代码中找它是相当不现实的。如果直要这样做,配好处理器,能做单频跟踪内核才好。但实际上手机这种成品,没有JTAG接口。通过源码分析,真的不现实。
再有,就是一个个引脚去试。因为我下的源码中没有otm8018b驱动,otm8018b的驱动是我在github中自已找的,正确否我也不清楚。去试引脚,没有断定的依据。
最后,就是找系统信息了。网上找linux gpio相关的内容,还真让我找到了点东西。
如下就是我找到的一些有用命令,不解释了。
常用命令
kernel目录下查找结构体dsi_cmd_desc定义
git grep -wn dsi_cmd_desc或是find ./ -iname *.c|xargs grep -wrn dsi_cmd_desc
内核符号表
/proc/sys/kernel # cat kptr_restrict
/proc/sys/kernel # echo 0 > kptr_restrict
echo 0 >/proc/sys/kernel/kptr_restrict
cat /proc/kallsyms
cat /proc/kallsyms |busybox grep "\<lcdc_gpio_table\>" |busybox awk '{print $1}'
cat /proc/kallsyms |busybox grep lcdc_gpio
/sys/class/gpio/export文件用于通知系统需要导出控制的GPIO引脚编号
/sys/class/gpio/unexport 用于通知系统取消导出
/sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的操作步骤
gpio状态查看
mount -t debugfs nodev /sys/kernel/debug
cat /sys/kernel/debug/gpio
或者
cat /mnt/debugfs/gpio
分析cat出的gpio信息,并对比我下的源码,联想的人也是在这基础上改的。
adb shell cat /proc/kallsyms |grep lcdc_truly_gpio >> c087cce0 d lcdc_truly_gpio_table
找了一下可以在用户空间打印c05d3a1c这个地址的内容。先提一下lcdc_gpio_table有lcdc接口的mipi没用。这个种分析数据的方法值得记录。lcdc_gpio_table一定要是内核导出符号才可以。如果是全局变量,通常是可以的。在代码中定义的就看不到了,会被编译优化,很难找。kmem是自编代码,把/dev/kmem这个设备mmap一下,然后访问内核的数据。
adb shell /ququfile/kmem 0xc087cce0 》》
PAGE_SIZE = 0x1000
varAddr = 0xC087CCE0
mapbase = 0x40063000
value = 0x13
这个value与源码中写的是一样的。如上这些都是无用数据。内核为这么大,因为内时间去减。减了就要调,这都是时间,做大一点,让用户换手机是好事。看源码中,多少东西是无用的!!!但数据代码之间的关系复杂,减真是要花时间的事。这个方法还是没找出reset的引脚。
但通过找的过程,自已写了一个可以在recovery这个小内核下做测试的直接写屏代码。是把android源码下的参考拿来用的。测试发现,recovery代码被改动了,源手机的和自编的都只能在相应的内核下才可用。否则,只少屏幕没显示。网上下的mipi_otm8018b的驱动,看dmesg是没有报错的。自已加入一些打印信息,调用过程基本正常。这时就是reset引脚了。对它对正常起动后的cat /sys/kernel/debug/gpio结果分析发现了一个
GPIOs 107-132:
gpio-112 (OVP_FLAG_N ) in hi
gpio-114 (GTP_RST_PORT ) out hi
gpio-118 (gc2235 ) in lo
gpio-120 (gc2235 ) out hi
gpio-121 (gc2235 ) out hi
gpio-129 (x820_lcd_reset_n ) in hi
gpio-131 (qup_scl ) in hi
gpio-132 (qup_sda ) in hi
发现了gpio-129 (x820_lcd_reset_n ) in 虽然它配成输入,但这个在dmesg中LCD的on off前后有x820_lcd_这个字符。因为这个引脚是被注册引用了。只是有在reset屏时才会改成out.外部有上拉,输入状态不影响屏的工作。
在命令模式下,做测式。
root@android:/sys/class/gpio # ls
export
gpiochip0
gpiochip107
gpiochip16
gpiochip43
gpiochip68
gpiochip95
unexport
在这下操作可以改变GPIO的状态,关提是这个IO没被内核用。
#echo 129 >export
#cd gpio129
#cat value
# echo high >direction //自动输出高
# echo low >direction //自动输出低
# echo high >direction //再输出高,实现复位脉冲。
#/recovery 这个recovery是与内核相应的android编译出的recovery.而不是原手机的/sbin/recovery. 图片出来了。但按键不正常。这个要recovery源码中改。基本上到这里屏的驱动就确定了。
再看源码,发现代码会调用
msm_fb_dsi_client_reset在这个里加入了自已的输出,确认会调用这个。也可就是说代码是会记用复位信号的,最后的调用
//#define GPIO_QRD3_LCD_BRDG_RESET_N 85
#define GPIO_QRD3_LCD_BRDG_RESET_N 129
这个85的引脚是可以在cat /sys/kernel/debug/gpio看到的,然后在源码中找。就找到这里了而129配在别的地方了,但这部129引脚的代码没有被用到。真接把85改正129再试就正常了。msm_fb_dsi_client_reset因为处理器的不财会调用不财的分支,从而最终所用引脚也是不同的。msm8625就这样改就可以了。
到这里mipi 的驱动就基本改好了。
所后从GPIO中还到了了一些相机不配的IO,就在代码中改了一下。看a385e没用到BT(bluebooth)make menuconfig配下net部分,把bluebooth整体去了。这样基本上IO就不冲突了,然后就是移相机的驱动了。相机用的是gc2235用到的gpio不多。改完了再补写。