mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
base-linux: add ARM support
This patch introduces a new platform 'linux_arm' for building and running Genode/Linux on an ARM device. Known limitations: - libc 'setjmp()'/'longjmp()' doesn't currently save/restore floating point registers Fixes #746.
This commit is contained in:
committed by
Norman Feske
parent
314d5c0975
commit
4a9b1c6aab
@ -70,7 +70,13 @@ Process::Process(Dataspace_capability elf_data_ds_cap,
|
||||
PERR("Dynamically linked file found, but no dynamic linker binary present");
|
||||
return;
|
||||
}
|
||||
elf_data_ds_cap = _dynamic_linker_cap;
|
||||
/*
|
||||
* Starting the dynamic linker directly may cause it to be loaded at the
|
||||
* wrong address on ARM-Linux. But since the dynamically linked
|
||||
* application has a dynamic linker (by default ld.lib.so) defined as its
|
||||
* interpreter in the ELF image, it's okay to just start the application
|
||||
* directly on Linux.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
66
base-linux/src/platform/arm/crt0.s
Normal file
66
base-linux/src/platform/arm/crt0.s
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* \brief Startup code for Genode applications
|
||||
* \author Christian Helmuth
|
||||
* \author Christian Prochaska
|
||||
* \date 2006-07-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
ldr r1,=__initial_sp
|
||||
str sp,[r1]
|
||||
|
||||
/*
|
||||
* environ = &argv[argc + 1]
|
||||
* in Genode argc is always 1
|
||||
*/
|
||||
add sp,sp,#12
|
||||
ldr r1,=lx_environ
|
||||
str sp,[r1]
|
||||
|
||||
/* XXX Switch to our own stack. */
|
||||
ldr sp,=_stack_high
|
||||
|
||||
/* Clear the frame pointer and the link register so that stack backtraces will work. */
|
||||
mov fp,#0
|
||||
mov lr,#0
|
||||
|
||||
/* Jump into init C code */
|
||||
b _main
|
||||
|
||||
/*--------------------------------------------------*/
|
||||
.data
|
||||
.globl __dso_handle
|
||||
__dso_handle:
|
||||
.long 0
|
||||
|
||||
.globl __initial_sp
|
||||
__initial_sp:
|
||||
.long 0
|
||||
|
||||
/*--- .eh_frame (exception frames) -----------------*/
|
||||
/*
|
||||
.section .eh_frame,"aw"
|
||||
.globl __EH_FRAME_BEGIN__
|
||||
__EH_FRAME_BEGIN__:
|
||||
*/
|
||||
|
||||
/*--- .bss (non-initialized data) ------------------*/
|
||||
.bss
|
||||
.p2align 4
|
||||
.globl _stack_low
|
||||
_stack_low:
|
||||
.space 64*1024
|
||||
.globl _stack_high
|
||||
_stack_high:
|
94
base-linux/src/platform/arm/lx_clone.S
Normal file
94
base-linux/src/platform/arm/lx_clone.S
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* \brief Linux clone() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-05-05
|
||||
*
|
||||
* based on eglibc-2.11.3/ports/sysdeps/unix/sysv/linux/arm/clone.S
|
||||
*/
|
||||
|
||||
#define SYS_clone 120
|
||||
#define SYS_exit 1
|
||||
#define SYS_getpid 20
|
||||
|
||||
#define __ARM_EABI__ 1
|
||||
|
||||
#define CLONE_VM 0x00000100
|
||||
#define CLONE_THREAD 0x00010000
|
||||
|
||||
.text
|
||||
.globl lx_clone
|
||||
.type lx_clone, #function
|
||||
lx_clone:
|
||||
|
||||
@ insert the args onto the new stack
|
||||
str r3, [r1, #-4]!
|
||||
str r0, [r1, #-4]!
|
||||
|
||||
@ do the system call
|
||||
@ get flags
|
||||
mov r0, r2
|
||||
#ifdef RESET_PID
|
||||
mov ip, r2
|
||||
#endif
|
||||
@ new sp is already in r1
|
||||
#ifdef __ARM_EABI__
|
||||
stmfd sp!, {r4, r7}
|
||||
#else
|
||||
str r4, [sp, #-8]!
|
||||
#endif
|
||||
ldr r2, [sp, #8]
|
||||
ldr r3, [sp, #12]
|
||||
ldr r4, [sp, #16]
|
||||
#ifdef __ARM_EABI__
|
||||
ldr r7, =SYS_clone
|
||||
swi 0x0
|
||||
#else
|
||||
swi SYS_clone
|
||||
#endif
|
||||
cmp r0, #0
|
||||
beq 1f
|
||||
#ifdef __ARM_EABI__
|
||||
ldmfd sp!, {r4, r7}
|
||||
#else
|
||||
ldr r4, [sp], #8
|
||||
#endif
|
||||
#blt PLTJMP(C_SYMBOL_NAME(__syscall_error))
|
||||
bx lr
|
||||
|
||||
1:
|
||||
#ifdef RESET_PID
|
||||
tst ip, #CLONE_THREAD
|
||||
bne 3f
|
||||
mov r0, #0xffff0fff
|
||||
mov lr, pc
|
||||
sub pc, r0, #31
|
||||
mov r1, r0
|
||||
tst ip, #CLONE_VM
|
||||
movne r0, #-1
|
||||
#ifdef __ARM_EABI__
|
||||
ldr r7, =SYS_getpid
|
||||
swieq 0x0
|
||||
#else
|
||||
swieq SYS_getpid
|
||||
#endif
|
||||
str r0, [r1, #PID_OFFSET]
|
||||
str r0, [r1, #TID_OFFSET]
|
||||
3:
|
||||
#endif
|
||||
@ pick the function arg and call address off the stack and execute
|
||||
ldr r0, [sp, #4]
|
||||
#if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
|
||||
ldr ip, [sp], #8
|
||||
mov lr, pc
|
||||
bx ip
|
||||
#else
|
||||
mov lr, pc
|
||||
ldr pc, [sp], #8
|
||||
#endif
|
||||
|
||||
@ and we are done, passing the return value through r0
|
||||
ldr r7, =SYS_exit
|
||||
swi 0x0
|
||||
|
||||
/* tell the linker that this code does not need an executable stack */
|
||||
.section .note.GNU-stack, "", %progbits
|
29
base-linux/src/platform/arm/lx_syscall.S
Normal file
29
base-linux/src/platform/arm/lx_syscall.S
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief Linux syscall() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-05-05
|
||||
*
|
||||
* based on eglibc-2.11.3/ports/sysdeps/unix/sysv/linux/arm/syscall.S
|
||||
*
|
||||
* error case:
|
||||
* glibc's syscall() function returns -1 and sets errno
|
||||
* lx_syscall() returns -errno
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl lx_syscall
|
||||
.type lx_syscall, #function
|
||||
lx_syscall:
|
||||
mov ip, sp
|
||||
stmfd sp!, {r4, r5, r6, r7}
|
||||
mov r7, r0
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
mov r2, r3
|
||||
ldmfd ip, {r3, r4, r5, r6}
|
||||
swi 0x0
|
||||
ldmfd sp!, {r4, r5, r6, r7}
|
||||
bx lr
|
||||
|
||||
/* tell the linker that this code does not need an executable stack */
|
||||
.section .note.GNU-stack, "", %progbits
|
Reference in New Issue
Block a user