综合技术交流
直播中

麦克泰技术

7年用户 423经验值
擅长:嵌入式技术
私信 关注
[经验]

使用SEGGER Linker的完整性检查功能

在嵌入式产品应用中,为了保证系统数据在存储或者传输过程中的完整性,固件映像中通常包含完整性检查(integrity checks),以检测映像是否损坏。例如,bootloader可以基于完整性检查验证一个更新的固件映像是否可信。或者固件基于完整性检查可以自我验证,检查Flash是否损坏。
SEGGER Embedded Studio从v5.10版本(Linker v3.00及以上版本)开始提供完整性检查功能,支持多种CRC和消息摘要算法(例如MD5和SHA)。
1.png 2.png
01
使用方法
使用Linker提供的完整性检查功能,首先需要将执行检查的区域定义为一个region,并为放置计算结果的区域定义一个region。
我们可以为整个Flash区域上创建一个CRC,并将结果放在Flash的末尾 。
此外,我们还可以定义计算CRC的区域的填充值。如:
  1. define region FLASH       = [0x80000000 size 512k];
  2. define region CRC         = [end(FLASH)-4, size 4];
  3. define region APPLICAtiON = FLASH - CRC;
  4. fill APPLICATION with 0xFF;
将应用段放到APPLICATION 域。

使用选择的算法如CRC-32计算CRC。
  1. place in CRC {
  2.   integrity check of APPLICATION with algorithm="CRC-32" fill=0xFF
  3. };
现在,APPLICATION域的CRC-32计算结果将保存在CRC域中。


02 实现

我们使用ST STM32F4_Discovery开发板,基于SEGGER Embedded Studio V7.10 提供的package manager创建STM32F4示例工程。
关于SES的使用,可以参考文章:SEGGER Embedded Studio使用体验与常用设置
修改链接脚本
首先,我们需要在链接定位文件STM32F4xx_Flash_CCM.icf中定义应用程序和计算出的CRC值放置的区域:
  1. define region CRC = [end(FLASH)-4 size 4];
  2. define region APPLICATION = FLASH - CRC;
将应用段放置在APPLICATION区域之后,执行完整性检查,并将结果将被放置在CRC区域:
  1. place in CRC {
  2. integrity check of APPLICATION with algorithm="CRC-32/STM32" fill=0xFF
  3. };
  4. fill APPLICATION with 0xFF;
最后一行是可选的,确保Flash的所有空白区域使用相同值填充,用于计算CRC。
使用的算法是CRC-32/STM32,与目标处理器使用的算法相同。


03 验证CRC结果

STM32系列内置了一个CRC-32硬件计算单元,为了验证生成的CRC,我们将计算结果与STM32 CRC外设的硬件实现进行比较。
在应用程序使用STM32 CRC外设计算应用程序区域上的CRC,然后将其与链接器计算的CRC进行比较。
首先使能CRC外设,基于ST CMSIS文件,操作如下:
  1. RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;  // Enable CRC clock
  2. CRC->CR |= CRC_CR_RESET;            // Reset peripheral
为了计算CRC,数据被逐字写入CRC数据寄存器:
  1. do {
  2.            CRC->DR = __REV(*pData);  // Calculate CRC
  3.         pData++;
  4. } while (NumItems--);      
  5. CRCResultHW = CRC->DR;      // Save CRC result
注意,STM32 CRC外设需要反转一个字中各个字节的顺序。为此,我们只需使用Embedded Studio的内部函数__REV()。


运行该应用程序,在Debug Terminal窗口可以看到SEGGER linker CRC和STM32 CRC是匹配的。
3.png

通过SEGGER linker支持固件(firmware)完整性检查,无需外部工具,所有工作都可以在Embedded Studio工具链中本地完成,大大简化了需要完整性检查的设置。

附:
  1. File    : main.c
  2. Purpose : Example application doing a CRC check using the STM32 CRC peripheral
  3. #include
  4. #include
  5. #include "stm32f4xx.h"
  6. #define FLASH_IMAGE_START 0x08000000
  7. #define FLASH_IMAGE_END   0x080FFFFC
  8. #define FLASH_APPLICATION_END (FLASH_IMAGE_END - 0x4)
  9. /*********************************************************************
  10. *
  11. *       main()
  12. *
  13. *  Function description
  14. *   Application entry point.
  15. */
  16. int main(void) {
  17.   int i;
  18.   unsigned int NumItems;
  19.   unsigned int* pData;
  20.   unsigned int CRCResultHW;
  21.   unsigned int CRCResult;
  22.   unsigned int OldValue;
  23.   
  24.   i = 0;
  25.   NumItems = (FLASH_APPLICATION_END - FLASH_IMAGE_START) / 4;
  26.   pData = (unsigned int*)FLASH_IMAGE_START;    // points to start of Flash
  27.   CRCResult = *(unsigned int*)FLASH_IMAGE_END; // Saves CRC value calculated by SEGGER Linker
  28.   //
  29.   // Config CRC Module
  30.   //
  31.   RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;
  32.   CRC->CR |= CRC_CR_RESET;
  33.   //
  34.   // Calculate CRC with ST CRC unit over complete Flash area
  35.   //
  36.   do {
  37.     CRC->DR = __REV(*pData);  // ST algorithm expects words in reversed order
  38.     pData++;
  39.   } while (NumItems--);
  40.   CRCResultHW = CRC->DR;
  41.   printf("Hardware calculated CRC over Flash is: 0x%X \n", CRCResultHW);
  42.   printf("SEGGER Linker calculated CRC over Flash is: 0x%X\n", CRCResult);
  43.   //
  44.   // Compare with Linker result
  45.   //
  46.   if (CRCResult == CRCResultHW) {
  47.     printf("Both CRC check sums are matching!\n");
  48.   } else {
  49.     printf("CRC check sums are not matching. Check parameters.\n");
  50.   }
  51.   do {
  52.     i++;
  53.   } while (1);
  54. }

更多回帖

发帖
×
20
完善资料,
赚取积分