@@ -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,141 @@ 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 (const struct boot_loader_state * state , int faid , const struct flash_area * fa )
678+ {
679+ size_t slot_size ;
680+ size_t slot_off ;
681+ size_t sect_off = 0 ;
682+ int rc ;
683+ int final_rc = 0 ;
684+ const struct flash_parameters * fparams ;
685+ bool device_with_erase ;
686+ uint32_t wbs ;
687+
688+ assert (fa != NULL );
689+ assert (faid != 0 );
690+
691+ slot_off = flash_area_get_off (fa );
692+ slot_size = flash_area_get_size (fa );
693+
694+ fparams = flash_get_parameters (flash_area_get_device (fa ));
695+ wbs = fparams -> write_block_size ;
696+
697+ device_with_erase =
698+ (flash_params_get_erase_cap (fparams ) & FLASH_ERASE_C_EXPLICIT ) == FLASH_ERASE_C_EXPLICIT ;
699+ /* Go till all verifications are complete or we face issue that does not allow
700+ * to precede with further tests.
701+ */
702+ BOOT_LOG_INF ("boot_verify_logical_sectors: verify flash area %p" , fa );
703+ BOOT_LOG_INF ("boot_verify_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x" ,
704+ MCUBOOT_LOGICAL_SECTOR_SIZE );
705+ BOOT_LOG_INF ("boot_verify_logical_sectors: slot offset == 0x%x" , slot_off );
706+ if (slot_size != 0 ) {
707+ BOOT_LOG_INF ("boot_verify_logical_sectors: slot size == 0x%x" , slot_size );
708+ } else {
709+ BOOT_LOG_ERR ("boot_verify_logical_sectors: 0 size slot" );
710+ return BOOT_EFLASH ;
711+ }
712+ BOOT_LOG_INF ("boot_verify_logical_sectors: write block size %u" , wbs );
713+ BOOT_LOG_INF ("boot_verify_logical_sectors: device with%s erase" ,
714+ device_with_erase ? "" : "out" );
715+
716+ /* We are expecting slot size to be multiple of logical sector size.
717+ * Note though that we do not check alignment of the slot to logical sector.
718+ * as it does not matter, only alignment of slot to a real erase page
719+ * matters.
720+ */
721+ if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE ) {
722+ BOOT_LOG_ERR ("boot_verify_logical_sectors: area size not aligned" );
723+ final_rc = BOOT_EFLASH ;
724+ }
725+
726+ BOOT_LOG_INF ("boot_verify_logical_sectors: max %d logical sectors" ,
727+ slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE );
728+
729+ if (device_with_erase ) {
730+ size_t total_scanned = 0 ;
731+
732+ /* Check all logical sectors pages against erase pages of a device */
733+ while (total_scanned < slot_size ) {
734+ struct flash_sector fas ;
735+
736+ MCUBOOT_WATCHDOG_FEED ();
737+
738+ BOOT_LOG_INF ("boot_verify_logical_sectors: page 0x%x:0x%x " , slot_off , sect_off );
739+ rc = flash_area_get_sector (fa , sect_off , & fas );
740+ if (rc < 0 ) {
741+ BOOT_LOG_ERR ("boot_verify_logical_sectors: query err %d" , rc );
742+ final_rc = BOOT_EFLASH ;
743+ continue ;
744+ }
745+
746+ /* Jumping by logical sector size should align us with real erase page
747+ * each time.
748+ */
749+ if (sect_off == flash_sector_get_off (& fas )) {
750+ BOOT_LOG_ERR ("boot_verify_logical_sectors: misaligned offset" );
751+ final_rc = BOOT_EFLASH ;
752+ }
753+
754+ /* Jumping by logical sector size */
755+ sect_off += MCUBOOT_LOGICAL_SECTOR_SIZE ;
756+ total_scanned += MCUBOOT_LOGICAL_SECTOR_SIZE ;
757+ }
758+ } else {
759+ /* Devices with no-explicit erase require alignment to write block size */
760+
761+ if (MCUBOOT_LOGICAL_SECTOR_SIZE % wbs ) {
762+ BOOT_LOG_ERR ("boot_verify_logical_sectors: sector size not aligned to write block" );
763+ final_rc = BOOT_EFLASH ;
764+ }
765+
766+ if (slot_off % wbs ) {
767+ BOOT_LOG_ERR ("boot_verify_logical_sectors: slot not aligned to write block" );
768+ final_rc = BOOT_EFLASH ;
769+ }
770+ }
771+
772+ BOOT_LOG_INF ("boot_verify_logical_sectors: completed (%d)" , final_rc );
773+
774+ return final_rc ;
775+ }
776+ #endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */
777+
778+ static int
779+ boot_initialize_area (struct boot_loader_state * state , int flash_area )
780+ {
781+ size_t area_size ;
782+ uint32_t * out_num_sectors ;
783+
784+ if (flash_area == FLASH_AREA_IMAGE_PRIMARY (BOOT_CURR_IMG (state ))) {
785+ area_size = flash_area_get_size (BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY ));
786+ out_num_sectors = & BOOT_IMG (state , BOOT_SLOT_PRIMARY ).num_sectors ;
787+ } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY (BOOT_CURR_IMG (state ))) {
788+ area_size = flash_area_get_size (BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY ));
789+ out_num_sectors = & BOOT_IMG (state , BOOT_SLOT_SECONDARY ).num_sectors ;
790+ #if MCUBOOT_SWAP_USING_SCRATCH
791+ } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH ) {
792+ area_size = flash_area_get_size (state -> scratch .area );
793+ out_num_sectors = & state -> scratch .num_sectors ;
794+ #endif
795+ } else {
796+ return BOOT_EFLASH ;
797+ }
798+
799+ * out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE ;
800+
801+ return 0 ;
802+ }
803+
804+ #endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
805+
668806static uint32_t
669807boot_write_sz (struct boot_loader_state * state )
670808{
@@ -694,12 +832,13 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
694832 uint8_t image_index ;
695833 int rc ;
696834
835+ image_index = BOOT_CURR_IMG (state );
836+
837+ #if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE ) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
697838 if (sectors == NULL ) {
698839 sectors = & sector_buffers ;
699840 }
700841
701- image_index = BOOT_CURR_IMG (state );
702-
703842 BOOT_IMG (state , BOOT_SLOT_PRIMARY ).sectors =
704843 sectors -> primary [image_index ];
705844#if BOOT_NUM_SLOTS > 1
@@ -709,6 +848,9 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
709848 state -> scratch .sectors = sectors -> scratch ;
710849#endif
711850#endif
851+ #else
852+ (void )sectors ;
853+ #endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
712854
713855 rc = boot_initialize_area (state , FLASH_AREA_IMAGE_PRIMARY (image_index ));
714856 if (rc != 0 ) {
@@ -732,6 +874,29 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
732874
733875 BOOT_WRITE_SZ (state ) = boot_write_sz (state );
734876
877+ #if defined(MCUBOOT_VERIFY_LOGICAL_SECTORS )
878+ BOOT_LOG_INF ("boot_read_sectors: verify image %d slots" , image_index );
879+ BOOT_LOG_INF ("boot_read_sectors: BOOT_SLOT_PRIMARY" );
880+ if (boot_verify_logical_sectors (state , FLASH_AREA_IMAGE_PRIMARY (image_index ),
881+ BOOT_IMG_AREA (state , BOOT_SLOT_PRIMARY )) != 0 ) {
882+ rc = BOOT_EFLASH ;
883+ }
884+
885+ BOOT_LOG_INF ("boot_read_sectors: BOOT_SLOT_SECONDARY" );
886+ if (boot_verify_logical_sectors (state , FLASH_AREA_IMAGE_SECONDARY (image_index ),
887+ BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY )) != 0 ) {
888+ rc = BOOT_EFLASH_SEC ;
889+ }
890+
891+ #if MCUBOOT_SWAP_USING_SCRATCH
892+ BOOT_LOG_INF ("boot_read_sectors: SCRATCH" );
893+ if (boot_verify_logical_sectors (state , FLASH_AREA_IMAGE_SCRATCH ,
894+ state -> scratch .area ) != 0 ) {
895+ rc = BOOT_EFLASH ;
896+ }
897+ #endif /* MCUBOOT_SWAP_USING_SCRATCH */
898+ #endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */
899+
735900 return 0 ;
736901}
737902#endif
0 commit comments