MSM8K Boot Flow

                              图1:

高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974、MSM8916、MSM8994等,会有微小区别。

从上图,可以看出高通8K平台的boot过程非常不一般啊。相比MTK平台,或者高通7K平台,复杂了非常多。 下图是高通文档对启动流程的说明,

已经很清楚了,我这边就直接贴出来啦。

                                   图2:

系统上电后从RPM PBL启动到 APPS PBL 然后SBL1 ,再启动APPSBL 等等,整个过程看似非常复杂,但其实很多代码OEM厂家是看不到,也修改不了的。

那我们需要我们做什么? 能做点什么呢? 呵呵!不会没事情做的。 SBL1和appsbl高通是有开放代码。

本章我重点关注SBL1,且主要描述我认为重点的几方面:

1、    CDT : Platform ID和DDR参数

2、 debug log :

3、 download : msm8K 新平台软件download支持两种协议,sahara和firehose

4、 ramdump :死机异常信息dump

好的,下面将SBL1我比较关注的点调用流程总结成如下图,后面再针对关注点展开,逐个分析。

                           图3:

二、CDT:Platform ID和DDR参数

1、CDT(Configuration Data Table ) 里到底有什么内容?

   参考下图,可知CDT包含CDB0: platform info信息和CDB1: DDR配置参数。
 
                图4:
 
   platform info 包含平台id,主板的版本号,项目号等信息
          图5:
 
CDB0: platform info 如下结构体表现:
typedef PACKED struct
{
  uint8                 nVersion;
  uint8                 nPlatform;      //这个是平台id,用于高通不同平台类型。我们不能去修改。
  uint8                 nHWVersionMajor;   //硬件版本号暂时没有使用,默认为0
  uint8                 nHWVersionMinor;
  uint8                 nSubtype;    // 默认为0没有用。我们可以用它来做项目区分   
  uint8                 nNumKVPS;
  PlatformInfoKVPSCDTType  aKVPS[];
} PlatformInfoCDTType;
 

参考如下文档和code:
80-N3411-1_B_EEPROM_SW_CDT.pdf
boot_images/core/boot/secboot3/hw/msm8916/boot_cdt_array.c

boot_images/core/systemdrivers/platforminfo/src/PlatformInfo.c

boot_images/core/boot/secboot3/scripts/cdt_generator.py

boot_images/core/boot/secboot3/scripts/jedec_lpddr3_single_channel.xml

2、CDB0: platform info信息有什么用处?

 上图3可以看到CDB0: platform info相关的代码调用有如下二函数:

voidboot_config_data_table_init(bl_shared_data_type* bl_shared_data)
{
  boot_log_message("boot_config_data_table_init, Start");
  boot_log_start_timer();
  
  /*populate configuration data table's info*/
  config_data_table_info.size = config_data_table_size;
  config_data_table_info.cdt_ptr = config_data_table;
   //get default config_data_table array from boot_cdt_array.c

boot_update_config_data_table(&config_data_table_info);
  //read the cdt from eMMC and update the default config_data_table array

/*put a pointer to the table info into sbl shared data so next sbl can access it*/
  bl_shared_data->sbl_shared_data->config_data_table_info = &config_data_table_info;
  
  boot_log_stop_timer("boot_config_data_table_init, Delta");
}  //该函数获取到cdt,并存放在config_data_table_info

void sbl1_hw_platform_smem(bl_shared_data_type* bl_shared_data)
{
    .......

if (eResult == DAL_SUCCESS) 
    {
      /*call the following API to store the platform id to DAL and SMEM*/
      boot_DalPlatformInfo_CDTConfigPostDDR(phPlatform, platform_id_cdb_ptr);

//调用 PlatformInfo.c 中的PlatformInfo_InitSMem保存platform info 到smem.
      boot_DAL_DeviceDetach(phPlatform);
    }
  }
  
}/* sbl1_hw_platform_smem() */

//好了

static DALResultPlatformInfo_InitSMem
(
  PlatformInfoDrvCtxt *pDrvCtxt
)
{
   //申请共享内存区:SMEM_HW_SW_BUILD_ID
  pSMem = (DalPlatformInfoSMemType *)
    smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(DalPlatformInfoSMemType));
   ...............

 //保存platform info到共享内存
  pSMem->ePlatformType = pDrvCtxt->PlatformInfo.platform;
  pSMem->nPlatformVersion = pDrvCtxt->PlatformInfo.version;
  pSMem->nPlatformSubtype = pDrvCtxt->PlatformInfo.subtype;
  pSMem->bFusion = pDrvCtxt->PlatformInfo.fusion;
   .................

return DAL_SUCCESS;

} /* END PlatformInfo_InitSMem */

花了这么多精力谈如何存platform info,得用啊?这些platform info在lk和kernel有何用呢?

lk 根据platform id及subtype id匹配正确的dts,这样后面kernel也可以利用dts里的

platform info。

注:msm8916-mtp.dts 包含如下platform id & subtype id信息。

{
model = "Qualcomm Technologies, Inc. MSM 8916 MTP xxx";
compatible = "qcom,msm8916-mtp", "qcom,msm8916", "qcom,mtp", "qcom,xxxx";
qcom,board-id = <8 0x21>;   //platform id & subtype id
};

lk请参考这些函数,后面专门研究lk,再详细描述。

platform_detect   //board.c , smem.h : enum platform_subtype

board_hardware_subtype //board.c , smem.h : enum platform_subtype

board_hardware_id   //board.c , smem.h : enum platform_subtype

dev_tree_get_entry_info  //dev_tree.c

kernel请参考setup.c

从上面CDT格式及代码分析,可以看出,如果不同项目cdt的nPlatform和nSubtype项配置成不同的值, 与dts 包含的platform id & subtype id信息进行匹配。就可以用来区分不同的项目。

即:我们在项目开发过程中,同一个分支代码要进行多项目开发时,

sbl、lk、kernel可以利用这些信息来区分不同项目,实现一套代码多项目配置目标。如下图:

图6:

总结:通过修改cdt和dts,sbl、lk、kernel阶段使用如下接口,可以将同一个branch代码中多项目区分出来!

sbl_board_subtype      // sbl高通没有,自己开发一个接口

board_hardware_subtype   // lk接口

of_board_is_xxx     // kernel 接口

3、CDB1:DDR参数的配置流程?

cdt中还有一项重要内容是CDB1: DDR参数,下面看看如何利用这些参数进行ddr初始化的。

ddr初始化涉及如下重要三函数:

boot_procedure_func_type load_qsee_pre_procs[] = 
{
  .......
  /* Copy the configure data table from eeprom */
  boot_config_data_table_init
  .......
  /* Configure ddr parameters based on eeprom CDT table data. */
  sbl1_ddr_set_params,   //  保存cdt ddr 参数到底层
  /* Initialize DDR */
  (boot_procedure_func_type)sbl1_ddr_init,    //初始化ddr
   .......

/* Last entry in the table. */
  NULL 
};

下面重点介绍这三个函数:

图7:

cdt数据 config_data_table保存到config_data_table_info.cdt_ptr

图8:

sbl1_ddr_set_params调用ddr_set_params,将ddr参数保存到ddr_device_table。

获取num_of_device保存到ddr_device_table_entry_num 。

 

图9:

sbl1_ddr_init 通过 HAL_SDRAM_Init调用到如下函数,

HAL_SDRAM_Ram_Rank_Detection,========》cs auto detect

HAL_SDRAM_Ram_Size_Detection, =========> ram size auto detect by :row、col、bank、width , manufacture_id

ddr_params_detection , ========》 two DDR chips auto detect

HAL_SDRAM_DPE_Update_AC_Paramenters  =========> update ddr timing with new DDR timing

上图说明,通过ddr_params_detection 实现一个项目自动支持多种ddr timing的方法。

好了,ddr timing就不再多说了,详细请阅读代码及参考文档:

80-NJ172-1_A_LPDDR2_CUSTOMIZATION_FOR_MSM8x26_DEVICES.pdf

三、Debug log

坑跌的高通,MSM6K/7K平台,包括旧的MSM8K平台bootloader都不支持uart。
需要自己添加uart debug log,否则只能连接jtag接口,使用Trace32调试。
哎,Trace32那价钱,咱这贫民企,都调试不起啦。
 
高通也赚了够多的,总算有良心,在MSM8916平台默认支持uart啦!
 
好了,不骂高通了,看下面代码。
 
void sbl1_main_ctl(boot_pbl_shared_data_type *pbl_shared)
{
 
 。。。。。。。。。
 //sbl入口足够早的地方就开始log初始化。再前面就没法打印log了,就当作前面的代码不出错吧。
  
  /* Initialize boot logger and start the log timer */
  sbl1_boot_logger_init(&boot_log_data,
                        pbl_shared);
 
  。。。。。。。。。
}
sbl1_boot_logger_init调用boot_log_init进行ram log , timer ,uart 初始化。
void boot_log_init(boot_log_init_data *init_data)
{
  /*we must first set meta info becasue boot_log_init_ram and
   * boot_log_init_timer will use the meta info structure*/
  boot_log_set_meta_info(init_data->meta_info_start);
  boot_log_init_ram(init_data);  //初始化ram log
  boot_init_timer(init_data);        //初始化timer ,可用于打印sbl各阶段的启动时间
  boot_log_init_uart();                //初始化uart
}
/* boot_log_init */
 
做完初始化的工作后,就可直接使用boot_log_message将log打印到ram和uart啦!
使用方法参考:
  static char error_message[BOOT_ERROR_MSG_LEN];
  //自己将打印的信息格式化到自定义的buffer:error_message
      snprintf(error_message, BOOT_ERROR_MSG_LEN, 
             "Error code %lx at %s Line %lu", err_code, filename_ptr, line);
      //打印log       
      boot_log_message(error_message);
 
参考代码:
boot_logger.c
boot_logger_uart.c
boot_logger_ram.c
boot_logger_timer.c

四、SW download

 待续:《高通 MSM8K bootloader之二: SBL1》

五、Crash ramdump

 待续:《高通 MSM8K bootloader之二: SBL1》

参考资料:

80_NA157_7_C_MSM8974_Boot_Architecture_Overview.pdf

80-NL239-1_A_MSM8916_Boot_Architecture_Overview.pdf

80-N3411-1_B_EEPROM_SW_CDT.pdf

80-NJ172-1_A_LPDDR2_CUSTOMIZATION_FOR_MSM8x26_DEVICES.pdf

高通 MSM8K bootloader之一: SBL1的更多相关文章

  1. 高通 MSM8K bootloader : SBL1 .

    一. MSM8K Boot Flow 图1: 高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974.MSM8916.MSM8994等,会有微小区别. 从上图,可以看 ...

  2. 高通 MSM8K bootloader 之四: ramdump

    前面说过高通平台,系统crash发生时,抓取crash ramdump非常重要,否则很难定位crash原因. 平台默认抓取ramdump的方法都有很强的局限性,如下: 1.PC端工具QPST提供的 M ...

  3. 高通 MSM8K bootloader 之三: LK

  4. Android图形合成和显示系统---基于高通MSM8k MDP4平台

    介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...

  5. 高通平台Bootloader启动流程【转】

    本文转载自:http://blog.csdn.net/fang_first/article/details/49615631 ====================基本知识============= ...

  6. 高通安卓调试LCD几方面总结

    来公司上班现在已经整整一个月了,蔽人不才,能力有限,学习进度缓慢,不过也是有一点点的收获与心得,在这里写出来与大家分享,养成良好的记录习惯也免得后忘记. 不啰嗦了,开入正题.来公司一个月左右的时间,主 ...

  7. 高通LCD驱动调试

    本文转载自:http://www.itgo.me/a/x6305658852004979994/lcd%20qcom 来自 :http://blog.csdn.net/dacaozuo/article ...

  8. 高通、猎户机型Android典型bootloader分析

    1.bootloader是什么? 简单地说,bootloader 就是在操作系统内核运行之前运行的一段小程序.通过这段小程序,我们可以初始化硬件设备.建立内存空间的映射图,从而将系统的软硬件环境带到一 ...

  9. 高通平台的bootloader过程【转】

    ====================基本知识=======================LK是(L)ittle (K)ernel的缩写.高通平台android普遍采用LK作为其bootloade ...

随机推荐

  1. 【php】单例模式和工厂模式

    单例模式:防止重复实例化,避免大量的new操作,减少消耗系统和内存的资源,使得有且仅有一个实例对象 header("Content-type: text/html; charset=utf- ...

  2. Perl 正则匹配经验记录

    0.正则匹配字典:http://www.cnblogs.com/itech/archive/2010/03/19/1689793.html 1.$/=">";重新定义字符串分 ...

  3. python中import与from方法总结

    一.模块&包简介 模块:所谓模块就是一个.py文件,用来存放变量,方法的文件,便于在其他python文件中导入(通过import或from). 包(package): 包是更大的组织单位,用来 ...

  4. leecode第二百三十六题(二叉树的最近公共祖先)

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  5. winform SerialPort串口通信问题

    一.串口通信简介串行接口(串口)是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件.一般完成这种功能的电路,我们称为串 ...

  6. 雷林鹏分享:CodeIgniter 数据库操作

    在平时项目开发过程中,除了处理那些繁琐的逻辑过程外,还有一个重要的任务就是对数据库的操作处理.这里总结下自己平时使用CI过程中使用的如何对数据库进行操作处理. 在CI框架中,我们一般会把对数据库的操作 ...

  7. python基础知识点(unittest)

    目录: unittest 单元测试框架 1.写用例: Testcase 2.执行:TestSuite 类 TestLoader 类 3.比对结果(期望值/实际值):断言函数 4.结果:TestText ...

  8. CMD命令:不是内部或者外部命令也不是可运行的程序或批处理文件

    [本文转自:https://blog.csdn.net/l_mloveforever/article/details/79513681] 前言:   相信有很多小伙伴都比较喜欢使用Command命令来 ...

  9. ggplot的boxplot添加显著性 | Add P-values and Significance Levels to ggplots | 方差分析

    参考:Add P-values and Significance Levels toggplots 多组比较,挑选感兴趣的显示显著性. data("ToothGrowth") he ...

  10. ionic2使用cordova打包的环境搭建

    1.安装node.js(不用说了) 2.安装JDK(java的开发基础类库) 3.安装SDK(安卓开发集成包) 4.gradle( JAVA界的Weboack ,支撑app的编译,打包的流程) 5.安 ...