mirror of
https://xff.cz/git/u-boot/
synced 2025-09-04 10:12:14 +02:00
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
This commit is contained in:
58
cmd/ubi.c
58
cmd/ubi.c
@@ -146,7 +146,8 @@ bad:
|
|||||||
return err;
|
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;
|
struct ubi_mkvol_req req;
|
||||||
int err;
|
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);
|
strcpy(req.name, volume);
|
||||||
req.name_len = strlen(volume);
|
req.name_len = strlen(volume);
|
||||||
req.name[req.name_len] = '\0';
|
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 */
|
/* It's duplicated at drivers/mtd/ubi/cdev.c */
|
||||||
err = verify_mkvol_req(ubi, &req);
|
err = verify_mkvol_req(ubi, &req);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -415,6 +419,30 @@ static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset)
|
|||||||
return 0;
|
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)
|
static int ubi_detach(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CMD_UBIFS
|
#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;
|
int64_t size = 0;
|
||||||
ulong addr = 0;
|
ulong addr = 0;
|
||||||
|
bool skipcheck = false;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return CMD_RET_USAGE;
|
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 */
|
/* Use maximum available size */
|
||||||
size = 0;
|
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 */
|
/* E.g., create volume size type vol_id */
|
||||||
if (argc == 6) {
|
if (argc == 6) {
|
||||||
id = simple_strtoull(argv[5], NULL, 16);
|
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);
|
printf("No size specified -> Using max size (%lld)\n", size);
|
||||||
}
|
}
|
||||||
/* E.g., create volume */
|
/* E.g., create volume */
|
||||||
if (argc == 3)
|
if (argc == 3) {
|
||||||
return ubi_create_vol(argv[2], size, dynamic, id);
|
return ubi_create_vol(argv[2], size, dynamic, id,
|
||||||
|
skipcheck);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(argv[1], "remove", 6) == 0) {
|
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]);
|
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) {
|
if (strncmp(argv[1], "write", 5) == 0) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -623,7 +668,7 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
ubi, 6, 1, do_ubi,
|
ubi, 7, 1, do_ubi,
|
||||||
"ubi commands",
|
"ubi commands",
|
||||||
"detach"
|
"detach"
|
||||||
" - detach ubi from a mtd partition\n"
|
" - detach ubi from a mtd partition\n"
|
||||||
@@ -634,7 +679,7 @@ U_BOOT_CMD(
|
|||||||
" - Display volume and ubi layout information\n"
|
" - Display volume and ubi layout information\n"
|
||||||
"ubi check volumename"
|
"ubi check volumename"
|
||||||
" - check if volumename exists\n"
|
" - 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"
|
" - create volume name with size ('-' for maximum"
|
||||||
" available size)\n"
|
" available size)\n"
|
||||||
"ubi write[vol] address volume size"
|
"ubi write[vol] address volume size"
|
||||||
@@ -645,6 +690,7 @@ U_BOOT_CMD(
|
|||||||
" - Read volume to address with size\n"
|
" - Read volume to address with size\n"
|
||||||
"ubi remove[vol] volume"
|
"ubi remove[vol] volume"
|
||||||
" - Remove volume\n"
|
" - Remove volume\n"
|
||||||
|
"ubi skipcheck volume on/off - Set or clear skip_check flag in volume header\n"
|
||||||
"[Legends]\n"
|
"[Legends]\n"
|
||||||
" volume: character name\n"
|
" volume: character name\n"
|
||||||
" size: specified in bytes\n"
|
" size: specified in bytes\n"
|
||||||
|
@@ -223,3 +223,36 @@ For example:
|
|||||||
|
|
||||||
=> ubifsumount
|
=> ubifsumount
|
||||||
Unmounting UBIFS volume recovery!
|
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.
|
||||||
|
@@ -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("\tlast_eb_bytes %d\n", vol->last_eb_bytes);
|
||||||
printf("\tcorrupted %d\n", vol->corrupted);
|
printf("\tcorrupted %d\n", vol->corrupted);
|
||||||
printf("\tupd_marker %d\n", vol->upd_marker);
|
printf("\tupd_marker %d\n", vol->upd_marker);
|
||||||
|
printf("\tskip_check %d\n", vol->skip_check);
|
||||||
|
|
||||||
if (vol->name_len <= UBI_VOL_NAME_MAX &&
|
if (vol->name_len <= UBI_VOL_NAME_MAX &&
|
||||||
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
|
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
|
||||||
|
@@ -196,7 +196,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
|
|||||||
desc->mode = mode;
|
desc->mode = mode;
|
||||||
|
|
||||||
mutex_lock(&ubi->ckvol_mutex);
|
mutex_lock(&ubi->ckvol_mutex);
|
||||||
if (!vol->checked) {
|
if (!vol->checked && !vol->skip_check) {
|
||||||
/* This is the first open - check the volume */
|
/* This is the first open - check the volume */
|
||||||
err = ubi_check_volume(ubi, vol_id);
|
err = ubi_check_volume(ubi, vol_id);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@@ -48,6 +48,11 @@ enum {
|
|||||||
* Volume flags used in the volume table record.
|
* Volume flags used in the volume table record.
|
||||||
*
|
*
|
||||||
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
|
* @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
|
* %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
|
* table. UBI automatically re-sizes the volume which has this flag and makes
|
||||||
@@ -79,6 +84,7 @@ enum {
|
|||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
UBI_VTBL_AUTORESIZE_FLG = 0x01,
|
UBI_VTBL_AUTORESIZE_FLG = 0x01,
|
||||||
|
UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -293,6 +293,9 @@ struct ubi_fm_pool {
|
|||||||
* atomic LEB change
|
* atomic LEB change
|
||||||
*
|
*
|
||||||
* @eba_tbl: EBA table of this volume (LEB->PEB mapping)
|
* @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
|
* @checked: %1 if this static volume was checked
|
||||||
* @corrupted: %1 if the volume is corrupted (static volumes only)
|
* @corrupted: %1 if the volume is corrupted (static volumes only)
|
||||||
* @upd_marker: %1 if the update marker is set for this volume
|
* @upd_marker: %1 if the update marker is set for this volume
|
||||||
@@ -341,6 +344,7 @@ struct ubi_volume {
|
|||||||
void *upd_buf;
|
void *upd_buf;
|
||||||
|
|
||||||
int *eba_tbl;
|
int *eba_tbl;
|
||||||
|
unsigned int skip_check:1;
|
||||||
unsigned int checked:1;
|
unsigned int checked:1;
|
||||||
unsigned int corrupted:1;
|
unsigned int corrupted:1;
|
||||||
unsigned int upd_marker:1;
|
unsigned int upd_marker:1;
|
||||||
|
@@ -162,6 +162,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
|||||||
if (!vol)
|
if (!vol)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
|
||||||
|
vol->skip_check = 1;
|
||||||
|
|
||||||
spin_lock(&ubi->volumes_lock);
|
spin_lock(&ubi->volumes_lock);
|
||||||
if (vol_id == UBI_VOL_NUM_AUTO) {
|
if (vol_id == UBI_VOL_NUM_AUTO) {
|
||||||
/* Find unused volume ID */
|
/* 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;
|
vtbl_rec.vol_type = UBI_VID_DYNAMIC;
|
||||||
else
|
else
|
||||||
vtbl_rec.vol_type = UBI_VID_STATIC;
|
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);
|
memcpy(vtbl_rec.name, vol->name, vol->name_len);
|
||||||
|
|
||||||
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
|
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");
|
ubi_err(ubi, "bad used_bytes");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vol->skip_check) {
|
||||||
|
ubi_err(ubi, "bad skip_check");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
|
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
|
||||||
ubi_err(ubi, "bad used_ebs");
|
ubi_err(ubi, "bad used_ebs");
|
||||||
|
@@ -554,6 +554,9 @@ static int init_volumes(struct ubi_device *ubi,
|
|||||||
vol->name[vol->name_len] = '\0';
|
vol->name[vol->name_len] = '\0';
|
||||||
vol->vol_id = i;
|
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) {
|
if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
|
||||||
/* Auto re-size flag may be set only for one volume */
|
/* Auto re-size flag may be set only for one volume */
|
||||||
if (ubi->autoresize_vol_id != -1) {
|
if (ubi->autoresize_vol_id != -1) {
|
||||||
|
6
env/Kconfig
vendored
6
env/Kconfig
vendored
@@ -516,6 +516,12 @@ config ENV_UBI_VOLUME_REDUND
|
|||||||
help
|
help
|
||||||
Name of the redundant volume that you want to store the environment in.
|
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
|
config ENV_UBI_VID_OFFSET
|
||||||
int "ubi environment VID offset"
|
int "ubi environment VID offset"
|
||||||
depends on ENV_IS_IN_UBI
|
depends on ENV_IS_IN_UBI
|
||||||
|
@@ -101,7 +101,7 @@ extern unsigned long nand_env_oob_offset;
|
|||||||
# ifndef CONFIG_ENV_UBI_VOLUME
|
# ifndef CONFIG_ENV_UBI_VOLUME
|
||||||
# error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
|
# error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
|
||||||
# endif
|
# endif
|
||||||
# if defined(CONFIG_ENV_UBI_VOLUME_REDUND)
|
# if defined(CONFIG_ENV_UBI_IS_VOLUME_REDUND)
|
||||||
# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
|
# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
|
||||||
# endif
|
# endif
|
||||||
# ifndef CONFIG_ENV_SIZE
|
# ifndef CONFIG_ENV_SIZE
|
||||||
|
@@ -271,6 +271,20 @@ struct ubi_attach_req {
|
|||||||
__s8 padding[10];
|
__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
|
* struct ubi_mkvol_req - volume description data structure used in
|
||||||
* volume creation requests.
|
* volume creation requests.
|
||||||
@@ -278,7 +292,7 @@ struct ubi_attach_req {
|
|||||||
* @alignment: volume alignment
|
* @alignment: volume alignment
|
||||||
* @bytes: volume size in bytes
|
* @bytes: volume size in bytes
|
||||||
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
|
* @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
|
* @name_len: volume name length
|
||||||
* @padding2: reserved for future, not used, has to be zeroed
|
* @padding2: reserved for future, not used, has to be zeroed
|
||||||
* @name: volume name
|
* @name: volume name
|
||||||
@@ -307,7 +321,7 @@ struct ubi_mkvol_req {
|
|||||||
__s32 alignment;
|
__s32 alignment;
|
||||||
__s64 bytes;
|
__s64 bytes;
|
||||||
__s8 vol_type;
|
__s8 vol_type;
|
||||||
__s8 padding1;
|
__u8 flags;
|
||||||
__s16 name_len;
|
__s16 name_len;
|
||||||
__s8 padding2[4];
|
__s8 padding2[4];
|
||||||
char name[UBI_MAX_VOLUME_NAME + 1];
|
char name[UBI_MAX_VOLUME_NAME + 1];
|
||||||
|
Reference in New Issue
Block a user