A/B系统是Android设计给OTA用,前面有文章分析过,只不过是LK下。现在看下QCOM UEFI下对A/B retry count是否递减的逻辑。
EFI_STATUS FindBootableSlot (Slot *BootableSlot) { Unbootable = (BootEntry->PartEntry.Attributes & PART_ATT_UNBOOTABLE_VAL) >> PART_ATT_UNBOOTABLE_BIT; BootSuccess = (BootEntry->PartEntry.Attributes & PART_ATT_SUCCESSFUL_VAL) >> PART_ATT_SUCCESS_BIT; RetryCount = (BootEntry->PartEntry.Attributes & PART_ATT_MAX_RETRY_COUNT_VAL) >> PART_ATT_MAX_RETRY_CNT_BIT;
if (Unbootable == 0 && BootSuccess == 1) { DEBUG ( (EFI_D_VERBOSE, "Active Slot %s is bootable\n", BootableSlot->Suffix)); } else if (Unbootable == 0 && BootSuccess == 0 && RetryCount > 0) { if ((!IsABRetryCountDisabled () && !IsBootDevImage ()) && IsABRetryCountUpdateRequired () ){ RetryCount--; BootEntry->PartEntry.Attributes &= ~PART_ATT_MAX_RETRY_COUNT_VAL; BootEntry->PartEntry.Attributes |= RetryCount << PART_ATT_MAX_RETRY_CNT_BIT; UpdatePartitionAttributes (PARTITION_ATTRIBUTES); DEBUG ((EFI_D_INFO, "Active Slot %s is bootable, retry count %ld\n", BootableSlot->Suffix, RetryCount)); } else { DEBUG ((EFI_D_INFO, "A/B retry count NOT decremented\n")); } } else { DEBUG ((EFI_D_INFO, "Slot %s is unbootable, trying alternate slot\n", BootableSlot->Suffix)); GUARD_OUT (HandleActiveSlotUnbootable ()); }
|
可以看到,如果当前槽是可以启动的(Unbootable == 0
)而且成功起来过(BootSuccess == 1
)就直接启动了,一般都是非第一次系统启动。
如果可以启动但是没有成功起来过(比如刚刷完机)启动次数还有时:
case1: 如果A/B次数被禁用了,就不减,有个feature宏控制。
#ifdef AB_RETRYCOUNT_DISABLE BOOLEAN IsABRetryCountDisabled (VOID) { return TRUE; } #else BOOLEAN IsABRetryCountDisabled (VOID) { return FALSE; } #endif
|
case2: 如果是IsBootDevImage()
,也不减。
BOOLEAN IsBootDevImage (VOID) { return BootDevImage; }
|
EFI_STATUS BootLinux (BootInfo *Info) { ... if (AsciiStrStr (BootParamlistPtr.CmdLine, "root=")) { BootDevImage = TRUE; }
|
应该是cmdline带了root=
,有个提交:
commit 6a54fe1c4a886ea1560fe617dfc975776d3edf97 Author: Channagoud Kadabi <ckadabi@codeaurora.org> Date: Fri Jun 2 17:00:56 2017 -0700
QcommodulePkg: BootLib: do no decrement retry count on dev images
Dev images with custom userspace/ramdisk do not have slot successful set, do not decrement retry count for such custom images.
Change-Id: Ia37e853b40b41bb62c766838d6a7efc4b37f4427
|
一般不用。
case3: if no case1而且no case2,我们根据boot into mode来决定是否递减。
也就是IsABRetryCountUpdateRequired()
:
BOOLEAN IsABRetryCountUpdateRequired (VOID) { BOOLEAN BatteryStatus;
TargetPauseForBatteryCharge (&BatteryStatus);
if ((BatteryStatus && IsChargingScreenEnable ()) || BootIntoFastboot || BootIntoRecovery) { return FALSE; } return TRUE; }
|
注释写的很清楚了,fastboot/fastbootd/charger/recovery state不减。
note that IsChargingScreenEnable()
。
提下fastbootd是userspace fastboot,是dynamic partition(动态分区,Android Q引入)里的东东。
Done.
版权声明:本站所有文章均采用 CC BY-NC-SA 4.0 CN 许可协议。转载请注明原文链接!