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
This commit is contained in:
Tom Rini 2019-10-17 07:26:16 -04:00
commit a2fce50455
11 changed files with 135 additions and 10 deletions

View File

@ -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"

View File

@ -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.

View File

@ -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) {

View File

@ -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) {

View File

@ -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,
};
/*

View File

@ -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;

View File

@ -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");

View File

@ -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) {

6
env/Kconfig vendored
View File

@ -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

View File

@ -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

View File

@ -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];