Merge tag 'u-boot-dfu-next-20241126' of https://source.denx.de/u-boot/custodians/u-boot-dfu into next

CI: https://source.denx.de/u-boot/custodians/u-boot-dfu/-/pipelines/23573

Android:
- bootstd: Implement bootimage v2 support
- bootstd: Support non-A/B in bootmeth_android
- Migrate VIM3 and VIM3L to use bootmeth_android
- bootstd: Additional test for bootimage v2
- bootstd: Optimize load time when reading partitions
This commit is contained in:
Tom Rini
2024-11-26 10:50:05 -06:00
16 changed files with 297 additions and 51 deletions
+9 -1
View File
@@ -44,6 +44,7 @@
mmc5 = "/mmc5";
mmc6 = "/mmc6";
mmc7 = "/mmc7";
mmc8 = "/mmc8";
pci0 = &pci0;
pci1 = &pci1;
pci2 = &pci2;
@@ -1138,13 +1139,20 @@
filename = "mmc6.img";
};
/* This is used for Android tests */
/* This is used for Android boot image v4 tests */
mmc7 {
status = "disabled";
compatible = "sandbox,mmc";
filename = "mmc7.img";
};
/* This is used for Android boot image v2 tests. */
mmc8 {
status = "disabled";
compatible = "sandbox,mmc";
filename = "mmc8.img";
};
pch {
compatible = "sandbox,pch";
};
-1
View File
@@ -500,7 +500,6 @@ config BOOTMETH_ANDROID
bool "Bootdev support for Android"
depends on X86 || ARM || SANDBOX
depends on CMDLINE
select ANDROID_AB
select ANDROID_BOOT_IMAGE
select CMD_BCB
imply CMD_FASTBOOT
+76 -28
View File
@@ -29,6 +29,7 @@
#define BCB_PART_NAME "misc"
#define BOOT_PART_NAME "boot"
#define VENDOR_BOOT_PART_NAME "vendor_boot"
#define SLOT_LEN 2
/**
* struct android_priv - Private data
@@ -42,8 +43,10 @@
*/
struct android_priv {
enum android_boot_mode boot_mode;
char slot[2];
char *slot;
u32 header_version;
u32 boot_img_size;
u32 vendor_boot_img_size;
};
static int android_check(struct udevice *dev, struct bootflow_iter *iter)
@@ -71,7 +74,11 @@ static int scan_boot_part(struct udevice *blk, struct android_priv *priv)
char *buf;
int ret;
sprintf(partname, BOOT_PART_NAME "_%s", priv->slot);
if (priv->slot)
sprintf(partname, BOOT_PART_NAME "_%s", priv->slot);
else
sprintf(partname, BOOT_PART_NAME);
ret = part_get_info_by_name(desc, partname, &partition);
if (ret < 0)
return log_msg_ret("part info", ret);
@@ -93,7 +100,13 @@ static int scan_boot_part(struct udevice *blk, struct android_priv *priv)
return log_msg_ret("header", -ENOENT);
}
if (!android_image_get_bootimg_size(buf, &priv->boot_img_size)) {
free(buf);
return log_msg_ret("get bootimg size", -EINVAL);
}
priv->header_version = ((struct andr_boot_img_hdr_v0 *)buf)->header_version;
free(buf);
return 0;
@@ -108,7 +121,11 @@ static int scan_vendor_boot_part(struct udevice *blk, struct android_priv *priv)
char *buf;
int ret;
sprintf(partname, VENDOR_BOOT_PART_NAME "_%s", priv->slot);
if (priv->slot)
sprintf(partname, VENDOR_BOOT_PART_NAME "_%s", priv->slot);
else
sprintf(partname, VENDOR_BOOT_PART_NAME);
ret = part_get_info_by_name(desc, partname, &partition);
if (ret < 0)
return log_msg_ret("part info", ret);
@@ -129,6 +146,12 @@ static int scan_vendor_boot_part(struct udevice *blk, struct android_priv *priv)
free(buf);
return log_msg_ret("header", -ENOENT);
}
if (!android_image_get_vendor_bootimg_size(buf, &priv->vendor_boot_img_size)) {
free(buf);
return log_msg_ret("get vendor bootimg size", -EINVAL);
}
free(buf);
return 0;
@@ -142,6 +165,11 @@ static int android_read_slot_from_bcb(struct bootflow *bflow, bool decrement)
char slot_suffix[3];
int ret;
if (!CONFIG_IS_ENABLED(ANDROID_AB)) {
priv->slot = NULL;
return 0;
}
ret = part_get_info_by_name(desc, BCB_PART_NAME, &misc);
if (ret < 0)
return log_msg_ret("part", ret);
@@ -150,6 +178,7 @@ static int android_read_slot_from_bcb(struct bootflow *bflow, bool decrement)
if (ret < 0)
return log_msg_ret("slot", ret);
priv->slot = malloc(SLOT_LEN);
priv->slot[0] = BOOT_SLOT_NAME(ret);
priv->slot[1] = '\0';
@@ -259,16 +288,12 @@ static int android_read_bootflow(struct udevice *dev, struct bootflow *bflow)
goto free_priv;
}
if (priv->header_version != 4) {
log_debug("only boot.img v4 is supported %u\n", priv->header_version);
ret = -EINVAL;
goto free_priv;
}
ret = scan_vendor_boot_part(bflow->blk, priv);
if (ret < 0) {
log_debug("scan vendor_boot failed: err=%d\n", ret);
goto free_priv;
if (priv->header_version >= 3) {
ret = scan_vendor_boot_part(bflow->blk, priv);
if (ret < 0) {
log_debug("scan vendor_boot failed: err=%d\n", ret);
goto free_priv;
}
}
/*
@@ -278,7 +303,7 @@ static int android_read_bootflow(struct udevice *dev, struct bootflow *bflow)
configure_serialno(bflow);
configure_bootloader_version(bflow);
if (priv->boot_mode == ANDROID_BOOT_MODE_NORMAL) {
if (priv->boot_mode == ANDROID_BOOT_MODE_NORMAL && priv->slot) {
ret = bootflow_cmdline_set_arg(bflow, "androidboot.force_normal_boot",
"1", false);
if (ret < 0) {
@@ -319,28 +344,44 @@ static int android_read_file(struct udevice *dev, struct bootflow *bflow,
* @blk: Block device to read
* @name: Partition name to read
* @slot: Nul-terminated slot suffixed to partition name ("a\0" or "b\0")
* @image_size: Image size in bytes used when reading the partition
* @addr: Address where the partition content is loaded into
* Return: 0 if OK, negative errno on failure.
*/
static int read_slotted_partition(struct blk_desc *desc, const char *const name,
const char slot[2], ulong addr)
const char slot[2], ulong image_size, ulong addr)
{
struct disk_partition partition;
char partname[PART_NAME_LEN];
size_t partname_len;
ulong num_blks = DIV_ROUND_UP(image_size, desc->blksz);
int ret;
u32 n;
/* Ensure name fits in partname it should be: <name>_<slot>\0 */
if (strlen(name) > (PART_NAME_LEN - 2 - 1))
/*
* Ensure name fits in partname.
* For A/B, it should be <name>_<slot>\0
* For non A/B, it should be <name>\0
*/
if (CONFIG_IS_ENABLED(ANDROID_AB))
partname_len = PART_NAME_LEN - 2 - 1;
else
partname_len = PART_NAME_LEN - 1;
if (strlen(name) > partname_len)
return log_msg_ret("name too long", -EINVAL);
sprintf(partname, "%s_%s", name, slot);
if (slot)
sprintf(partname, "%s_%s", name, slot);
else
sprintf(partname, "%s", name);
ret = part_get_info_by_name(desc, partname, &partition);
if (ret < 0)
return log_msg_ret("part", ret);
n = blk_dread(desc, partition.start, partition.size, map_sysmem(addr, 0));
if (n < partition.size)
n = blk_dread(desc, partition.start, num_blks, map_sysmem(addr, 0));
if (n < num_blks)
return log_msg_ret("part read", -EIO);
return 0;
@@ -386,7 +427,7 @@ static int run_avb_verification(struct bootflow *bflow)
AvbSlotVerifyData *out_data;
enum avb_boot_state boot_state;
char *extra_args;
char slot_suffix[3];
char slot_suffix[3] = "";
bool unlocked = false;
int ret;
@@ -394,7 +435,8 @@ static int run_avb_verification(struct bootflow *bflow)
if (!avb_ops)
return log_msg_ret("avb ops", -ENOMEM);
sprintf(slot_suffix, "_%s", priv->slot);
if (priv->slot)
sprintf(slot_suffix, "_%s", priv->slot);
ret = avb_ops->read_is_device_unlocked(avb_ops, &unlocked);
if (ret != AVB_IO_RESULT_OK)
@@ -472,16 +514,22 @@ static int boot_android_normal(struct bootflow *bflow)
if (ret < 0)
return log_msg_ret("read slot", ret);
ret = read_slotted_partition(desc, "boot", priv->slot, loadaddr);
ret = read_slotted_partition(desc, "boot", priv->slot, priv->boot_img_size,
loadaddr);
if (ret < 0)
return log_msg_ret("read boot", ret);
ret = read_slotted_partition(desc, "vendor_boot", priv->slot, vloadaddr);
if (ret < 0)
return log_msg_ret("read vendor_boot", ret);
if (priv->header_version >= 3) {
ret = read_slotted_partition(desc, "vendor_boot", priv->slot,
priv->vendor_boot_img_size, vloadaddr);
if (ret < 0)
return log_msg_ret("read vendor_boot", ret);
set_avendor_bootimg_addr(vloadaddr);
}
set_abootimg_addr(loadaddr);
set_avendor_bootimg_addr(vloadaddr);
if (priv->slot)
free(priv->slot);
ret = bootm_boot_start(loadaddr, bflow->cmdline);
+45
View File
@@ -178,6 +178,51 @@ static void android_boot_image_v0_v1_v2_parse_hdr(const struct andr_boot_img_hdr
data->boot_img_total_size = end - (ulong)hdr;
}
bool android_image_get_bootimg_size(const void *hdr, u32 *boot_img_size)
{
struct andr_image_data data;
if (!hdr || !boot_img_size) {
printf("hdr or boot_img_size can't be NULL\n");
return false;
}
if (!is_android_boot_image_header(hdr)) {
printf("Incorrect boot image header\n");
return false;
}
if (((struct andr_boot_img_hdr_v0 *)hdr)->header_version <= 2)
android_boot_image_v0_v1_v2_parse_hdr(hdr, &data);
else
android_boot_image_v3_v4_parse_hdr(hdr, &data);
*boot_img_size = data.boot_img_total_size;
return true;
}
bool android_image_get_vendor_bootimg_size(const void *hdr, u32 *vendor_boot_img_size)
{
struct andr_image_data data;
if (!hdr || !vendor_boot_img_size) {
printf("hdr or vendor_boot_img_size can't be NULL\n");
return false;
}
if (!is_android_vendor_boot_image_header(hdr)) {
printf("Incorrect vendor boot image header\n");
return false;
}
android_vendor_boot_image_v3_v4_parse_hdr(hdr, &data);
*vendor_boot_img_size = data.vendor_boot_img_total_size;
return true;
}
bool android_image_get_data(const void *boot_hdr, const void *vendor_boot_hdr,
struct andr_image_data *data)
{
+1
View File
@@ -11,6 +11,7 @@ CONFIG_RANDOM_UUID=y # Needed for FASTBOOT_CMD_OEM_FORMAT
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
# Enable Android boot flow
CONFIG_BOOTMETH_ANDROID=y
CONFIG_ANDROID_AB=y
CONFIG_SYS_BOOTM_LEN=0x4000000
CONFIG_SYS_MALLOC_LEN=0x08000000
CONFIG_AVB_VERIFY=y
+6 -1
View File
@@ -24,6 +24,12 @@ CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTMETH_ANDROID=y
# CONFIG_BOOTMETH_EXTLINUX is not set
# CONFIG_BOOTMETH_EXTLINUX_PXE is not set
# CONFIG_BOOTMETH_EFILOADER is not set
# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
# CONFIG_BOOTMETH_VBE is not set
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
# CONFIG_DISPLAY_CPUINFO is not set
@@ -35,7 +41,6 @@ CONFIG_SYS_MAXARGS=32
CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y
# CONFIG_CMD_IMI is not set
CONFIG_CMD_BCB=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
+6 -1
View File
@@ -24,6 +24,12 @@ CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTMETH_ANDROID=y
# CONFIG_BOOTMETH_EXTLINUX is not set
# CONFIG_BOOTMETH_EXTLINUX_PXE is not set
# CONFIG_BOOTMETH_EFILOADER is not set
# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
# CONFIG_BOOTMETH_VBE is not set
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
# CONFIG_DISPLAY_CPUINFO is not set
@@ -34,7 +40,6 @@ CONFIG_SYS_MAXARGS=32
CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y
# CONFIG_CMD_IMI is not set
CONFIG_CMD_BCB=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
+6 -1
View File
@@ -24,6 +24,12 @@ CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTMETH_ANDROID=y
# CONFIG_BOOTMETH_EXTLINUX is not set
# CONFIG_BOOTMETH_EXTLINUX_PXE is not set
# CONFIG_BOOTMETH_EFILOADER is not set
# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
# CONFIG_BOOTMETH_VBE is not set
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
# CONFIG_DISPLAY_CPUINFO is not set
@@ -35,7 +41,6 @@ CONFIG_SYS_MAXARGS=32
CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y
# CONFIG_CMD_IMI is not set
CONFIG_CMD_BCB=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
+6 -1
View File
@@ -24,6 +24,12 @@ CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTMETH_ANDROID=y
# CONFIG_BOOTMETH_EXTLINUX is not set
# CONFIG_BOOTMETH_EXTLINUX_PXE is not set
# CONFIG_BOOTMETH_EFILOADER is not set
# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
# CONFIG_BOOTMETH_VBE is not set
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
# CONFIG_DISPLAY_CPUINFO is not set
@@ -34,7 +40,6 @@ CONFIG_SYS_MAXARGS=32
CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y
# CONFIG_CMD_IMI is not set
CONFIG_CMD_BCB=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
+1
View File
@@ -50,6 +50,7 @@ CONFIG_LOG_DEFAULT_LEVEL=6
CONFIG_LOGF_FUNC=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_STACKPROTECTOR=y
CONFIG_ANDROID_AB=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_SMBIOS=y
+21 -4
View File
@@ -41,10 +41,27 @@
"name=rootfs,size=-,uuid=" ROOT_UUID
#endif
#define EXTRA_ANDROID_ENV_SETTINGS \
"board=vim3\0" \
"board_name=vim3\0" \
#define CFG_EXTRA_ENV_SETTINGS \
"board=vim3\0" \
"board_name=vim3\0" \
"bootmeths=android\0" \
"bootcmd=bootflow scan\0" \
"adtb_idx=3\0" \
"partitions=" PARTS_DEFAULT "\0" \
"mmcdev=2\0" \
"fastboot_raw_partition_bootloader=0x1 0xfff mmcpart 1\0" \
"fastboot_raw_partition_bootenv=0x0 0xfff mmcpart 2\0" \
"stdin=" STDIN_CFG "\0" \
"stdout=" STDOUT_CFG "\0" \
"stderr=" STDOUT_CFG "\0" \
"dtboaddr=0x08200000\0" \
"loadaddr=0x01080000\0" \
"fdt_addr_r=0x01000000\0" \
"scriptaddr=0x08000000\0" \
"kernel_addr_r=0x01080000\0" \
"pxefile_addr_r=0x01080000\0" \
"ramdisk_addr_r=0x13000000\0" \
#include <configs/meson64_android.h>
#include <configs/meson64.h>
#endif /* __CONFIG_H */
+21 -4
View File
@@ -41,10 +41,27 @@
"name=rootfs,size=-,uuid=" ROOT_UUID
#endif
#define EXTRA_ANDROID_ENV_SETTINGS \
"board=vim3l\0" \
"board_name=vim3l\0" \
#define CFG_EXTRA_ENV_SETTINGS \
"board=vim3l\0" \
"board_name=vim3l\0" \
"bootmeths=android\0" \
"bootcmd=bootflow scan\0" \
"adtb_idx=2\0" \
"partitions=" PARTS_DEFAULT "\0" \
"mmcdev=2\0" \
"fastboot_raw_partition_bootloader=0x1 0xfff mmcpart 1\0" \
"fastboot_raw_partition_bootenv=0x0 0xfff mmcpart 2\0" \
"stdin=" STDIN_CFG "\0" \
"stdout=" STDOUT_CFG "\0" \
"stderr=" STDOUT_CFG "\0" \
"dtboaddr=0x08200000\0" \
"loadaddr=0x01080000\0" \
"fdt_addr_r=0x01000000\0" \
"scriptaddr=0x08000000\0" \
"kernel_addr_r=0x01080000\0" \
"pxefile_addr_r=0x01080000\0" \
"ramdisk_addr_r=0x13000000\0" \
#include <configs/meson64_android.h>
#include <configs/meson64.h>
#endif /* __CONFIG_H */
-6
View File
@@ -104,12 +104,6 @@
"elif test $board_name = sei610; then " \
"echo \" Reading DTB for sei610...\"; " \
"setenv dtb_index 1;" \
"elif test $board_name = vim3l; then " \
"echo \" Reading DTB for vim3l...\"; " \
"setenv dtb_index 2;" \
"elif test $board_name = vim3; then " \
"echo \" Reading DTB for vim3...\"; " \
"setenv dtb_index 3;" \
"else " \
"echo Error: Android boot is not supported for $board_name; " \
"exit; " \
+24
View File
@@ -1801,6 +1801,30 @@ int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo);
struct cipher_algo *image_get_cipher_algo(const char *full_name);
struct andr_image_data;
/**
* android_image_get_bootimg_size() - Extract size of Android boot image
*
* This is used to extract the size of an Android boot image
* from boot image header.
*
* @hdr: Pointer to boot image header
* @boot_img_size: On exit returns the size in bytes of the boot image
* Return: true if succeeded, false otherwise
*/
bool android_image_get_bootimg_size(const void *hdr, u32 *boot_img_size);
/**
* android_image_get_vendor_bootimg_size() - Extract size of Android vendor-boot image
*
* This is used to extract the size of an Android vendor-boot image
* from vendor-boot image header.
*
* @hdr: Pointer to vendor-boot image header
* @vendor_boot_img_size: On exit returns the size in bytes of the vendor-boot image
* Return: true if succeeded, false otherwise
*/
bool android_image_get_vendor_bootimg_size(const void *hdr, u32 *vendor_boot_img_size);
/**
* android_image_get_data() - Parse Android boot images
*
+26 -3
View File
@@ -1199,8 +1199,8 @@ static int bootflow_cros(struct unit_test_state *uts)
}
BOOTSTD_TEST(bootflow_cros, UTF_CONSOLE | UTF_DM | UTF_SCAN_FDT);
/* Test Android bootmeth */
static int bootflow_android(struct unit_test_state *uts)
/* Test Android bootmeth with boot image version 4 */
static int bootflow_android_image_v4(struct unit_test_state *uts)
{
if (!IS_ENABLED(CONFIG_BOOTMETH_ANDROID))
return -EAGAIN;
@@ -1220,7 +1220,30 @@ static int bootflow_android(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootflow_android, UTF_CONSOLE | UTF_DM | UTF_SCAN_FDT);
BOOTSTD_TEST(bootflow_android_image_v4, UTF_CONSOLE | UTF_DM | UTF_SCAN_FDT);
/* Test Android bootmeth with boot image version 2 */
static int bootflow_android_image_v2(struct unit_test_state *uts)
{
if (!IS_ENABLED(CONFIG_BOOTMETH_ANDROID))
return -EAGAIN;
ut_assertok(scan_mmc_android_bootdev(uts, "mmc8"));
ut_assertok(run_command("bootflow list", 0));
ut_assert_nextlinen("Showing all");
ut_assert_nextlinen("Seq");
ut_assert_nextlinen("---");
ut_assert_nextlinen(" 0 extlinux");
ut_assert_nextlinen(" 1 android ready mmc 0 mmc8.bootdev.whole ");
ut_assert_nextlinen("---");
ut_assert_skip_to_line("(2 bootflows, 2 valid)");
ut_assert_console_end();
return 0;
}
BOOTSTD_TEST(bootflow_android_image_v2, UTF_CONSOLE | UTF_DM | UTF_SCAN_FDT);
/* Test EFI bootmeth */
static int bootflow_efi(struct unit_test_state *uts)
+49
View File
@@ -501,6 +501,55 @@ def setup_android_image(cons):
print(f'wrote to {fname}')
mmc_dev = 8
fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img')
u_boot_utils.run_and_log(cons, f'qemu-img create {fname} 20M')
u_boot_utils.run_and_log(cons, f'cgpt create {fname}')
ptr = 40
# Number of sectors in 1MB
sect_size = 512
sect_1mb = (1 << 20) // sect_size
required_parts = [
{'num': 1, 'label':'misc', 'size': '1M'},
{'num': 2, 'label':'boot_a', 'size': '4M'},
{'num': 3, 'label':'boot_b', 'size': '4M'},
]
for part in required_parts:
size_str = part['size']
if 'M' in size_str:
size = int(size_str[:-1]) * sect_1mb
else:
size = int(size_str)
u_boot_utils.run_and_log(
cons,
f"cgpt add -i {part['num']} -b {ptr} -s {size} -l {part['label']} -t basicdata {fname}")
ptr += size
u_boot_utils.run_and_log(cons, f'cgpt boot -p {fname}')
out = u_boot_utils.run_and_log(cons, f'cgpt show -q {fname}')
# Create a dict (indexed by partition number) containing the above info
for line in out.splitlines():
start, size, num, name = line.split(maxsplit=3)
parts[int(num)] = Partition(int(start), int(size), name)
with open(fname, 'rb') as inf:
disk_data = inf.read()
test_abootimg.AbootimgTestDiskImage(cons, 'boot.img', test_abootimg.img_hex)
boot_img = os.path.join(cons.config.result_dir, 'boot.img')
with open(boot_img, 'rb') as inf:
set_part_data(2, inf.read())
with open(fname, 'wb') as outf:
outf.write(disk_data)
print(f'wrote to {fname}')
return fname
def setup_cedit_file(cons):