175 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
| i.MX7D/i.MX8MM SRC_GPR10 PERSIST_SECONDARY_BOOT for bootloader A/B switching
 | |
| ============================================================================
 | |
| 
 | |
| Introduction
 | |
| ------------
 | |
| Since at least iMX53 until iMX8MM, it is possible to have two copies of
 | |
| bootloader in SD/eMMC and switch between them. The switch is triggered
 | |
| either by the BootROM in case the bootloader image is faulty OR can be
 | |
| enforced by the user.
 | |
| 
 | |
| Operation
 | |
| ---------
 | |
|  #. Upon Power-On Reset (POR)
 | |
| 
 | |
|     - SRC_GPR10 bit PERSIST_SECONDARY_BOOT is set to 0
 | |
|     - BootROM attempts to start bootloader A-copy
 | |
| 
 | |
|       - if A-copy valid
 | |
| 
 | |
|          - BootROM starts A-copy
 | |
|          - END
 | |
| 
 | |
|       - if A-copy NOT valid
 | |
| 
 | |
|          - BootROM sets SRC_GPR10 bit PERSIST_SECONDARY_BOOT to 1
 | |
|          - BootROM triggers WARM reset, GOTO 1)
 | |
|          - END
 | |
| 
 | |
|  #. Upon COLD Reset
 | |
| 
 | |
|     - GOTO 1)
 | |
|     - END
 | |
| 
 | |
|  #. Upon WARM Reset
 | |
| 
 | |
|     - SRC_GPR10 bit PERSIST_SECONDARY_BOOT is retained
 | |
| 
 | |
|       - if SRC_GPR10 bit PERSIST_SECONDARY_BOOT is 0
 | |
| 
 | |
|         - BootROM attempts to start bootloader A-copy
 | |
| 
 | |
|           - if A-copy valid
 | |
| 
 | |
|             - BootROM starts A-copy
 | |
|             - END
 | |
| 
 | |
|           - if A-copy NOT valid
 | |
| 
 | |
|             - BootROM sets SRC_GPR10 bit PERSIST_SECONDARY_BOOT to 1
 | |
|             - BootROM triggers WARM reset. GOTO 1.3)
 | |
|             - END
 | |
| 
 | |
|       - if SRC_GPR10 bit PERSIST_SECONDARY_BOOT is 1
 | |
| 
 | |
|         - BootROM attempts to start bootloader B-copy
 | |
| 
 | |
|           - if B-copy valid
 | |
| 
 | |
|             - BootROM starts B-copy
 | |
|             - END
 | |
| 
 | |
|           - if B-copy NOT valid
 | |
|             - System hangs
 | |
|             - END
 | |
| 
 | |
| Setup
 | |
| -----
 | |
| The bootloader A-copy must be placed at predetermined offset in SD/eMMC. The
 | |
| bootloader B-copy area offset is determined by an offset stored in Secondary
 | |
| Image Table (SIT). The SIT must be placed at predetermined offset in SD/eMMC.
 | |
| 
 | |
| The following table contains offset of SIT, bootloader A-copy and recommended
 | |
| bootloader B-copy offset. The offsets are in 512 Byte sector units (that is
 | |
| offset 0x1 means 512 Bytes from the start of SD/eMMC card data partition).
 | |
| For details on the addition of two numbers in recommended B-copy offset, see
 | |
| SIT format below.
 | |
| 
 | |
| +----------+--------------------+-----------------------+-----------------------------+
 | |
| |   SoC    | SIT offset (fixed) | A-copy offset (fixed) | B-copy offset (recommended) |
 | |
| +----------+--------------------+-----------------------+-----------------------------+
 | |
| | iMX7D    |         0x1        |          0x2          |          0x800+0x2          |
 | |
| +----------+--------------------+-----------------------+-----------------------------+
 | |
| | iMX8MM   |        0x41        |         0x42          |         0x1000+0x42         |
 | |
| +----------+--------------------+-----------------------+-----------------------------+
 | |
| 
 | |
| SIT format
 | |
| ~~~~~~~~~~
 | |
| SIT is a 20 byte long structure containing of 5 32-bit words. Those encode
 | |
| bootloader B-copy area offset (called "firstSectorNumber"), magic value
 | |
| (called "tag") that is always 0x00112233, and three unused words set to 0.
 | |
| SIT is documented in [1] and [2]. Example SIT are below::
 | |
| 
 | |
|   $ hexdump -vC sit-mx7d.bin
 | |
|     00000000  00 00 00 00
 | |
|     00000004  00 00 00 00
 | |
|     00000008  33 22 11 00 <--- This is the "tag"
 | |
|     0000000c  00 08 00 00 <--- This is the "firstSectorNumber"
 | |
|     00000010  00 00 00 00
 | |
| 
 | |
|   $ hexdump -vC sit-mx8mm.bin
 | |
|     00000000  00 00 00 00
 | |
|     00000004  00 00 00 00
 | |
|     00000008  33 22 11 00 <--- This is the "tag"
 | |
|     0000000c  00 10 00 00 <--- This is the "firstSectorNumber"
 | |
|     00000010  00 00 00 00
 | |
| 
 | |
| B-copy area offset ("firstSectorNumber") is offset, in units of 512 Byte
 | |
| sectors, that is added to the start of boot media when switching between
 | |
| A-copy and B-copy. For A-copy, this offset is 0x0. For B-copy, this offset
 | |
| is determined by SIT (e.g. if firstSectorNumber is 0x1000 as it is above
 | |
| in sit-mx8mm.bin, then the B-copy offset is 0x1000 sectors = 2 MiB).
 | |
| 
 | |
| Bootloader A-copy (e.g. u-boot.imx or flash.bin) is placed at fixed offset
 | |
| from A-copy area offset (e.g. 0x2 sectors from sector 0x0 for iMX7D, which
 | |
| means u-boot.imx A-copy must be written to sector 0x2).
 | |
| 
 | |
| The same applies to bootloader B-copy, which is placed at fixed offset from
 | |
| B-copy area offset determined by SIT (e.g. 0x2 sectors from sector 0x800 [see
 | |
| sit-mx7d.bin example above, this can be changed in SIT firstSectorNumber] for
 | |
| iMX7D, which means u-boot.imx B-copy must be written to sector 0x802)
 | |
| 
 | |
| **WARNING:**
 | |
| B-copy area offset ("firstSectorNumber") is NOT equal to bootloader
 | |
| (image, which is u-boot.imx or flash.bin) B-copy offset.
 | |
| 
 | |
| To generate SIT, use for example the following bourne shell printf command::
 | |
| 
 | |
| $ printf '\x0\x0\x0\x0\x0\x0\x0\x0\x33\x22\x11\x00\x00\x08\x00\x00\x0\x0\x0\x0' > sit-mx7d.bin
 | |
| $ printf '\x0\x0\x0\x0\x0\x0\x0\x0\x33\x22\x11\x00\x00\x10\x00\x00\x0\x0\x0\x0' > sit-mx8mm.bin
 | |
| 
 | |
| Write bootloader A/B copy and SIT to SD/eMMC
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Examples of writing SIT and two copies of bootloader to SD or eMMC:
 | |
| 
 | |
| - iMX8MM, SD card at /dev/sdX, Linux command line
 | |
|   ::
 | |
| 
 | |
|     $ dd if=sit-mx8mm.bin of=/dev/sdX bs=512 seek=65
 | |
|     $ dd if=flash.bin     of=/dev/sdX bs=512 seek=66
 | |
|     $ dd if=flash.bin     of=/dev/sdX bs=512 seek=4162
 | |
| 
 | |
| - iMX8MM, eMMC 1 data partition, U-Boot command line
 | |
|   ::
 | |
| 
 | |
|     => mmc partconf 1 0 0 0
 | |
| 
 | |
|     => dhcp ${loadaddr} sit-mx8mm.bin
 | |
|     => mmc dev 1
 | |
|     => mmc write ${loadaddr} 0x41 0x1
 | |
| 
 | |
|     => dhcp ${loadaddr} flash.bin
 | |
|     => setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt
 | |
|     => mmc dev 1
 | |
|     => mmc write ${loadaddr} 0x42   ${blkcnt}
 | |
|     => mmc write ${loadaddr} 0x1042 ${blkcnt}
 | |
| 
 | |
| WARM reset into B-copy using WDT
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| To perform a reboot into B-copy, the PERSIST_SECONDARY_BOOT must be set
 | |
| in SRC_GPR0 register. Example on iMX8MM::
 | |
| 
 | |
|   => mw 0x30390098 0x40000000
 | |
| 
 | |
| A WARM reset can be triggered using WDT as follows::
 | |
| 
 | |
|   => mw.w 0x30280000 0x25
 | |
| 
 | |
| References
 | |
| ----------
 | |
| 
 | |
| .. [1] i.MX 7Dual Applications Processor Reference Manual, Rev. 1, 01/2018 ; section 6.6.5.3.5 Redundant boot support for expansion device
 | |
| .. [2] i.MX 8M Mini Applications Processor Reference Manual, Rev. 3, 11/2020 ; section 6.1.5.4.5 Redundant boot support for expansion device
 |