serial_recovery: Replace CBOR decoding code with generated code

- Add the cddl_gen repository as a submodule.
 - Add a CDDL description file for the serial recovery packets to be
   decoded.
 - Add generated code files and cddl_gen's CBOR library to CMakeList.txt
   for Zephyr.
 - Convert boot_serial.c to use the new code.
 - Add a bash script to (re)generate code files using cddl_gen.py.

Serial recovery should work exactly as before, but the binary should be
about 1k smaller.

Signed-off-by: Øyvind Rønningstad <oyvind.ronningstad@nordicsemi.no>
This commit is contained in:
Øyvind Rønningstad 2019-12-13 03:27:54 +01:00 committed by David Brown
parent fab12e0524
commit f42a8205e8
6 changed files with 95 additions and 98 deletions

3
.gitmodules vendored
View File

@ -16,3 +16,6 @@
[submodule "boot/cypress/libs/cy-mbedtls-acceleration"]
path = boot/cypress/libs/cy-mbedtls-acceleration
url = https://github.com/cypresssemiconductorco/cy-mbedtls-acceleration.git
[submodule "boot/boot_serial/src/cddl_gen"]
path = ext/cddl_gen
url = https://github.com/oyvindronningstad/cddl_gen.git

View File

@ -43,7 +43,6 @@
#include <crc/crc16.h>
#include <base64/base64.h>
#include <tinycbor/cbor.h>
#include <tinycbor/cbor_buf_reader.h>
#endif /* __ZEPHYR__ */
#include <flash_map_backend/flash_map_backend.h>
@ -60,6 +59,8 @@
#include "bootutil_priv.h"
#endif
#include "serial_recovery_cbor.h"
MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
#define BOOT_SERIAL_INPUT_MAX 512
@ -226,18 +227,13 @@ bs_list(char *buf, int len)
static void
bs_upload(char *buf, int len)
{
CborParser parser;
struct cbor_buf_reader reader;
struct CborValue root_value;
struct CborValue value;
uint8_t img_data[512];
const uint8_t *img_data = NULL;
long long int off = UINT_MAX;
size_t img_blen = 0;
uint8_t rem_bytes;
long long int data_len = UINT_MAX;
int img_num;
size_t slen;
char name_str[8];
const struct flash_area *fap = NULL;
int rc;
#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
@ -245,7 +241,6 @@ bs_upload(char *buf, int len)
struct flash_sector sector;
#endif
memset(img_data, 0, sizeof(img_data));
img_num = 0;
/*
@ -258,99 +253,36 @@ bs_upload(char *buf, int len)
* }
*/
/*
* Object comes within { ... }
*/
cbor_buf_reader_init(&reader, (uint8_t *)buf, len);
cbor_parser_init(&reader.r, 0, &parser, &root_value);
Upload_t upload;
if (!cbor_decode_Upload((const uint8_t *)buf, len, &upload)) {
goto out_invalid_data;
}
if (!cbor_value_is_container(&root_value)) {
goto out_invalid_data;
}
if (cbor_value_enter_container(&root_value, &value)) {
goto out_invalid_data;
}
while (cbor_value_is_valid(&value)) {
/*
* Decode key.
*/
if (cbor_value_calculate_string_length(&value, &slen)) {
goto out_invalid_data;
}
if (!cbor_value_is_text_string(&value) ||
slen >= sizeof(name_str) - 1) {
goto out_invalid_data;
}
if (cbor_value_copy_text_string(&value, name_str, &slen, &value)) {
goto out_invalid_data;
}
name_str[slen] = '\0';
if (!strcmp(name_str, "data")) {
/*
* Image data
*/
if (value.type != CborByteStringType) {
goto out_invalid_data;
}
if (cbor_value_calculate_string_length(&value, &slen) ||
slen >= sizeof(img_data)) {
goto out_invalid_data;
}
if (cbor_value_copy_byte_string(&value, img_data, &slen, &value)) {
goto out_invalid_data;
}
img_blen = slen;
} else if (!strcmp(name_str, "off")) {
/*
* Offset of the data.
*/
if (value.type != CborIntegerType) {
goto out_invalid_data;
}
if (cbor_value_get_int64(&value, &off)) {
goto out_invalid_data;
}
if (cbor_value_advance(&value)) {
goto out_invalid_data;
}
} else if (!strcmp(name_str, "len")) {
/*
* Length of the image. This should only be present in the first
* block of data; when offset is 0.
*/
if (value.type != CborIntegerType) {
goto out_invalid_data;
}
if (cbor_value_get_int64(&value, &data_len)) {
goto out_invalid_data;
}
if (cbor_value_advance(&value)) {
goto out_invalid_data;
}
} else if (!strcmp(name_str, "image")) {
/*
* In a multi-image system, image number to upload to, if not
* present will upload to slot 0 of image set 0.
*/
if (value.type != CborIntegerType) {
goto out_invalid_data;
}
if (cbor_value_get_int(&value, &img_num)) {
goto out_invalid_data;
}
if (cbor_value_advance(&value)) {
goto out_invalid_data;
}
} else {
/*
* Unknown keys.
*/
if (cbor_value_advance(&value)) {
goto out_invalid_data;
}
for (int i = 0; i < upload._Upload_members_count; i++) {
_Member_t *member = &upload._Upload_members[i];
switch(member->_Member_choice) {
case _Member_image:
img_num = member->_Member_image;
break;
case _Member_data:
img_data = member->_Member_data.value;
slen = member->_Member_data.len;
img_blen = slen;
break;
case _Member_len:
data_len = member->_Member_len;
break;
case _Member_off:
off = member->_Member_off;
break;
case _Member_sha:
default:
/* Nothing to do. */
break;
}
}
if (off == UINT_MAX) {
if (off == UINT_MAX || img_data == NULL) {
/*
* Offset must be set in every block.
*/

View File

@ -0,0 +1,44 @@
#!/bin/bash
if [ "$1" == "--help" ] || [ "$1" == "" ]; then
echo "Regenerate serial_recovery_cbor.c|h if the cddl_gen submodule is updated."
echo "Usage: $0 <copyright>"
echo " e.g. $0 \"2020 Nordic Semiconductor ASA\""
exit -1
fi
add_copy_notice() {
echo "$(printf '/*
* This file has been %s from the cddl_gen submodule.
* Commit %s
*/
' "$2" "$(git -C ../../../ext/cddl_gen rev-parse HEAD)"; cat $1;)" > $1
}
echo "Copying cbor_decode.c|h"
copy_with_copy_notice() {
cp $1 $2
add_copy_notice $2 "copied"
}
copy_with_copy_notice ../../../ext/cddl_gen/src/cbor_decode.c cbor_decode.c
copy_with_copy_notice ../../../ext/cddl_gen/include/cbor_decode.h cbor_decode.h cbor_decode.h
echo "Generating serial_recovery_cbor.c|h"
python3 ../../../ext/cddl_gen/scripts/cddl_gen.py -i serial_recovery.cddl -t Upload --oc serial_recovery_cbor.c --oh serial_recovery_cbor.h --time-header
add_copyright() {
echo "$(printf '/*
* Copyright (c) %s
*
* SPDX-License-Identifier: Apache-2.0
*/
' "$2"; cat $1;)" > $1
}
add_copyright serial_recovery_cbor.c "$1"
add_copyright serial_recovery_cbor.h "$1"
add_copy_notice serial_recovery_cbor.c "generated"
add_copy_notice serial_recovery_cbor.h "generated"

View File

@ -0,0 +1,15 @@
;
; Copyright (c) 2020 Nordic Semiconductor ASA
;
; SPDX-License-Identifier: Apache-2.0
;
Member = ("image" => int) /
("data" => bstr) /
("len" => int) /
("off" => int) /
("sha" => bstr)
Upload = {
3**5members: Member
}

View File

@ -191,6 +191,8 @@ endif()
if(CONFIG_MCUBOOT_SERIAL)
zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/serial_recovery_cbor.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_decode.c)
zephyr_include_directories(${BOOT_DIR}/bootutil/include)
zephyr_include_directories(${BOOT_DIR}/boot_serial/include)

1
ext/cddl_gen Submodule

@ -0,0 +1 @@
Subproject commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576