summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig15
-rw-r--r--common/Makefile2
-rw-r--r--common/bootargs.c83
-rw-r--r--common/env.c2
-rw-r--r--common/environment.c6
-rw-r--r--common/filetype.c2
-rw-r--r--common/globalvar.c65
-rw-r--r--common/misc.c2
-rw-r--r--common/oftree.c3
9 files changed, 173 insertions, 7 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 73d620a57..9f0e0f86f 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -47,6 +47,9 @@ config BINFMT
bool
select FILETYPE
+config GLOBALVAR
+ bool
+
menu "General Settings "
config LOCALVERSION
@@ -307,7 +310,13 @@ config GLOB
depends on SHELL_HUSH
help
If you want to use wildcards like * or ? say y here.
-
+
+config GLOB_SORT
+ select QSORT
+ bool
+ prompt "glob sort support"
+ depends on GLOB
+
config PROMPT_HUSH_PS2
string
depends on SHELL_HUSH
@@ -493,6 +502,7 @@ config DEFAULT_ENVIRONMENT_GENERIC
select HUSH_GETOPT
select CMD_CRC
select CMD_CRC_CMP
+ select CMD_AUTOMOUNT if HAVE_DEFAULT_ENVIRONMENT_NEW
prompt "Default environment generic"
help
With this option barebox will use the generic default
@@ -502,6 +512,9 @@ config DEFAULT_ENVIRONMENT_GENERIC
at least contain a /env/config file.
This will be able to overwrite the files from defaultenv.
+config HAVE_DEFAULT_ENVIRONMENT_NEW
+ bool
+
config DEFAULT_ENVIRONMENT_PATH
string
depends on DEFAULT_ENVIRONMENT
diff --git a/common/Makefile b/common/Makefile
index a58aef94c..b49e6e014 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -29,11 +29,13 @@ obj-$(CONFIG_CMD_BOOTM) += uimage.o
obj-y += startup.o
obj-y += misc.o
obj-y += memsize.o
+obj-$(CONFIG_GLOBALVAR) += globalvar.o
obj-$(CONFIG_FILETYPE) += filetype.o
obj-y += resource.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_PASSWORD) += password.o
obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_FLEXIBLE_BOOTARGS) += bootargs.o
extra-$(CONFIG_MODULES) += module.lds
ifdef CONFIG_DEFAULT_ENVIRONMENT
diff --git a/common/bootargs.c b/common/bootargs.c
new file mode 100644
index 000000000..60e936da3
--- /dev/null
+++ b/common/bootargs.c
@@ -0,0 +1,83 @@
+/*
+ * bootargs.c - concatenate Linux bootargs
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <common.h>
+#include <boot.h>
+#include <malloc.h>
+#include <magicvar.h>
+#include <globalvar.h>
+#include <environment.h>
+
+static char *linux_bootargs;
+static int linux_bootargs_overwritten;
+
+/*
+ * This returns the Linux bootargs
+ *
+ * There are two ways to handle bootargs. The old legacy way is to use the
+ * 'bootargs' environment variable. The new and more flexible way is to use
+ * global variables beginning with "global.linux.bootargs." and
+ * "global.linux.mtdparts.". These variables will be concatenated together to
+ * the resulting bootargs. If there are no "global.linux.bootargs." variables
+ * we fall back to "bootargs"
+ */
+const char *linux_bootargs_get(void)
+{
+ char *bootargs, *mtdparts;
+
+ if (linux_bootargs_overwritten)
+ return linux_bootargs;
+
+ free(linux_bootargs);
+
+ bootargs = globalvar_get_match("linux.bootargs.", " ");
+ if (!strlen(bootargs))
+ return getenv("bootargs");
+
+ mtdparts = globalvar_get_match("linux.mtdparts.", ";");
+
+ if (strlen(mtdparts)) {
+ linux_bootargs = asprintf("%s mtdparts=%s", bootargs, mtdparts);
+ free(bootargs);
+ free(mtdparts);
+ } else {
+ free(mtdparts);
+ linux_bootargs = bootargs;
+ }
+
+ return linux_bootargs;
+}
+
+int linux_bootargs_overwrite(const char *bootargs)
+{
+ if (bootargs) {
+ free(linux_bootargs);
+ linux_bootargs = xstrdup(bootargs);
+ linux_bootargs_overwritten = 1;
+ } else {
+ linux_bootargs_overwritten = 0;
+ }
+
+ return 0;
+}
+
+BAREBOX_MAGICVAR_NAMED(global_linux_bootargs_, global.linux.bootargs.*, "Linux bootargs variables");
+BAREBOX_MAGICVAR_NAMED(global_linux_mtdparts_, global.linux.mtdparts.*, "Linux mtdparts variables");
diff --git a/common/env.c b/common/env.c
index e57a520a3..a01a27e24 100644
--- a/common/env.c
+++ b/common/env.c
@@ -219,7 +219,7 @@ int setenv(const char *_name, const char *value)
else
ret = -ENODEV;
- errno = ret;
+ errno = -ret;
if (ret < 0)
perror("set parameter");
diff --git a/common/environment.c b/common/environment.c
index 0fdbd03e0..52ce0de1d 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -187,7 +187,7 @@ int envfs_load(char *filename, char *dir)
ret = read(envfd, &super, sizeof(struct envfs_super));
if ( ret < sizeof(struct envfs_super)) {
perror("read");
- ret = errno;
+ ret = -errno;
goto out;
}
@@ -210,7 +210,7 @@ int envfs_load(char *filename, char *dir)
ret = read(envfd, buf, size);
if (ret < size) {
perror("read");
- ret = errno;
+ ret = -errno;
goto out;
}
@@ -256,7 +256,7 @@ int envfs_load(char *filename, char *dir)
inode_size);
if (ret < inode_size) {
perror("write");
- ret = errno;
+ ret = -errno;
close(fd);
goto out;
}
diff --git a/common/filetype.c b/common/filetype.c
index 15a37325d..39c209886 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -78,6 +78,8 @@ enum filetype file_detect_type(void *_buf)
return filetype_oftree;
if (strncmp(buf8, "ANDROID!", 8) == 0)
return filetype_aimage;
+ if (strncmp(buf8 + 0x10, "barebox", 7) == 0)
+ return filetype_mips_barebox;
return filetype_unknown;
}
diff --git a/common/globalvar.c b/common/globalvar.c
new file mode 100644
index 000000000..71296ff5a
--- /dev/null
+++ b/common/globalvar.c
@@ -0,0 +1,65 @@
+#include <common.h>
+#include <malloc.h>
+#include <globalvar.h>
+#include <init.h>
+
+static struct device_d global_device = {
+ .name = "global",
+ .id = DEVICE_ID_SINGLE,
+};
+
+int globalvar_add(const char *name,
+ int (*set)(struct device_d *dev, struct param_d *p, const char *val),
+ const char *(*get)(struct device_d *, struct param_d *p),
+ unsigned long flags)
+{
+ return dev_add_param(&global_device, name, set, get, flags);
+}
+
+/*
+ * globalvar_get_match
+ *
+ * get a concatenated string of all globalvars beginning with 'match'.
+ * This adds whitespaces between the different globalvars
+ */
+char *globalvar_get_match(const char *match, const char *seperator)
+{
+ char *val = NULL;
+ struct param_d *param;
+
+ list_for_each_entry(param, &global_device.parameters, list) {
+ if (!strncmp(match, param->name, strlen(match))) {
+ const char *p = dev_get_param(&global_device, param->name);
+ if (val) {
+ char *new = asprintf("%s%s%s", val, seperator, p);
+ free(val);
+ val = new;
+ } else {
+ val = xstrdup(p);
+ }
+ }
+ }
+
+ if (!val)
+ val = xstrdup("");
+
+ return val;
+}
+
+/*
+ * globalvar_add_simple
+ *
+ * add a new globalvar named 'name'
+ */
+int globalvar_add_simple(const char *name)
+{
+ return globalvar_add(name, NULL, NULL, 0);
+}
+
+static int globalvar_init(void)
+{
+ register_device(&global_device);
+
+ return 0;
+}
+postconsole_initcall(globalvar_init);
diff --git a/common/misc.c b/common/misc.c
index b31a45c1a..01e1b19e0 100644
--- a/common/misc.c
+++ b/common/misc.c
@@ -112,7 +112,7 @@ EXPORT_SYMBOL(strerror);
const char *errno_str(void)
{
- return strerror(-errno);
+ return strerror(errno);
}
EXPORT_SYMBOL(errno_str);
diff --git a/common/oftree.c b/common/oftree.c
index a657d3166..49758a9dd 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -11,6 +11,7 @@
#include <errno.h>
#include <getopt.h>
#include <init.h>
+#include <boot.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
@@ -257,7 +258,7 @@ static int of_fixup_bootargs(struct fdt_header *fdt)
if (nodeoffset < 0)
return nodeoffset;
- str = getenv("bootargs");
+ str = linux_bootargs_get();
if (str) {
err = fdt_setprop(fdt, nodeoffset,
"bootargs", str, strlen(str)+1);