@@ -56,13 +56,15 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
5656/* Currently only used by imgmgr */
5757int boot_current_slot ;
5858
59+ #if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE ) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
5960#if (!defined(MCUBOOT_DIRECT_XIP ) && !defined(MCUBOOT_RAM_LOAD )) || \
6061defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO )
6162/* Used for holding static buffers in multiple functions to work around issues
6263 * in older versions of gcc (e.g. 4.8.4)
6364 */
6465static struct boot_sector_buffer sector_buffers ;
6566#endif
67+ #endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
6668
6769/**
6870 * @brief Determine if the data at two memory addresses is equal
@@ -625,6 +627,7 @@ boot_erase_region(const struct flash_area *fa, uint32_t off, uint32_t size, bool
625627
626628#if (!defined(MCUBOOT_DIRECT_XIP ) && !defined(MCUBOOT_RAM_LOAD )) || \
627629defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO )
630+ #if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE ) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
628631int
629632boot_initialize_area (struct boot_loader_state * state , int flash_area )
630633{
@@ -665,6 +668,139 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area)
665668 return 0 ;
666669}
667670
671+ #else /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
672+ #if defined(MCUBOOT_VERIFY_LOGICAL_SECTORS )
673+ /* Validation can only run once all flash areas are open and pointers to
674+ * flash area objects are stored in state.
675+ */
676+ static int
677+ boot_verify_logical_sectors (int faid , const struct flash_area * fa )
678+ {
679+ uint32_t slot_size ;
680+ uint32_t slot_off ;
681+ uint32_t sect_off = 0 ;
682+ int rc ;
683+ int final_rc = 0 ;
684+ bool device_with_erase ;
685+ uint32_t wbs ;
686+
687+ assert (fa != NULL );
688+ assert (faid != 0 );
689+
690+ slot_off = (uint32_t )flash_area_get_off (fa );
691+ slot_size = (uint32_t )flash_area_get_size (fa );
692+
693+ wbs = flash_area_align (fa );
694+
695+ device_with_erase = device_requires_erase (fa );
696+ /* Go till all verifications are complete or we face issue that does not allow
697+ * to precede with further tests.
698+ */
699+ BOOT_LOG_INF ("boot_verify_logical_sectors: verify flash area %p" , fa );
700+ BOOT_LOG_INF ("boot_verify_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x" ,
701+ MCUBOOT_LOGICAL_SECTOR_SIZE );
702+ BOOT_LOG_INF ("boot_verify_logical_sectors: slot offset == 0x%x" , slot_off );
703+ if (slot_size != 0 ) {
704+ BOOT_LOG_INF ("boot_verify_logical_sectors: slot size == 0x%x" , slot_size );
705+ } else {
706+ BOOT_LOG_ERR ("boot_verify_logical_sectors: 0 size slot" );
707+ return BOOT_EFLASH ;
708+ }
709+ BOOT_LOG_INF ("boot_verify_logical_sectors: write block size %u" , wbs );
710+ BOOT_LOG_INF ("boot_verify_logical_sectors: device with%s erase" ,
711+ device_with_erase ? "" : "out" );
712+
713+ /* We are expecting slot size to be multiple of logical sector size.
714+ * Note though that we do not check alignment of the slot to logical sector.
715+ * as it does not matter, only alignment of slot to a real erase page
716+ * matters.
717+ */
718+ if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE ) {
719+ BOOT_LOG_ERR ("boot_verify_logical_sectors: area size not aligned" );
720+ final_rc = BOOT_EFLASH ;
721+ }
722+
723+ BOOT_LOG_INF ("boot_verify_logical_sectors: max %d logical sectors" ,
724+ slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE );
725+
726+ if (device_with_erase ) {
727+ size_t total_scanned = 0 ;
728+
729+ /* Check all logical sectors pages against erase pages of a device */
730+ while (total_scanned < slot_size ) {
731+ struct flash_sector fas ;
732+
733+ MCUBOOT_WATCHDOG_FEED ();
734+
735+ BOOT_LOG_INF ("boot_verify_logical_sectors: page 0x%x:0x%x " , slot_off , sect_off );
736+ rc = flash_area_get_sector (fa , sect_off , & fas );
737+ if (rc < 0 ) {
738+ BOOT_LOG_ERR ("boot_verify_logical_sectors: query err %d" , rc );
739+ final_rc = BOOT_EFLASH ;
740+ continue ;
741+ }
742+
743+ /* Jumping by logical sector size should align us with real erase page
744+ * each time.
745+ */
746+ if (sect_off != flash_sector_get_off (& fas )) {
747+ BOOT_LOG_ERR ("boot_verify_logical_sectors: misaligned offset (0x%x)" ,
748+ (uint32_t )flash_sector_get_off (& fas ));
749+ final_rc = BOOT_EFLASH ;
750+ }
751+
752+ /* Jumping by logical sector size */
753+ sect_off += MCUBOOT_LOGICAL_SECTOR_SIZE ;
754+ total_scanned += MCUBOOT_LOGICAL_SECTOR_SIZE ;
755+ }
756+ } else {
757+ /* Devices with no-explicit erase require alignment to write block size */
758+
759+ if (MCUBOOT_LOGICAL_SECTOR_SIZE % wbs ) {
760+ BOOT_LOG_ERR ("boot_verify_logical_sectors: sector size not aligned to write block" );
761+ final_rc = BOOT_EFLASH ;
762+ }
763+
764+ if (slot_off % wbs ) {
765+ BOOT_LOG_ERR ("boot_verify_logical_sectors: slot not aligned to write block" );
766+ final_rc = BOOT_EFLASH ;
767+ }
768+ }
769+
770+ BOOT_LOG_INF ("boot_verify_logical_sectors: completed (%d)" , final_rc );
771+
772+ return final_rc ;
773+ }
774+ #endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */
775+
776+ static int
777+ boot_initialize_area (struct boot_loader_state * state , int flash_area )
778+ {
779+ size_t area_size ;
780+ uint32_t * out_num_sectors ;
781+
782+ if (flash_area == FLASH_AREA_IMAGE_PRIMARY (BOOT_CURR_IMG (state ))) {
783+ area_size = flash_area_get_size (BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY ));
784+ out_num_sectors = & BOOT_IMG (state , BOOT_SLOT_PRIMARY ).num_sectors ;
785+ } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY (BOOT_CURR_IMG (state ))) {
786+ area_size = flash_area_get_size (BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY ));
787+ out_num_sectors = & BOOT_IMG (state , BOOT_SLOT_SECONDARY ).num_sectors ;
788+ #if MCUBOOT_SWAP_USING_SCRATCH
789+ } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH ) {
790+ area_size = flash_area_get_size (state -> scratch .area );
791+ out_num_sectors = & state -> scratch .num_sectors ;
792+ #endif
793+ } else {
794+ return BOOT_EFLASH ;
795+ }
796+
797+ * out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE ;
798+
799+ return 0 ;
800+ }
801+
802+ #endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
803+
668804static uint32_t
669805boot_write_sz (struct boot_loader_state * state )
670806{
@@ -694,12 +830,13 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
694830 uint8_t image_index ;
695831 int rc ;
696832
833+ image_index = BOOT_CURR_IMG (state );
834+
835+ #if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE ) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
697836 if (sectors == NULL ) {
698837 sectors = & sector_buffers ;
699838 }
700839
701- image_index = BOOT_CURR_IMG (state );
702-
703840 BOOT_IMG (state , BOOT_SLOT_PRIMARY ).sectors =
704841 sectors -> primary [image_index ];
705842#if BOOT_NUM_SLOTS > 1
@@ -709,6 +846,9 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
709846 state -> scratch .sectors = sectors -> scratch ;
710847#endif
711848#endif
849+ #else
850+ (void )sectors ;
851+ #endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
712852
713853 rc = boot_initialize_area (state , FLASH_AREA_IMAGE_PRIMARY (image_index ));
714854 if (rc != 0 ) {
@@ -732,6 +872,28 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
732872
733873 BOOT_WRITE_SZ (state ) = boot_write_sz (state );
734874
875+ #if defined(MCUBOOT_VERIFY_LOGICAL_SECTORS )
876+ BOOT_LOG_INF ("boot_read_sectors: verify image %d slots" , image_index );
877+ BOOT_LOG_INF ("boot_read_sectors: BOOT_SLOT_PRIMARY" );
878+ if (boot_verify_logical_sectors (FLASH_AREA_IMAGE_PRIMARY (image_index ),
879+ BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY )) != 0 ) {
880+ rc = BOOT_EFLASH ;
881+ }
882+
883+ BOOT_LOG_INF ("boot_read_sectors: BOOT_SLOT_SECONDARY" );
884+ if (boot_verify_logical_sectors (FLASH_AREA_IMAGE_SECONDARY (image_index ),
885+ BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY )) != 0 ) {
886+ rc = BOOT_EFLASH_SEC ;
887+ }
888+
889+ #if MCUBOOT_SWAP_USING_SCRATCH
890+ BOOT_LOG_INF ("boot_read_sectors: SCRATCH" );
891+ if (boot_verify_logical_sectors (FLASH_AREA_IMAGE_SCRATCH , state -> scratch .area ) != 0 ) {
892+ rc = BOOT_EFLASH ;
893+ }
894+ #endif /* MCUBOOT_SWAP_USING_SCRATCH */
895+ #endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */
896+
735897 return 0 ;
736898}
737899#endif
0 commit comments