一、 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  转自:http://www.cnblogs.com/liang123/p/6325257.html            http://blog.csdn.net/F ...

  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. ACM FatMouse' Trade

    FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containi ...

  2. Python3 错误和异常

    Python有两种错误很容易辨认:语法错误和异常. 语法错误 Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例 >>> while True print('He ...

  3. 《读书报告 -- Elasticsearch入门 》-- 安装以及简单使用(1)

    <读书报告 – Elasticsearch入门 > 第一章 Elasticsearch入门 Elasticsearch是一个实时的分布式搜索和分析引擎,使得人们可以在一定规模上和一定速度上 ...

  4. 使用Spring Boot开发Web项目

    前面两篇博客中我们简单介绍了Spring Boot项目的创建.并且也带小伙伴们来DIY了一个Spring Boot自动配置功能,那么这些东西说到底最终还是要回归到Web上才能体现出它的更大的价值,so ...

  5. android M Launcher之数据库实现

    前面一系列文章我们分析了LauncherModel的工作过程,它会把数据绑定到桌面上.从今天开始我们来分析下Launcher的数据来源即Launcher数据库的实现. 一个完整的数据库实现都应该包括两 ...

  6. Servlet常用操作(基础)

    ----------------------------------------------------------------------------------------------[版权申明: ...

  7. iOS开发基础之开发证书的说明和发布

    1.首先通过钥匙串访问--证书助理--从证书颁发机构请求证书--填写证书信息(邮箱,常用名称,存储到磁盘)--存储为(自定义名称.certSigningReuqest,简称CSR文件,只是为了提交到苹 ...

  8. 剑指Offer——京东实习笔试题汇总

    剑指Offer--京东实习笔试题汇总 编程题1 题目的详细信息已经记不住,只能大致描述一下,就是求最有价值的的委托信息. n.s.B.S其中n代表委托信息,s要求的最有价值的委托信息的个数,B代表买入 ...

  9. Linux Java开发坏境搭建,Ubuntu-jdk+tomcat+eclipse+svn 包安装详细操作

    更新时间2015-03-15 更新2015-04-12 svn安装更新 第一步 安装jdk (在linux上使用yum安装JDK  http://blog.chinaunix.net/uid-1546 ...

  10. lucene内存索引库、分词器

    内存索引库 特点 在内存中开辟一块空间,专门为索引库存放.这样有以下几个特征: 1)    因为索引库在内存中,所以访问速度更快. 2)    在程序退出时,索引库中的文件也相应的消失了. 3)    ...