背景
使用 swupdate
作为 OTA
方案 ,有项目要求在写入数据到分区之后需要再次读出校验。
初步实现:readout-verify attribute
初步分析有两种方式
- 方案一
在每一笔数据写入后,立刻读出校验。此时原始数据还在 buffer
中,读出的数据直接跟原始 buffer
做比较即可
- 方案二
在将分区数据完全写入后,再读出校验。
注意在流式升级的情况下,源数据是分片传输写入的,用完即弃,因此写完整个分区之后已经没有原始数据可以比较了。
此时要么重新从数据源获取(不可取,相当于下载两次 OTA
包),要么需要在 OTA
包中额外配置好校验值,对读出数据计算得到的校验值进行比较。
出于简单考虑,选择了方案一进行实现,为 image
增加了一个 readout-verify
属性,配置后在每笔数据写入后均会读出校验,校验的方式是直接跟源 buffer
比较。
功能很简单,但由于源码中并未考虑这种情况,因此用于校验的 buffer
无法传递,只能反复申请和释放,问题不大只是看着有点别扭。
尝试把 patch
发出来,想听听作者的意见,结果作者回复已经有一个 readback handler
用于支持读出分区数据进行校验了。
社区实现: readback handler
这个 reabback handler
采用 scripts
的形式,在所有 image
写入完成后,再对 image
进行读出校验,sha256
校验值需要在 sw-description
中预先配置好。
举个例子:
scripts: (
{
device = "/dev/mmcblk2p1";
type = "readback";
properties: {
sha256 = "e7afc9bd98afd4eb7d8325196d21f1ecc0c8864d6342bfc6b6b6c84eac86eb42";
size = "184728576";
offset = "0";
};
}
);
功能顾名思义,就是读出指定 device
的指定范围的数据,算出 sha256
值,验证与配置中的 sha256
值是否一致。
具体的配置描述如下表。
字段 | 类型 | 描述 |
---|---|---|
device | string | 要校验的分区节点 |
type | string | 标注handler |
sha256 | string | 分区的sha256值 |
size | string | 要校验的数据大小(单位:字节)。如果未设置或设置为0,则会自动获取分区大小 |
offset | string | 要校验的数据偏移(单位:字节)。如果未设置,默认为0 |
总结
稍微比较下两种实现(以下列出的缺点是相对另一个而言,所以优点就不赘述了)
readback handler
的缺点在于
- 实现较为复杂,使用也较为复杂,需要配置
sha256
(当然一般是通过脚本自动化生成) - 先完全写入再校验,即出问题时不会立刻报错保留现场,而是在所有
image
均写入完成后,才进行校验 - 对某些定制不方便实现,例如要求在出错时重试该笔数据的写入
readout-verify attribute
的缺点在于
- 在某些情况下不适用,例如配合
ubi handler
,配合rdiff handler
- 只能保证该笔数据写入正确,无法保证完整数据未被篡改。例如写入
A
数据后读出校验成功,再写入B
时影响到了A
,则无法被检测到
综上,优先选择社区默认的 readback handler
,实在有无法满足的定制化需求时,再考虑自行实现特殊属性和行为。
blog: https://www.cnblogs.com/zqb-all/p/12827506.html
公众号:https://sourl.cn/T4Skam