[PATCH 09/20] arm: add application support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Wed Mar 6 04:29:38 EST 2013


Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/Kconfig                       |    1 +
 arch/arm/Makefile                      |    6 +-
 arch/arm/apps/Kconfig                  |   11 ++++
 arch/arm/apps/Makefile                 |    6 ++
 arch/arm/apps/apps.lds.S               |   64 ++++++++++++++++++
 arch/arm/apps/binfmt.c                 |  111 ++++++++++++++++++++++++++++++++
 arch/arm/apps/head.S                   |   59 +++++++++++++++++
 arch/arm/apps/include/arch/asm/macro.h |   46 +++++++++++++
 arch/arm/apps/include/arch/setjmp.h    |   26 ++++++++
 arch/arm/apps/raise.c                  |   27 ++++++++
 arch/arm/apps/setjmp.S                 |   60 +++++++++++++++++
 arch/arm/apps/start.c                  |   35 ++++++++++
 12 files changed, 451 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/apps/Kconfig
 create mode 100644 arch/arm/apps/Makefile
 create mode 100644 arch/arm/apps/apps.lds.S
 create mode 100644 arch/arm/apps/binfmt.c
 create mode 100644 arch/arm/apps/head.S
 create mode 100644 arch/arm/apps/include/arch/asm/macro.h
 create mode 100644 arch/arm/apps/include/arch/setjmp.h
 create mode 100644 arch/arm/apps/raise.c
 create mode 100644 arch/arm/apps/setjmp.S
 create mode 100644 arch/arm/apps/start.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f25dcf7..f30859b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
 	bool
 	select HAS_KALLSYMS
 	select HAS_MODULES
+	select HAS_APPLICATIONS
 	select HAVE_CONFIGURABLE_TEXT_BASE
 	select HAVE_PBL_IMAGE
 	select HAVE_IMAGE_COMPRESSION
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 100a3c4..731d92a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -275,9 +275,13 @@ else
 MACH :=
 endif
 
+APP_LDFLAGS += -L $(shell dirname `$(CC) $(CPPFLAGS) -print-libgcc-file-name`) -lgcc
+
 common-y += $(BOARD) $(MACH)
 common-y += arch/arm/lib/ arch/arm/cpu/
+common-$(CONFIG_APPLICATIONS) += arch/arm/apps/
 
 lds-y	:= arch/arm/lib/barebox.lds
+apps-lds-y	:= arch/arm/apps/apps.lds
 
-CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds barebox-flash-image
+CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds arch/arm/apps/apps.lds barebox-flash-image
diff --git a/arch/arm/apps/Kconfig b/arch/arm/apps/Kconfig
new file mode 100644
index 0000000..8fcb79d
--- /dev/null
+++ b/arch/arm/apps/Kconfig
@@ -0,0 +1,11 @@
+
+config APP_TEXT_BASE_OFFSET
+	hex
+	default 0x800000
+	prompt "application text base offset"
+	help
+	  APP_TEXT_BASE = TEXT_BASE - APP_TEXT_BASE_OFFSET
+	  all the application will be link at this address
+	  the syscall table region of 0x2000 will be add
+	  APP_TEXT_BASE - 0x2000 and then the malloc region at
+	  APP_TEXT_BASE - 0x2000 - APP_MALLOC_SIZE
diff --git a/arch/arm/apps/Makefile b/arch/arm/apps/Makefile
new file mode 100644
index 0000000..c7e9a80
--- /dev/null
+++ b/arch/arm/apps/Makefile
@@ -0,0 +1,6 @@
+obj-y += binfmt.o
+app-y += head.o
+app-y += start.o
+app-y += raise.o
+app-y += setjmp.o
+extry-y += apps.lds
diff --git a/arch/arm/apps/apps.lds.S b/arch/arm/apps/apps.lds.S
new file mode 100644
index 0000000..b6e4ab9
--- /dev/null
+++ b/arch/arm/apps/apps.lds.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sizes.h>
+#include <asm-generic/barebox.lds.h>
+#include <asm-generic/memory_layout.h>
+
+#define HEAD_BASE (TEXT_BASE - CONFIG_APP_TEXT_BASE_OFFSET)
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = HEAD_BASE;
+
+	. = ALIGN(4);
+	.text      :
+	{
+		_stext = .;
+		_text = .;
+		*(.text_head_entry*)
+		. = 0x80;
+		KEEP(*(.appinfo.start))
+		__appinfo_start = .;
+		KEEP(*(.appinfo))
+		__appinfo_end = .;
+		KEEP(*(.appinfo.end))
+		*(.text*)
+	}
+
+	/* Discard unwind if enable in barebox */
+	/DISCARD/ : { *(.ARM.ex*) }
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata*) }
+
+	_etext = .;			/* End of text and rodata section */
+
+	. = ALIGN(4);
+	.data : { *(.data*) }
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss*) }
+	__bss_stop = .;
+	_end = .;
+
+	_barebox_app_image_size = __bss_start - HEAD_BASE;
+	_barebox_app_info_size = __appinfo_end - __appinfo_start;
+}
diff --git a/arch/arm/apps/binfmt.c b/arch/arm/apps/binfmt.c
new file mode 100644
index 0000000..f6bc450
--- /dev/null
+++ b/arch/arm/apps/binfmt.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <common.h>
+#include <binfmt.h>
+#include <init.h>
+#include <fs.h>
+#include <sizes.h>
+#include <memory.h>
+#include <malloc.h>
+#include <apps/syscall_init.h>
+
+static int arm_application(char *file, int argc, char **argv, bool is_gpl)
+{
+	struct syscall_trace st;
+	u32 *buf32;
+	u32 load_addr, size;
+	int (*jump)(int argc, char** argv);
+	void *barebox_app;
+	int ret = 0;
+	struct resource *app_res, *syscall_res, *malloc_res;
+
+	barebox_app = read_file(file, NULL);
+	if (!barebox_app)
+		return -EINVAL;
+
+	buf32 = barebox_app + 0x30;
+	load_addr = buf32[0];
+	size = buf32[1];
+
+	app_res = request_sdram_region("application", load_addr, size);
+	if (!app_res) {
+		perror("application: request_sdram_region");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	load_addr -= 0x2000;
+
+	syscall_res = request_sdram_region("bsyscall", load_addr, 0x2000);
+	if (!syscall_res) {
+		perror("application: bsyscall request_sdram_region");
+		ret = -ENOMEM;
+		goto err_app_res;
+	}
+
+	load_addr -= CONFIG_APP_MALLOC_SIZE;
+
+	malloc_res = request_sdram_region("application_malloc", load_addr, CONFIG_APP_MALLOC_SIZE);
+	if (!malloc_res) {
+		perror("application: bsyscall request_sdram_region");
+		ret = -ENOMEM;
+		goto err_malloc_res;
+	}
+
+	memset((void*)malloc_res->start, 0, resource_size(malloc_res));
+	memcpy((void*)app_res->start, barebox_app, size);
+
+	st.dest = (void*)syscall_res->start;
+	st.malloc_base = malloc_res->start;
+	st.malloc_size = resource_size(malloc_res);
+	syscalls_init(&st);
+
+	jump = (void*)app_res->start;
+	ret = jump(argc, argv);
+
+	syscalls_exit(&st);
+
+	release_sdram_region(malloc_res);
+err_malloc_res:
+	release_sdram_region(syscall_res);
+err_app_res:
+	release_sdram_region(app_res);
+err:
+	free(barebox_app);
+	return ret;
+}
+
+static int arm_gpl_application(struct binfmt_hook *b, char *file, int argc, char **argv)
+{
+	return arm_application(file, argc, argv, true);
+}
+
+static struct binfmt_hook binfmt_barebox_gpl_app_hook = {
+	.type = filetype_arm_gpl_application,
+	.hook = arm_gpl_application,
+};
+
+static int arm_non_gpl_application(struct binfmt_hook *b, char *file, int argc, char **argv)
+{
+	/* You are NOT allow to remove this warning */
+	pr_warn("non gpl compatible application\n");
+	return arm_application(file, argc, argv, false);
+}
+
+static struct binfmt_hook binfmt_barebox_app_hook = {
+	.type = filetype_arm_application,
+	.hook = arm_non_gpl_application,
+};
+
+static int arm_app_register_image_handler(void)
+{
+	binfmt_register(&binfmt_barebox_app_hook);
+	binfmt_register(&binfmt_barebox_gpl_app_hook);
+
+	return 0;
+}
+late_initcall(arm_app_register_image_handler);
diff --git a/arch/arm/apps/head.S b/arch/arm/apps/head.S
new file mode 100644
index 0000000..9cc714c
--- /dev/null
+++ b/arch/arm/apps/head.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+	.section ".text_head_entry.start"
+	.globl _start
+_start:
+	/* save register */
+	stmfd	sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, lr}
+	/* save barebox stack */
+	mov	r2, sp
+	/* setup new stack */
+	ldr	sp, =_text
+	sub	sp, #CONFIG_STACK_SIZE
+	b _next
+	.org 0x20
+	.asciz "barebox_arm_app"
+	.word _text				/* text base. If copied there,
+						* barebox can skip relocation
+						*/
+	.word _barebox_app_image_size		/* image size to copy */
+
+_next:
+	stmfd	sp!, {r0-r2}
+1:	ldr	r0, =__bss_start
+	mov	r1, #0
+	ldr	r2, =__bss_stop
+	sub	r2, r2, r0
+	bl	memset			/* clear bss */
+	ldmfd	sp!, {r0-r2}
+
+	b arm_app_start
+
+	.section ".appinfo.start"
+	.asciz "#appinf"
+	.word _barebox_app_info_size
+
+	.section ".appinfo.end"
+	.asciz "appinf#"
+
+	.text
+	.globl barebox_return
+barebox_return:
+	/* restore barebox the stack */
+	mov	sp, r1
+	/* restore register */
+	ldmfd	sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, pc}
diff --git a/arch/arm/apps/include/arch/asm/macro.h b/arch/arm/apps/include/arch/asm/macro.h
new file mode 100644
index 0000000..e451024
--- /dev/null
+++ b/arch/arm/apps/include/arch/asm/macro.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ARCH_ASM_MACRO_H__
+#define __ARCH_ASM_MACRO_H__
+
+#if (!defined(__ARM_ARCH_2__) && !defined(__ARM_ARCH_3__) \
+	&& !defined(__ARM_ARCH_3M__) && !defined(__ARM_ARCH_4__))
+#define BX(x)	bx	x
+#else
+#define BX(x)	mov	pc, x
+#endif
+
+#define __FUNC(x)		\
+	.balign 4;		\
+	.globl x;		\
+
+#ifdef __thumb__
+#define FUNC(x)	\
+	__FUNC(x)	\
+	.thumb_func;	\
+x:
+#else
+#define FUNC(x)		\
+	__FUNC(x)	\
+x:
+#endif
+
+#define ENDFUNC(x)		\
+	.type x, #function;	\
+	.size x, .-x
+
+#endif /* __ARCH_ASM_MACRO_H__ */
diff --git a/arch/arm/apps/include/arch/setjmp.h b/arch/arm/apps/include/arch/setjmp.h
new file mode 100644
index 0000000..82058a9
--- /dev/null
+++ b/arch/arm/apps/include/arch/setjmp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ARCH_SETJMP_H__
+#define __ARCH_SETJMP_H__
+
+struct __jmp_buf {
+		unsigned int regs[10];
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* __ARCH_SETJMP_H__ */
diff --git a/arch/arm/apps/raise.c b/arch/arm/apps/raise.c
new file mode 100644
index 0000000..18cc0d8
--- /dev/null
+++ b/arch/arm/apps/raise.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <stdio.h>
+
+int raise(int signum)
+{
+	/* use puts as printf may not be availlable */
+	puts("raise: ");
+	puts(itoa(signum));
+	puts(" caught\n");
+
+	return 0;
+}
diff --git a/arch/arm/apps/setjmp.S b/arch/arm/apps/setjmp.S
new file mode 100644
index 0000000..1607ce3
--- /dev/null
+++ b/arch/arm/apps/setjmp.S
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <arch/asm/macro.h>
+
+	.text
+FUNC(setjmp)
+#ifndef	__thumb__
+	stmia	r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+#else
+	/* we need to do it in 2 steps in thumb */
+	mov	r3, lr
+	stmia	r0!, {r3, r4, r5, r6, r7}
+	mov	r3, r8
+	mov	r4, r9
+	mov	r5, r10
+	mov	r6, fp
+	mov	r7, sp
+	stmia	r0!, {r3, r4, r5, r6, r7}
+#endif /* __thumb__ */
+	mov	r0, #0
+	BX(lr)
+ENDFUNC(setjmp)
+
+	.text
+FUNC(longjmp)
+#ifndef	__thumb__
+	ldmia	r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+	mov	r0, r1
+	BX(lr)
+#else
+	/* we need to do it in 2 steps in thumb */
+	mov	r2, r0
+	add	r0, #20
+	ldmia	r0!, {r3, r4, r5, r6, r7}
+	mov	r8, r3
+	mov	r9, r4
+	mov	r10, r5
+	mov	fp, r6
+	mov	sp, r7
+	ldmia	r2!, {r3, r4, r5, r6, r7}
+	mov	r0, r1
+	bne	1f
+	mov	r0, #1
+1:	BX(r3)
+#endif /* __thumb__ */
+ENDFUNC(longjmp)
diff --git a/arch/arm/apps/start.c b/arch/arm/apps/start.c
new file mode 100644
index 0000000..af072a1
--- /dev/null
+++ b/arch/arm/apps/start.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+
+static void *barebox_sp;
+void barebox_return(int, void*);
+int app_start(int argc, char **argv);
+
+void exit(int c)
+{
+	barebox_return(c, barebox_sp);
+}
+
+void arm_app_start(int argc, char** argv, void *sp)
+{
+	int ret;
+	barebox_sp = sp;
+
+	ret = app_start(argc, argv);
+	exit(ret);
+}
-- 
1.7.10.4




More information about the barebox mailing list