summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig25
-rw-r--r--common/Makefile20
-rw-r--r--common/binfmt.c5
-rw-r--r--common/bootm.c74
-rw-r--r--common/console.c24
-rw-r--r--common/console_common.c82
-rw-r--r--common/console_simple.c14
-rw-r--r--common/env.c71
-rw-r--r--common/filetype.c3
-rw-r--r--common/globalvar.c5
-rw-r--r--common/hush.c6
-rw-r--r--common/parser.c9
-rw-r--r--common/password.c94
-rw-r--r--common/startup.c2
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));
}
}