上面说了这么多,这里就添加一个CDT的使用实例和简单的代码解析。
首先生成cdt_configure.xml配置文件,然后执行如下命令:
python cdt_generator.py cdt_configure.xml CDT.bin;
就可以生成对应的CDT.bin文件。同时也会生成, 我们会利用hardware major/minor version number来定义同平台的不同SKU.
同样,对应我们可以定义sku的dtsi中的board id。 bootloader透过的CDT中的board id进行对应device tree的选择。
对应,同平台的多SKU的情况,利用CDT进行ID的定义,大概就是这样一个情况。
bootloaer中对cdt的解析代码,先参考如下的高通的说明,知道具体是使用什么接口进行CDT的解析的;
对应目录搜索涉及到的文件:
核心代码如下:
/*===========================================================================
** Function : get_config_data_block
** ==========================================================================
*/
/*!
*
* @brief
* given a pointer to the start of cdt and an configuration data block index,
* return a pointer to beginning of that configuration data block.
* //此时CDT是刷在ufs/emmc中。其实如果有好的方案,我们建议把CDT.bin备份到eeprom中,那样即使使用高通的刷机软件/或者手动 full reset ,CDT.bin依然保留;某种层度上可以避免机器便转。
* @param[in] uint8* pointer to the start of cdt table //怎么理解这里的指针呢?emmc文件系统中的地址?
* @param[in] uint32 Index of the configuration data block.
*
* @param[out] uint32* length of the configuration data block
*
* @return pointer to the beginning of request cdb.
* Null if error or cdb doesn't exist
*
* @par Dependencies
* None
*
* @retval
* None
*
* @par Side Effects
* None
*/
bl_error_boot_type boot_get_config_data_block(const uint8 *raw_cdt, uint32 index, uint32 *length, uint8** cdb_data_ptr)
{
struct cdb_meta *cdb_meta_ptr;
uint8 *cdb_ptr;
bl_error_boot_type return_status = BL_ERR_NONE;
*length = 0;
do{
if(raw_cdt != NULL)
{
cdb_meta_ptr = (struct cdb_meta*)((uintnt)raw_cdt + sizeof(struct cdt_header));
//直接跳过header部分;
/* Integer overflow check */
if(((uintnt)raw_cdt > ((uintnt)raw_cdt + (uintnt)cdb_meta_ptr->offset)))
{
return_status = BL_ERR_INTEGER_OVERFLOW;
break;
}
cdb_ptr = (uint8*)((uintnt)raw_cdt + (uintnt)cdb_meta_ptr->offset);
/*get the meta data of request block*/
cdb_meta_ptr += index;
if(
/*first check if cdt has valid magic number*/
(((struct cdt_header*)raw_cdt)->magic == CONFIG_DATA_MAGIC) &&
/*then check if meta data pointer of requested block is in valid range*/
((uintnt)cdb_meta_ptr < (uintnt)cdb_ptr) &&
(((uintnt)raw_cdt + (uintnt)cdb_meta_ptr->offset) >= (uintnt)cdb_ptr) &&
((uintnt)cdb_meta_ptr->offset < CONFIG_DATA_TABLE_MAX_SIZE) &&
/*at last check if requested block has valid size*/
(cdb_meta_ptr->size > 0) &&
(((uintnt)cdb_meta_ptr->offset + (uintnt)cdb_meta_ptr->size) > (uintnt)cdb_meta_ptr->offset) &&
(((uintnt)cdb_meta_ptr->offset + (uintnt)cdb_meta_ptr->size) < CONFIG_DATA_TABLE_MAX_SIZE)
)
{
*length = cdb_meta_ptr->size;
*cdb_data_ptr = (uint8*) (uintnt)((uintnt)raw_cdt + (uintnt)cdb_meta_ptr->offset);
}
}
if(*cdb_data_ptr == NULL)
{
return_status = BL_ERR_GET_CDT_FAIL;
break;
}
}while(FALSE);
return return_status;
}
看下参数:@param[in] uint8* pointer to the start of cdt table //溯源地址来源:
//* @param[in] uint8* pointer to the destination CDT
boot_copy_config_data_block(
uint8 *dst_cdt,
uint32 cdb_index,
const uint8 *src_cdb_data,
uint32 src_cdb_size
);
这个boot_copy_config_data_blcok(..);的调用点,在源码里面尽然没有找到,后面提个case问问高通。