From 386f20cade50ed36674e3e5827cb282eb1da95c2 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Thu, 12 Sep 2019 16:41:01 +0200 Subject: ubi: provide a way to skip CRC checks 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. Adapted to U-Boot by Stefan Roese. Signed-off-by: Quentin Schulz Signed-off-by: Stefan Roese Reviewed-by: Heiko Schocher Cc: Quentin Schulz Cc: Boris Brezillon --- cmd/ubi.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'cmd') diff --git a/cmd/ubi.c b/cmd/ubi.c index ca5dc90..c857f07 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) { @@ -469,6 +473,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 +532,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 +566,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) { @@ -623,7 +636,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 +647,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" -- cgit v1.1 From e6661cf767ce644e6ff835537449979859060c5b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 17 Sep 2019 09:17:53 +0200 Subject: ubi: Add "skipcheck" command to set/clear this bit in the UBI volume hdr U-Boot now supports the "skip_check" flag to optionally skip the CRC check at open time. Currently its only possible to set this bit upon UBI volume creation. But it might be very useful to also set this bit on already installed systems (e.g. field upgrade) to make also use of the boot-time decrease on those systems. This patch now adds a new "ubi" command "ubi skipcheck" to set or clear this bit in the UBI volume header: => 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. Signed-off-by: Stefan Roese Reviewed-by: Heiko Schocher Cc: Quentin Schulz Cc: Boris Brezillon Cc: Heiko Schocher Cc: Andreas Dannenberg --- cmd/ubi.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'cmd') diff --git a/cmd/ubi.c b/cmd/ubi.c index c857f07..22ba5b1 100644 --- a/cmd/ubi.c +++ b/cmd/ubi.c @@ -419,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 @@ -578,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; @@ -658,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" -- cgit v1.1