Message ID | 20230105015818.19053-1-andre.przywara@arm.com |
---|---|
State | Superseded |
Delegated to: | Andre Przywara |
Headers | show |
Series | sunxi: eMMC: support TOC0 on boot partitions | expand |
Hi Andre, On 1/4/23 19:58, Andre Przywara wrote: > To determine whether we have been booted from an eMMC boot partition, we > replay some of the checks that the BROM must have done to successfully > load the SPL. This involves a checksum check, which currently relies on > the SPL being wrapped in an "eGON" header. > > If a board has secure boot enabled, the BROM will only accept the "TOC0" > format, which is internally very different, but uses the same > checksumming algorithm. Actually the only difference for calculating the > checksum is that the size of the SPL is stored at a different offset. > > Do a header check to determine whether we deal with an eGON or TOC0 > format, then set the SPL size accordingly. The rest of the code is > unchanged. > > This fixes booting from an eMMC boot partition on devices with secure > boot enabled, like the Remix Mini PC. > > Signed-off-by: Andre Przywara <andre.przywara@arm.com> > --- > arch/arm/mach-sunxi/board.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c > index 0c4b6dd1ca3..a90c88210cd 100644 > --- a/arch/arm/mach-sunxi/board.c > +++ b/arch/arm/mach-sunxi/board.c > @@ -365,6 +365,7 @@ static bool sunxi_valid_emmc_boot(struct mmc *mmc) > struct blk_desc *bd = mmc_get_blk_desc(mmc); > u32 *buffer = (void *)(uintptr_t)CONFIG_TEXT_BASE; > struct boot_file_head *egon_head = (void *)buffer; > + struct toc0_main_info *toc0_info = (void *)buffer; > int bootpart = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); > uint32_t spl_size, emmc_checksum, chksum = 0; > ulong count; > @@ -391,11 +392,17 @@ static bool sunxi_valid_emmc_boot(struct mmc *mmc) > > /* Read the first block to do some sanity checks on the eGON header. */ > count = blk_dread(bd, 0, 1, buffer); > - if (count != 1 || !sunxi_egon_valid(egon_head)) > + if (count != 1) > + return false; > + > + if (sunxi_egon_valid(egon_head)) > + spl_size = buffer[4]; > + else if (sunxi_toc0_valid(toc0_info)) > + spl_size = buffer[7]; Please dereference the appropriate structure member here instead of indexing the buffer. Regards, Samuel > + else > return false; > > /* Read the rest of the SPL now we know it's halfway sane. */ > - spl_size = buffer[4]; > count = blk_dread(bd, 1, DIV_ROUND_UP(spl_size, bd->blksz) - 1, > buffer + bd->blksz / 4); >
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 0c4b6dd1ca3..a90c88210cd 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -365,6 +365,7 @@ static bool sunxi_valid_emmc_boot(struct mmc *mmc) struct blk_desc *bd = mmc_get_blk_desc(mmc); u32 *buffer = (void *)(uintptr_t)CONFIG_TEXT_BASE; struct boot_file_head *egon_head = (void *)buffer; + struct toc0_main_info *toc0_info = (void *)buffer; int bootpart = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); uint32_t spl_size, emmc_checksum, chksum = 0; ulong count; @@ -391,11 +392,17 @@ static bool sunxi_valid_emmc_boot(struct mmc *mmc) /* Read the first block to do some sanity checks on the eGON header. */ count = blk_dread(bd, 0, 1, buffer); - if (count != 1 || !sunxi_egon_valid(egon_head)) + if (count != 1) + return false; + + if (sunxi_egon_valid(egon_head)) + spl_size = buffer[4]; + else if (sunxi_toc0_valid(toc0_info)) + spl_size = buffer[7]; + else return false; /* Read the rest of the SPL now we know it's halfway sane. */ - spl_size = buffer[4]; count = blk_dread(bd, 1, DIV_ROUND_UP(spl_size, bd->blksz) - 1, buffer + bd->blksz / 4);
To determine whether we have been booted from an eMMC boot partition, we replay some of the checks that the BROM must have done to successfully load the SPL. This involves a checksum check, which currently relies on the SPL being wrapped in an "eGON" header. If a board has secure boot enabled, the BROM will only accept the "TOC0" format, which is internally very different, but uses the same checksumming algorithm. Actually the only difference for calculating the checksum is that the size of the SPL is stored at a different offset. Do a header check to determine whether we deal with an eGON or TOC0 format, then set the SPL size accordingly. The rest of the code is unchanged. This fixes booting from an eMMC boot partition on devices with secure boot enabled, like the Remix Mini PC. Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- arch/arm/mach-sunxi/board.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)