diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 25 | ||||
-rw-r--r-- | common/Makefile | 20 | ||||
-rw-r--r-- | common/binfmt.c | 5 | ||||
-rw-r--r-- | common/bootm.c | 74 | ||||
-rw-r--r-- | common/console.c | 24 | ||||
-rw-r--r-- | common/console_common.c | 82 | ||||
-rw-r--r-- | common/console_simple.c | 14 | ||||
-rw-r--r-- | common/env.c | 71 | ||||
-rw-r--r-- | common/filetype.c | 3 | ||||
-rw-r--r-- | common/globalvar.c | 5 | ||||
-rw-r--r-- | common/hush.c | 6 | ||||
-rw-r--r-- | common/parser.c | 9 | ||||
-rw-r--r-- | common/password.c | 94 | ||||
-rw-r--r-- | common/startup.c | 2 |
14 files changed, 403 insertions, 31 deletions
diff --git a/common/Kconfig b/common/Kconfig index dd705782ab..13419dc5bd 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -32,6 +32,7 @@ config GENERIC_GPIO bool config BOOTM + select UIMAGE bool config BLOCK @@ -385,6 +386,11 @@ config PASSWORD help allow you to have password protection framework +config PASSWORD_DEFAULT + string + prompt "Password default" + depends on PASSWORD + if PASSWORD choice @@ -549,6 +555,7 @@ config DEFAULT_ENVIRONMENT_GENERIC_NEW select CMD_READLINK select CMD_DIRNAME select FLEXIBLE_BOOTARGS + select CMD_BOOT prompt "Generic environment template" config DEFAULT_ENVIRONMENT_GENERIC @@ -602,7 +609,7 @@ endmenu menu "Debugging" config COMPILE_LOGLEVEL - int "loglevel" + int "compile loglevel" default 6 help This defines the maximum loglevel compiled into the binary. Less important @@ -617,6 +624,22 @@ config COMPILE_LOGLEVEL 6 informational (info) 7 debug-level messages (debug) +config DEFAULT_LOGLEVEL + int "default loglevel" + default 7 + help + This defines the default runtime loglevel. It can be changed using the + global.loglevel variable. Available logelevels are: + + 0 system is unusable (emerg) + 1 action must be taken immediately (alert) + 2 critical conditions (crit) + 3 error conditions (err) + 4 warning conditions (warn) + 5 normal but significant condition (notice) + 6 informational (info) + 7 debug-level messages (debug) + config DEBUG_INFO bool prompt "enable debug symbols" diff --git a/common/Makefile b/common/Makefile index 64eacc3047..9a9e3fe7d9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -114,6 +114,26 @@ cmd_env_h = cat $< | (cd $(obj) && $(objtree)/scripts/bin2c default_environment) $(obj)/barebox_default_env.h: $(obj)/barebox_default_env$(barebox_default_env_comp) FORCE $(call if_changed,env_h) +quiet_cmd_pwd_h = PWDH $@ +ifneq ($(CONFIG_PASSWORD_DEFAULT),"") +PASSWD_FILE := $(shell cd $(srctree); find $(CONFIG_PASSWORD_DEFAULT) -type f) +cmd_pwd_h = echo -n "const char default_passwd[] = \"" > $@; \ + cat $< | tr -d '\n' >> $@; \ + echo "\";" >> $@ + +include/generated/passwd.h: $(PASSWD_FILE) + $(call if_changed,pwd_h) +else +cmd_pwd_h = echo "const char default_passwd[] = \"\";" > $@ + +include/generated/passwd.h: FORCE + $(call if_changed,pwd_h) +endif + +targets += include/generated/passwd.h + +$(obj)/password.o: include/generated/passwd.h + # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/common/binfmt.c b/common/binfmt.c index 7dcf5d737d..f2ff624587 100644 --- a/common/binfmt.c +++ b/common/binfmt.c @@ -60,6 +60,9 @@ int execute_binfmt(int argc, char **argv) if (strchr(argv[0], '/')) return binfmt_run(argv[0], argc, argv); + if (find_cmd(argv[0])) + return execute_command(argc, &argv[0]); + path = find_execable(argv[0]); if (path) { ret = binfmt_run(path, argc, argv); @@ -67,7 +70,7 @@ int execute_binfmt(int argc, char **argv) return ret; } - return execute_command(argc, &argv[0]); + return -ENOENT; } int binfmt_register(struct binfmt_hook *b) diff --git a/common/bootm.c b/common/bootm.c index 1987a09352..2da6e59129 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -16,6 +16,8 @@ #include <fs.h> #include <malloc.h> #include <memory.h> +#include <globalvar.h> +#include <init.h> static LIST_HEAD(handler_list); @@ -167,6 +169,7 @@ static int bootm_open_oftree(struct image_data *data, const char *oftree, int nu data->of_root_node = of_unflatten_dtb(NULL, fdt); if (!data->of_root_node) { pr_err("unable to unflatten devicetree\n"); + free(fdt); return -EINVAL; } @@ -203,12 +206,55 @@ static void bootm_print_info(struct image_data *data) } } -int bootm_boot(struct image_data *data) +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; +} + +/* + * bootm_boot - Boot an application image described by bootm_data + */ +int bootm_boot(struct bootm_data *bootm_data) +{ + struct image_data *data; struct image_handler *handler; int ret; enum filetype os_type, initrd_type = filetype_unknown; + if (!bootm_data->os_file) { + printf("no image given\n"); + return -ENOENT; + } + + data = xzalloc(sizeof(*data)); + + data->os_file = bootm_image_name_and_no(bootm_data->os_file, &data->os_num); + data->oftree_file = bootm_image_name_and_no(bootm_data->oftree_file, &data->oftree_num); + data->initrd_file = bootm_image_name_and_no(bootm_data->initrd_file, &data->initrd_num); + data->verbose = bootm_data->verbose; + data->verify = bootm_data->verify; + data->force = bootm_data->force; + data->dryrun = bootm_data->dryrun; + data->initrd_address = bootm_data->initrd_address; + data->os_address = bootm_data->os_address; + data->os_entry = bootm_data->os_entry; + os_type = file_name_detect_type(data->os_file); if ((int)os_type < 0) { printf("could not open %s: %s\n", data->os_file, @@ -288,7 +334,10 @@ int bootm_boot(struct image_data *data) printf("Passing control to %s handler\n", handler->name); } - ret = handler->bootm(data); + if (data->dryrun) + ret = 0; + else + ret = handler->bootm(data); err_out: if (data->os_res) release_sdram_region(data->os_res); @@ -298,6 +347,27 @@ err_out: uimage_close(data->initrd); if (data->os) uimage_close(data->os); + if (data->of_root_node && data->of_root_node != of_get_root_node()) + of_delete_node(data->of_root_node); + + free(data->os_file); + free(data->oftree_file); + free(data->initrd_file); + free(data); return ret; } + +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; +} +late_initcall(bootm_init); diff --git a/common/console.c b/common/console.c index 6ca94e2a02..56bc864ad1 100644 --- a/common/console.c +++ b/common/console.c @@ -63,19 +63,21 @@ static int console_std_set(struct device_d *dev, struct param_d *param, unsigned int flag = 0, i = 0; if (val) { - if (strchr(val, 'i') && cdev->f_caps & CONSOLE_STDIN) { + if (strchr(val, 'i') && cdev->getc) { active[i++] = 'i'; flag |= CONSOLE_STDIN; } - if (strchr(val, 'o') && cdev->f_caps & CONSOLE_STDOUT) { - active[i++] = 'o'; - flag |= CONSOLE_STDOUT; - } + if (cdev->putc) { + if (strchr(val, 'o')) { + active[i++] = 'o'; + flag |= CONSOLE_STDOUT; + } - if (strchr(val, 'e') && cdev->f_caps & CONSOLE_STDERR) { - active[i++] = 'e'; - flag |= CONSOLE_STDERR; + if (strchr(val, 'e')) { + active[i++] = 'e'; + flag |= CONSOLE_STDERR; + } } } @@ -236,6 +238,9 @@ int getc(void) unsigned char ch; uint64_t start; + if (unlikely(!console_is_input_allow())) + return -EPERM; + /* * For 100us we read the characters from the serial driver * into a kfifo. This helps us not to lose characters @@ -270,6 +275,9 @@ EXPORT_SYMBOL(fgetc); int tstc(void) { + if (unlikely(!console_is_input_allow())) + return 0; + return kfifo_len(console_input_fifo) || tstc_raw(); } EXPORT_SYMBOL(tstc); diff --git a/common/console_common.c b/common/console_common.c index d139d1a8fe..5d2ccdb6e7 100644 --- a/common/console_common.c +++ b/common/console_common.c @@ -21,9 +21,69 @@ #include <common.h> #include <fs.h> #include <errno.h> +#include <console.h> +#include <init.h> +#include <environment.h> +#include <globalvar.h> +#include <magicvar.h> +#include <password.h> #ifndef CONFIG_CONSOLE_NONE +static int console_input_allow; + +static int console_global_init(void) +{ + if (IS_ENABLED(CONFIG_CMD_LOGIN) && is_passwd_enable()) + console_input_allow = 0; + else + console_input_allow = 1; + + globalvar_add_simple_bool("console.input_allow", &console_input_allow); + + return 0; +} +late_initcall(console_global_init); + +BAREBOX_MAGICVAR_NAMED(global_console_input_allow, global.console.input_allow, "console input allowed"); + +bool console_is_input_allow(void) +{ + return console_input_allow; +} + +void console_allow_input(bool val) +{ + console_input_allow = val; +} + +int barebox_loglevel = CONFIG_DEFAULT_LOGLEVEL; + +int pr_print(int level, const char *fmt, ...) +{ + va_list args; + uint i; + char printbuffer[CFG_PBSIZE]; + + if (level > barebox_loglevel) + return 0; + + va_start(args, fmt); + i = vsprintf(printbuffer, fmt, args); + va_end(args); + + /* Print the string */ + puts(printbuffer); + + return i; +} + +static int loglevel_init(void) +{ + return globalvar_add_simple_int("loglevel", &barebox_loglevel, "%d"); +} +device_initcall(loglevel_init); + int printf(const char *fmt, ...) { va_list args; @@ -108,3 +168,25 @@ int fputc(int fd, char c) return 0; } EXPORT_SYMBOL(fputc); + +/* + * @brief returns current used console device + * + * @return console device which is registered with CONSOLE_STDIN and + * CONSOLE_STDOUT + */ +struct console_device *console_get_first_active(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; +} +EXPORT_SYMBOL(console_get_first_active); diff --git a/common/console_simple.c b/common/console_simple.c index 101064b69a..6cb72bb46a 100644 --- a/common/console_simple.c +++ b/common/console_simple.c @@ -3,6 +3,7 @@ #include <fs.h> #include <errno.h> #include <debug_ll.h> +#include <console.h> LIST_HEAD(console_list); EXPORT_SYMBOL(console_list); @@ -40,6 +41,9 @@ EXPORT_SYMBOL(console_putc); int tstc(void) { + if (unlikely(!console_is_input_allow())) + return 0; + if (!console) return 0; @@ -49,6 +53,9 @@ EXPORT_SYMBOL(tstc); int getc(void) { + if (unlikely(!console_is_input_allow())) + return -EPERM; + if (!console) return -EINVAL; return console->getc(console); @@ -82,6 +89,13 @@ int console_register(struct console_device *newcdev) console_list.prev = console_list.next = &newcdev->list; newcdev->list.prev = newcdev->list.next = &console_list; + if (newcdev->setbrg) { + newcdev->baudrate = CONFIG_BAUDRATE; + newcdev->setbrg(newcdev, newcdev->baudrate); + } + + newcdev->f_active = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; + barebox_banner(); return 0; diff --git a/common/env.c b/common/env.c index 33a871f7eb..748b655a6b 100644 --- a/common/env.c +++ b/common/env.c @@ -267,13 +267,74 @@ void export_env_ull(const char *name, unsigned long long val) } EXPORT_SYMBOL(export_env_ull); -unsigned long long getenv_ull(const char *name) +/* + * Like regular getenv, but never returns an empty string. + * If the string is empty, NULL is returned instead + */ +const char *getenv_nonempty(const char *var) { - const char *valstr = getenv(name); + const char *val = getenv(var); - if (!valstr) - return 0; + if (val && *val) + return val; - return simple_strtoull(valstr, NULL, 0); + return NULL; +} +EXPORT_SYMBOL(getenv_nonempty); + +int getenv_ull(const char *var , unsigned long long *val) +{ + const char *valstr = getenv(var); + + if (!valstr || !*valstr) + return -EINVAL; + + *val = simple_strtoull(valstr, NULL, 0); + + return 0; } EXPORT_SYMBOL(getenv_ull); + +int getenv_ul(const char *var , unsigned long *val) +{ + const char *valstr = getenv(var); + + if (!valstr || !*valstr) + return -EINVAL; + + *val = simple_strtoul(valstr, NULL, 0); + + return 0; +} +EXPORT_SYMBOL(getenv_ul); + +int getenv_uint(const char *var , unsigned int *val) +{ + const char *valstr = getenv(var); + + if (!valstr || !*valstr) + return -EINVAL; + + *val = simple_strtoul(valstr, NULL, 0); + + return 0; +} +EXPORT_SYMBOL(getenv_uint); + +int getenv_bool(const char *var, int *val) +{ + const char *valstr = getenv(var); + + if (!valstr || !*valstr) + return -EINVAL; + + if (!*valstr) + *val = false; + else if (*valstr == '0') + *val = false; + else + *val = true; + + return 0; +} +EXPORT_SYMBOL(getenv_bool); diff --git a/common/filetype.c b/common/filetype.c index 7507d85de0..8cdf82741a 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -50,6 +50,7 @@ static const struct filetype_str filetype_str[] = { [filetype_png] = { "PNG image", "png" }, [filetype_ext] = { "ext filesystem", "ext" }, [filetype_gpt] = { "GUID Partition Table", "gpt" }, + [filetype_bpk] = { "Binary PacKage", "bpk" }, }; const char *file_type_to_string(enum filetype f) @@ -220,6 +221,8 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) return filetype_png; if (is_barebox_mips_head(_buf)) return filetype_mips_barebox; + if (buf[0] == be32_to_cpu(0x534F4659)) + return filetype_bpk; if (bufsize < 64) return filetype_unknown; diff --git a/common/globalvar.c b/common/globalvar.c index edb66ddca6..41ce06e468 100644 --- a/common/globalvar.c +++ b/common/globalvar.c @@ -6,7 +6,7 @@ #include <magicvar.h> #include <generated/utsrelease.h> -static struct device_d global_device = { +struct device_d global_device = { .name = "global", .id = DEVICE_ID_SINGLE, }; @@ -72,6 +72,9 @@ int globalvar_add_simple(const char *name, const char *value) if (ret && ret != -EEXIST) return ret; + if (!value) + return 0; + return dev_set_param(&global_device, name, value); } diff --git a/common/hush.c b/common/hush.c index a3235ba19f..bf1d9e6fd7 100644 --- a/common/hush.c +++ b/common/hush.c @@ -123,6 +123,7 @@ #include <linux/list.h> #include <binfmt.h> #include <init.h> +#include <shell.h> /*cmd_boot.c*/ extern int do_bootd(int flag, int argc, char *argv[]); /* do_bootd */ @@ -226,6 +227,11 @@ static char console_buffer[CONFIG_CBSIZE]; /* console I/O buffer */ * the first three support $?, $#, and $1 */ static unsigned int last_return_code; +int shell_get_last_return_code(void) +{ + return last_return_code; +} + /* "globals" within this file */ static uchar *ifs; static char map[256]; diff --git a/common/parser.c b/common/parser.c index 4d993dfd35..d390fb6afe 100644 --- a/common/parser.c +++ b/common/parser.c @@ -1,6 +1,15 @@ #include <common.h> #include <command.h> #include <environment.h> +#include <shell.h> + +/* + * not yet supported + */ +int shell_get_last_return_code(void) +{ + return 0; +} static int parse_line (char *line, char *argv[]) { diff --git a/common/password.c b/common/password.c index d157a11b7b..9c1e54a359 100644 --- a/common/password.c +++ b/common/password.c @@ -25,6 +25,7 @@ #include <malloc.h> #include <xfuncs.h> #include <clock.h> +#include <generated/passwd.h> #if defined(CONFIG_PASSWD_SUM_MD5) #define PASSWD_SUM "md5" @@ -97,7 +98,13 @@ int password(unsigned char *passwd, size_t length, int flags, int timeout) } EXPORT_SYMBOL(password); -int is_passwd_enable(void) +int is_passwd_default_enable(void) +{ + return strlen(default_passwd) > 0; +} +EXPORT_SYMBOL(is_passwd_default_enable); + +int is_passwd_env_enable(void) { int fd; @@ -110,13 +117,13 @@ int is_passwd_enable(void) return 1; } -EXPORT_SYMBOL(is_passwd_enable); +EXPORT_SYMBOL(is_passwd_env_enable); -int passwd_disable(void) +int passwd_env_disable(void) { return unlink(PASSWD_FILE); } -EXPORT_SYMBOL(passwd_disable); +EXPORT_SYMBOL(passwd_env_disable); static unsigned char to_digit(unsigned char c) { @@ -140,6 +147,43 @@ static unsigned char to_hexa(unsigned char c) int read_passwd(unsigned char *sum, size_t length) { + if (is_passwd_env_enable()) + return read_env_passwd(sum, length); + else if (is_passwd_default_enable()) + return read_default_passwd(sum, length); + else + return -EINVAL; +} + +int read_default_passwd(unsigned char *sum, size_t length) +{ + int i = 0; + int len = strlen(default_passwd); + unsigned char *buf = (unsigned char *)default_passwd; + unsigned char c; + + if (!sum || length < 1) + return -EINVAL; + + for (i = 0; i < len && length > 0; i++) { + c = buf[i]; + i++; + + *sum = to_digit(c) << 4; + + c = buf[i]; + + *sum |= to_digit(c); + sum++; + length--; + } + + return 0; +} +EXPORT_SYMBOL(read_default_passwd); + +int read_env_passwd(unsigned char *sum, size_t length) +{ int fd; int ret = 0; unsigned char c; @@ -178,9 +222,9 @@ exit: return ret; } -EXPORT_SYMBOL(read_passwd); +EXPORT_SYMBOL(read_env_passwd); -int write_passwd(unsigned char *sum, size_t length) +int write_env_passwd(unsigned char *sum, size_t length) { int fd; unsigned char c; @@ -227,9 +271,9 @@ exit: return ret; } -EXPORT_SYMBOL(write_passwd); +EXPORT_SYMBOL(write_env_passwd); -int check_passwd(unsigned char* passwd, size_t length) +static int __check_passwd(unsigned char* passwd, size_t length, int std) { struct digest *d; unsigned char *passwd1_sum; @@ -256,7 +300,10 @@ int check_passwd(unsigned char* passwd, size_t length) d->final(d, passwd1_sum); - ret = read_passwd(passwd2_sum, d->length); + if (std) + ret = read_env_passwd(passwd2_sum, d->length); + else + ret = read_default_passwd(passwd2_sum, d->length); if (ret < 0) goto err2; @@ -271,9 +318,30 @@ err1: return ret; } -EXPORT_SYMBOL(check_passwd); -int set_passwd(unsigned char* passwd, size_t length) +int check_default_passwd(unsigned char* passwd, size_t length) +{ + return __check_passwd(passwd, length, 0); +} +EXPORT_SYMBOL(check_default_passwd); + +int check_env_passwd(unsigned char* passwd, size_t length) +{ + return __check_passwd(passwd, length, 1); +} +EXPORT_SYMBOL(check_env_passwd); + +int check_passwd(unsigned char* passwd, size_t length) +{ + if (is_passwd_env_enable()) + return check_env_passwd(passwd, length); + else if (is_passwd_default_enable()) + return check_default_passwd(passwd, length); + else + return -EINVAL; +} + +int set_env_passwd(unsigned char* passwd, size_t length) { struct digest *d; unsigned char *passwd_sum; @@ -292,10 +360,10 @@ int set_passwd(unsigned char* passwd, size_t length) d->final(d, passwd_sum); - ret = write_passwd(passwd_sum, d->length); + ret = write_env_passwd(passwd_sum, d->length); free(passwd_sum); return ret; } -EXPORT_SYMBOL(set_passwd); +EXPORT_SYMBOL(set_env_passwd); diff --git a/common/startup.c b/common/startup.c index 9b33a92c86..0a36c07aae 100644 --- a/common/startup.c +++ b/common/startup.c @@ -138,6 +138,8 @@ void __noreturn start_barebox(void) run_command("source /env/bin/init", 0); } else { pr_err("/env/bin/init not found\n"); + if (IS_ENABLED(CONFIG_CMD_LOGIN)) + while(run_command("login -t 0", 0)); } } |