diff options
Diffstat (limited to 'commands')
-rw-r--r-- | commands/Kconfig | 11 | ||||
-rw-r--r-- | commands/Makefile | 2 | ||||
-rw-r--r-- | commands/boot.c | 258 | ||||
-rw-r--r-- | commands/bootm.c | 85 | ||||
-rw-r--r-- | commands/crc.c | 20 | ||||
-rw-r--r-- | commands/devinfo.c | 158 | ||||
-rw-r--r-- | commands/loadb.c | 22 | ||||
-rw-r--r-- | commands/loads.c | 7 | ||||
-rw-r--r-- | commands/loadxy.c | 24 | ||||
-rw-r--r-- | commands/login.c | 24 | ||||
-rw-r--r-- | commands/passwd.c | 8 | ||||
-rw-r--r-- | commands/ubi.c | 20 |
12 files changed, 512 insertions, 127 deletions
diff --git a/commands/Kconfig b/commands/Kconfig index 55e46a0392..9738ec4630 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -514,6 +514,17 @@ config CMD_LINUX16 Compile the linux16 command to be able to boot bzImages via real mode. +config CMD_BOOT + tristate + select BOOTM + prompt "boot" + help + Select this for booting based on scripts. unlike the bootm command which + can boot a single image this command offers the possibility to boot with + scripts (by default placed under /env/boot/). This command iterates over + multiple scripts until one succeeds. It supersedes the previous 'boot' + script. + config CMD_RESET tristate prompt "reset" diff --git a/commands/Makefile b/commands/Makefile index 6acffc8284..58d27fa905 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -91,3 +91,5 @@ obj-$(CONFIG_CMD_FILETYPE) += filetype.o obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o obj-$(CONFIG_CMD_MIITOOL) += miitool.o obj-$(CONFIG_CMD_DETECT) += detect.o +obj-$(CONFIG_CMD_BOOT) += boot.o +obj-$(CONFIG_CMD_DEVINFO) += devinfo.o diff --git a/commands/boot.c b/commands/boot.c new file mode 100644 index 0000000000..33d1177861 --- /dev/null +++ b/commands/boot.c @@ -0,0 +1,258 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <environment.h> +#include <globalvar.h> +#include <magicvar.h> +#include <command.h> +#include <common.h> +#include <getopt.h> +#include <libgen.h> +#include <malloc.h> +#include <boot.h> +#include <fs.h> + +#include <linux/stat.h> + +static int verbose; +static int dryrun; + +static void bootsources_list(void) +{ + DIR *dir; + struct dirent *d; + const char *path = "/env/boot"; + + dir = opendir(path); + if (!dir) { + printf("cannot open %s: %s\n", path, strerror(-errno)); + return; + } + + printf("Bootsources: "); + + while ((d = readdir(dir))) { + if (*d->d_name == '.') + continue; + + printf("%s ", d->d_name); + } + + printf("\n"); + + closedir(dir); +} + +static const char *getenv_or_null(const char *var) +{ + const char *val = getenv(var); + + if (val && *val) + return val; + return NULL; +} + +/* + * Start a single boot script. 'path' is a full path to a boot script. + */ +static int boot_script(char *path) +{ + struct bootm_data data = {}; + int ret; + + printf("booting %s...\n", basename(path)); + + globalvar_set_match("linux.bootargs.dyn.", ""); + globalvar_set_match("bootm.", ""); + + ret = run_command(path, 0); + if (ret) { + printf("Running %s failed\n", path); + goto out; + } + + data.initrd_address = UIMAGE_INVALID_ADDRESS; + data.os_address = UIMAGE_SOME_ADDRESS; + data.oftree_file = getenv_or_null("global.bootm.oftree"); + data.os_file = getenv_or_null("global.bootm.image"); + getenv_ul("global.bootm.image.loadaddr", &data.os_address); + getenv_ul("global.bootm.initrd.loadaddr", &data.initrd_address); + data.initrd_file = getenv_or_null("global.bootm.initrd"); + data.verbose = verbose; + data.dryrun = dryrun; + + ret = bootm_boot(&data); + if (ret) + pr_err("Booting %s failed: %s\n", basename(path), strerror(-ret)); +out: + return ret; +} + +/* + * boot a script. 'name' can either be a filename under /env/boot/, + * a full path to a boot script or a path to a directory. This function + * returns a negative error on failure, or 0 on a successful dryrun boot. + */ +static int boot(const char *name) +{ + char *path; + DIR *dir; + struct dirent *d; + struct stat s; + int ret; + + if (*name == '/') + path = xstrdup(name); + else + path = asprintf("/env/boot/%s", name); + + ret = stat(path, &s); + if (ret) { + pr_err("%s: %s\n", path, strerror(-ret)); + goto out; + } + + if (S_ISREG(s.st_mode)) { + ret = boot_script(path); + goto out; + } + + dir = opendir(path); + if (!dir) { + ret = -errno; + printf("cannot open %s: %s\n", path, strerror(-errno)); + goto out; + } + + while ((d = readdir(dir))) { + char *file; + struct stat s; + + if (*d->d_name == '.') + continue; + + file = asprintf("%s/%s", path, d->d_name); + + ret = stat(file, &s); + if (ret) { + free(file); + continue; + } + + if (!S_ISREG(s.st_mode)) { + free(file); + continue; + } + + ret = boot_script(file); + + free(file); + + if (!ret) + break; + } + + closedir(dir); +out: + free(path); + + return ret; +} + +static int do_boot(int argc, char *argv[]) +{ + const char *sources = NULL; + char *source, *freep; + int opt, ret = 0, do_list = 0; + + verbose = 0; + dryrun = 0; + + while ((opt = getopt(argc, argv, "vld")) > 0) { + switch (opt) { + case 'v': + verbose++; + break; + case 'l': + do_list = 1; + break; + case 'd': + dryrun = 1; + break; + } + } + + if (do_list) { + bootsources_list(); + return 0; + } + + if (optind < argc) { + while (optind < argc) { + source = argv[optind]; + optind++; + ret = boot(source); + if (!ret) + break; + } + return ret; + } + + sources = getenv("global.boot.default"); + if (!sources) + return 0; + + freep = source = xstrdup(sources); + + while (1) { + char *sep = strchr(source, ' '); + if (sep) + *sep = 0; + ret = boot(source); + if (!ret) + break; + + if (sep) + source = sep + 1; + else + break; + } + + free(freep); + + return ret; +} + +BAREBOX_CMD_HELP_START(boot) +BAREBOX_CMD_HELP_USAGE("boot [OPTIONS] [BOOTSRC...]\n") +BAREBOX_CMD_HELP_SHORT("Boot an operating system.\n") +BAREBOX_CMD_HELP_SHORT("[BOOTSRC...] can be:\n") +BAREBOX_CMD_HELP_SHORT("- a filename from /env/boot/\n") +BAREBOX_CMD_HELP_SHORT("- a full path to a file\n") +BAREBOX_CMD_HELP_SHORT("- a path to a directory. All files in this directory are treated\n") +BAREBOX_CMD_HELP_SHORT(" as boot scripts.\n") +BAREBOX_CMD_HELP_SHORT("Multiple bootsources may be given which are probed in order until\n") +BAREBOX_CMD_HELP_SHORT("one succeeds.\n") +BAREBOX_CMD_HELP_SHORT("\nOptions:\n") +BAREBOX_CMD_HELP_OPT ("-v","Increase verbosity\n") +BAREBOX_CMD_HELP_OPT ("-d","Dryrun. See what happens but do no actually boot\n") +BAREBOX_CMD_HELP_OPT ("-l","List available boot sources\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(boot) + .cmd = do_boot, + .usage = "boot the machine", + BAREBOX_CMD_HELP(cmd_boot_help) +BAREBOX_CMD_END + +BAREBOX_MAGICVAR_NAMED(global_boot_default, global.boot.default, "default boot order"); diff --git a/commands/bootm.c b/commands/bootm.c index a4004dfb4c..5dff7dd674 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -46,33 +46,7 @@ #include <magicvar.h> #include <asm-generic/memory_layout.h> -/* - * Additional oftree size for the fixed tree - */ -#define OFTREE_SIZE_INCREASE 0x8000 - -static char *bootm_image_name_and_no(const char *name, int *no) -{ - char *at, *ret; - - if (!name || !*name) - return NULL; - - *no = 0; - - ret = xstrdup(name); - at = strchr(ret, '@'); - if (!at) - return ret; - - *at++ = 0; - - *no = simple_strtoul(at, NULL, 10); - - return ret; -} - -#define BOOTM_OPTS_COMMON "ca:e:vo:f" +#define BOOTM_OPTS_COMMON "ca:e:vo:fd" #ifdef CONFIG_CMD_BOOTM_INITRD #define BOOTM_OPTS BOOTM_OPTS_COMMON "L:r:" @@ -80,28 +54,13 @@ static char *bootm_image_name_and_no(const char *name, int *no) #define BOOTM_OPTS BOOTM_OPTS_COMMON #endif -unsigned long long getenv_loadaddr(const char *name) -{ - const char *valstr = getenv(name); - - if (!valstr) - return UIMAGE_SOME_ADDRESS; - - if (valstr[0] == '\0') - return UIMAGE_SOME_ADDRESS; - - return simple_strtoull(valstr, NULL, 0); -} - static int do_bootm(int argc, char *argv[]) { int opt; - struct image_data data; + struct bootm_data data = {}; int ret = 1; const char *oftree = NULL, *initrd_file = NULL, *os_file = NULL; - memset(&data, 0, sizeof(struct image_data)); - data.initrd_address = UIMAGE_INVALID_ADDRESS; data.os_address = UIMAGE_SOME_ADDRESS; data.verify = 0; @@ -109,8 +68,8 @@ static int do_bootm(int argc, char *argv[]) oftree = getenv("global.bootm.oftree"); os_file = getenv("global.bootm.image"); - data.os_address = getenv_loadaddr("global.bootm.image.loadaddr"); - data.initrd_address = getenv_loadaddr("global.bootm.initrd.loadaddr"); + getenv_ul("global.bootm.image.loadaddr", &data.os_address); + getenv_ul("global.bootm.initrd.loadaddr", &data.initrd_address); if (IS_ENABLED(CONFIG_CMD_BOOTM_INITRD)) initrd_file = getenv("global.bootm.initrd"); @@ -142,6 +101,9 @@ static int do_bootm(int argc, char *argv[]) case 'f': data.force = 1; break; + case 'd': + data.dryrun = 1; + break; default: break; } @@ -161,39 +123,28 @@ static int do_bootm(int argc, char *argv[]) if (oftree && !*oftree) oftree = NULL; - data.os_file = bootm_image_name_and_no(os_file, &data.os_num); - data.oftree_file = bootm_image_name_and_no(oftree, &data.oftree_num); - data.initrd_file = bootm_image_name_and_no(initrd_file, &data.initrd_num); + data.os_file = os_file; + data.oftree_file = oftree; + data.initrd_file = initrd_file; ret = bootm_boot(&data); + if (ret) { + printf("handler failed with: %s\n", strerror(-ret)); + goto err_out; + } - printf("handler failed with %s\n", strerror(-ret)); + if (data.dryrun) + printf("Dryrun. Aborted\n"); err_out: - free(data.initrd_file); - free(data.os_file); - - return 1; -} - -static int bootm_init(void) -{ - globalvar_add_simple("bootm.image", NULL); - globalvar_add_simple("bootm.image.loadaddr", NULL); - globalvar_add_simple("bootm.oftree", NULL); - if (IS_ENABLED(CONFIG_CMD_BOOTM_INITRD)) { - globalvar_add_simple("bootm.initrd", NULL); - globalvar_add_simple("bootm.initrd.loadaddr", NULL); - } - - return 0; + return ret ? 1 : 0; } -late_initcall(bootm_init); BAREBOX_CMD_HELP_START(bootm) BAREBOX_CMD_HELP_USAGE("bootm [OPTIONS] image\n") BAREBOX_CMD_HELP_SHORT("Boot an application image.\n") BAREBOX_CMD_HELP_OPT ("-c", "crc check uImage data\n") +BAREBOX_CMD_HELP_OPT ("-d", "dryrun. Check data, but do not run\n") #ifdef CONFIG_CMD_BOOTM_INITRD BAREBOX_CMD_HELP_OPT ("-r <initrd>","specify an initrd image\n") BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address\n") diff --git a/commands/crc.c b/commands/crc.c index a0071b0e8b..ee8dacff0b 100644 --- a/commands/crc.c +++ b/commands/crc.c @@ -82,6 +82,19 @@ out: return ret; } +static int crc_from_file(const char* file, ulong *crc) +{ + char * buf; + + buf= read_file(file, NULL); + + if (!buf) + return -ENOMEM; + + *crc = simple_strtoul(buf, NULL, 16); + return 0; +} + static int do_crc(int argc, char *argv[]) { loff_t start = 0, size = ~0; @@ -92,7 +105,7 @@ static int do_crc(int argc, char *argv[]) #endif int opt, err = 0, filegiven = 0, verify = 0; - while((opt = getopt(argc, argv, "f:F:v:")) > 0) { + while((opt = getopt(argc, argv, "f:F:v:V:")) > 0) { switch(opt) { case 'f': filename = optarg; @@ -108,6 +121,10 @@ static int do_crc(int argc, char *argv[]) verify = 1; vcrc = simple_strtoul(optarg, NULL, 0); break; + case 'V': + if (!crc_from_file(optarg, &vcrc)) + verify = 1; + break; default: return COMMAND_ERROR_USAGE; } @@ -153,6 +170,7 @@ BAREBOX_CMD_HELP_OPT ("-f <file>", "Use file instead of memory.\n") BAREBOX_CMD_HELP_OPT ("-F <file>", "Use file to compare.\n") #endif BAREBOX_CMD_HELP_OPT ("-v <crc>", "Verify\n") +BAREBOX_CMD_HELP_OPT ("-V <file>", "Verify with crc read from <file>\n") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(crc32) diff --git a/commands/devinfo.c b/commands/devinfo.c new file mode 100644 index 0000000000..806e45c9ba --- /dev/null +++ b/commands/devinfo.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2013 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <command.h> +#include <common.h> +#include <complete.h> +#include <driver.h> + +static int do_devinfo_subtree(struct device_d *dev, int depth) +{ + struct device_d *child; + struct cdev *cdev; + int i; + + for (i = 0; i < depth; i++) + printf(" "); + + printf("`---- %s", dev_name(dev)); + if (!list_empty(&dev->cdevs)) { + printf("\n"); + list_for_each_entry(cdev, &dev->cdevs, devices_list) { + for (i = 0; i < depth + 1; i++) + printf(" "); + printf("`---- 0x%08llx-0x%08llx: /dev/%s\n", + cdev->offset, + cdev->offset + cdev->size - 1, + cdev->name); + } + } else { + printf("\n"); + } + + if (!list_empty(&dev->children)) { + device_for_each_child(dev, child) { + do_devinfo_subtree(child, depth + 1); + } + } + + return 0; +} + +static int do_devinfo(int argc, char *argv[]) +{ + struct device_d *dev; + struct driver_d *drv; + struct param_d *param; + int i; + struct resource *res; + + if (argc == 1) { + printf("devices:\n"); + + for_each_device(dev) { + if (!dev->parent) + do_devinfo_subtree(dev, 0); + } + + printf("\ndrivers:\n"); + for_each_driver(drv) + printf("%s\n",drv->name); + } else { + dev = get_device_by_name(argv[1]); + + if (!dev) { + printf("no such device: %s\n",argv[1]); + return -1; + } + + printf("resources:\n"); + for (i = 0; i < dev->num_resources; i++) { + res = &dev->resource[i]; + printf("num : %d\n", i); + if (res->name) + printf("name : %s\n", res->name); + printf("start : " PRINTF_CONVERSION_RESOURCE "\nsize : " + PRINTF_CONVERSION_RESOURCE "\n", + res->start, resource_size(res)); + } + + printf("driver: %s\n", dev->driver ? + dev->driver->name : "none"); + + printf("bus: %s\n\n", dev->bus ? + dev->bus->name : "none"); + + if (dev->info) + dev->info(dev); + + printf("%s\n", list_empty(&dev->parameters) ? + "no parameters available" : "Parameters:"); + + list_for_each_entry(param, &dev->parameters, list) { + printf("%16s = %s", param->name, dev_get_param(dev, param->name)); + if (param->info) + param->info(param); + printf("\n"); + } +#ifdef CONFIG_OFDEVICE + if (dev->device_node) { + printf("\ndevice node: %s\n", dev->device_node->full_name); + of_print_nodes(dev->device_node, 0); + } +#endif + } + + return 0; +} + +BAREBOX_CMD_HELP_START(devinfo) +BAREBOX_CMD_HELP_USAGE("devinfo [DEVICE]\n") +BAREBOX_CMD_HELP_SHORT("Output device information.\n") +BAREBOX_CMD_HELP_END + +/** + * @page devinfo_command + +If called without arguments, devinfo shows a summary of the known +devices and drivers. + +If called with a device path being the argument, devinfo shows more +default information about this device and its parameters. + +Example from an MPC5200 based system: + +@verbatim + barebox:/ devinfo /dev/eth0 + base : 0x1002b000 + size : 0x00000000 + driver: fec_mpc5xxx + + no info available for eth0 + Parameters: + ipaddr = 192.168.23.197 + ethaddr = 80:81:82:83:84:86 + gateway = 192.168.23.1 + netmask = 255.255.255.0 + serverip = 192.168.23.2 +@endverbatim + */ + +BAREBOX_CMD_START(devinfo) + .cmd = do_devinfo, + .usage = "Show information about devices and drivers.", + BAREBOX_CMD_HELP(cmd_devinfo_help) + BAREBOX_CMD_COMPLETE(device_complete) +BAREBOX_CMD_END diff --git a/commands/loadb.c b/commands/loadb.c index a2f3315b64..b527e0095c 100644 --- a/commands/loadb.c +++ b/commands/loadb.c @@ -591,26 +591,6 @@ err_quit: } /** - * @brief returns current used console device - * - * @return console device which is registered with CONSOLE_STDIN and - * CONSOLE_STDOUT - */ -static struct console_device *get_current_console(void) -{ - struct console_device *cdev; - /* - * Assumption to have BOTH CONSOLE_STDIN AND STDOUT in the - * same output console - */ - for_each_console(cdev) { - if ((cdev->f_active & (CONSOLE_STDIN | CONSOLE_STDOUT))) - return cdev; - } - return NULL; -} - -/** * @brief provide the loadb(Kermit) or loadY mode support * * @param cmdtp @@ -650,7 +630,7 @@ static int do_load_serial_bin(int argc, char *argv[]) } } - cdev = get_current_console(); + cdev = console_get_first_active(); if (NULL == cdev) { printf("%s:No console device with STDIN and STDOUT\n", argv[0]); return -ENODEV; diff --git a/commands/loads.c b/commands/loads.c index bfc465bdc7..58cd24b572 100644 --- a/commands/loads.c +++ b/commands/loads.c @@ -40,14 +40,9 @@ static int do_load_serial(int argc, char *argv[]) ulong offset = 0; ulong addr; int i; - const char *env_echo; int rcode = 0; - if (((env_echo = getenv("loads_echo")) != NULL) && (*env_echo == '1')) { - do_echo = 1; - } else { - do_echo = 0; - } + getenv_bool("loads_echo", &do_echo); if (argc == 2) { offset = simple_strtoul(argv[1], NULL, 16); diff --git a/commands/loadxy.c b/commands/loadxy.c index 52ecdcaa0b..7a912864e3 100644 --- a/commands/loadxy.c +++ b/commands/loadxy.c @@ -40,26 +40,6 @@ #define DEF_FILE "image.bin" -/** - * @brief returns current used console device - * - * @return console device which is registered with CONSOLE_STDIN and - * CONSOLE_STDOUT - */ -static struct console_device *get_current_console(void) -{ - struct console_device *cdev; - /* - * Assumption to have BOTH CONSOLE_STDIN AND STDOUT in the - * same output console - */ - for_each_console(cdev) { - if ((cdev->f_active & (CONSOLE_STDIN | CONSOLE_STDOUT))) - return cdev; - } - return NULL; -} - static int console_change_speed(struct console_device *cdev, int baudrate) { int current_baudrate; @@ -134,7 +114,7 @@ static int do_loady(int argc, char *argv[]) if (cname) cdev = get_named_console(cname); else - cdev = get_current_console(); + cdev = console_get_first_active(); if (!cdev) { printf("%s:No console device %s with STDIN and STDOUT\n", argv[0], cname ? cname : "default"); @@ -202,7 +182,7 @@ static int do_loadx(int argc, char *argv[]) if (cname) cdev = get_named_console(cname); else - cdev = get_current_console(); + cdev = console_get_first_active(); if (!cdev) { printf("%s:No console device %s with STDIN and STDOUT\n", argv[0], cname ? cname : "default"); diff --git a/commands/login.c b/commands/login.c index fb6bb35cfc..b616bf15fc 100644 --- a/commands/login.c +++ b/commands/login.c @@ -20,6 +20,11 @@ #include <complete.h> #include <password.h> #include <getopt.h> +#include <environment.h> +#include <globalvar.h> +#include <magicvar.h> +#include <init.h> +#include <console.h> #define PASSWD_MAX_LENGTH (128 + 1) @@ -31,13 +36,16 @@ #define LOGIN_MODE HIDE #endif +static int login_timeout = 0; + static int do_login(int argc, char *argv[]) { unsigned char passwd[PASSWD_MAX_LENGTH]; int passwd_len, opt; - int timeout = 0; + int timeout = login_timeout; char *timeout_cmd = "boot"; + console_allow_input(true); if (!is_passwd_enable()) { puts("login: password not set\n"); return 0; @@ -58,8 +66,10 @@ static int do_login(int argc, char *argv[]) puts("Password: "); passwd_len = password(passwd, PASSWD_MAX_LENGTH, LOGIN_MODE, timeout); - if (passwd_len < 0) + if (passwd_len < 0) { + console_allow_input(false); run_command(timeout_cmd, 0); + } if (check_passwd(passwd, passwd_len)) return 0; @@ -80,3 +90,13 @@ BAREBOX_CMD_START(login) BAREBOX_CMD_HELP(cmd_login_help) BAREBOX_CMD_COMPLETE(empty_complete) BAREBOX_CMD_END + +static int login_global_init(void) +{ + globalvar_add_simple_int("login.timeout", &login_timeout, "%d"); + + return 0; +} +late_initcall(login_global_init); + +BAREBOX_MAGICVAR_NAMED(global_login_timeout, global.login.timeout, "timeout to type the password"); diff --git a/commands/passwd.c b/commands/passwd.c index baccfa6c0c..368c4016b9 100644 --- a/commands/passwd.c +++ b/commands/passwd.c @@ -63,7 +63,7 @@ static int do_passwd(int argc, char *argv[]) goto err; } - ret = set_passwd(passwd1, passwd1_len); + ret = set_env_passwd(passwd1, passwd1_len); if (ret < 0) { puts("Sorry, passwords write failed\n"); @@ -78,15 +78,15 @@ err: return 1; disable: - passwd_disable(); + passwd_env_disable(); puts("passwd: password disabled\n"); return ret; } static const __maybe_unused char cmd_passwd_help[] = "Usage: passwd\n" -"passwd allow you to specify a password\n" -"to disable it put an empty password\n" +"passwd allow you to specify a password in the env\n" +"to disable it put an empty password will still use the default password if set\n" ; BAREBOX_CMD_START(passwd) diff --git a/commands/ubi.c b/commands/ubi.c index 2041df3fd5..57ae79025d 100644 --- a/commands/ubi.c +++ b/commands/ubi.c @@ -58,13 +58,25 @@ BAREBOX_CMD_END static int do_ubiattach(int argc, char *argv[]) { + int opt; struct mtd_info_user user; int fd, ret; + int vid_hdr_offset = 0; + + while((opt = getopt(argc, argv, "O:")) > 0) { + switch(opt) { + case 'O': + vid_hdr_offset = simple_strtoul(optarg, NULL, 0); + break; + default: + return COMMAND_ERROR_USAGE; + } + } - if (argc != 2) + if (optind == argc) return COMMAND_ERROR_USAGE; - fd = open(argv[1], O_RDWR); + fd = open(argv[optind], O_RDWR); if (fd < 0) { perror("open"); return 1; @@ -76,7 +88,7 @@ static int do_ubiattach(int argc, char *argv[]) goto err; } - ret = ubi_attach_mtd_dev(user.mtd, UBI_DEV_NUM_AUTO, 0, 20); + ret = ubi_attach_mtd_dev(user.mtd, UBI_DEV_NUM_AUTO, vid_hdr_offset, 20); if (ret < 0) printf("failed to attach: %s\n", strerror(-ret)); else @@ -88,7 +100,7 @@ err: } static const __maybe_unused char cmd_ubiattach_help[] = -"Usage: ubiattach <mtddev>\n" +"Usage: ubiattach [-O vid-hdr-offset] <mtddev>\n" "Attach <mtddev> to ubi\n"; BAREBOX_CMD_START(ubiattach) |