高通 MSM8K bootloader : SBL1 .

时间:2022-12-27 13:15:03

一、 MSM8K Boot Flow


高通 MSM8K bootloader : SBL1 .

                              图1:

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

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

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

高通 MSM8K bootloader : SBL1 .

                                   图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我比较关注的点调用流程总结成如下图,后面再针对关注点展开,逐个分析。

高通 MSM8K bootloader : SBL1 .

                           图3:

二、CDT:Platform ID和DDR参数

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

   参考下图,可知CDT包含CDB0: platform info信息和CDB1: DDR配置参数。

高通 MSM8K bootloader : SBL1 .
                图4:

   platform info 包含平台id,主板的版本号,项目号等信息
高通 MSM8K bootloader : SBL1 .
          图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可以利用这些信息来区分不同项目,实现一套代码多项目配置目标。如下图:

高通 MSM8K bootloader : SBL1 .

图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 
};

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

高通 MSM8K bootloader : SBL1 .

图7:

cdt数据 config_data_table保存到config_data_table_info.cdt_ptr

高通 MSM8K bootloader : SBL1 .

图8:

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

获取num_of_device保存到ddr_device_table_entry_num 。


高通 MSM8K bootloader : SBL1 .

图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. 《Genesis-3D开源游戏引擎-官方录制系列视频教程:进阶实例篇》

    注:本系列教程仅针对引擎编辑器:v1.2.2及以下版本 G3D进阶实例   第四课<2D编辑与脚本的统一入口> 使用G3D完成一个简单的类飞机大战游戏,介绍了G3D2d游戏制作的流程包括: ...

  2. 关于python文件操作 (转载)

    总是记不住API.昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Pyth ...

  3. Apache&colon;To Config The Vhost of Django Project

    It is not a good idea to use dev server in Production Environment. Apache or Nginx are good choice.B ...

  4. Linux网络配置命令ifconfig输出信息解析

    eth0      Link encap:Ethernet  HWaddr 00:1e:4f:e9:c2:84 inet addr:128.224.163.153  Bcast:128.224.163 ...

  5. C&num;编程规范

    C#编程规范 Version 1.0   目录 第一章 概述.... 4 规范制定原则.... 4 术语定义.... 4 Pascal 大小写.... 4 Camel 大小写.... 4 文件命名组织 ...

  6. 转&colon;在控制台中调试AngularJS应用

    在控制台中调试AngularJS应用 在创建AngularJS应用时,一个很棘手的问题是如何在Chrome,Firefox,以及IE的JavaScript控制台中访问深藏在应用中的数据和服务.本文将会 ...

  7. Linux 链接详解&lpar;2&rpar;

    可执行文件加载执行过程: 上一节我们说到ELF文件格式,静态库的符号解析和重定位的内容.这一节我们来分析一下可执行文件. 由上一节我们知道可执行文件也是ELF文件,当程序被加载器加载到内存时是按照EL ...

  8. JavaScript设计模式 Item 6 --单例模式Singleton

    单例模式的定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如线程池.全局缓存.浏览器的window对象.在js开发中,单例模式的 ...

  9. Windows上安装配置SSH教程(7)——几种方式对比

    服务端:Windows XP 客户端:Windows 10 由于Cygwin也可以安装OpenSSH,所以客户端其实可以直接使用Cygwin安装OpenSSH,那么在Windows下使用SCP(安全拷 ...

  10. V8引擎的垃圾回收策略

    V8 的垃圾回收策略主要基于分代式垃圾回收机制.所谓分代式,就是将内存空间分为新生代和老生代两种,然后采用不同的回收算法进行回收. 新生代空间 新生代空间中的对象为存活时间较短的对象,大多数的对象被分 ...