summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-10-17 07:26:16 -0400
committerTom Rini <trini@konsulko.com>2019-10-17 07:26:16 -0400
commita2fce50455c9831f36765e5813b0b5e98f55d70b (patch)
tree4a0d4bfaf6392a1639b93ce4f09e9f0f68aa63b9
parentc83b1bb923421e95e499b22b010d2f9f463c1226 (diff)
parent611623417403256dc79205a89d4dc7f826bc805f (diff)
downloadu-boot-a2fce50455c9831f36765e5813b0b5e98f55d70b.tar.gz
u-boot-a2fce50455c9831f36765e5813b0b5e98f55d70b.tar.bz2
u-boot-a2fce50455c9831f36765e5813b0b5e98f55d70b.zip
Merge tag 'for-v2020.01' of https://gitlab.denx.de/u-boot/custodians/u-boot-ubi
ubi enhancements for 2020.01 - provide a way for skipping crc checks ported from linux, and add an U-Boot command to set this flag on already installed systems. - fix redundand environment management
-rw-r--r--cmd/ubi.c58
-rw-r--r--doc/README.ubi33
-rw-r--r--drivers/mtd/ubi/debug.c1
-rw-r--r--drivers/mtd/ubi/kapi.c2
-rw-r--r--drivers/mtd/ubi/ubi-media.h6
-rw-r--r--drivers/mtd/ubi/ubi.h4
-rw-r--r--drivers/mtd/ubi/vmt.c12
-rw-r--r--drivers/mtd/ubi/vtbl.c3
-rw-r--r--env/Kconfig6
-rw-r--r--include/env_internal.h2
-rw-r--r--include/mtd/ubi-user.h18
11 files changed, 135 insertions, 10 deletions
diff --git a/cmd/ubi.c b/cmd/ubi.c
index ca5dc9021b..22ba5b1a2c 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -146,7 +146,8 @@ bad:
return err;
}
-static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id)
+static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
+ bool skipcheck)
{
struct ubi_mkvol_req req;
int err;
@@ -163,7 +164,10 @@ static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id)
strcpy(req.name, volume);
req.name_len = strlen(volume);
req.name[req.name_len] = '\0';
- req.padding1 = 0;
+ req.flags = 0;
+ if (skipcheck)
+ req.flags |= UBI_VOL_SKIP_CRC_CHECK_FLG;
+
/* It's duplicated at drivers/mtd/ubi/cdev.c */
err = verify_mkvol_req(ubi, &req);
if (err) {
@@ -415,6 +419,30 @@ static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset)
return 0;
}
+static int ubi_set_skip_check(char *volume, bool skip_check)
+{
+ struct ubi_vtbl_record vtbl_rec;
+ struct ubi_volume *vol;
+
+ vol = ubi_find_volume(volume);
+ if (!vol)
+ return ENODEV;
+
+ printf("%sing skip_check on volume %s\n",
+ skip_check ? "Sett" : "Clear", volume);
+
+ vtbl_rec = ubi->vtbl[vol->vol_id];
+ if (skip_check) {
+ vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
+ vol->skip_check = 1;
+ } else {
+ vtbl_rec.flags &= ~UBI_VTBL_SKIP_CRC_CHECK_FLG;
+ vol->skip_check = 0;
+ }
+
+ return ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
+}
+
static int ubi_detach(void)
{
#ifdef CONFIG_CMD_UBIFS
@@ -469,6 +497,7 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int64_t size = 0;
ulong addr = 0;
+ bool skipcheck = false;
if (argc < 2)
return CMD_RET_USAGE;
@@ -527,6 +556,12 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* Use maximum available size */
size = 0;
+ /* E.g., create volume with "skipcheck" bit set */
+ if (argc == 7) {
+ skipcheck = strncmp(argv[6], "--skipcheck", 11) == 0;
+ argc--;
+ }
+
/* E.g., create volume size type vol_id */
if (argc == 6) {
id = simple_strtoull(argv[5], NULL, 16);
@@ -555,8 +590,10 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("No size specified -> Using max size (%lld)\n", size);
}
/* E.g., create volume */
- if (argc == 3)
- return ubi_create_vol(argv[2], size, dynamic, id);
+ if (argc == 3) {
+ return ubi_create_vol(argv[2], size, dynamic, id,
+ skipcheck);
+ }
}
if (strncmp(argv[1], "remove", 6) == 0) {
@@ -565,6 +602,14 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return ubi_remove_vol(argv[2]);
}
+ if (strncmp(argv[1], "skipcheck", 9) == 0) {
+ /* E.g., change skip_check flag */
+ if (argc == 4) {
+ skipcheck = strncmp(argv[3], "on", 2) == 0;
+ return ubi_set_skip_check(argv[2], skipcheck);
+ }
+ }
+
if (strncmp(argv[1], "write", 5) == 0) {
int ret;
@@ -623,7 +668,7 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
U_BOOT_CMD(
- ubi, 6, 1, do_ubi,
+ ubi, 7, 1, do_ubi,
"ubi commands",
"detach"
" - detach ubi from a mtd partition\n"
@@ -634,7 +679,7 @@ U_BOOT_CMD(
" - Display volume and ubi layout information\n"
"ubi check volumename"
" - check if volumename exists\n"
- "ubi create[vol] volume [size] [type] [id]\n"
+ "ubi create[vol] volume [size] [type] [id] [--skipcheck]\n"
" - create volume name with size ('-' for maximum"
" available size)\n"
"ubi write[vol] address volume size"
@@ -645,6 +690,7 @@ U_BOOT_CMD(
" - Read volume to address with size\n"
"ubi remove[vol] volume"
" - Remove volume\n"
+ "ubi skipcheck volume on/off - Set or clear skip_check flag in volume header\n"
"[Legends]\n"
" volume: character name\n"
" size: specified in bytes\n"
diff --git a/doc/README.ubi b/doc/README.ubi
index 9efab6cdc9..c78a81795b 100644
--- a/doc/README.ubi
+++ b/doc/README.ubi
@@ -223,3 +223,36 @@ For example:
=> ubifsumount
Unmounting UBIFS volume recovery!
+
+
+Usage of the UBI CRC skip-check flag of static volumes:
+-------------------------------------------------------
+Some users of static UBI volumes implement their own integrity check,
+thus making the volume CRC check done at open time useless. For
+instance, this is the case when one use the ubiblock + dm-verity +
+squashfs combination, where dm-verity already checks integrity of the
+block device but this time at the block granularity instead of verifying
+the whole volume.
+
+Skipping this test drastically improves the boot-time.
+
+U-Boot now supports the "skip_check" flag to optionally skip the CRC
+check at open time.
+
+Usage: Case A - Upon UBI volume creation:
+You can optionally add "--skipcheck" to the "ubi create" command:
+
+ubi create[vol] volume [size] [type] [id] [--skipcheck]
+ - create volume name with size ('-' for maximum available size)
+
+Usage: Case B - With an already existing UBI volume:
+Use the "ubi skipcheck" command:
+
+ubi skipcheck volume on/off - Set or clear skip_check flag in volume header
+
+Example:
+=> ubi skipcheck rootfs0 on
+Setting skip_check on volume rootfs0
+
+BTW: This saves approx. 10 seconds Linux bootup time on a MT7688 based
+target with 128MiB of SPI NAND.
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 0a7427522c..f3d348da83 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -109,6 +109,7 @@ void ubi_dump_vol_info(const struct ubi_volume *vol)
printf("\tlast_eb_bytes %d\n", vol->last_eb_bytes);
printf("\tcorrupted %d\n", vol->corrupted);
printf("\tupd_marker %d\n", vol->upd_marker);
+ printf("\tskip_check %d\n", vol->skip_check);
if (vol->name_len <= UBI_VOL_NAME_MAX &&
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 2e171b0209..bcea71b1b2 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -196,7 +196,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
desc->mode = mode;
mutex_lock(&ubi->ckvol_mutex);
- if (!vol->checked) {
+ if (!vol->checked && !vol->skip_check) {
/* This is the first open - check the volume */
err = ubi_check_volume(ubi, vol_id);
if (err < 0) {
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index bd7a580961..4af85c4247 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -48,6 +48,11 @@ enum {
* Volume flags used in the volume table record.
*
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
+ * @UBI_VTBL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
+ * open time. Should only be set on volumes that
+ * are used by upper layers doing this kind of
+ * check. Main use-case for this flag is
+ * boot-time reduction
*
* %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
* table. UBI automatically re-sizes the volume which has this flag and makes
@@ -79,6 +84,7 @@ enum {
*/
enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01,
+ UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
};
/*
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 918d03590c..f44960186b 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -293,6 +293,9 @@ struct ubi_fm_pool {
* atomic LEB change
*
* @eba_tbl: EBA table of this volume (LEB->PEB mapping)
+ * @skip_check: %1 if CRC check of this static volume should be skipped.
+ * Directly reflects the presence of the
+ * %UBI_VTBL_SKIP_CRC_CHECK_FLG flag in the vtbl entry
* @checked: %1 if this static volume was checked
* @corrupted: %1 if the volume is corrupted (static volumes only)
* @upd_marker: %1 if the update marker is set for this volume
@@ -341,6 +344,7 @@ struct ubi_volume {
void *upd_buf;
int *eba_tbl;
+ unsigned int skip_check:1;
unsigned int checked:1;
unsigned int corrupted:1;
unsigned int upd_marker:1;
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 94c8a98d47..a2ff1b5769 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -162,6 +162,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
if (!vol)
return -ENOMEM;
+ if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
+ vol->skip_check = 1;
+
spin_lock(&ubi->volumes_lock);
if (vol_id == UBI_VOL_NUM_AUTO) {
/* Find unused volume ID */
@@ -295,6 +298,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vtbl_rec.vol_type = UBI_VID_DYNAMIC;
else
vtbl_rec.vol_type = UBI_VID_STATIC;
+
+ if (vol->skip_check)
+ vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
+
memcpy(vtbl_rec.name, vol->name, vol->name_len);
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
@@ -738,6 +745,11 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
ubi_err(ubi, "bad used_bytes");
goto fail;
}
+
+ if (vol->skip_check) {
+ ubi_err(ubi, "bad skip_check");
+ goto fail;
+ }
} else {
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
ubi_err(ubi, "bad used_ebs");
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index fe96d3a894..fb535c1a87 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -554,6 +554,9 @@ static int init_volumes(struct ubi_device *ubi,
vol->name[vol->name_len] = '\0';
vol->vol_id = i;
+ if (vtbl[i].flags & UBI_VTBL_SKIP_CRC_CHECK_FLG)
+ vol->skip_check = 1;
+
if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
/* Auto re-size flag may be set only for one volume */
if (ubi->autoresize_vol_id != -1) {
diff --git a/env/Kconfig b/env/Kconfig
index e4ba12ece3..bc03816bc8 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -516,6 +516,12 @@ config ENV_UBI_VOLUME_REDUND
help
Name of the redundant volume that you want to store the environment in.
+config ENV_UBI_IS_VOLUME_REDUND
+ bool
+ depends on ENV_IS_IN_UBI
+ default y if ENV_UBI_VOLUME_REDUND != ""
+ default n
+
config ENV_UBI_VID_OFFSET
int "ubi environment VID offset"
depends on ENV_IS_IN_UBI
diff --git a/include/env_internal.h b/include/env_internal.h
index b1ddcb5adf..88c36b32a1 100644
--- a/include/env_internal.h
+++ b/include/env_internal.h
@@ -101,7 +101,7 @@ extern unsigned long nand_env_oob_offset;
# ifndef CONFIG_ENV_UBI_VOLUME
# error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
# endif
-# if defined(CONFIG_ENV_UBI_VOLUME_REDUND)
+# if defined(CONFIG_ENV_UBI_IS_VOLUME_REDUND)
# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
# endif
# ifndef CONFIG_ENV_SIZE
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h
index cd81ef965c..8d472cc013 100644
--- a/include/mtd/ubi-user.h
+++ b/include/mtd/ubi-user.h
@@ -271,6 +271,20 @@ struct ubi_attach_req {
__s8 padding[10];
};
+/*
+ * UBI volume flags.
+ *
+ * @UBI_VOL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
+ * open time. Only valid for static volumes and
+ * should only be used if the volume user has a
+ * way to verify data integrity
+ */
+enum {
+ UBI_VOL_SKIP_CRC_CHECK_FLG = 0x1,
+};
+
+#define UBI_VOL_VALID_FLGS (UBI_VOL_SKIP_CRC_CHECK_FLG)
+
/**
* struct ubi_mkvol_req - volume description data structure used in
* volume creation requests.
@@ -278,7 +292,7 @@ struct ubi_attach_req {
* @alignment: volume alignment
* @bytes: volume size in bytes
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
- * @padding1: reserved for future, not used, has to be zeroed
+ * @flags: volume flags (%UBI_VOL_SKIP_CRC_CHECK_FLG)
* @name_len: volume name length
* @padding2: reserved for future, not used, has to be zeroed
* @name: volume name
@@ -307,7 +321,7 @@ struct ubi_mkvol_req {
__s32 alignment;
__s64 bytes;
__s8 vol_type;
- __s8 padding1;
+ __u8 flags;
__s16 name_len;
__s8 padding2[4];
char name[UBI_MAX_VOLUME_NAME + 1];