mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
base-linux: 64-bit ARM support
This patch adds support for running Genode/Linux on the AARCH64 architecture. - The kernel-agnostic startup code (crt0) had to be extended to capture the initial stack pointer, which the Linux kernel uses to pass the process environment. This is in line with the existing startup code for x86_32 and x86_64. - The link order of the host libraries linked to lx_hybrid programs had to be adjusted such that libgcc appears at last because the other libraries depend on symbols provided by libgcc. - When using AARCH64 Linux as host, one can execute run scripts via 'make run/<script> KERNEL=linux BOARD=linux' now. Issue #4136
This commit is contained in:
parent
718f44ae5b
commit
2f9d430c00
@ -74,7 +74,7 @@ EXT_OBJECTS += $(shell $(CUSTOM_CC) $(CC_MARCH) -print-file-name=crtbegin.o)
|
||||
EXT_OBJECTS += $(shell $(CUSTOM_CC) $(CC_MARCH) -print-file-name=crtend.o)
|
||||
EXT_OBJECTS += $(shell $(CUSTOM_HOST_CC) $(CC_MARCH) -print-file-name=crtn.o)
|
||||
|
||||
LX_LIBS_OPT += -lgcc -lgcc_s -lsupc++ -lc -lpthread
|
||||
LX_LIBS_OPT += -lgcc_s -lsupc++ -lc -lpthread -lgcc
|
||||
|
||||
USE_HOST_LD_SCRIPT = yes
|
||||
|
||||
@ -98,6 +98,11 @@ CXX_LINK_OPT += -Wl,--dynamic-linker=/lib/ld-linux.so.3
|
||||
LD_SCRIPT_STATIC = ldscripts/armelf_linux_eabi.xc
|
||||
endif
|
||||
|
||||
ifeq (arm_64,$(findstring arm_64,$(SPECS)))
|
||||
CXX_LINK_OPT += -Wl,--dynamic-linker=/lib/ld-linux-aarch64.so.1
|
||||
LD_SCRIPT_STATIC = /usr/lib/aarch64-linux-gnu/ldscripts/aarch64elf.xc
|
||||
endif
|
||||
|
||||
#
|
||||
# Because we use the host compiler's libgcc, omit the Genode toolchain's
|
||||
# version and put all libraries here we depend on.
|
||||
|
@ -11,6 +11,7 @@ HOST_INC_DIR += /usr/include/$(shell $(CUSTOM_HOST_CC) -dumpmachine)
|
||||
#
|
||||
HOST_INC_DIR += /usr/include/i386-linux-gnu
|
||||
HOST_INC_DIR += /usr/include/x86_64-linux-gnu
|
||||
HOST_INC_DIR += /usr/include/aarch64-linux-gnu
|
||||
|
||||
#
|
||||
# Some header files installed on GNU/Linux test for the GNU compiler. For
|
||||
|
3
repos/base-linux/lib/mk/spec/arm_64/base-linux.mk
Normal file
3
repos/base-linux/lib/mk/spec/arm_64/base-linux.mk
Normal file
@ -0,0 +1,3 @@
|
||||
LIBS += timeout-arm
|
||||
|
||||
include $(REP_DIR)/lib/mk/base-linux.mk
|
3
repos/base-linux/lib/mk/spec/arm_64/ld-linux.mk
Normal file
3
repos/base-linux/lib/mk/spec/arm_64/ld-linux.mk
Normal file
@ -0,0 +1,3 @@
|
||||
BASE_LIBS += base-linux-common base-linux
|
||||
|
||||
include $(BASE_DIR)/lib/mk/spec/arm_64/ld-platform.inc
|
3
repos/base-linux/lib/mk/spec/arm_64/seccomp.mk
Normal file
3
repos/base-linux/lib/mk/spec/arm_64/seccomp.mk
Normal file
@ -0,0 +1,3 @@
|
||||
SRC_BIN += seccomp_bpf_policy.bin
|
||||
|
||||
vpath seccomp_bpf_policy.bin $(REP_DIR)/src/lib/seccomp/spec/arm_64
|
1
repos/base-linux/lib/mk/spec/arm_64/startup-linux.mk
Normal file
1
repos/base-linux/lib/mk/spec/arm_64/startup-linux.mk
Normal file
@ -0,0 +1 @@
|
||||
include $(BASE_DIR)/lib/mk/spec/arm_64/startup.inc
|
5
repos/base-linux/lib/mk/spec/arm_64/syscall-linux.mk
Normal file
5
repos/base-linux/lib/mk/spec/arm_64/syscall-linux.mk
Normal file
@ -0,0 +1,5 @@
|
||||
SRC_S += lx_clone.S
|
||||
SRC_S += lx_syscall.S
|
||||
|
||||
vpath lx_clone.S $(REP_DIR)/src/lib/syscall/spec/arm_64
|
||||
vpath lx_syscall.S $(REP_DIR)/src/lib/syscall/spec/arm_64
|
@ -6,7 +6,7 @@ lib/import src/ld:
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
content:
|
||||
for spec in x86_32 x86_64 arm; do \
|
||||
for spec in x86_32 x86_64 arm arm_64; do \
|
||||
mv lib/mk/spec/$$spec/ld-linux.mk lib/mk/spec/$$spec/ld.mk; done;
|
||||
sed -i "/TARGET/s/core-linux/core/" src/core/linux/target.mk
|
||||
sed -i "s/BOARD.*unknown/BOARD := linux/" lib/mk/core-linux.inc
|
||||
|
@ -60,6 +60,11 @@ inline int lx_open(char const *pathname, int flags, mode_t mode = 0)
|
||||
|
||||
inline int lx_stat_size(char const *path, Genode::uint64_t &out_size)
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
struct statx buf { };
|
||||
int result = lx_syscall(SYS_statx, AT_FDCWD, path, 0, STATX_SIZE, &buf);
|
||||
out_size = buf.stx_size;
|
||||
#else
|
||||
#ifdef _LP64
|
||||
struct stat buf { };
|
||||
int result = lx_syscall(SYS_stat, path, &buf);
|
||||
@ -68,6 +73,7 @@ inline int lx_stat_size(char const *path, Genode::uint64_t &out_size)
|
||||
struct stat64 buf { };
|
||||
int result = lx_syscall(SYS_stat64, path, &buf);
|
||||
out_size = buf.st_size;
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
Binary file not shown.
@ -356,7 +356,7 @@ inline int lx_sigaction(int signum, void (*handler)(int), bool altstack)
|
||||
* with EINTR. We therefore set the SA_RESTART flag in signal handlers.
|
||||
*/
|
||||
|
||||
#ifdef _LP64
|
||||
#ifdef __x86_64__
|
||||
/*
|
||||
* The SA_RESTORER flag is not officially documented, but used internally
|
||||
* by the glibc implementation of sigaction(). Without specifying this flag
|
||||
|
19
repos/base-linux/src/lib/syscall/spec/arm_64/lx_clone.S
Normal file
19
repos/base-linux/src/lib/syscall/spec/arm_64/lx_clone.S
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* \brief Linux clone() binding
|
||||
* \author Norman Feske
|
||||
* \date 2021-04-12
|
||||
*/
|
||||
|
||||
#define SYS_clone 220
|
||||
|
||||
.text
|
||||
.globl lx_clone
|
||||
.type lx_clone, #function
|
||||
lx_clone:
|
||||
stp x29, x30, [sp, #-16]! /* save sp and link register */
|
||||
stp x3, x0, [x1, #-16]! /* supply fn and argp at new thread's stack */
|
||||
mov x0, x2 /* flags */
|
||||
mov w8, #SYS_clone
|
||||
svc #0 /* syscall, return value in x0 */
|
||||
ldp x29, x30, [sp], #16 /* restore sp and link register */
|
||||
ret
|
21
repos/base-linux/src/lib/syscall/spec/arm_64/lx_syscall.S
Normal file
21
repos/base-linux/src/lib/syscall/spec/arm_64/lx_syscall.S
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Linux syscall() binding
|
||||
* \author Norman Feske
|
||||
* \date 2021-04-07
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl lx_syscall
|
||||
.type lx_syscall, #function
|
||||
lx_syscall:
|
||||
stp x29, x30, [sp, #-16]! /* save sp and link register */
|
||||
mov x8, x0 /* system call number */
|
||||
mov x0, x1 /* arguments ... */
|
||||
mov x1, x2
|
||||
mov x2, x3
|
||||
mov x3, x4
|
||||
mov x4, x5
|
||||
mov x5, x6
|
||||
svc #0 /* syscall, return value in x0 */
|
||||
ldp x29, x30, [sp], #16 /* restore sp and link register */
|
||||
ret
|
3
repos/base/lib/mk/spec/arm_64/startup.inc
Normal file
3
repos/base/lib/mk/spec/arm_64/startup.inc
Normal file
@ -0,0 +1,3 @@
|
||||
include $(BASE_DIR)/lib/mk/startup.inc
|
||||
|
||||
vpath crt0.s $(call select_from_repositories,src/lib/startup/spec/arm_64)
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
* Copyright (C) 2019-2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -24,6 +24,12 @@
|
||||
.global _start_initial_stack
|
||||
_start_initial_stack:
|
||||
|
||||
/* save initial SP value, used to pass the environment on base-linux */
|
||||
adrp x4, :got:__initial_sp
|
||||
ldr x4, [x4, #:got_lo12:__initial_sp]
|
||||
mov x1, sp
|
||||
str x1, [x4]
|
||||
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
@ -53,6 +59,10 @@
|
||||
*********************************/
|
||||
|
||||
.bss
|
||||
/* initial value of the SP register */
|
||||
.global __initial_sp
|
||||
__initial_sp:
|
||||
.space 8
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 8
|
||||
|
@ -8,6 +8,7 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu
|
||||
#BOARD ?= rpi3
|
||||
|
||||
# local variable for run-tool arguments that depend on the used board
|
||||
BOARD_RUN_OPT(linux) := --include power_on/linux --include log/linux
|
||||
BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT)
|
||||
BOARD_RUN_OPT(virt_qemu) := $(QEMU_RUN_OPT)
|
||||
|
||||
|
3
tool/seccomp/.gitignore
vendored
3
tool/seccomp/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/seccomp_bpf_policy_arm.bin
|
||||
/seccomp_bpf_policy_arm_32.bin
|
||||
/seccomp_bpf_policy_arm_64.bin
|
||||
/seccomp_bpf_policy_x86_32.bin
|
||||
/seccomp_bpf_policy_x86_64.bin
|
||||
|
@ -1,6 +1,8 @@
|
||||
.DEFAULT_GOAL := seccomp_bpf_filters
|
||||
|
||||
seccomp_bpf_filters: seccomp_bpf_policy_x86_32.bin seccomp_bpf_policy_x86_64.bin seccomp_bpf_policy_arm.bin
|
||||
ARCHS := x86_32 x86_64 arm_32 arm_64
|
||||
|
||||
seccomp_bpf_filters: $(foreach A,$(ARCHS),seccomp_bpf_policy_$A.bin)
|
||||
|
||||
seccomp_bpf_policy_%.bin: seccomp_bpf_compiler_%.prg
|
||||
./$< > $@
|
||||
|
@ -122,8 +122,9 @@ class Filter
|
||||
_add_allow_rule(SCMP_SYS(gettimeofday));
|
||||
_add_allow_rule(SCMP_SYS(getpeername));
|
||||
|
||||
int clone_flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
|
||||
| CLONE_THREAD | CLONE_SYSVSEM;
|
||||
unsigned long clone_flags = CLONE_VM | CLONE_FS | CLONE_FILES
|
||||
| CLONE_SIGHAND | CLONE_THREAD
|
||||
| CLONE_SYSVSEM;
|
||||
|
||||
switch (_arch)
|
||||
{
|
||||
@ -196,6 +197,16 @@ class Filter
|
||||
_add_allow_rule(SCMP_SYS(sigreturn));
|
||||
}
|
||||
break;
|
||||
case SCMP_ARCH_AARCH64:
|
||||
{
|
||||
_add_allow_rule(SCMP_SYS(tgkill), SCMP_CMP32(0, SCMP_CMP_EQ, 0xCAFEAFFE),
|
||||
SCMP_CMP32(2, SCMP_CMP_EQ, SIGRTMIN));
|
||||
_add_allow_rule(SCMP_SYS(clone), SCMP_CMP32(0, SCMP_CMP_EQ, clone_flags));
|
||||
_add_allow_rule(SCMP_SYS(mmap));
|
||||
_add_allow_rule(SCMP_SYS(cacheflush));
|
||||
_add_allow_rule(SCMP_SYS(sigreturn));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported architecture\n");
|
||||
throw -104;
|
||||
|
23
tool/seccomp/seccomp_bpf_compiler_arm_64.cc
Normal file
23
tool/seccomp/seccomp_bpf_compiler_arm_64.cc
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* \brief Generate seccomp filter policy for base-linux on arm
|
||||
* \author Stefan Thoeni
|
||||
* \date 2019-12-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
* Copyright (C) 2019 gapfruit AG
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* printf */
|
||||
#include <seccomp.h> /* libseccomp */
|
||||
#include "seccomp_bpf_compiler.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
Filter filter(SCMP_ARCH_AARCH64);
|
||||
return filter.create();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user