[PATCH 1/2] bootcount: add bootcount flash driver
Daniel Schwierzeck
daniel.schwierzeck at gmail.com
Thu Apr 23 20:59:40 CEST 2020
Am 22.04.20 um 12:46 schrieb Arnaud Ferraris:
> In order to save the bootcounter on raw flash device, this commit
> introduces a new bootcount driver, enabled using the
> CONFIG_BOOTCOUNT_FLASH option.
>
> The bootcounter is stored at address CONFIG_SYS_BOOTCOUNT_FLASH_ADDR
> (absolute address, can also be computed from
> CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET), and it uses a data structure
> providing several useful enhancements:
> - a `flags` field, used to check whether the bootcounter should be
> written to flash (similar to the `upgrade_available` environment
> variable)
> - a `crc` field to ensure integrity of the structure, which will be
> used later on when adding redundancy support
> - a `data` field, which can be used to store and pass user data
> between u-boot and the OS (e.g boot partition selection)
>
> Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
> ---
>
> drivers/bootcount/Kconfig | 14 ++++++
> drivers/bootcount/Makefile | 1 +
> drivers/bootcount/bootcount_flash.c | 78 +++++++++++++++++++++++++++++
> include/bootcount.h | 12 +++++
> scripts/config_whitelist.txt | 2 +
> 5 files changed, 107 insertions(+)
> create mode 100644 drivers/bootcount/bootcount_flash.c
>
> diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
> index 0e506c9ea2..94de3f5ef8 100644
> --- a/drivers/bootcount/Kconfig
> +++ b/drivers/bootcount/Kconfig
> @@ -66,6 +66,20 @@ config BOOTCOUNT_I2C
> CONFIG_SYS_BOOTCOUNT_ADDR = i2c addr which is used for
> the bootcounter.
>
> +config BOOTCOUNT_FLASH
> + bool "Boot counter on flash device"
> + help
> + Store the bootcounter on raw flash. The bootcounter will be stored
> + as a structure using one flash sector, and will only be written when
> + a specific flag is set in the structure. Additionnally, this driver
> + relies on one of the following to be defined:
> +
> + CONFIG_SYS_BOOTCOUNT_FLASH_ADDR = address used for storing the
> + bootcounter on flash.
> + or
> + CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET = bootcounter offset on flash
> + (relative to SYS_FLASH_BASE).
> +
> config BOOTCOUNT_AT91
> bool "Boot counter for Atmel AT91SAM9XE"
> depends on AT91SAM9XE
> diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
> index 73ccfb5a08..bddcd136f3 100644
> --- a/drivers/bootcount/Makefile
> +++ b/drivers/bootcount/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_BOOTCOUNT_RAM) += bootcount_ram.o
> obj-$(CONFIG_BOOTCOUNT_ENV) += bootcount_env.o
> obj-$(CONFIG_BOOTCOUNT_I2C) += bootcount_i2c.o
> obj-$(CONFIG_BOOTCOUNT_EXT) += bootcount_ext.o
> +obj-$(CONFIG_BOOTCOUNT_FLASH) += bootcount_flash.o
>
> obj-$(CONFIG_DM_BOOTCOUNT) += bootcount-uclass.o
> obj-$(CONFIG_DM_BOOTCOUNT_RTC) += rtc.o
> diff --git a/drivers/bootcount/bootcount_flash.c b/drivers/bootcount/bootcount_flash.c
> new file mode 100644
> index 0000000000..1222bb4ae0
> --- /dev/null
> +++ b/drivers/bootcount/bootcount_flash.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2020 Collabora Ltd. All rights reserved.
> + */
> +
> +#include <bootcount.h>
> +#include <common.h>
> +#include <asm/io.h>
> +#include <u-boot/crc.h>
> +#include <flash.h>
> +
> +#ifndef CONFIG_SYS_BOOTCOUNT_FLASH_ADDR
> +# ifdef CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET
> +# define CONFIG_SYS_BOOTCOUNT_FLASH_ADDR \
> + (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET)
> +# else
> +# error "Either CONFIG_SYS_BOOTCOUNT_FLASH_ADDR or " \
> + "CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET should be defined!"
> +# endif
> +#endif
> +
> +#define BOOTCOUNT_CRC_SIZE (sizeof(*bootcount) - sizeof(bootcount->crc))
> +
> +static struct bootcount *bootcount = (void *)CONFIG_SYS_BOOTCOUNT_ADDR;
> +static ulong bc_flash = CONFIG_SYS_BOOTCOUNT_FLASH_ADDR;
> +static ulong bc_flash_end =
> + CONFIG_SYS_BOOTCOUNT_FLASH_ADDR + CONFIG_SYS_FLASH_SECT_SIZE - 1;
> +
> +static void bootcount_write(void)
> +{
> + if (flash_sect_protect(0, bc_flash, bc_flash_end))
> + return;
> +
> + puts("Erasing Flash...\n");
> + if (flash_sect_erase(bc_flash, bc_flash_end))
> + return;
> +
> + puts("Writing bootcount to Flash...\n");
> + if (flash_write((char *)bootcount, bc_flash, sizeof(*bootcount)))
> + return;
> +
> + flash_sect_protect(1, bc_flash, bc_flash_end);
Why don't you build this on top of the MTD layer to make it compatible
with all flash media types? Nowadays no one uses parallel NOR flash
devices anymore ;)
Also why don't you continously write new entries until the sector is
full? Erasing the sector on every boot kills the flash sector early.
> +}
> +
> +static void bootcount_init(void)
> +{
> + memset(bootcount, 0, sizeof(*bootcount));
> + bootcount->magic = CONFIG_SYS_BOOTCOUNT_MAGIC;
> + bootcount->crc = crc32(0, (uchar *)bootcount, BOOTCOUNT_CRC_SIZE);
> + bootcount_write();
> +}
> +
> +void bootcount_store(ulong a)
> +{
> + bootcount->count = a;
> + bootcount->crc = crc32(0, (uchar *)bootcount, BOOTCOUNT_CRC_SIZE);
> + if (bootcount->flags & BOOTCOUNT_FLAGS_UPDATE)
> + bootcount_write();
> +}
> +
> +ulong bootcount_load(void)
> +{
> + static int initialized;
> + u32 crc;
> +
> + if (!initialized) {
> + memcpy(bootcount, (void *)bc_flash, sizeof(*bootcount));
> + initialized = 1;
> + }
> +
> + crc = crc32(0, (uchar *)bootcount, BOOTCOUNT_CRC_SIZE);
> + if (bootcount->magic != CONFIG_SYS_BOOTCOUNT_MAGIC ||
> + bootcount->crc != crc) {
> + bootcount_init();
> + }
> +
> + return bootcount->count;
> +}
> diff --git a/include/bootcount.h b/include/bootcount.h
> index cd30403984..5698bd3239 100644
> --- a/include/bootcount.h
> +++ b/include/bootcount.h
> @@ -79,6 +79,18 @@ ulong bootcount_load(void);
> # endif
> #endif
>
> +#ifdef CONFIG_BOOTCOUNT_FLASH
> +struct bootcount {
> + u32 magic;
> + u32 count;
> + u32 flags;
> + u32 data;
> + u32 crc;
> +};
> +
> +#define BOOTCOUNT_FLAGS_UPDATE 0x1
> +#endif
> +
> #ifdef CONFIG_SYS_BOOTCOUNT_LE
> static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
> {
> diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
> index 6908431d03..672483f040 100644
> --- a/scripts/config_whitelist.txt
> +++ b/scripts/config_whitelist.txt
> @@ -1829,6 +1829,8 @@ CONFIG_SYS_BOARD_NAME
> CONFIG_SYS_BOARD_OMAP3_HA
> CONFIG_SYS_BOOK3E_HV
> CONFIG_SYS_BOOTCOUNT_BE
> +CONFIG_SYS_BOOTCOUNT_FLASH_ADDR
> +CONFIG_SYS_BOOTCOUNT_FLASH_OFFSET
> CONFIG_SYS_BOOTCOUNT_LE
> CONFIG_SYS_BOOTFILE_PREFIX
> CONFIG_SYS_BOOTMAPSZ
>
--
- Daniel
More information about the U-Boot
mailing list