手机出现Error Fatal Hold # key to enter product keydload mode代表什

db:: 4.70::sshd error 7x
Widget settings form goes here列表网公众号列表活动随时有扫我活动不错过
热门城市:
黑莓手机维修
微信扫一扫
快速获取电话
oppo忘记手机解锁图案怎么办 支持R11 R15系列oppo忘记手机解锁图案怎么办 支持R11 R15系列oppo忘记手机解锁图案怎么办 支持R11 R15系列新款手机OPPOR11或者R15系列,很多人在忘记手机解锁图案后,会想到自己双清,利用音量下和电源键,进入color模式里,想清除手机锁屏密码,结果现在根本无法实现了。因为新款手机采用了特殊的加密方式,必须使用解锁工具解锁。
OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15忘记解锁密码了不用担心,有专用解锁工具可以解锁安全可靠快捷您只需要一台电脑,一根数据线,足不出户在家里就可以完成解锁OPPOR15解锁流程:1:手机解锁必须要电脑,数据线,没有电脑的朋友可以去网吧!2没有电脑,在手机上可以解锁吗?答案是肯定的,手机上是不能完成解锁的,因为新款的已经不支持双清了;3没有开USB调试也是可以解锁的,大可不必担心没有开USB调试的问题4解锁注意事项:手机电量要充足,5技术支持QQ、微信:
一加手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
iphone手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
其他手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
三星手机维修
微信扫一扫
快速获取电话
iphone手机维修
微信扫一扫
快速获取电话
iphone手机维修
微信扫一扫
快速获取电话
LG手机维修
微信扫一扫
快速获取电话
HTC手机维修
微信扫一扫
快速获取电话
诺基亚手机维修
微信扫一扫
快速获取电话
HTC手机维修
微信扫一扫
快速获取电话
乐视手机维修
微信扫一扫
快速获取电话
夏普手机维修
微信扫一扫
快速获取电话
LG手机维修
微信扫一扫
快速获取电话
vivo手机维修
微信扫一扫
快速获取电话
夏普手机维修
微信扫一扫
快速获取电话
金立手机维修
微信扫一扫
快速获取电话
诺基亚手机维修
微信扫一扫
快速获取电话
黑莓手机维修
微信扫一扫
快速获取电话
诺基亚手机维修
微信扫一扫
快速获取电话
小米手机维修
微信扫一扫
快速获取电话
多普达手机维修
微信扫一扫
快速获取电话
vivo手机维修
微信扫一扫
快速获取电话
多普达手机维修
微信扫一扫
快速获取电话
vivo手机维修
微信扫一扫
快速获取电话
锤子手机维修
微信扫一扫
快速获取电话
一加手机维修
微信扫一扫
快速获取电话
天语手机维修
微信扫一扫
快速获取电话
夏普手机维修
微信扫一扫
快速获取电话
锤子手机维修
微信扫一扫
快速获取电话
联想手机维修
微信扫一扫
快速获取电话
小米手机维修
微信扫一扫
快速获取电话
锤子手机维修
微信扫一扫
快速获取电话
联想手机维修
微信扫一扫
快速获取电话
多普达手机维修
微信扫一扫
快速获取电话
夏普手机维修
微信扫一扫
快速获取电话
乐视手机维修
微信扫一扫
快速获取电话
锤子手机维修
微信扫一扫
快速获取电话
oppo忘记手机解锁图案怎么办 支持R11 R15系列oppo忘记手机解锁图案怎么办 支持R11 R15系列oppo忘记手机解锁图案怎么办 支持R11 R15系列新款手机OPPOR11或者R15系列,很多人在忘记手机解锁图案后,会想到自己双清,利用音量下和电源键,进入color模式里,想清除手机锁屏密码,结果现在根本无法实现了。因为新款手机采用了特殊的加密方式,必须使用解锁工具解锁。
OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15解锁密码忘记怎么解锁OPPOR15解锁密码忘记解锁教程OPPOR15忘记解锁密码了不用担心,有专用解锁工具可以解锁安全可靠快捷您只需要一台电脑,一根数据线,足不出户在家里就可以完成解锁OPPOR15解锁流程:1:手机解锁必须要电脑,数据线,没有电脑的朋友可以去网吧!2没有电脑,在手机上可以解锁吗?答案是肯定的,手机上是不能完成解锁的,因为新款的已经不支持双清了;3没有开USB调试也是可以解锁的,大可不必担心没有开USB调试的问题4解锁注意事项:手机电量要充足,5技术支持QQ、微信:
综合评价:
塘沽htc手机修理友情提示
塘沽htc手机修理相关推荐
塘沽htc手机修理相关分类
&2017 列表网&琼ICP备号-12&增值电信业务经营许可证B2-& 违法信息举报电话 400-
还没关注列表网?一大波金豆等你拿!当前位置: &
求翻译:Data Abort Hold # Key toenter dload mode是什么意思?
Data Abort Hold # Key toenter dload mode
问题补充:
数据中止按住#键toenter DLOAD模式
dload Data Abort Hold # Key toenter mode
Data Abort Hold # Key toenter dload mode
Data Abort Hold # Key toenter dload mode
Data Abort Hold # Key toenter dload mode
我来回答:
参考资料:
* 验证码:
登录后回答可以获得积分奖励,并可以查看和管理所有的回答。 |
我要翻译和提问
请输入您需要翻译的文本!db:: 3.42::No route to host / failed sending message to null j3
Widget settings form goes here下次自动登录
现在的位置:
& 综合 & 正文
高通 MSM8K bootloader 之二: SBL1
续:高通 MSM8K bootloader 之一: SBL1
上篇将我重点关注SBL1的内容1和2基本说明完,本篇继续内容3和4。
CDT : Platform ID和DDR参数
2、 debug log :
3、 download : msm8K 新平台软件download支持两种协议,sahara和firehose
4、 ramdump :死机异常信息dump
四、SW download
1、软件升级模式
  高通8K以后平台支持如下两种,说到下载模式,忍不住又得骂高通。 
  以前6K, 7K平台不支持紧急下载模式,工厂生产软件要down到手机里,非常复杂。
  要嘛先用烧录器烧一段sbl image,然后剩下的image自己开发升级软件用usb多路升级。
  要嘛全部image用烧录器一次性烧完。
  坑人的高通啊!么得办法,就害苦咱苦命的民工。 好了,介绍一下现在支持的两种下载模式吧! 
  紧急下载模式:pbl负责与PC交互,实现软件下载
  自动进入紧急下载模式:主板刚生产emmc是裸片时,或者sbl运行异常时,系统自动进入紧急下载模式。
            这种情况就不多说了,主要是用于工厂生产,及sbl异常处理。
  手动进入紧急下载模式:通过硬件一个gpio下拉,pbl检测到该gpio后强制进入紧急下载模式。这种主要
             以防不测情况。
   另外一种就是软件通过设置magic number,然后由热重启,pbl检测到magic number后,强制进入下载模式。
  软件切换接口,参考如下boot_dload.c代码:
/*=============================================================================
Function :
boot_dload_transition_pbl_forced_dload
** ==========================================================================
This function sets the magic numbers for PBL to detect and enter forced
download mode.
It then calls the target specific function to trigger a
system reset.
* @par Dependencies
* @par Side Effects
Set's PBL magic numbers to enter forced download, resets target, never to
void &strong&boot_dload_transition_pbl_forced_dload&/strong&( void )
/* PBL uses the last four bits of BOOT_MISC_DETECT to trigger forced download.
Preserve the other bits of the register. */
uint32 register_value =
HWIO_TCSR_BOOT_MISC_DETECT_INM(HWIO_TCSR_BOOT_MISC_DETECT_RMSK);
/* Clear the PBL masked area and then apply HS_USB value */
register_value &= ~(FORCE_DLOAD_MASK);
register_value |= FORCE_DLOAD_HS_USB_MAGIC_NUM;
/* Write the new value back out to the register */
HWIO_TCSR_BOOT_MISC_DETECT_OUTM(FORCE_DLOAD_MASK,
register_value);
boot_hw_reset(BOOT_WARM_RESET_TYPE);
} /* boot_dload_transition_pbl_forced_dload() */
 普通下载模式:sbl负责与PC交互,实现软件下载
 手机第一次下载完软件以后,普通情况下,可不进入pbl紧急下载模式,可由sbl进行软件升级。
 sbl是如何进入普通下载模式的呢?看如下函数boot_dload_check()。
 boot_dload_check()检测到USB D+ 接地、或者sbl发生异常时调用boot_dload_set_cookie()设置了cookie,进自  动进入普通的下载模式。
&pre name="code" class="cpp"&
/*===========================================================================
Function :
boot_dload_check
** ==========================================================================
This function will check to see if the downloader should be entered
for QPST download, and enter the downloader if directed to.
* @param[in] bl_shared_data Pointer to the shared data
* @par Dependencies
Download ID must be present in IRAM if downloader is to be entered.
* @par Side Effects
Boot may be halted and QPST downloader entered.
void boot_dload_check
bl_shared_data_type *bl_shared_data
/* Check whether USB D+ line is grounded. If it is, then enter
PBL Download mode */
if(boot_qhsusb_al_check_for_pbl_dload(0))
boot_dload_transition_pbl_forced_dload();
/* Determine if the downloader should be entered at this time,
instead of continuing with the normal boot process. */
if ( boot_dload_entry( ) == TRUE )
/* Check the UEFI ram dump cookie, we enter download mode
only if UEFI ram dump cookie is NOT set*/
if ( !( boot_shared_imem_cookie_ptr != NULL &&
boot_shared_imem_cookie_ptr-&uefi_ram_dump_magic ==
UEFI_CRASH_DUMP_MAGIC_NUM ) )
/* Before entering downloader clear RESET_DEBUG[BLOCK_RESIN] so
the next resin_n is not blocked.
This is part of the abnormal
reset logic in Bear family */
HWIO_GCC_RESET_DEBUG_OUTM(HWIO_GCC_RESET_DEBUG_BLOCK_RESIN_BMSK,
/* Enter downloader for QPST */
sbl_dload_entry();
} /* boot_dload_check() */
/*===========================================================================
Function :
boot_dload_set_cookie
** ==========================================================================
Set the SBL dload mode cookie
* @par Dependencies
void boot_dload_set_cookie()
HWIO_TCSR_BOOT_MISC_DETECT_OUTM(SBL_DLOAD_MODE_BIT_MASK,
SBL_DLOAD_MODE_BIT_MASK);
再看看下面的代码!!! 我们又有新的发现!
sbl1_target.c
&pre name="code" class="cpp"&/*===========================================================================
Function :
sbl_dload_entry
** ==========================================================================
This function pointer is defined in each SBL* Bootloader to handle SBL-specific
requirements to enter a download routine. It is initialized to
boot_dload_transition_pbl_forced_dload by default.
* @par Dependencies
* @par Side Effects
void (*sbl_dload_entry)(void) = boot_dload_transition_pbl_forced_
函数指针sbl_dload_entry默认指向紧急下载模式的入口:boot_dload_transition_pbl_forced_dload ,
该下载方式会切换到pbl,由pbl通过firehose协议实现download。
void sbl1_dload_entry ()
static uint32 dload_entry_count = 0;
dload_entry_count++;
/* Only execute the pre-dload procedures the first time we try to enter
* dload in case there is an error within these procedures. */
if( dload_entry_count == 1 && &bl_shared_data != NULL )
/* Entering dload routine for the first time */
&strong&boot_do_procedures&/strong&( &bl_shared_data, sbl1_pre_dload_procs );
pm_device_config_in_dloadmode();
/* Enter boot Sahara */
&strong&boot_dload_transition_enter_sahara&/strong&();
}/* sbl1_dload_entry() */
而sbl1定义了另一个下载模式的入口:sbl1_dload_entry,它支持直接在sbl1中通过sahara协议download,
还支持crash ram dump 功能。包括dump to raw partition ,and dump to sdcard 。
见:boot_do_procedures( &bl_shared_data, sbl1_pre_dload_procs ); 
crash ramdump章节再详细看看。
&pre name="code" class="cpp"&/*DLOAD flag for SBL1 to enter PBL error handler*/
#ifdef BOOT_ENTER_PBL_DLOAD_ON_SBL_ERROR
static boot_boolean edload_flag = TRUE;
static boot_boolean edload_flag = FALSE;
&/pre&&pre name="code" class="cpp"&void sbl1_post_ddr_init(bl_shared_data_type *bl_shared_data)
..........
if (edload_flag != TRUE)
/* Update the dload entry to sbl1 sahara dload entry function */
sbl_dload_entry = sbl1_dload_
好,既然在sbl1有两个download入口,如何选则呢?
sbl1_mc.c 中通过宏BOOT_ENTER_PBL_DLOAD_ON_SBL_ERROR控制。
如果定义该宏,则dload处理会转交给PBL帮忙处理了。
2、进入升级模式的方法
  上节描述的高通默认进入下载模式的方法,都是自动的,显然无法满足开发、生产、售后等需求。
  因此如下两种方法,实用于开发、生产、售后。
  sbl1扫描按键组合:
  关机状态下,sbl1扫描按键组合,比如,扫描到power & vol+ 两个按键同时按下,则进入pbl紧急下模模式。
  当然,有些结构设计可能导致power & vol+ 两个按键开机容易误触,则可以采用别的硬件组合方式。比如,
  vol+ & usb 等等!
  关机状态,进入下载模式,没有ram dump的需求,因此当扫描到相应的硬件组合,
  直接调用:boot_dload_transition_pbl_forced_dload
  adb reboot + edl / dload :
手机正常开机,能连接usb上的状态下,可以使用 adb reboot edl 或者 adb reboot dload 命令,
  使手机进入pbl紧急下载模式,或者进入sbl1普通下载模式。 
  MSM8916平台参考如下代码,
  kernel/drivers/power/reset/msm-poweroff.c ,相关代码由宏CONFIG_MSM_DLOAD_MODE控制。
static int msm_restart_probe(struct platform_device *pdev)
struct device *dev = &pdev-&
struct resource *
struct device_node *
int ret = 0;
#ifdef CONFIG_MSM_DLOAD_MODE
if (scm_is_call_available(SCM_SVC_BOOT, SCM_DLOAD_CMD) & 0)
scm_dload_supported =
atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
np = of_find_compatible_node(NULL, NULL, DL_MODE_PROP);
if (!np) {
pr_err("unable to find DT imem DLOAD mode node\n");
dload_mode_addr = of_iomap(np, 0);
if (!dload_mode_addr)
pr_err("unable to map imem DLOAD offset\n");
np = of_find_compatible_node(NULL, NULL, EDL_MODE_PROP);
if (!np) {
pr_err("unable to find DT imem EDLOAD mode node\n");
emergency_dload_mode_addr = of_iomap(np, 0);
if (!emergency_dload_mode_addr)
pr_err("unable to map imem EDLOAD mode offset\n");
set_dload_mode(download_mode);
np = of_find_compatible_node(NULL, NULL,
"qcom,msm-imem-restart_reason");
if (!np) {
pr_err("unable to find DT imem restart reason node\n");
restart_reason = of_iomap(np, 0);
if (!restart_reason) {
pr_err("unable to map imem restart reason offset\n");
ret = -ENOMEM;
goto err_restart_
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
msm_ps_hold = devm_ioremap_resource(dev, mem);
if (IS_ERR(msm_ps_hold))
return PTR_ERR(msm_ps_hold);
pm_power_off = do_msm_
arm_pm_restart = do_msm_
if (scm_is_call_available(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER) & 0)
scm_pmic_arbiter_disable_supported =
err_restart_reason:
#ifdef CONFIG_MSM_DLOAD_MODE
iounmap(emergency_dload_mode_addr);
iounmap(dload_mode_addr);
msm_restart_probe函数在执行过程中打印出如下log,说明dts中没有设置emergency_dload_mode_addr,及dload_mode_addr的地址。
6.627538] unable to find DT imem DLOAD mode node
6.628075] unable to find DT imem EDLOAD mode node
但添加scm_dload_supported的打印信息,可以看到如下log,
scm_dload_supported=1 ,
说明,scm dload是支持的。因此,接下来的两个函数,都是通过scm dload实现download模式切换。
static void enable_emergency_dload_mode(void)
if (emergency_dload_mode_addr) {
__raw_writel(EMERGENCY_DLOAD_MAGIC1,
emergency_dload_mode_addr);
__raw_writel(EMERGENCY_DLOAD_MAGIC2,
emergency_dload_mode_addr +
sizeof(unsigned int));
__raw_writel(EMERGENCY_DLOAD_MAGIC3,
emergency_dload_mode_addr +
(2 * sizeof(unsigned int)));
/* Need disable the pmic wdt, then the emergency dload mode
* will not auto reset. */
qpnp_pon_wd_config(0);
if (scm_dload_supported) {
ret = scm_call_atomic2(SCM_SVC_BOOT,
SCM_DLOAD_CMD, SCM_EDLOAD_MODE, 0);
pr_err("Failed to set EDLOAD mode: %d\n", ret);
使能紧急下载模式。
static void set_dload_mode(int on)
if (dload_mode_addr) {
__raw_writel(on ? 0xE47B337D : 0, dload_mode_addr);
__raw_writel(on ? 0xCE14091A : 0,
dload_mode_addr + sizeof(unsigned int));
if (scm_dload_supported) {
ret = scm_call_atomic2(SCM_SVC_BOOT,
SCM_DLOAD_CMD, on ? SCM_DLOAD_MODE : 0, 0);
pr_err("Failed to set DLOAD mode: %d\n", ret);
dload_mode_enabled =
使能普通下载模式。
这样adb reboot edl 或者 adb reboot dload 命令就可以使手机进入下载模式了。
3、软件升级工具及协议
高通平台,从MSM6K 、7K 到8K, download的方法和协议,一直在更新。
协议经历了从stream dload到sahara,再到现在firehose 。
每一种协议的具体描述参考如下文档:
80-V5348-1_J_Streaming_DLoad_Protocol.pdf
80-N1008-1_H_SaharaProtocolSpecification.pdf
80-NG319-1_A_Firehose Protocol V1.0_Def_Doc.pdf
参见本人的另一篇介绍《》。
根据使用不同协议,相应的,高通提供两个下载工具:eMMC Software Download
和 QFIL (Qualcomm Flash Image Loader )
如下俩图 :
通过这种普通下载模式,进入下载模后,windows设备管理器可以看到PC端枚举出一个9006的USB端口,
同时枚举出一个mass storage。
高通这种mass storage模式下载速率是非常的快。可是我也它有如下一些缺点:
pc端枚举mass storage速度很慢,根据测试也非常耗cpu。
pc端枚举mass storage容易出错,特别是多台手机同时枚举时。
纠错不易,按文件方式写入,目前我还没想到什么方法进行纠错?
好,下面贴相关代码所在的路径,及调用到的重要函数贴出来!
boot_images/core/storage/tools/emmcbld
boot_images/core/boot/secboot3/hw/msm8916/sbl1/
sbl1_target.c
sbl1_sahara.c
boot_images/core/boot/secboot3/src/
boot_sahara.c
boot_extern_hsusb_interface.c
boot_images/core/wiredconnectivity/qhsusb/src/al/qhsusb_al_bulk.c
boot_images/core/wiredconnectivity/qhsusb/src/func/
qhsusb_fd_hdlc.c
qhsusb_fd_ms.c
qhsusb_scsi.c
void sbl1_dload_entry ()
static uint32 dload_entry_count = 0;
dload_entry_count++;
/* Only execute the pre-dload procedures the first time we try to enter
* dload in case there is an error within these procedures. */
if( dload_entry_count == 1 && &bl_shared_data != NULL )
/* Entering dload routine for the first time */
boot_do_procedures( &bl_shared_data, sbl1_pre_dload_procs );
pm_device_config_in_dloadmode();
/* Enter boot Sahara */
boot_dload_transition_enter_sahara();
}/* sbl1_dload_entry() */
/*===========================================================================
Function :
boot_dload_transition_enter_sahara
** ==========================================================================
This function is implemented in each SBL to enter sahara dload mode
* @par Dependencies
* @par Side Effects
void boot_dload_transition_enter_sahara(void)
/* Get Sahara interface */
struct boot_sahara_interface* sbl_sahara_interface = sbl_sahara_get_interface();
BL_VERIFY(sbl_sahara_interface != NULL, BL_ERR_NULL_PTR);
/* Set Sahara mode to memory debug */
sbl_sahara_interface-&sahara_mode = SAHARA_MODE_MEMORY_DEBUG;
/* Flush the cache before calling into sahara so that all data is flushed to memory */
mmu_flush_cache();
/* Enter Sahara */
boot_sahara_entry(sbl_sahara_interface);
调用sbl_sahara_get_interface获取sahara如下函数接口:sbl_sahara_interface
调用boot_sahara_entry。
/* SBL Sahara dispatch table */
static struct boot_sahara_dispatch_tbl sbl_sahara_dispatch_tbl =
SAHARA_INTERFACE_DISPATCH_VERSION,
sbl_sahara_bulk_init,
boot_qhsusb_al_bulk_shutdown,
boot_qhsusb_al_bulk_poll,
(sahara_rx_bulk_type) sbl_sahara_rx_bulk,
(sahara_tx_bulk_type) boot_qhsusb_al_bulk_transmit,
boot_qhsusb_al_bulk_get_max_packet_size,
sbl_sahara_reset,
boot_clobber_check_global_whitelist_range,
sbl_sahara_exec_cmd,
boot_qhsusb_al_bulk_get_max_raw_data_size,
sbl_sahara_is_auth_enabled,
sbl_sahara_get_bin_header_size,
sbl_sahara_get_bin_image_id,
sbl_sahara_get_bin_image_dest,
sbl_sahara_get_bin_image_size,
sbl_sahara_get_bin_code_size,
sbl_sahara_get_bin_cert_chain_size,
sbl_sahara_get_bin_signature_size,
sbl_sahara_get_bin_image_src,
sbl_sahara_unrecoverable_error_handler,
sbl_sahara_image_load_post_proc,
sbl_sahara_skip_image_load,
boot_get_hash_segment_buffer,
sbl_elf_optimized_segment_load,
/* ============================================================================
Function : boot_sahara_entry
** ============================================================================
This function provides an entry into the Sahara protocol and jumps into
the protocol.
This function initializes the Sahara protocol followed by sending a HELLO
packet to the host. After that, the target will proceed to wait for
incoming packets and handle them appropriately.
@param sahara_interface
[IN/OUT] Interface to be used by protocol
@par Dependencies
@par Side Effects
boot_sahara_init() will be called which calls the dispatch table's init()
routine - this is intended to initialize any hardware that is required
for the protocol to execute.
boolean boot_sahara_entry
struct boot_sahara_interface* sahara_interface
boolean status = TRUE;
sahara_if = sahara_
// Validate interface and initialize Sahara protocol if not previously executed
status = boot_sahara_init();
if (status)
// Send hello packet
boot_sahara_handle_hello();
// Enter Sahara packet handler
boot_sahara_process_packets();
// Reset authentication information
sahara_auth_tbl = NULL;
sahara_auth_elf = FALSE;
sahara_auth_bin = FALSE;
调用函数boot_sahara_init初始化sahara协议,枚举usb com口及mass storage。
调用函数boot_sahara_handle_hello主动发送hello packet,
调用函数boot_sahara_process_packets处理其它cmd packets。
/* ============================================================================
Function : boot_sahara_init
** ============================================================================
This function initializes the state for the Sahara protocol
This function performs basic initialization in order to transfer an image.
Based on the image type, the current image in shared data will be updated.
This function also initializes the internal state machine and hardware
@par Dependencies
@par Side Effects
TRUE if initializ FALSE otherwise
static boolean boot_sahara_init ( void )
boolean status = TRUE;
// Check parameters
if (sahara_if == NULL)
status = FALSE;
if ((sahara_if-&sahara_shared_data == NULL) ||
(sahara_if-&dispatch_tbl == NULL))
status = FALSE;
sahara_shared_data = sahara_if-&sahara_shared_
sahara_dispatch_tbl = sahara_if-&dispatch_
if (sahara_if-&sahara_shared_data-&cur_image == NULL)
status = FALSE;
// Verify dispatch table
if ((sahara_dispatch_tbl-&init == NULL) ||
(sahara_dispatch_tbl-&shutdown == NULL) ||
(sahara_dispatch_tbl-&poll == NULL) ||
(sahara_dispatch_tbl-&rx_bulk == NULL) ||
(sahara_dispatch_tbl-&tx_bulk == NULL) ||
(sahara_dispatch_tbl-&shutdown == NULL) ||
(sahara_dispatch_tbl-&get_max_packet_size == NULL) ||
(sahara_dispatch_tbl-&reset == NULL) ||
(sahara_dispatch_tbl-&valid_address_range == NULL) ||
(sahara_dispatch_tbl-&exec_cmd == NULL) ||
(sahara_dispatch_tbl-&get_max_raw_data_size == NULL) ||
(sahara_dispatch_tbl-&auth_enabled == NULL) ||
(sahara_dispatch_tbl-&memcpy == NULL) ||
(sahara_dispatch_tbl-&memset == NULL) ||
(sahara_dispatch_tbl-&get_bin_header_size == NULL) ||
(sahara_dispatch_tbl-&get_bin_image_id == NULL) ||
(sahara_dispatch_tbl-&get_bin_image_dest == NULL) ||
(sahara_dispatch_tbl-&get_bin_image_size == NULL) ||
(sahara_dispatch_tbl-&get_bin_code_size == NULL) ||
(sahara_dispatch_tbl-&get_bin_cert_chain_size == NULL) ||
(sahara_dispatch_tbl-&get_bin_signature_size == NULL) ||
(sahara_dispatch_tbl-&get_hash_segment_buffer == NULL))
status = FALSE;
// Determine if image should be authenticated
sahara_shared_data-&is_secure = sahara_dispatch_tbl-&auth_enabled();
sahara_auth_tbl = sahara_if-&auth_
if (((sahara_auth_tbl == NULL) ||
(sahara_auth_tbl-&authenticate == NULL)) &&
(sahara_if-&sahara_mode != SAHARA_MODE_MEMORY_DEBUG))
status = FALSE;
else if (sahara_shared_data-&is_secure &&
(sahara_shared_data-&expected_image_type == SAHARA_IMAGE_TYPE_ELF))
sahara_auth_elf = TRUE;
else if (sahara_shared_data-&is_secure &&
(sahara_shared_data-&expected_image_type == SAHARA_IMAGE_TYPE_BINARY))
sahara_auth_bin = TRUE;
sahara_mem_debug_tbl = sahara_if-&mem_debug_
if (sahara_mem_debug_tbl == NULL)
sahara_mem_debug_enabled = FALSE;
if ((sahara_mem_debug_tbl-&mem_debug_supported == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_init == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_verify_addr == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_table_addr == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_table_len == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_is_restricted_addr == NULL) ||
(sahara_mem_debug_tbl-&mem_debug_copy_restricted == NULL))
status = FALSE;
sahara_mem_debug_enabled = TRUE;
if (sahara_shared_data-&expected_image_type == SAHARA_IMAGE_TYPE_BINARY)
sahara_binary_image_info =
(struct boot_sahara_binary_image_info*)sahara_shared_data-&cur_
// Initialize binary image info
sahara_binary_image_info-&image_id = 0;
// Check the binary image header has been initialized to a valid address
if (sahara_binary_image_info-&header == NULL)
status = FALSE;
sahara_dispatch_tbl-&memset(sahara_binary_image_info-&header,
sahara_dispatch_tbl-&get_bin_header_size());
else if (sahara_shared_data-&expected_image_type == SAHARA_IMAGE_TYPE_ELF)
sahara_elf_image_info =
(struct boot_sahara_elf_image_info*)sahara_shared_data-&cur_
// Check program headers buffer has been initialized to a valid address
if (sahara_elf_image_info-&prog_headers == NULL)
status = FALSE;
// Initialize ELF image info
sahara_elf_image_info-&image_id = 0;
sahara_dispatch_tbl-&memset(&(sahara_elf_image_info-&elf_header),
sizeof(Elf32_Ehdr));
sahara_elf_image_info-&hash_table = NULL;
sahara_dispatch_tbl-&memset(&(sahara_elf_image_info-&shared_seg_index),
sizeof(uint32));
sahara_dispatch_tbl-&memset(&(sahara_elf_image_info-&entry_address),
sizeof(uint32));
/* zero initialize progressive_boot_block up to max possible
prog-header entries */
sahara_dispatch_tbl-&memset((sahara_elf_image_info-&prog_headers),
sizeof(struct progressive_boot_block));
else if (sahara_if-&sahara_mode != SAHARA_MODE_MEMORY_DEBUG)
// Image type not supported and not in memory debug mode
status = FALSE;
// Initialize Sahara state information
sahara_if-&sahara_shared_data-&image_rx_complete = FALSE;
sahara_mode = (enum boot_sahara_mode) sahara_if-&sahara_
sahara_state = SAHARA_STATE_ENTRY;
sahara_done = FALSE;
// Initialize hardware driver interface
if(BULK_SUCCESS != sahara_dispatch_tbl-&init())
status = FALSE;
} while (0);
if(NULL != sahara_if)
if (status == FALSE)
// Report error in initialize to Sahara client
sahara_if-&sahara_status = SAHARA_NAK_TARGET_INIT_FAILURE;
// Initialize sahara status
sahara_if-&sahara_status = SAHARA_STATUS_SUCCESS;
调用sahara_dispatch_tbl-&init函数指针, 即sbl1_sahara.c文件中的sbl_sahara_bulk_init()。
struct qhsusb_dcd_dsc_device* qhsusb_fd_hdlc_init(void (*rx_callback)(struct qhsusb_urb* urb),
uint8* str_product,
void (*tx_callback)(struct qhsusb_urb* urb),
void (*enum_complete)(void),
void (*error_handler)(void),
qhsusb_transfer_mode transfer_mode)
struct qhsusb_dcd_dsc_device* qhsusb_fd_hdlc_init(void (*rx_callback)(struct qhsusb_urb* urb),
uint8* str_product,
void (*tx_callback)(struct qhsusb_urb* urb),
void (*enum_complete)(void),
qhsusb_transfer_mode transfer_mode)
boolean hdlc_enum_already_exists = FALSE;
struct qhsusb_urb*
qhsusb_transfer_mode_g = transfer_
qhsusb_log(QHSUSB_FD_HDLC_INIT_LOG,0,0);
#ifndef FEATURE_SKIP_SERIAL_STR_UPDATE
qhsusb_fd_hdlc_update_pid_and_serial_number_string();
if ( NULL != str_product ) {
sw_device.strings[2].descriptor = (struct usb_desc_header*)(void*)str_
/* set up sw -& hw links */
#if defined(FEATURE_QHSUSB_HDLC_CDCACM)
hdlc_shutdown_in_progress = 0;
if ( 0 != hdlc_use_cdcacm ) {
sw_data_eps[0].descriptor = &hdlc_usb_config_cdcacm.ep_
sw_data_eps[1].descriptor = &hdlc_usb_config_cdcacm.ep_
sw_data_ifc.descriptor = &hdlc_usb_config_cdcacm.ifc_
sw_config.descriptor = &hdlc_usb_config_cdcacm.conf1;
sw_device.descriptor = &hdlc_usb_device_
sw_config.interfaces = &sw_cdc_control_
#endif /* defined(FEATURE_QHSUSB_HDLC_CDCACM) */
if(QHSUSB_MODE__SER_MS == qhsusb_bulk_mode_g)
sw_data_eps[0].descriptor = &hdlc_usb_config_obex.ep_
sw_data_eps[1].descriptor = &hdlc_usb_config_obex.ep_
sw_data_ifc.descriptor = &hdlc_usb_config_obex.ifc_
sw_config.descriptor = &hdlc_usb_config_obex.conf1;
else if (QHSUSB_MODE__SER_ONLY == qhsusb_bulk_mode_g)
sw_data_ifc.next = NULL;
sw_data_eps[0].descriptor = &hdlc_usb_config_obex_only.ep_
sw_data_eps[1].descriptor = &hdlc_usb_config_obex_only.ep_
sw_data_ifc.descriptor = &hdlc_usb_config_obex_only.ifc_
sw_config.descriptor = &hdlc_usb_config_obex_only.conf1;
if(hdlc_usb_device_obex.idProduct == USB_PRODUCT_DIAG_MS )
/*For serial only mode, change the product ID to 0x9008*/
hdlc_usb_device_obex.idProduct = USB_PRODUCT_DIAG_ONLY;
hdlc_usb_device_obex.iSerialNumber = 0x0;
else if (QHSUSB_MODE__SER_ONLY__DL_MODE == qhsusb_bulk_mode_g)
sw_data_ifc.next = NULL;
sw_data_eps[0].descriptor = &hdlc_usb_config_obex_only.ep_
sw_data_eps[1].descriptor = &hdlc_usb_config_obex_only.ep_
sw_data_ifc.descriptor = &hdlc_usb_config_obex_only.ifc_
sw_config.descriptor = &hdlc_usb_config_obex_only.conf1;
if(hdlc_usb_device_obex.idProduct == USB_PRODUCT_DIAG_MS )
/*For serial only mode, change the product ID to 0x9008*/
hdlc_usb_device_obex.idProduct = USB_PRODUCT_DIAG_ONLY;
hdlc_usb_device_obex.iSerialNumber = 0x0;
sw_device.descriptor = &hdlc_usb_device_
sw_config.interfaces = &sw_data_
#ifdef FEATURE_QHSUSB_MS
if( QHSUSB_MODE__SER_MS == qhsusb_bulk_mode_g )
/*Initialize the MS stack when you are in download mode only*/
qhsusb_fd_ms_init();
#endif /* FEATURE_QHSUSB_MS */
// Set enum flag for RS bit to be turned ON in qhsusb_dci_init();
qhsusb_dci_set_enum_flag(TRUE);
qhsusb_dcd_init(&sw_device);
user_rx_callback = rx_
if (tx_callback != NULL)
user_tx_callback = tx_
if (enum_complete != NULL)
user_enum_complete = enum_
#ifdef FEATURE_QHSUSB_SAHARA_DOWNLOAD_PIPO
if( error_handler !=NULL)
user_error_handler = error_
hdlc_enum_already_exists = dci_skip_enumeration(sw_device.core_id);
/* Data buffers & URB's */
= &hdlc_tx_
urb-&usb_device
urb-&endpoint_address
= sw_data_eps[0].descriptor-&bEndpointA
urb-&transfer_buffer_ptr = hdlc_tx_
urb-&transfer_length
urb-&transfer_status
urb-&send_zlp
urb-&complete_callback
= hdlc_tx_
urb-&is_zero_address_chain_required
if (transfer_mode == FD_CLIENT_SUPPLIED_BUFFER_MODE) /* Client Supplied Buffer Mode */
= &hdlc_rx_
urb-&usb_device
urb-&endpoint_address
= sw_data_eps[1].descriptor-&bEndpointA
urb-&transfer_buffer_ptr = NULL; /* to be filled by al layer */
urb-&transfer_length
= 0; /* to be filled by al layer */
urb-&send_zlp
urb-&complete_callback
= hdlc_rx_
urb-&actual_length
/*Initially set the is_zero_address_chain_required to FALSE*/
urb-&is_zero_address_chain_required
else /* Internal Buffer Mode */
uint8 i = 0;
for (i = 0; i & 2; i++) {
= &hdlc_rx_urb_fixed[i];
urb-&usb_device
urb-&endpoint_address
= sw_data_eps[1].descriptor-&bEndpointA
urb-&transfer_buffer_ptr = hdlc_rx_buffer_fixed[i];
urb-&transfer_length
= RX_BUF_SIZE_FIXED;
urb-&send_zlp
urb-&complete_callback
= hdlc_rx_callback_int_buf_
urb-&actual_length
/*Initially set the is_zero_address_chain_required to FALSE*/
urb-&is_zero_address_chain_required
/* cdc_notify_urb */
#if defined(FEATURE_QHSUSB_HDLC_CDCACM)
if ( 0 != hdlc_use_cdcacm ) {
urb = &cdc_notify_
urb-&usb_device
urb-&endpoint_address
= hdlc_usb_config_cdcacm.ep_notify.bEndpointA
urb-&transfer_length
urb-&complete_callback
#endif /* defined(FEATURE_QHSUSB_HDLC_CDCACM) */
#ifndef FEATURE_QHSUSB_PBL
if (hdlc_enum_already_exists)
We got here without reconnect. enumeration already
completed. Simulate connection and SET_CONFIG
qhsusb_dcd_port_status_changed(&sw_device); /* attachment, speed... */
sw_device.address = 1;
/* don't care, just not 0 */
qhsusb_dci_cancel_transfer_wo_dqh_dtd(sw_device.core_id, 1, QHSUSB_EP_DIR_RX);
qhsusb_dci_cancel_transfer_wo_dqh_dtd(sw_device.core_id, 1, QHSUSB_EP_DIR_TX);
qhsusb_dci_cancel_transfer_wo_dqh_dtd(sw_device.core_id, 2, QHSUSB_EP_DIR_RX);
qhsusb_dci_cancel_transfer_wo_dqh_dtd(sw_device.core_id, 2, QHSUSB_EP_DIR_TX);
qhsusb_dcd_set_config(&sw_device, 1);
if (transfer_mode == FD_USB_INTERNAL_BUFFER_MODE)
hdlc_init_rx_int_buf_mode(urb-&usb_device);
/* !FEATURE_QHSUSB_PBL */
return &sw_
sbl_sahara_bulk_init函数最终调用到qhsusb_fd_ms.c文件中的函数:qhsusb_fd_ms_init
整个初始化过程结束后完成com端口及mass storage枚举过程。
还有!!! 坑爹的高通,以前不提供生产用的软件下载工具,都得手机厂商自己开发。
高通思想终于改变了,QRD加入后,为手机厂商提供支持多路的软件升级工具:QMSCT 。
虽然设置比较繁琐,不管怎么样,总算可用。上张图吧!
QFIL和QMSCT是使用紧急下载模式,由PBL及下面firehose prog代码完成下载过程。
boot_images/core/storage/tools/deviceprogrammer
五、Crash ramdump
哎,这篇被我写得又长又臭啦。算了,这节就不详细写了。
  高通平台开放,本身也不稳定,因此做出的手机系统很多都不稳定。因此系统crash发生时,抓取crash现场就非常重要。
  这里简单说一下,高通平台抓取系统crash现场的几种方法:
  1、 通过QPST提供的 Memory Debug Application工具,当crash发生时,手机通过usb连接到PC, 然后用这个工具将crash现场的ram dump到电脑。
   显然,这种方法是最可靠的,但它有自身的局限性:不可能每次crash发生时,测试人员或者试用人员、研发人员都刚好在pc旁边。
  2、 高通平台sbl1提供将crash现场dump到sdcard的功能,如下代码。 这种方法的局性限是:
   现在高端手机,都没有外置sdcard的配置的,而内置sdcard又使用fuse ext4文件系统,而sbl1只支持fat文件系统。 
   因此,这种不配置外置sdcard的手机,这种方法根本不可行。
/*==========================================================================
List of SBL1 procedures to execute prior to dload entry
===========================================================================*/
boot_procedure_func_type sbl1_pre_dload_procs[] =
/*-----------------------------------------------------------------------
* Initialization functions for dload. This has to be the first function
* called before Dload entry
*----------------------------------------------------------------------*/
boot_init_for_dload,
/*-----------------------------------------------------------------------
* Setup clocks for ram dump
*----------------------------------------------------------------------*/
sbl1_hw_dload_init,
/*-----------------------------------------------------------------------
* Ram dump to eMMC raw partition, this function will reset device
* after successful dump collection if cookie is set
*----------------------------------------------------------------------*/
(boot_procedure_func_type) boot_ram_dump_to_raw_parition,
#ifdef FEATURE_BOOT_RAMDUMPS_TO_SD_CARD
/*----------------------------------------------------------------------
* Take the Ramdumps to SD card if
cookie file is
present in SD card
*---------------------------------------------------------------------*/
boot_ram_dumps_to_sd_card,
#endif /*FEATURE_BOOT_RAMDUMPS_TO_SD_CARD*/
/*-----------------------------------------------------------------------
* NULL pointer indicates the end of the list
*-----------------------------------------------------------------------*/
  3、 campact ramdump:这是QRD提出来的思路,即:仅dump一部分比较有用的ram到一个专门为crash分配的emmc分区。
system crash 的主要发生的,ap核的 kernel及service,rpm , modem 等核,而上层java代码不容易导致system crash。
 而现在手机的内置越来越大,1G、2G甚至3G,整个ram都dump到一个特定分区,就浪费emmc空间了。
 因此,compact ramdump就是将一部分关键的ram dump到专门为crash分配的emmc分区。 这样就不依赖于sdcard,也不依赖于usb。而且也不浪费emmc空间。
高通很多平台都没实现这功能,比如,msm8916, msm8974等,实现思路可以参考QRD8x25平台。
sbl1_hw_init ()
boot_smem_store_pon_status()
sbl1_hw_init_secondary()
=========&
初始化,电池低电时利用内部pmic进行预充电,power key 配置,获取、保存开机原因等。 见:pm_sbl_boot.c
sbl1_tlmm_init()
//gpio 初始化
sbl初始化gpio的初始状态代码如下:core/systemdrivers/tlmm/config/msm8916/TLMMChipset.xml
sbl1_efs_handle_cookies
// efs backup/restore
boot_populate_ram_partition_table
====& 解析iram , imem , system ram 的起始地址,大小等, 并保存到smem: SMEM_USABLE_RAM_PARTITION_TABLE ,传递给lk和kernel。
见: boot_ram_partition.c , 这里重点看看ram的情况吧.
/*===========================================================================
Function :
sbl1_update_ddr_info
** ==========================================================================
This funcion will get ddr information from ddr driver and put it in
sbl_shared_data.
* @param[in] bl_shared_data Pointer to shared data
* @par Dependencies
Must be called after sbl1_ddr_init
* @par Side Effects
static void sbl1_update_ddr_info(bl_shared_data_type *bl_shared_data)
static sbl_if_shared_ddr_device_info_type ddr_
ddr_size_info ddr_available = boot_ddr_get_size();
ddr_size_partition ddr_partition_info = boot_ddr_get_partition();
boot_share_extended_ddr_info(&ddr_info, &ddr_available, &ddr_partition_info);
bl_shared_data-&sbl_shared_data-&ddr_shared_info = &ddr_
boot_set_ddr_info(bl_shared_data);
从ddr driver层获取到ddr 类型、大小,cs等信息,保存到sbl_shared_data-&ddr_shared_info, 同时保存到sbl全局变量:boot_ddr_size_info
/*===========================================================================
Function :
add_system_ram_partitions
** ==========================================================================
Function adds all the DDR interfaces to ram partition table.
Each DDR interface will be added as a single entry in the table.
Partition category
will be RAM_PARTITION_SDRAM for all DDR entries.
* @param[in] usable_ram_part_tbl_ptr Pointer to the ram partition table that
should be populated
* @par Dependencies
ram_partition_return_type
RAM_PART_SUCCESS
- if function is successful.
RAM_PART_TABLE_FULL_ERR - if table is full or not enough space in
RAM_PART_CATEGORY_NOT_EXIST_ERR - if unable to populate certain DDR information
* @par Side Effects
static ram_partition_return_type add_system_ram_partitions
usable_ram_part_table_t usable_ram_part_tbl_ptr
ram_part_entry_t ram_part_entry_ptr = NULL;
sbl_if_shared_ddr_info_type *ddr_info = NULL;
sbl_if_shared_extended_ddr_info_type *ddr_extended_info = NULL;
uint32 partition_index = 0;
ram_partition_return_type result = RAM_PART_SUCCESS;
sbl_if_shared_ddr_device_info_type *ddr_shared_info = boot_get_ddr_info();
/*ram_part_entry_ptr points to first empty slot in the table*/
ram_part_entry_ptr =
&usable_ram_part_tbl_ptr-&
ram_part_entry[usable_ram_part_tbl_ptr-&num_partitions];
/*Loop through ddr_info and add all DDR interfaces into the table*/
for(; partition_index & ddr_shared_info-&noofddr
usable_ram_part_tbl_ptr-&num_partitions & RAM_NUM_PART_ENTRIES;
partition_index++)
ddr_info = &ddr_shared_info-&ddr_info[partition_index];
ram_part_entry_ptr-&partition_category = RAM_PARTITION_SDRAM;
ram_part_entry_ptr-&start_address = ddr_info-&cs_
ram_part_entry_ptr-&length = ddr_info-&ramsize && CONVERT_TO_BYTE_SHIFT;
ram_part_entry_ptr-&partition_attribute = RAM_PARTITION_READWRITE;
ram_part_entry_ptr-&partition_domain = RAM_PARTITION_DEFAULT_DOMAIN;
ram_part_entry_ptr-&partition_type = RAM_PARTITION_SYS_MEMORY;
/*Add the extended ddr information to current ram partition entry*/
if(ddr_shared_info-&ddr_partition_info != NULL)
ddr_extended_info = &ddr_shared_info-&ddr_partition_info[partition_index];
/*Make sure the base address of ddr extended info matches the current ddr base address*/
if (ddr_extended_info-&sdram_addr != ram_part_entry_ptr-&start_address)
result = RAM_PART_CATEGORY_NOT_EXIST_ERR;
ram_part_entry_ptr-&num_partitions = ddr_extended_info-&num_
ram_part_entry_ptr++;
usable_ram_part_tbl_ptr-&num_partitions++;
添加如下打印log语句在代码ddr_info = &ddr_shared_info-&ddr_info[partition_index];后面,
snprintf(message, 256,
"noofddr %d , cs_addr %d,
ramsize %d", ddr_shared_info-&noofddr, ddr_info-&cs_addr, ddr_info-&ramsize);
boot_log_message(message);
可以看到如下ddr info log信息:
376400 - noofddr 2 , cs_addr ,
ramsize 1024
376431 - noofddr 2 , cs_addr c0000000,
ramsize 1024
七、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/
//分区生成工具 partition =========& rawprogram0.xml
Python ptool.py –x partition.xml:
//ubuntu使用:根据 rawprogram0.xml进行升级软件工具
singleimage.py  //根据singleimage_partition_8974.xml生成single boot image: 8974_msimage.mbn
python singleimage.py -x singleimage_partition_8974.xml
// dd command
checksparse.py
//sparse system/cache/userdata image
【上篇】【下篇】

我要回帖

更多关于 谜画之塔3 enter key 的文章

 

随机推荐