summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig44
-rw-r--r--common/Makefile2
-rw-r--r--common/command.c20
-rw-r--r--common/environment.c150
-rw-r--r--common/filetype.c20
-rw-r--r--common/hush.c45
-rw-r--r--common/menu.c17
7 files changed, 232 insertions, 66 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 7eb5b49a8f..b97392cfdb 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -101,6 +101,48 @@ config ENVIRONMENT_VARIABLES
menu "memory layout "
+config HAVE_PBL_IMAGE
+ bool
+
+config HAVE_IMAGE_COMPRESSION
+ bool
+
+config PBL_IMAGE
+ bool "Pre-Bootloader image"
+ depends on HAVE_PBL_IMAGE
+
+config PBL_FORCE_PIGGYDATA_COPY
+ bool
+ help
+ In some case we need to copy the PIGGYDATA as the link address
+ as example we run from SRAM and shutdown the SDRAM/DDR for
+ reconfiguration but most of the time we just need to copy the
+ executable code.
+
+if PBL_IMAGE
+
+config IMAGE_COMPRESSION
+ bool
+ depends on HAVE_IMAGE_COMPRESSION
+ default y
+
+if IMAGE_COMPRESSION
+
+choice
+ prompt "Compression"
+
+config IMAGE_COMPRESSION_LZO
+ bool "lzo"
+
+config IMAGE_COMPRESSION_GZIP
+ bool "gzip"
+
+endchoice
+
+endif
+
+endif
+
config MMU
bool "Enable MMU"
help
@@ -481,6 +523,8 @@ config DEFAULT_ENVIRONMENT
config DEFAULT_ENVIRONMENT_COMPRESSED
bool
depends on DEFAULT_ENVIRONMENT
+ depends on !IMAGE_COMPRESSION_LZO
+ depends on !IMAGE_COMPRESSION_GZIP
default y if ZLIB
default y if BZLIB
default y if LZO_DECOMPRESS
diff --git a/common/Makefile b/common/Makefile
index d74dffb916..df9f301234 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -58,7 +58,7 @@ ifneq ($(CONFIG_DEFAULT_ENVIRONMENT_PATH),"")
DEFAULT_ENVIRONMENT_PATH += $(CONFIG_DEFAULT_ENVIRONMENT_PATH)
endif
-ENV_FILES := $(shell cd $(srctree); for i in $(DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f -exec readlink -f '{}' \;; done)
+ENV_FILES := $(shell cd $(srctree); for i in $(DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f ; done)
endif # ifdef CONFIG_DEFAULT_ENVIRONMENT
diff --git a/common/command.c b/common/command.c
index c18998c129..2bfc5117e8 100644
--- a/common/command.c
+++ b/common/command.c
@@ -38,26 +38,6 @@
LIST_HEAD(command_list);
EXPORT_SYMBOL(command_list);
-#ifdef CONFIG_SHELL_HUSH
-
-static int do_exit(int argc, char *argv[])
-{
- int r;
-
- r = 0;
- if (argc > 1)
- r = simple_strtoul(argv[1], NULL, 0);
-
- return -r - 2;
-}
-
-BAREBOX_CMD_START(exit)
- .cmd = do_exit,
- .usage = "exit script",
-BAREBOX_CMD_END
-
-#endif
-
void barebox_cmd_usage(struct command *cmdtp)
{
#ifdef CONFIG_LONGHELP
diff --git a/common/environment.c b/common/environment.c
index 52ce0de1da..ce46f4a0e6 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -53,7 +53,21 @@ int file_size_action(const char *filename, struct stat *statbuf,
data->writep += sizeof(struct envfs_inode);
data->writep += PAD4(strlen(filename) + 1 - strlen(data->base));
- data->writep += PAD4(statbuf->st_size);
+ data->writep += sizeof(struct envfs_inode_end);
+ if (S_ISLNK(statbuf->st_mode)) {
+ char path[PATH_MAX];
+
+ memset(path, 0, PATH_MAX);
+
+ if (readlink(filename, path, PATH_MAX - 1) < 0) {
+ perror("read");
+ return 0;
+ }
+ data->writep += PAD4(strlen(path) + 1);
+ } else {
+ data->writep += PAD4(statbuf->st_size);
+ }
+
return 1;
}
@@ -62,34 +76,60 @@ int file_save_action(const char *filename, struct stat *statbuf,
{
struct action_data *data = userdata;
struct envfs_inode *inode;
+ struct envfs_inode_end *inode_end;
int fd;
int namelen = strlen(filename) + 1 - strlen(data->base);
- debug("handling file %s size %ld namelen %d\n", filename + strlen(data->base),
- statbuf->st_size, namelen);
-
inode = (struct envfs_inode*)data->writep;
inode->magic = ENVFS_32(ENVFS_INODE_MAGIC);
- inode->namelen = ENVFS_32(namelen);
- inode->size = ENVFS_32(statbuf->st_size);
+ inode->headerlen = ENVFS_32(PAD4(namelen + sizeof(struct envfs_inode_end)));
data->writep += sizeof(struct envfs_inode);
strcpy(data->writep, filename + strlen(data->base));
data->writep += PAD4(namelen);
+ inode_end = (struct envfs_inode_end*)data->writep;
+ data->writep += sizeof(struct envfs_inode_end);
+ inode_end->magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
+ inode_end->mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- printf("Open %s %s\n", filename, errno_str());
- goto out;
- }
+ if (S_ISLNK(statbuf->st_mode)) {
+ char path[PATH_MAX];
+ int len;
- if (read(fd, data->writep, statbuf->st_size) < statbuf->st_size) {
- perror("read");
- goto out;
- }
- close(fd);
+ memset(path, 0, PATH_MAX);
+
+ if (readlink(filename, path, PATH_MAX - 1) < 0) {
+ perror("read");
+ goto out;
+ }
+ len = strlen(path) + 1;
+
+ inode_end->mode |= ENVFS_32(S_IFLNK);
+
+ memcpy(data->writep, path, len);
+ inode->size = ENVFS_32(len);
+ data->writep += PAD4(len);
+ debug("handling symlink %s size %ld namelen %d headerlen %d\n", filename + strlen(data->base),
+ len, namelen, ENVFS_32(inode->headerlen));
+ } else {
+ debug("handling file %s size %ld namelen %d headerlen %d\n", filename + strlen(data->base),
+ statbuf->st_size, namelen, ENVFS_32(inode->headerlen));
- data->writep += PAD4(statbuf->st_size);
+ inode->size = ENVFS_32(statbuf->st_size);
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ printf("Open %s %s\n", filename, errno_str());
+ goto out;
+ }
+
+ if (read(fd, data->writep, statbuf->st_size) < statbuf->st_size) {
+ perror("read");
+ goto out;
+ }
+ close(fd);
+
+ data->writep += PAD4(statbuf->st_size);
+ }
out:
return 1;
@@ -125,6 +165,8 @@ int envfs_save(char *filename, char *dirname)
super = (struct envfs_super *)buf;
super->magic = ENVFS_32(ENVFS_MAGIC);
+ super->major = ENVFS_MAJOR;
+ super->minor = ENVFS_MINOR;
super->size = ENVFS_32(size);
/* second pass: copy files to buffer */
@@ -174,8 +216,13 @@ int envfs_load(char *filename, char *dir)
int envfd;
int fd, ret = 0;
char *str, *tmp;
- int namelen_full;
+ int headerlen_full;
unsigned long size;
+ /* for envfs < 1.0 */
+ struct envfs_inode_end inode_end_dummy;
+
+ inode_end_dummy.mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
+ inode_end_dummy.magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
envfd = open(filename, O_RDONLY);
if (envfd < 0) {
@@ -221,11 +268,18 @@ int envfs_load(char *filename, char *dir)
goto out;
}
+ if (super.major < ENVFS_MAJOR)
+ printf("envfs version %d.%d loaded into %d.%d\n",
+ super.major, super.minor,
+ ENVFS_MAJOR, ENVFS_MINOR);
+
while (size) {
struct envfs_inode *inode;
- uint32_t inode_size, inode_namelen;
+ struct envfs_inode_end *inode_end;
+ uint32_t inode_size, inode_headerlen, namelen;
inode = (struct envfs_inode *)buf;
+ buf += sizeof(struct envfs_inode);
if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
printf("envfs: wrong magic on %s\n", filename);
@@ -233,38 +287,58 @@ int envfs_load(char *filename, char *dir)
goto out;
}
inode_size = ENVFS_32(inode->size);
- inode_namelen = ENVFS_32(inode->namelen);
+ inode_headerlen = ENVFS_32(inode->headerlen);
+ namelen = strlen(inode->data) + 1;
+ if (super.major < 1)
+ inode_end = &inode_end_dummy;
+ else
+ inode_end = (struct envfs_inode_end *)(buf + PAD4(namelen));
- debug("loading %s size %d namelen %d\n", inode->data,
- inode_size, inode_namelen);
+ debug("loading %s size %d namelen %d headerlen %d\n", inode->data,
+ inode_size, namelen, inode_headerlen);
str = concat_path_file(dir, inode->data);
tmp = strdup(str);
make_directory(dirname(tmp));
free(tmp);
- fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- free(str);
- if (fd < 0) {
- printf("Open %s\n", errno_str());
- ret = fd;
+ headerlen_full = PAD4(inode_headerlen);
+ buf += headerlen_full;
+
+ if (ENVFS_32(inode_end->magic) != ENVFS_INODE_END_MAGIC) {
+ printf("envfs: wrong inode_end_magic on %s\n", filename);
+ ret = -EIO;
goto out;
}
- namelen_full = PAD4(inode_namelen);
- ret = write(fd, buf + namelen_full + sizeof(struct envfs_inode),
- inode_size);
- if (ret < inode_size) {
- perror("write");
- ret = -errno;
+ if (S_ISLNK(ENVFS_32(inode_end->mode))) {
+ debug("symlink: %s -> %s\n", str, (char*)buf);
+ if (symlink((char*)buf, str) < 0) {
+ printf("symlink: %s -> %s :", str, (char*)buf);
+ perror("");
+ }
+ free(str);
+ } else {
+ fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ free(str);
+ if (fd < 0) {
+ printf("Open %s\n", errno_str());
+ ret = fd;
+ goto out;
+ }
+
+ ret = write(fd, buf, inode_size);
+ if (ret < inode_size) {
+ perror("write");
+ ret = -errno;
+ close(fd);
+ goto out;
+ }
close(fd);
- goto out;
}
- close(fd);
- buf += PAD4(inode_namelen) + PAD4(inode_size) +
- sizeof(struct envfs_inode);
- size -= PAD4(inode_namelen) + PAD4(inode_size) +
+ buf += PAD4(inode_size);
+ size -= headerlen_full + PAD4(inode_size) +
sizeof(struct envfs_inode);
}
diff --git a/common/filetype.c b/common/filetype.c
index 1a5b82da47..e736d43efe 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -22,6 +22,7 @@
#include <common.h>
#include <filetype.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <fcntl.h>
#include <fs.h>
#include <malloc.h>
@@ -40,6 +41,7 @@ static const char *filetype_str[] = {
[filetype_aimage] = "Android boot image",
[filetype_sh] = "Bourne Shell",
[filetype_mips_barebox] = "MIPS barebox image",
+ [filetype_fat] = "FAT filesytem",
};
const char *file_type_to_string(enum filetype f)
@@ -50,6 +52,22 @@ const char *file_type_to_string(enum filetype f)
return NULL;
}
+static int is_fat(u8 *buf)
+{
+ if (get_unaligned_le16(&buf[510]) != 0xAA55)
+ return 0;
+
+ /* FAT */
+ if ((get_unaligned_le32(&buf[54]) & 0xFFFFFF) == 0x544146)
+ return 1;
+
+ /* FAT32 */
+ if ((get_unaligned_le32(&buf[82]) & 0xFFFFFF) == 0x544146)
+ return 1;
+
+ return 0;
+}
+
enum filetype file_detect_type(void *_buf)
{
u32 *buf = _buf;
@@ -81,6 +99,8 @@ enum filetype file_detect_type(void *_buf)
return filetype_aimage;
if (strncmp(buf8 + 0x10, "barebox", 7) == 0)
return filetype_mips_barebox;
+ if (is_fat(buf8))
+ return filetype_fat;
return filetype_unknown;
}
diff --git a/common/hush.c b/common/hush.c
index 8200931387..61aac13d1b 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -557,6 +557,18 @@ static int builtin_getopt(struct p_context *ctx, struct child_prog *child,
}
#endif
+static int builtin_exit(struct p_context *ctx, struct child_prog *child,
+ int argc, char *argv[])
+{
+ int r;
+
+ r = last_return_code;
+ if (argc > 1)
+ r = simple_strtoul(argv[1], NULL, 0);
+
+ return -r - 2;
+}
+
static void remove_quotes_in_str(char *src)
{
char *trg = src;
@@ -773,10 +785,17 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
remove_quotes(globbuf.gl_pathc, globbuf.gl_pathv);
- if (!strcmp(globbuf.gl_pathv[0], "getopt"))
+ if (!strcmp(globbuf.gl_pathv[0], "getopt")) {
ret = builtin_getopt(ctx, child, globbuf.gl_pathc, globbuf.gl_pathv);
- else
+ } else if (!strcmp(globbuf.gl_pathv[0], "exit")) {
+ ret = builtin_exit(ctx, child, globbuf.gl_pathc, globbuf.gl_pathv);
+ } else {
ret = execute_binfmt(globbuf.gl_pathc, globbuf.gl_pathv);
+ if (ret < 0) {
+ printf("%s: %s\n", globbuf.gl_pathv[0], strerror(-ret));
+ ret = 127;
+ }
+ }
globfree(&globbuf);
@@ -1885,16 +1904,28 @@ BAREBOX_CMD_START(source)
BAREBOX_CMD_HELP(cmd_source_help)
BAREBOX_CMD_END
-#ifdef CONFIG_HUSH_GETOPT
-static int do_getopt(int argc, char *argv[])
+static int do_dummy_command(int argc, char *argv[])
{
/*
- * This function is never reached. The 'getopt' command is
- * only here to provide a help text for the getopt builtin.
+ * This function is never reached. These commands are only here to
+ * provide help texts for the builtins.
*/
return 0;
}
+static const __maybe_unused char cmd_exit_help[] =
+"Usage: exit [n]\n"
+"\n"
+"exit script with a status of n. If n is omitted, the exit status is that\n"
+"of the last command executed\n";
+
+BAREBOX_CMD_START(exit)
+ .cmd = do_dummy_command,
+ .usage = "exit script",
+ BAREBOX_CMD_HELP(cmd_exit_help)
+BAREBOX_CMD_END
+
+#ifdef CONFIG_HUSH_GETOPT
static const __maybe_unused char cmd_getopt_help[] =
"Usage: getopt <optstring> <var>\n"
"\n"
@@ -1905,7 +1936,7 @@ static const __maybe_unused char cmd_getopt_help[] =
"can be accessed starting from $1\n";
BAREBOX_CMD_START(getopt)
- .cmd = do_getopt,
+ .cmd = do_dummy_command,
.usage = "getopt <optstring> <var>",
BAREBOX_CMD_HELP(cmd_getopt_help)
BAREBOX_CMD_END
diff --git a/common/menu.c b/common/menu.c
index 9f536d6aee..97c6b184bd 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -314,6 +314,23 @@ int menu_show(struct menu *m)
m->auto_select = -1;
switch (ch) {
+ case '0' ... '9': {
+ struct menu_entry *me;
+ int num = ch - '0';
+ int next_num = m->selected->num + 10;
+ if (!num)
+ num = 10;
+
+ if (ch_previous == ch && next_num <= m->nb_entries)
+ num = next_num;
+
+ me = menu_entry_get_by_num(m, num);
+ if (me) {
+ m->selected = me;
+ repaint = 1;
+ }
+ break;
+ }
case KEY_UP:
m->selected = list_entry(m->selected->list.prev, struct menu_entry,
list);