summaryrefslogtreecommitdiffstats
path: root/arch/sandbox
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2023-08-17 09:39:41 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-08-18 07:54:28 +0200
commitaf0c0b3f99c94df502276522197bf05d24444b96 (patch)
treee5877d5844485d6e991c5f1259dcc2a95d632f73 /arch/sandbox
parentc63f4e88caf158a044ec3e6a5f39dd0561f734ca (diff)
downloadbarebox-af0c0b3f99c94df502276522197bf05d24444b96.tar.gz
barebox-af0c0b3f99c94df502276522197bf05d24444b96.tar.xz
sandbox: store stickypage in runtime dir
The stickypage is a hack to have a 4K hostfile persist over reboot. This was so far done by compiling the stickypage separately and referencing it from the device tree via the magic $build variable that expands to the working directory. This breaks a number of assumptions: - KBUILD_IMAGE: should only have a single entry, e.g. barebox-flash-images ends up with two files per one line - stickypage must be writable, which may fail if barebox is installed, e.g. in r/o Nix Store Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20230817073941.1261154-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/sandbox')
-rw-r--r--arch/sandbox/Makefile9
-rw-r--r--arch/sandbox/board/.gitignore1
-rw-r--r--arch/sandbox/board/Makefile7
-rw-r--r--arch/sandbox/board/hostfile.c22
-rw-r--r--arch/sandbox/board/stickypage.S3
-rw-r--r--arch/sandbox/dts/sandbox.dts3
-rw-r--r--arch/sandbox/mach-sandbox/include/mach/linux.h2
-rw-r--r--arch/sandbox/os/common.c74
8 files changed, 85 insertions, 36 deletions
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index d5ba05ba86..04fb7a1f1d 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -31,7 +31,8 @@ KBUILD_CFLAGS += -Dmalloc=barebox_malloc -Dcalloc=barebox_calloc \
-Dclosedir=barebox_closedir -Dreadlink=barebox_readlink \
-Doptarg=barebox_optarg -Doptind=barebox_optind \
-Dsetjmp=barebox_setjmp -Dlongjmp=barebox_longjmp \
- -Dputchar=barebox_putchar
+ -Dmkdir=barebox_mkdir -Ddirname=barebox_dirname \
+ -Dremove=barebox_remove -Dputchar=barebox_putchar
machdirs := $(patsubst %,arch/sandbox/mach-%/,$(machine-y))
@@ -75,11 +76,7 @@ cmd_barebox__ = $(CC) -o $@ $(BAREBOX_LDFLAGS)
common-y += $(BOARD) arch/sandbox/os/ arch/sandbox/lib/
-stickypage.bin:
- @$(kecho) " LN stickypage.bin"
- @ln -fs arch/sandbox/board/stickypage.bin stickypage.bin
-
-KBUILD_IMAGE := barebox stickypage.bin
+KBUILD_IMAGE := barebox
common-$(CONFIG_OFTREE) += arch/sandbox/dts/
diff --git a/arch/sandbox/board/.gitignore b/arch/sandbox/board/.gitignore
index c0acd24b98..03987a7009 100644
--- a/arch/sandbox/board/.gitignore
+++ b/arch/sandbox/board/.gitignore
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
barebox.lds
-stickypage.bin
diff --git a/arch/sandbox/board/Makefile b/arch/sandbox/board/Makefile
index 11688c5aba..b4bab02163 100644
--- a/arch/sandbox/board/Makefile
+++ b/arch/sandbox/board/Makefile
@@ -13,9 +13,4 @@ obj-$(CONFIG_LED) += led.o
extra-y += barebox.lds
-extra-y += stickypage.bin
-
-OBJCOPYFLAGS_stickypage.bin = -O binary
-
-%.bin: %.o
- $(call if_changed,objcopy)
+obj-y += stickypage.o
diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index ca21703544..225617fe91 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -248,7 +248,20 @@ static int of_hostfile_map_fixup(struct device_node *root, void *ctx)
struct device_node *node;
int ret;
- for_each_compatible_node_from(node, root, NULL, hostfile_dt_ids->compatible) {
+ for_each_compatible_node_from(node, root, NULL, "barebox,stickypage") {
+ char *filename;
+
+ filename = linux_get_stickypage_path();
+ if (!filename) {
+ pr_err("error allocating stickypage\n");
+ continue;
+ }
+
+ of_property_write_string(node, "barebox,filename", filename);
+ of_property_write_string(node, "compatible", "barebox,hostfile");
+ }
+
+ for_each_compatible_node_from(node, root, NULL, "barebox,hostfile") {
struct hf_info hf = {};
uint64_t reg[2] = {};
@@ -260,13 +273,6 @@ static int of_hostfile_map_fixup(struct device_node *root, void *ctx)
continue;
}
- if (memcmp(hf.filename, "$build/", 7) == 0) {
- char *fullpath = xasprintf("%s/%s", linux_get_builddir(),
- hf.filename + sizeof "$build/" - 1);
-
- hf.filename = fullpath;
- }
-
hf.is_blockdev = of_property_read_bool(node, "barebox,blockdev");
hf.is_cdev = of_property_read_bool(node, "barebox,cdev");
hf.is_readonly = of_property_read_bool(node, "barebox,read-only");
diff --git a/arch/sandbox/board/stickypage.S b/arch/sandbox/board/stickypage.S
index f1915ab986..1d3861c373 100644
--- a/arch/sandbox/board/stickypage.S
+++ b/arch/sandbox/board/stickypage.S
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
+.section .note.GNU-stack,"",%progbits
+.section .rodata.stickypage,"a"
+
.globl stickypage;
stickypage:
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 6a0ae77d65..f3fe6ce65c 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -56,8 +56,7 @@
};
stickypage: stickypage {
- compatible = "barebox,hostfile", "syscon";
- barebox,filename = "$build/stickypage.bin";
+ compatible = "barebox,stickypage", "syscon";
reg = <0 0 0 4096>;
barebox,cdev; /* no caching allowed */
barebox,feature-controller;
diff --git a/arch/sandbox/mach-sandbox/include/mach/linux.h b/arch/sandbox/mach-sandbox/include/mach/linux.h
index 028bc2fa90..f4d91f08de 100644
--- a/arch/sandbox/mach-sandbox/include/mach/linux.h
+++ b/arch/sandbox/mach-sandbox/include/mach/linux.h
@@ -15,7 +15,7 @@ int linux_register_device(const char *name, void *start, void *end);
int tap_alloc(const char *dev);
uint64_t linux_get_time(void);
int linux_open(const char *filename, int readwrite);
-const char *linux_get_builddir(void);
+char *linux_get_stickypage_path(void);
int linux_open_hostfile(struct hf_info *hf);
int linux_read(int fd, void *buf, size_t count);
int linux_read_nonblock(int fd, void *buf, size_t count);
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index 2878eda29e..3446074f99 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -75,6 +75,15 @@ static void cookmode(void)
tcsetattr(0, TCSANOW, &term_orig);
}
+static char *stickypage_path;
+
+static void prepare_exit(void)
+{
+ cookmode();
+ if (stickypage_path)
+ remove(stickypage_path);
+}
+
int linux_tstc(int fd)
{
struct timeval tv = {
@@ -122,7 +131,7 @@ uint64_t linux_get_time(void)
void __attribute__((noreturn)) linux_exit(void)
{
- cookmode();
+ prepare_exit();
exit(0);
}
@@ -167,7 +176,7 @@ void linux_reexec(void)
void linux_hang(void)
{
- cookmode();
+ prepare_exit();
/* falls through to generic hang() */
}
@@ -329,19 +338,60 @@ static int add_image(const char *_str, char *devname_template, int *devname_numb
return ret;
}
-const char *linux_get_builddir(void)
+extern uint8_t stickypage[4096];
+
+char *linux_get_stickypage_path(void)
{
- static char path[4097];
- int ret;
+ size_t nwritten;
+ ssize_t ret;
+ int fd;
- if (!path[0]) {
- ret = selfpath(path, sizeof(path));
- if (ret < 0)
- return NULL;
- dirname(path);
+ ret = asprintf(&stickypage_path, "%s/barebox/stickypage.%lu",
+ getenv("XDG_RUNTIME_DIR") ?: "/run", (long)getpid());
+ if (ret < 0)
+ goto err_asprintf;
+
+ ret = mkdir(dirname(stickypage_path), 0755);
+ if (ret < 0 && errno != EEXIST) {
+ perror("mkdir");
+ goto err_creat;
}
- return path;
+ stickypage_path[strlen(stickypage_path)] = '/';
+
+ fd = open(stickypage_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644);
+ if (fd < 0) {
+ if (errno == EEXIST)
+ return stickypage_path;
+
+ perror("open");
+ goto err_creat;
+ }
+
+ for (nwritten = 0; nwritten < sizeof(stickypage); ) {
+ ret = write(fd, &stickypage[nwritten], sizeof(stickypage) - nwritten);
+ if (ret < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ perror("write");
+ goto err_write;
+ }
+
+ nwritten += ret;
+ }
+
+ close(fd);
+
+ return stickypage_path;
+
+err_write:
+ close(fd);
+err_creat:
+ free(stickypage_path);
+err_asprintf:
+ stickypage_path = NULL;
+
+ return NULL;
}
int linux_open_hostfile(struct hf_info *hf)
@@ -469,7 +519,7 @@ int main(int argc, char *argv[])
char *aux;
#ifdef CONFIG_ASAN
- __sanitizer_set_death_callback(cookmode);
+ __sanitizer_set_death_callback(prepare_exit);
#endif
while (1) {