解析MCUboot的實現原理和Image結構

目錄

概述

1 MCUboot的功能

1.1 代碼包結構

1.2 限制

2 MCUboot Image

2.1 Image格式

2.2 Flash Map

2.3 Image 槽

2.4 使用scratch交換

?2.5 Image 尾部數據結構

3 交換區

3.1 單交換區

?3.2 Multiple Image boot?

3.3 Image交換

4??交換狀態(swap status)

?5 復位覆蓋


概述

本文主要介紹MCUboot的實現原理和Image的結構,主要包括MCUboot的Image的格式,交換區,Resetrecovery等概念,還介紹了使用Image進行代碼更新的步驟。

1 MCUboot的功能

1.1 代碼包結構

MCUboot包含兩個代碼包:

1)The bootutil library (boot/bootutil)

2)The boot application (each port has its own at boot/)

bootutil 庫執行了引導加載程序的大部分功能。特別缺少的是實際跳轉到主映像的最后一步。這最后一步則由引導應用程序來實現。以這種方式分離引導加載程序的功能是為了能夠對引導加載程序進行單元測試。庫可以進行單元測試,但應用程序不行。因此,只要有可能,功能就會委托給 bootutil 庫。?

1.2 限制

當前,引導加載程序僅支持具有以下特征的映像:

1)?Built to run from flash.

2)? ?Built to run from a fixed location (i.e., not position-independent).

2 MCUboot Image

2.1 Image格式

以下定義描述image格式:

#define IMAGE_MAGIC                 0x96f3b83d#define IMAGE_HEADER_SIZE           32struct image_version {uint8_t iv_major;uint8_t iv_minor;uint16_t iv_revision;uint32_t iv_build_num;
};/** Image header.  All fields are in little endian byte order. */
struct image_header {uint32_t ih_magic;uint32_t ih_load_addr;uint16_t ih_hdr_size;           /* Size of image header (bytes). */uint16_t ih_protect_tlv_size;   /* Size of protected TLV area (bytes). */uint32_t ih_img_size;           /* Does not include header. */uint32_t ih_flags;              /* IMAGE_F_[...]. */struct image_version ih_ver;uint32_t _pad1;
};#define IMAGE_TLV_INFO_MAGIC        0x6907
#define IMAGE_TLV_PROT_INFO_MAGIC   0x6908/** Image TLV header.  All fields in little endian. */
struct image_tlv_info {uint16_t it_magic;uint16_t it_tlv_tot;  /* size of TLV area (including tlv_info header) */
};/** Image trailer TLV format. All fields in little endian. */
struct image_tlv {uint8_t  it_type;   /* IMAGE_TLV_[...]. */uint8_t  _pad;uint16_t it_len;    /* Data length (not including TLV header). */
};/** Image header flags.*/
#define IMAGE_F_PIC                      0x00000001 /* Not supported. */
#define IMAGE_F_ENCRYPTED_AES128         0x00000004 /* Encrypted using AES128. */
#define IMAGE_F_ENCRYPTED_AES256         0x00000008 /* Encrypted using AES256. */
#define IMAGE_F_NON_BOOTABLE             0x00000010 /* Split image app. */
#define IMAGE_F_RAM_LOAD                 0x00000020/** Image trailer TLV types.*/
#define IMAGE_TLV_KEYHASH           0x01   /* hash of the public key */
#define IMAGE_TLV_SHA256            0x10   /* SHA256 of image hdr and body */
#define IMAGE_TLV_RSA2048_PSS       0x20   /* RSA2048 of hash output */
#define IMAGE_TLV_ECDSA224          0x21   /* ECDSA of hash output - Not supported anymore */
#define IMAGE_TLV_ECDSA_SIG         0x22   /* ECDSA of hash output */
#define IMAGE_TLV_RSA3072_PSS       0x23   /* RSA3072 of hash output */
#define IMAGE_TLV_ED25519           0x24   /* ED25519 of hash output */
#define IMAGE_TLV_SIG_PURE          0x25   /* If true then any signature found has beencalculated over image directly. */
#define IMAGE_TLV_ENC_RSA2048       0x30   /* Key encrypted with RSA-OAEP-2048 */
#define IMAGE_TLV_ENC_KW            0x31   /* Key encrypted with AES-KW-128 or256 */
#define IMAGE_TLV_ENC_EC256         0x32   /* Key encrypted with ECIES-P256 */
#define IMAGE_TLV_ENC_X25519        0x33   /* Key encrypted with ECIES-X25519 */
#define IMAGE_TLV_DEPENDENCY        0x40   /* Image depends on other image */
#define IMAGE_TLV_SEC_CNT           0x50   /* security counter */

ih_hdr_size:?

字段表示頭部的長度,因此表示Image本身的偏移量。這個字段提供了向后兼容性,以防更改Image頭的格式。


ih_protect_tlv_size:? ?

字段表示TLV保護區域的長度。如果存在受保護的TLV,則必須存在一個magic等于IMAGE_TLV_PROT_INFO_MAGIC的TLV信息頭,并且受保護的TLV(加上信息頭本身)必須包含在哈希計算中。否則,哈希值只計算Image標題和Image本身。

在此例中,ih_protect_tlv_size字段的值為0。

2.2 Flash Map

設備的閃存根據其閃存映射進行分區。在高層次上,flash映射將數字id映射到flash區域。閃存區是磁盤的一個區域,具有以下屬性:

1)?一個區域可以完全擦除而不影響任何其他區域

2)?對一個區域的寫入不限制對其他區域的寫入。

引導加載程序使用以下flash區域id:

/* Independent from multiple image boot */
#define FLASH_AREA_BOOTLOADER         0
#define FLASH_AREA_IMAGE_SCRATCH      3
/* If the bootloader is working with the first image */
#define FLASH_AREA_IMAGE_PRIMARY      1
#define FLASH_AREA_IMAGE_SECONDARY    2
/* If the bootloader is working with the second image */
#define FLASH_AREA_IMAGE_PRIMARY      5
#define FLASH_AREA_IMAGE_SECONDARY    6

引導加載程序區域包含引導加載程序映像本身。其他方面將在后面的部分中描述。閃存可以包含多個可執行映像,因此主區域和輔助區域的閃存區域id是根據活動映像(引導加載程序當前正在其上工作)的數量映射的。

2.3 Image的槽

閃存的一部分可劃分為多個Image區域,每個Image區域包含兩個Image插槽:

1)主插槽

2)輔助插槽

正常情況下,引導加載程序只會從主插槽運行Image,因此必須構建映像,使它們能夠從flash中的固定位置運行(這方面的例外是direct-xip和ram-load升級模式)。如果引導加載程序需要運行駐留在輔助插槽中的映像,那么它必須在這樣做之前將其內容復制到主插槽中,要么交換兩個映像,要么覆蓋主插槽的內容。

2.4 使用scratch交換

當使用使用scratch交換算法時,除了Image區域的插槽之外,引導加載程序還需要scratch區域來允許可靠的Image交換。scratch區必須具有足夠的大小,至少可以存儲將要交換的最大扇區。許多設備都有同樣大小的小扇區,例如4K,而其他設備則有可變大小的扇區,其中最大的扇區可能是128K或256K,因此scratch必須足夠大才能存儲這些扇區。

scratch只在交換固件時使用,這意味著只在進行升級時使用。考慮到這一點,使用更大尺寸的劃痕的主要原因是閃存磨損將更均勻地分布,因為單個扇區的寫入次數是使用兩個扇區的兩倍,例如。為您的用例評估劃痕的理想大小,以下參數是相關的:

  • the ratio of image size / scratch size
  • the number of erase cycles supported by the flash hardware

?2.5 Image 尾部數據結構

為了使引導加載程序能夠確定當前狀態以及在當前引導操作期間應該采取什么操作,它使用存儲在映像閃存區域中的元數據。在交換時,其中一些元數據被臨時復制到刮痕區或從scratch區復制出來。

這個元數據位于Inage區域的末尾,稱為Image trailer。其具體結構如下:

 0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~                                                               ~~    Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3)    ~~                                                               ~+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                 Encryption key 0 (16 octets) [*]              ||                                                               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    0xff padding as needed                     ||  (BOOT_MAX_ALIGN minus 16 octets from Encryption key 0) [*]   |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                 Encryption key 1 (16 octets) [*]              ||                                                               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    0xff padding as needed                     ||  (BOOT_MAX_ALIGN minus 16 octets from Encryption key 1) [*]   |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                      Swap size (4 octets)                     |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    0xff padding as needed                     ||        (BOOT_MAX_ALIGN minus 4 octets from Swap size)         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|   Swap info   |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|   Copy done   |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|   Image OK    |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    0xff padding as needed                     ||         (BOOT_MAX_ALIGN minus 16 octets from MAGIC)           |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                       MAGIC (16 octets)                       ||                                                               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

?1)Swap info

交換信息:單個字節,編碼以下信息:
交換類型:0 ~ 3位存儲。指示正在進行的交換操作的類型。當MCUboot恢復被中斷的交換時,它使用這個字段來確定要執行的操作類型。該字段包含下表中下列值之一。


圖像號:存儲在4-7位。它在單映像引導時總是0值。在多映像引導的情況下,它指示中斷發生時交換了哪個映像。在所有圖像交換操作期間使用相同的劃痕區域。因此使用該字段

NameValue
BOOT_SWAP_TYPE_TEST2
BOOT_SWAP_TYPE_PERM3
BOOT_SWAP_TYPE_REVERT4

BOOT_SWAP_TYPE_TEST是嵌入式系統中固件升級機制的一部分,通常用于測試固件鏡像的交換功能。以下是其主要功能的詳細介紹:


BOOT_SWAP_TYPE_TEST是一種啟動交換類型,主要用于:

  • 測試新固件鏡像的可靠性

  • 驗證固件升級流程

  • 在不永久提交新固件的情況下進行測試


典型工作流程

  1. 標記狀態:系統將當前固件標記為"測試"狀態

  2. 交換鏡像:引導加載程序(bootloader)會加載新固件進行測試

  3. 驗證階段:新固件運行一段時間進行驗證

  4. 結果處理

    • 如果測試成功,系統可能將狀態改為永久

    • 如果測試失敗,系統會回退到舊固件


使用場景

  • 安全關鍵的固件升級前驗證

  • A/B分區系統中的測試啟動

  • 開發階段的固件驗證

  • 現場設備的安全升級測試


優勢

  1. 安全性:避免直接升級可能導致設備變磚

  2. 可靠性:確保新固件穩定后再永久應用

  3. 靈活性:開發人員可以測試不同版本的固件


實現細節

具體實現可能因系統而異,但通常涉及:

  • 引導加載程序中的特殊處理邏輯

  • 非易失性存儲器中的狀態標志

  • 鏡像完整性檢查機制

  • 超時或條件觸發的回退機制

2)拷貝完成:單字節表示該槽中的映像是否完成(0x01=done;0 xff =沒有完成)。

3)image OK:一個單字節,表示這個槽中的映像是否已被用戶確認為好的(0x01=confirmed;0 xff =沒有證實)。

4)MAGIC:標識Image trailer布局的16字節字段。它可以根據映像支持的最大寫對齊(BOOT_MAX_ALIGN)假設不同的值,由以下結構定義:

union boot_img_magic_t
{struct {uint16_t align;uint8_t magic[14];};uint8_t val[16];
};

如果BOOT_MAX_ALIGN是8字節,那么MAGIC包含以下16字節:

const union boot_img_magic_t boot_img_magic = {.val = {0x77, 0xc2, 0x95, 0xf3,0x60, 0xd2, 0xef, 0x7f,0x35, 0x52, 0x50, 0x0f,0x2c, 0xb6, 0x79, 0x80}
};

如果BOOT_MAX_ALIGN被定義為任何不同于8的值,那么支持的最大寫對齊值將在MAGIC字段中編碼,后跟一個固定的14字節模式:

const union boot_img_magic_t boot_img_magic = {.align = BOOT_MAX_ALIGN,.magic = {0x2d, 0xe1,0x5d, 0x29, 0x41, 0x0b,0x8d, 0x77, 0x67, 0x9c,0x11, 0x0f, 0x1f, 0x8a}
};

3 交換區

3.1 單交換區

對于新的交換,MCUboot必須檢查一個字段集合,以確定執行哪個交換操作。
Image trailers記錄是圍繞flash硬件施加的限制構建的。因此,它們沒有一個非常直觀的設計,并且很難通過查看圖像預告片來了解設備的狀態。最好通過一組表將所有可能的跟蹤狀態映射到上面描述的交換類型。這些表格轉載如下。

    State I (swap using offset only)| primary slot | secondary slot |-----------------+--------------+----------------|magic | Any          | Good           |image-ok | Any          | Unset          |copy-done | Any          | Set            |-----------------+--------------+----------------'result: BOOT_SWAP_TYPE_REVERT                   |-------------------------------------------------'State II| primary slot | secondary slot |-----------------+--------------+----------------|magic | Any          | Good           |image-ok | Any          | Unset          |copy-done | Any          | Any            |-----------------+--------------+----------------'result: BOOT_SWAP_TYPE_TEST                     |-------------------------------------------------'State III| primary slot | secondary slot |-----------------+--------------+----------------|magic | Any          | Good           |image-ok | Any          | 0x01           |copy-done | Any          | Any            |-----------------+--------------+----------------'result: BOOT_SWAP_TYPE_PERM                     |-------------------------------------------------'State IV| primary slot | secondary slot |-----------------+--------------+----------------|magic | Good         | Any            |image-ok | 0xff         | Any            |copy-done | 0x01         | Any            |-----------------+--------------+----------------'result: BOOT_SWAP_TYPE_REVERT                   |-------------------------------------------------'

上述三種狀態中的任何一種都會導致MCUboot嘗試交換Image。否則,MCUboot不會嘗試交換映像,從而導致其他三種交換類型之一,如狀態IV所示。

    State V| primary slot | secondary slot |-----------------+--------------+----------------|magic | Any          | Any            |image-ok | Any          | Any            |copy-done | Any          | Any            |-----------------+--------------+----------------'result: BOOT_SWAP_TYPE_NONE,                    |BOOT_SWAP_TYPE_FAIL, or                 |BOOT_SWAP_TYPE_PANIC                    |-------------------------------------------------'

?3.2 Multiple Image boot?

當閃存包含多個可執行映像時,引導加載程序的操作稍微復雜一些,但與前面描述的使用一個映像的過程類似。每個圖像都可以獨立更新,因此閃存進一步分區,為每個圖像安排兩個插槽。

+--------------------+
| MCUboot            |
+--------------------+~~~~~            <- memory might be not contiguous
+--------------------+
| Image 0            |
| primary   slot     |
+--------------------+
| Image 0            |
| secondary slot     |
+--------------------+~~~~~            <- memory might be not contiguous
+--------------------+
| Image N            |
| primary   slot     |
+--------------------+
| Image N            |
| secondary slot     |
+--------------------+
| Scratch            |
+--------------------+

3.3 Image交換

?引導程序交換兩個映像槽的內容有兩個原因:
1) 用戶發出了“設置掛起”操作;次要插槽中的映像應該運行一次(狀態I)或重復運行一次(狀態II),這取決于是否指定了永久交換。
2) 測試映像在未確認的情況下重啟;引導加載程序應該恢復到當前在輔助插槽中的原始映像(狀態III)。

?如果映像顯示應該運行輔助插槽中的映像,則引導加載程序需要將其復制到主插槽。當前在主插槽中的映像也需要保留在flash中,以便以后使用。此外,如果引導加載程序在交換操作中重置,則兩個映像都需要是可恢復的。按照以下步驟交換兩個鏡像:

Step-1:?確定兩個插槽是否足夠兼容以交換它們的映像。為了兼容,兩者都必須只有能夠容納劃痕區域的扇區,如果其中一個扇區比另一個扇區大,它必須能夠完全容納來自另一個插槽的某些四舍五入扇區。在接下來的步驟中,我們將使用術語“區域”來表示復制/擦除的數據總量,因為這可以是任何數量的扇區,這取決于有多少扇區能夠適合某些交換操作。

Step-2:?按降序迭代區域索引列表(即從最大索引開始);僅復制預定為圖像一部分的區域;當前元素= "index"。

a.擦除劃痕區域。
b.將secondary_slot[index]拷貝到劃痕區。
如果這是槽中的最后一個區域,則刮擦區域具有初始化以存儲初始狀態的臨時狀態區域,因為必須擦除主槽的最后一個區域。在這種情況下,只復制計算為圖像的數據。
否則,如果這是交換的第一個區域,但不是槽中的最后一個區域,則初始化主槽中的狀態區域并復制完整的區域內容。否則,復制整個區域的內容。

c.寫入更新后的swap狀態(i)。
d.擦除secondary_slot[index]

e.將primary_slot[index]拷貝到secondary_slot[index]。
如果這不是槽中的最后一個區域,則擦除輔助槽中的預告片,以始終使用主槽中的預告片。
f.寫入更新后的swap狀態(ii)。
g.擦除primary_slot[index]。
h.將刮痕區復制到primary_slot[index]中,根據之前在步驟b中復制的數量。如果這是槽中的最后一個區域,則從頭讀取狀態(它臨時存儲在那里),然后在主槽中重新寫入狀態

Step-3:? 將交換過程的完成持久化到主插槽映像 trailer。

注意點:?

步驟2-f中的附加警告是必要的,以便用戶可以在稍后的時間寫入輔助插槽映像預告片。在不寫入映像預告片的情況下,用戶可以在二級插槽中測試映像(即切換到狀態I)。

步驟3的細節取決于是否正在測試映像、永久使用映像、恢復映像或在請求交換時發生了輔助插槽的驗證失敗:

* test:o Write primary_slot.copy_done = 1(swap caused the following values to be written:primary_slot.magic = BOOT_MAGICsecondary_slot.magic = UNSETprimary_slot.image_ok = Unset)* permanent:o Write primary_slot.copy_done = 1(swap caused the following values to be written:primary_slot.magic = BOOT_MAGICsecondary_slot.magic = UNSETprimary_slot.image_ok = 0x01)* revert:o Write primary_slot.copy_done = 1o Write primary_slot.image_ok = 1(swap caused the following values to be written:primary_slot.magic = BOOT_MAGIC)* failure to validate the secondary slot:o Write primary_slot.image_ok = 1

4??交換狀態(swap status)

交換狀態區域允許引導加載程序在映像交換操作中間重新啟動時進行恢復。交換狀態區域由一系列單字節記錄組成。這些記錄是獨立寫入的,因此必須根據flash硬件施加的最小寫入大小進行填充。交換狀態區域的結構如下所示。在該圖中,為了簡單起見,假設最小寫大小為1,該圖顯示了每個扇區的3種狀態,適用于使用scratch交換和使用move交換,但是在使用offset交換模式中只有3種狀態。

     0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|sec125,state 2 |                                               |+-+-+-+-+-+-+-+-+                                               +~                                                               ~~               [Records for indices 124 through 1              ~~                                                               ~~               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~               |sec000,state 0 |sec000,state 1 |sec000,state 2 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

?以上可能一點幫助都沒有;這里有一段英文描述。
每個映像槽被劃分成一系列的閃存扇區。如果我們枚舉單個槽中的扇區,從0開始,我們將得到一個扇區索引列表。由于有兩個映像槽,每個扇區索引將對應一對扇區。例如,扇區索引0分別對應主槽位的第一個扇區和從槽位的第一個扇區。最后,反轉索引列表,使列表以索引BOOT_MAX_IMG_SECTORS - 1開始,以0結束。

在交換操作期間,每個扇區索引通過四個不同的狀態轉換:

0. primary slot: image 0,   secondary slot: image 1,   scratch: N/A
1. primary slot: image 0,   secondary slot: N/A,       scratch: image 1 (1->s, erase 1)
2. primary slot: N/A,       secondary slot: image 0,   scratch: image 1 (0->1, erase 0)
3. primary slot: image 1,   secondary slot: image 0,   scratch: N/A     (s->0)

?每次扇區索引轉換到新狀態時,引導加載程序都會向交換狀態區域寫入一條記錄。邏輯上,引導加載程序只需要每個扇區索引一個記錄來跟蹤當前的交換狀態。然而,由于flash硬件的限制,當索引狀態改變時,不能重寫記錄。為了解決這個問題,引導加載程序為每個扇區索引使用三條記錄,而不是一條。

每個部門-狀態對表示為一組三條記錄。記錄值映射到上述四種狀態如下所示:

            | rec0 | rec1 | rec2--------+------+------+------state 0 | 0xff | 0xff | 0xffstate 1 | 0x01 | 0xff | 0xffstate 2 | 0x01 | 0x02 | 0xffstate 3 | 0x01 | 0x02 | 0x03

?5 復位覆蓋

如果引導加載程序在交換操作中重置,則兩個Image可能在flash中不連續。Bootutil通過使用Image起始數據來確定Image部分如何在flash中分布來從這種情況中恢復。

第一步是確定相關交換狀態區域的位置。由于該區域嵌入到映像槽中,因此在交換操作期間,它在閃存中的位置會發生變化。下面的一組表將圖像預告片內容映射到交換狀態位置。在這些表中,“source”字段表示交換狀態區域的位置。在多IMage啟動的情況下,總是成對地檢查圖像的主區和單劃痕區。如果在劃痕區域找到交換狀態,那么它可能不屬于當前IMage。交換狀態的swap_info字段存儲相應的信息.

              | primary slot | scratch      |----------+--------------+--------------|magic | Good         | Any          |copy-done | 0x01         | N/A          |----------+--------------+--------------'source: none                            |----------------------------------------'| primary slot | scratch      |----------+--------------+--------------|magic | Good         | Any          |copy-done | 0xff         | N/A          |----------+--------------+--------------'source: primary slot                    |----------------------------------------'| primary slot | scratch      |----------+--------------+--------------|magic | Any          | Good         |copy-done | Any          | N/A          |----------+--------------+--------------'source: scratch                         |----------------------------------------'| primary slot | scratch      |----------+--------------+--------------|magic | Unset        | Any          |copy-done | 0xff         | N/A          |----------+--------------+--------------|source: primary slot                    |----------------------------------------+------------------------------+This represents one of two cases:                                      |o No swaps ever (no status to read, so no harm in checking).           |o Mid-revert; status in the primary slot.                              |For this reason we assume the primary slot as source, to trigger a     |check of the status area and find out if there was swapping under way. |-----------------------------------------------------------------------'

如果交換狀態區域表明映像不是連續的,那么MCUboot通過讀取活動映像尾片中的交換信息字段并從0-3位提取交換類型來確定被中斷的交換操作的類型,然后恢復操作。換句話說,它應用前一節中定義的過程,將映像1移動到主插槽中,將映像0移動到輔助插槽中。如果引導狀態表明在刮擦區域中存在映像部分,則從區域交換過程中的步驟e或步驟h開始將該部分復制到正確的位置。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91968.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91968.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91968.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

YOLOv8目標檢測項目代碼詳解與習題

YOLOv8目標檢測項目代碼詳解與習題一、項目代碼詳解該代碼是基于 YOLOv8 和 OpenCV 實現的圖像目標檢測項目&#xff0c;核心功能是加載預訓練的 YOLOv8 模型&#xff0c;對指定圖像進行目標檢測&#xff0c;然后可視化檢測結果并保存或顯示。以下是逐行解析&#xff1a;# -*- …

gradle關于dependency-management的使用

1、相關文檔Spring官方文檔&#xff1a;https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/#introduction倉庫版本查看&#xff1a;https://mvnrepository.com/artifact/io.spring.gradle/dependency-management-plugin/1.0.15.RELEA…

Java SpringBoot 對接FreeSwitch

1.增加Maven依賴<dependency><groupId>org.freeswitch.esl.client</groupId><artifactId>org.freeswitch.esl.client</artifactId><version>0.9.2</version></dependency><!-- XML-RPC --><dependency><groupI…

限流算法與實現

費曼學習法學習限流算法為什么要限流mysql插入600次/秒超過這個閾值&#xff0c;要么使用mysql集群、要么限流&#xff0c;防止宕機有哪些算法固定窗口就是個計數器&#xff0c;一秒內超過閾值&#xff0c;不允許訪問缺點&#xff1a;不均勻&#xff0c;跨越臨界點的一秒內&…

Android本地瀏覽PDF(Android PDF.js 簡要學習手冊)

環境 Min SDK: 21 依賴&#xff1a; implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1" implementation "androidx.webkit:webkit:1.12.0"權限&#xff1a; <uses-permission android:name"android.permission.INTERNE…

CVE-2022-41128

概述CVE-2022-41128 是 Microsoft Internet Explorer&#xff08;IE&#xff09;瀏覽器中 JavaScript 引擎&#xff08;JScript/Chakra&#xff09;的一個 0day 漏洞&#xff08;披露時無官方補丁&#xff09;&#xff0c;屬于內存破壞類漏洞&#xff0c;可被用于遠程代碼執行&…

基于LSTM的時間序列到時間序列的回歸模擬

獲取項目源碼點擊文末名片項目背景與目標 本項目旨在開發一種基于長短期記憶網絡&#xff08;LSTM&#xff09;的模型&#xff0c;用于時間序列到時間序列的回歸模擬任務。通過處理多組不同來源的時間序列數據&#xff0c;本模型的目標是從給定的輸入序列中預測相應的輸出序列。…

Linux基礎命令詳解:從入門到精通

本文整理了Linux系統中最常用的基礎命令&#xff0c;每個命令都配有詳細說明和具體示例&#xff0c;幫助你快速掌握Linux操作技巧。文章中用的終端是XShell,系統是Centos&#x1f4c1; 1. ls - 列出目錄&#xff08;文件夾&#xff09;內容 功能&#xff1a;顯示當前目錄下的文…

正點原子stm32F407學習筆記10——輸入捕獲實驗

一、輸入捕獲簡介 輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。我們以測量脈寬為例&#xff0c;用一個簡圖來 說明輸入捕獲的原理&#xff0c;如圖所示&#xff1a;假定定時器工作在向上計數模式&#xff0c;圖中 t1到t2 時間&#xff0c;就是我們需要測量的高電平時間。測…

深入理解設計模式:狀態模式(State Pattern)

在軟件開發中&#xff0c;我們經常會遇到對象的行為隨著其內部狀態的變化而變化的情況。例如&#xff0c;一個訂單可能處于"待支付"、"已支付"、"已發貨"或"已完成"等不同狀態&#xff0c;每個狀態下訂單的操作邏輯可能完全不同。如果…

企業級網絡綜合集成實踐:VLAN、Trunk、STP、路由協議(OSPF/RIP)、PPP、服務管理(TELNET/FTP)與安全(ACL)

NE綜合實驗4 一、實驗拓撲二、實驗需求 按照圖示配置IP地址。Sw7和sw8之間的直連鏈路配置鏈路聚合。公司內部業務網段為vlan10和vlan20&#xff0c;vlan10是市場部&#xff0c;vlan20是技術部&#xff0c;要求對vlan進行命名以便區分識別&#xff1b;pc10屬于vlan10&#xff0c…

小架構step系列20:請求和響應的擴展點

1 概述通過上一篇了解請求和響應的流程&#xff0c;Spring在設計上留了不少擴展點。里面通過查找接口的方式獲取的地方&#xff0c;都可以成為一種擴展點&#xff0c;因為只要實現這類接口就可以成為Spring加載的一部分。本文了解一下這些擴展點&#xff0c;方便后面進行擴展。…

模型材質一鍵替換~輕松還原多種三維場景

1. 概述模型的材質決定了三維場景的整體視效&#xff0c;山海鯨可視化不僅支持模型材質的替換與編輯&#xff0c;而且提供了大量現成的模型材質供大家使用&#xff0c;能夠幫助大家實現更高效的三維場景搭建。模型材質主要分為PBR材質和水面材質兩個部分。其中大部分靜態模型都…

【JS逆向基礎】數據庫之mysql

前言&#xff1a;mysql數據庫管理系統&#xff0c;由瑞典MySQL AB 公司開發&#xff0c;目前屬于 Oracle 旗下公司。MySQL 最流行的關MySQL是一個開源免費的關系型數據庫管系型數據庫管理系統&#xff0c;在 WEB 應用方面ySQL是最好的 RDBMS (Relational Database Management S…

金融工程、金融與經濟學知識點

本文整理了20個金融工程、金融和經濟學知識點及邏輯&#xff0c;這些是理解金融市場運作和進行量化分析的基石。 1. 金融工程 - 遠期與期權&#xff08;Forward & Option&#xff09;的定價與風險管理 遠期定價&#xff1a; 利用無套利原則&#xff0c;遠期合約的價格應等…

Vue 3 中導出 Excel 文件

在 Vue 3 中導出 Excel 文件&#xff0c;通常可以使用一些流行的 JavaScript 庫&#xff0c;如 SheetJS (xlsx) 或者 exceljs。這里我將分別介紹如何使用這兩個庫來在 Vue 3 應用中導出 Excel 文件。方法 1&#xff1a;使用 SheetJS (xlsx)安裝 SheetJS首先&#xff0c;你需要安…

奇麟大數據:前端大文件上傳解決方案

在奇麟大數據業務系統的開發及使用過程中&#xff0c;例如OBS對象存儲文件管理、流計算DSC依賴管理&#xff0c;經常會遇到上傳文件這樣的基礎需求&#xff0c;一般情況下&#xff0c;前端上傳文件就是new FormData&#xff0c;然后把文件 append 進去&#xff0c;然后post發送…

立創EDA中雙層PCB疊層分析

立創EDA中雙層PCB疊層分析 結論&#xff1a;立創EDA中的雙層 PCB 疊層視圖相比傳統視圖&#xff0c;多出一個焊盤層&#xff08;博主命名&#xff09;&#xff1b; 1. 傳統雙層 PCB 疊層示意圖 絲印層 印刷元件標識、極性標記及廠商信息 輔助組裝與后期維護 阻焊層 覆蓋銅層表…

深入理解進程:從底層原理到硬件系統實戰

深入理解進程&#xff1a;從底層原理到嵌入式實戰&#xff08;3-4 萬字詳解&#xff09; 前言&#xff1a;為什么硬件開發者必須吃透進程&#xff1f; 作為嵌入式開發者&#xff0c;你可能會說&#xff1a;“我平時用的 RTOS 里只有任務&#xff08;Task&#xff09;&#xff0…

Elasticsearch 簡化指南:GCP Google Compute Engine

作者&#xff1a;來自 Elastic Eduard Martin 系列內容的一部分&#xff1a;開始使用 Elasticsearch&#xff1a;GCP 想獲得 Elastic 認證&#xff1f;看看下一期 Elasticsearch Engineer 培訓什么時候開始&#xff01; Elasticsearch 擁有豐富的新功能&#xff0c;幫助你根據…