安卓系统从power键按下释放,到lcm驱动显示,整个驱动的加载流程as follows:
LK阶段:
首先执行main.c(vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6739/src/core/main.c)文件,然后执行
platform_init(/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/platform.c),然后执行mt_disp_init((void *)g_fb_base);

然后执行disp_lcm_probe -->

其中重点分析下 disp_lcm_probe(vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/disp_lcm.c)

check_lcm_node_from_DT() == 0 读取dts节点信息?

if (_lcm_count() == 0) 得到lcm的数量,如果为0返回NULL,如果为1,则

(_lcm_count()返回的是lcm_count,而lcm_count是从mt65xx_lcm_list.c中extern过来的lcm_count= sizeof(lcm_driver_list) / sizeof(LCM_DRIVER *))

lcm_drv = lcm_driver_list[0]; 读取这个数组的第一个元素;

lcm_driver_list数组从mt65xx_lcm_list.c中extern过来的

这个数组中在添加lcm驱动的时候添加了各个驱动的lcm_drv

比如,我们要添加名为Eighty_80的lcm驱动

那么我们就会在vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm/mt65xx_lcm_list.c添加
+extern LCM_DRIVER Eighty_80_lcm_drv;

并且在LCM_DRIVER *lcm_driver_list[]中添加

#if defined(EIGHTY_80)

&Eighty_80_lcm_drv,//对应lcm驱动的主函数

#endif

其中&Eighty_80_lcm_drv则对应驱动文件中的lcm_drv

这样的话,lcm_drv= lcm_driver_list[0];就是取得驱动文件中的lcm_drv

如果为大于一个lcm驱动,首先是for循环,依次遍历lcm_driver_list这个数组:lcm_drv=lcm_driver_list[i],遍历取得各个lcm驱动的lcm_drv

之后会做判断if(lcm_drv->compare_id() != 0)

这个函数会调用到lk中lcm ic 驱动文件的compare_id函数,返回lcd的id,如果id存在,就会break跳出遍历,告诉系统使用当前这个lcm,这样的话遍历的目的就是取得机器上当前所使用的lcm的各种信息

之后会将这个lcm的各类信息传递给kernel…………这里 disp_lcm_probe就执行完

–>然后执行到primary_display_init(vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6739/primary_display.c)

–> 执行pgc->plcm= disp_lcm_probe,将当前使用的lcm驱动模型赋值给pgc->plcm

–> 之后执行ret = disp_lcm_init(pgc->plcm)就是调用到这个lcm驱动文件中的各个函数,进行初始化,load参数等等。到这里就把lcm lk加载流程串通了。

KERNEL阶段:
驱动入口函数:mtkfb_init(kernel-4.4/drivers/misc/mediatek/video/mt6739/videox/mtkfb.c)–> 执行mtkfb_driver的mtkfb_probe
–> 执行_parse_tag_videolfb(mtkfb.c) --> primary_display_init(kernel-4.4/drivers/misc/mediatek/video/mt6739/videox/primary_display.c)
–> mtkfb_find_lcm_driver(mtkfb.c)
–> mtkfb_fbinfo_init(mtkfb.c)初始化fbi
–>disp_lcm_probe():

check_lcm_node_from_DT() == 0 读取dts节点信息?

if (_lcm_count() == 0) 得到lcm的数量,如果为0返回NULL,如果为1,则

lcm_drv = lcm_driver_list[0]; if (plcm_name == NULL) 读取lcm_driver_list这个数组的第一个元素,isLCMFound = true;isLCMInited = false;

if (strcmp(lcm_drv->name, plcm_name):比较lcm_drv->name和 plcm_name,如果kernel lcm name和lk lcm name不同,return NULL;

lcm_driver_list数组从mt65xx_lcm_list.c(kernel-4.4/drivers/misc/mediatek/lcm/mt65xx_lcm_list.c)中extern过来的

这个数组中在添加lcm驱动的时候添加了各个驱动的lcm_drv

执行lcm_drv = lcm_driver_list[i]遍历取得各个lcm驱动的lcm_drv, if (!strcmp(lcm_drv->name, plcm_name))如果kernel lcm name和lk lcm name一致,
isLCMFound = true;isLCMInited = true;lcmindex = i; 然后break 跳出遍历。去执行相应lcm ic驱动的函数。
————————————————

1、Android中查看当前函数被哪个函数调用,也就是打印函数栈,方便自己平常跟读代码

a、内核的C代码中

dump_stack()


           
b、框架层的JAVA代码中

Exception dump = new Exception("[dumplog]");
       dump.printStackTrace();

c、HAL层的CPP代码中

#include <utils/CallStack.h>
      
       android::CallStack stack;
       stack.update();
       stack.log("[dumplog]", ANDROID_LOG_ERROR, "stackdump:");


     
      Android.mk中增加(默认一般都有加了可以检查一下):
      LOCAL_SHARED_LIBRARIES += libutils
2、开机过程lcm驱动初始化的重要函数调用过程

Lk中涉及到的主要文件:

vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/ddp_manager.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/disp_lcm.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/mt_disp_drv.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/platform.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/primary_display.c
 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm/hx8363a_wvga_dsi_vdo_dz/hx8363a_wvga_dsi_vdo_dz.c

lk中重点函数调用过程:

\void kmain(void)//main.c
     \static int bootstrap2(void *arg)
         \void platform_init(void)//platform.c
             \g_fb_size = mt_disp_get_vram_size();
                 \UINT32 mt_disp_get_vram_size(void)
                     \unsigned int DISP_GetVRamSize(void)
                         \vramSize = DISP_GetFBRamSize();
                             \UINT32 DISP_GetFBRamSize(void)
                                 \return ALIGN_TO(DISP_GetScreenWidth(), MTK_FB_ALIGNMENT) * 
                                      DISP_GetScreenHeight() * ((DISP
                                     \UINT32 DISP_GetScreenWidth(void)
                                         \int primary_display_get_width(void)
                                             \pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);
                                                 \disp_lcm_handle *disp_lcm_probe(char *plcm_name, LCM_INTERFACE_ID lcm_id)
                                                     \plcm->drv->get_params(plcm->params);
                                                         \static void lcm_get_params(LCM_PARAMS *params)//LCM driver c file
                                     \UINT32 DISP_GetScreenHeight(void)
                                         \int primary_display_get_height(void)
             \mt_disp_init((void *)g_fb_base);
                 \void mt_disp_init(void *lcdbase)
                     \primary_display_init(NULL);
                         \int primary_display_init(char *lcm_name)
                             \_build_path_direct_link();
                                 \static int _build_path_direct_link(void)
                                     \dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv);
                                         \ddp_modules_driver[module_name]->set_lcm_utils(module_name, lcm_drv);
                                             \static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util)//LCM driver c file
                             \ret = disp_lcm_init(pgc->plcm);
                                 \lcm_drv->init()
                                     \static void lcm_init(void)//LCM driver c file

kernel中涉及到的主要文件:

kernel-3.18/drivers/misc/mediatek/video/common/mtkfb.c
 kernel-3.18/drivers/misc/mediatek/video/mt6735/ddp_manager.c
 kernel-3.18/drivers/misc/mediatek/video/mt6735/disp_lcm.c
 kernel-3.18/drivers/misc/mediatek/video/mt6735/primary_display.c
 kernel-3.18/drivers/misc/mediatek/lcm/ hx8363a_wvga_dsi_vdo_dz/hx8363a_wvga_dsi_vdo_dz.c

kernel中重点函数调用过程:

\static int mtkfb_probe(struct device *dev)//mtkfb.c
     \primary_display_init(mtkfb_find_lcm_driver(), lcd_fps, is_lcm_inited);
         \int primary_display_init(char *lcm_name, unsigned int lcm_fps, int is_lcm_inited)
             \pgc->plcm = disp_lcm_probe(lcm_name, LCM_INTERFACE_NOTDEFINED, is_lcm_inited);//disp_lcm.c
                 \disp_lcm_handle *disp_lcm_probe(char *plcm_name, LCM_INTERFACE_ID lcm_id, int is_lcm_inited)
                     \plcm->drv->get_params(plcm->params);
                         \static void lcm_get_params(LCM_PARAMS *params) //LCM driver c file
             \__build_path_direct_link();
                  \static int __build_path_direct_link(void)
                     \dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv);
                        \int dpmgr_set_lcm_utils(disp_path_handle dp_handle, void *lcm_drv)
                            \ddp_modules_driver[module_name]->set_lcm_utils(module_name, lcm_drv);
                               \static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util) //LCM driver c file