分類: 嵌入式
一、 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 ) 裏到底有什麼內容?
{
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
platform/msm_shared/smem.h
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
{
/* Initialize boot logger and start the log timer */
sbl1_boot_logger_init(&boot_log_data,
pbl_shared);
{
/*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 */
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);
四、SW download
待續:《高通 MSM8K bootloader之二: SBL1》
待續:《高通 MSM8K bootloader之二: SBL1》
六、其它
七、sbl1 常用的tools介紹
sbl1常用的tools及源碼在如下目錄:
boot_images/core/storage/tools/
1、 fat32 udisk 生成工具:
boot_images/core/storage/tools/fattool ,
python fatgen.py –fat32 --name=udisk.bin --size=2048 # Generate a 2GB FAT32 container.
python fatadd.py --name=udisk.bin --from=rdcookie.txt ----add rdcookie.txt into udisk.bin ,for test
這兩個py比原來7k平臺可執行文件cpfatfs功能更強了,cpfatfs只支持fat16
2、QPST下載工具(shahara):emmc programmer
:/boot_images/core/storage/tools/emmcbld/MPRG8974.mbn
3、 T32 Jtag下載工具
boot_images/core/storage/tools/jsdcc/mjsdload.cmm 與jsdcc.elf
4、分區相關工具
boot_images/core/storage/tools/ptool/
ptool.py //分區生成工具 partition =========> rawprogram0.xml
Python ptool.py –x partition.xml:
msp.py //ubuntu使用:根據 rawprogram0.xml進行升級軟件工具
singleimage.py //根據singleimage_partition_8974.xml生成single boot image: 8974_msimage.mbn
python singleimage.py -x singleimage_partition_8974.xml
lsusb.py // ls usb
dd.py // dd command
checksparse.py //sparse system/cache/userdata image
參考資料:
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
http://blog.csdn.net/fybon/article/details/18185441
上篇將我重點關注SBL1的內容1和2基本說明完,本篇繼續內容3和4。
1、 CDT : Platform ID和DDR參數
2、 debug log :
3、 download : msm8K 新平臺軟件download支持兩種協議,sahara和firehose
4、 ramdump :死機異常信息dump