mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
Added ARMv7-A SMP Linux build scripts(A5,A7,A9) (#674)
* ports: add Linux build scripts for Cortex-A5 SMP * ports: fix Cortex-A5 SMP sample linking on Linux * ports: add Linux build scripts for Cortex-A7 and A9 SMP * ports: fix Cortex-A7 SMP assembly source path * wip: add ATFE selection to Armv7 SMP scripts * ports: complete Armv7 SMP Linux toolchain support * ports: add local startup for Armv7 SMP samples * ports: add license headers to Armv7 SMP scripts * Dropped the preprocessing flag the file extension now carries Two lines named assembly sources that #672 renamed. That change moved twenty-nine files under gnu trees from .s to .S, because GAS runs the C preprocessor on .S and not on .s: in a .s file every # line is a comment, so a #define is never substituted and an #if/#else pair emits both arms. Four files were silently doing the wrong thing as a result, including ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s, which ignored all four of its own feature macros. These scripts had worked around the same defect with -x assembler-with-cpp rather than hitting it, which was correct when they were written. With the rename the flag is redundant and the lowercase names no longer resolve, so cortex_a5_smp/build_threadx.sh failed with "cc1: fatal error: tx_initialize_low_level.s: No such file or directory". The other seven references to those two files across these three scripts already named them with a capital S. Verified with the pinned Arm GNU 14.3.rel1 rather than the 13.2 that a distro package supplies: build_threadx.sh and build_threadx_sample.sh both succeed for a5, a7 and a9, all three link a sample_threadx.out, and scripts/check_gcc.sh passes end to end with its example stage reading 45 of 45, up from 42. Assisted-by: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
This commit is contained in:
co-authored by
Frédéric Desbiens
parent
383dd311cd
commit
a8c84593dd
+295
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
##############################################################################
|
||||
# Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the MIT License which is available at
|
||||
# https://opensource.org/licenses/MIT.
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
##############################################################################
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# this script builds the ThreadX sample image for the Cortex-A5 SMP port using
|
||||
# GNU toolchain or llvm/clang toolchain (defaults to GNU).
|
||||
: "${TOOLCHAIN:=gnu}"
|
||||
case "${TOOLCHAIN}" in
|
||||
gnu)
|
||||
CC="arm-none-eabi-gcc"
|
||||
TARGET_FLAGS=""
|
||||
# GNU and Clang use different driver syntax for selecting the program's
|
||||
# entry-point symbol.
|
||||
ENTRY_FLAG="-e Vectors"
|
||||
# Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
|
||||
# while ATFE requires a semihost library.
|
||||
SYSCALL_LIB="--specs=nosys.specs"
|
||||
;;
|
||||
atfe)
|
||||
CC="${ATFE_CLANG:-clang}"
|
||||
TARGET_FLAGS="--target=arm-none-eabi"
|
||||
ENTRY_FLAG="-Wl,--entry=Vectors"
|
||||
SYSCALL_LIB="-lsemihost"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a5 sample_threadx.c
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 startup.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 crt0.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_GIC.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_SCU.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_Mutexes.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_PrivateTimer.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 v7.S
|
||||
"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a5 -nostartfiles \
|
||||
-T sample_threadx.ld \
|
||||
${ENTRY_FLAG} \
|
||||
${SYSCALL_LIB} \
|
||||
-o sample_threadx.out \
|
||||
MP_PrivateTimer.o MP_GIC.o MP_Mutexes.o MP_SCU.o \
|
||||
sample_threadx.o startup.o crt0.o v7.o tx.a \
|
||||
-Wl,-M > sample_threadx.map
|
||||
@@ -0,0 +1,101 @@
|
||||
|
||||
.syntax unified
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb
|
||||
#else
|
||||
.arm
|
||||
#endif
|
||||
|
||||
/* .text is used instead of .section .text so it works with arm-aout too. */
|
||||
.text
|
||||
.align 0
|
||||
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _mainCRTStartup
|
||||
_mainCRTStartup:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _start
|
||||
_start:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global start
|
||||
start:
|
||||
|
||||
/* Start by setting up a stack */
|
||||
/* Set up the stack pointer to a fixed value */
|
||||
ldr r3, .LC0
|
||||
mov sp, r3
|
||||
/* Setup a default stack-limit in case the code has been
|
||||
compiled with "-mapcs-stack-check". Hard-wiring this value
|
||||
is not ideal, since there is currently no support for
|
||||
checking that the heap and stack have not collided, or that
|
||||
this default 64k is enough for the program being executed.
|
||||
However, it ensures that this simple crt0 world will not
|
||||
immediately cause an overflow event: */
|
||||
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
|
||||
mov a2, #0 /* Second arg: fill value */
|
||||
mov fp, a2 /* Null frame pointer */
|
||||
mov r7, a2 /* Null frame pointer for Thumb */
|
||||
|
||||
ldr a1, .LC1 /* First arg: start of memory block */
|
||||
ldr a3, .LC2
|
||||
sub a3, a3, a1 /* Third arg: length of block */
|
||||
|
||||
|
||||
|
||||
bl memset
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
#ifdef __USES_INITFINI__
|
||||
/* Some arm/elf targets use the .init and .fini sections
|
||||
to create constructors and destructors, and for these
|
||||
targets we need to call the _init function and arrange
|
||||
for _fini to be called at program exit. */
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
/* ldr r0, .Lfini */
|
||||
bl atexit
|
||||
/* bl init */
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
#endif
|
||||
bl main
|
||||
|
||||
bl exit /* Should not return. */
|
||||
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
positive offsets are supported for PC relative addresses. */
|
||||
|
||||
.align 0
|
||||
.LC0:
|
||||
.LC1:
|
||||
.word __bss_start__
|
||||
.LC2:
|
||||
.word __bss_end__
|
||||
/*
|
||||
#ifdef __USES_INITFINI__
|
||||
.Lfini:
|
||||
.word _fini
|
||||
#endif */
|
||||
/* Return ... */
|
||||
bx lr
|
||||
|
||||
.global _fini
|
||||
.type _fini,function
|
||||
_fini:
|
||||
BX lr // Return to caller
|
||||
|
||||
/* Workspace for Angel calls. */
|
||||
.data
|
||||
/* Data returned by monitor SWI. */
|
||||
.global __stack_base__
|
||||
HeapBase: .word 0
|
||||
HeapLimit: .word 0
|
||||
__stack_base__: .word 0
|
||||
StackLimit: .word 0
|
||||
+295
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
##############################################################################
|
||||
# Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the MIT License which is available at
|
||||
# https://opensource.org/licenses/MIT.
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
##############################################################################
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# this script builds the ThreadX sample image for the Cortex-A7 SMP port using
|
||||
# GNU toolchain or llvm/clang toolchain (defaults to GNU).
|
||||
: "${TOOLCHAIN:=gnu}"
|
||||
case "${TOOLCHAIN}" in
|
||||
gnu)
|
||||
CC="arm-none-eabi-gcc"
|
||||
TARGET_FLAGS=""
|
||||
# GNU and Clang use different driver syntax for selecting the program's
|
||||
# entry-point symbol.
|
||||
ENTRY_FLAG="-e Vectors"
|
||||
# Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
|
||||
# while ATFE requires a semihost library.
|
||||
SYSCALL_LIB="--specs=nosys.specs"
|
||||
;;
|
||||
atfe)
|
||||
CC="${ATFE_CLANG:-clang}"
|
||||
TARGET_FLAGS="--target=arm-none-eabi"
|
||||
ENTRY_FLAG="-Wl,--entry=Vectors"
|
||||
SYSCALL_LIB="-lsemihost"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a7 sample_threadx.c
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 startup.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 crt0.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 MP_GIC.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 MP_Mutexes.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 v7.S
|
||||
"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a7 -nostartfiles \
|
||||
-T sample_threadx.ld \
|
||||
${SYSCALL_LIB} \
|
||||
${ENTRY_FLAG} \
|
||||
-o sample_threadx.out \
|
||||
MP_GIC.o MP_Mutexes.o \
|
||||
sample_threadx.o startup.o crt0.o v7.o tx.a \
|
||||
-Wl,-M > sample_threadx.map
|
||||
@@ -0,0 +1,101 @@
|
||||
|
||||
.syntax unified
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb
|
||||
#else
|
||||
.arm
|
||||
#endif
|
||||
|
||||
/* .text is used instead of .section .text so it works with arm-aout too. */
|
||||
.text
|
||||
.align 0
|
||||
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _mainCRTStartup
|
||||
_mainCRTStartup:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _start
|
||||
_start:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global start
|
||||
start:
|
||||
|
||||
/* Start by setting up a stack */
|
||||
/* Set up the stack pointer to a fixed value */
|
||||
ldr r3, .LC0
|
||||
mov sp, r3
|
||||
/* Setup a default stack-limit in case the code has been
|
||||
compiled with "-mapcs-stack-check". Hard-wiring this value
|
||||
is not ideal, since there is currently no support for
|
||||
checking that the heap and stack have not collided, or that
|
||||
this default 64k is enough for the program being executed.
|
||||
However, it ensures that this simple crt0 world will not
|
||||
immediately cause an overflow event: */
|
||||
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
|
||||
mov a2, #0 /* Second arg: fill value */
|
||||
mov fp, a2 /* Null frame pointer */
|
||||
mov r7, a2 /* Null frame pointer for Thumb */
|
||||
|
||||
ldr a1, .LC1 /* First arg: start of memory block */
|
||||
ldr a3, .LC2
|
||||
sub a3, a3, a1 /* Third arg: length of block */
|
||||
|
||||
|
||||
|
||||
bl memset
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
#ifdef __USES_INITFINI__
|
||||
/* Some arm/elf targets use the .init and .fini sections
|
||||
to create constructors and destructors, and for these
|
||||
targets we need to call the _init function and arrange
|
||||
for _fini to be called at program exit. */
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
/* ldr r0, .Lfini */
|
||||
bl atexit
|
||||
/* bl init */
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
#endif
|
||||
bl main
|
||||
|
||||
bl exit /* Should not return. */
|
||||
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
positive offsets are supported for PC relative addresses. */
|
||||
|
||||
.align 0
|
||||
.LC0:
|
||||
.LC1:
|
||||
.word __bss_start__
|
||||
.LC2:
|
||||
.word __bss_end__
|
||||
/*
|
||||
#ifdef __USES_INITFINI__
|
||||
.Lfini:
|
||||
.word _fini
|
||||
#endif */
|
||||
/* Return ... */
|
||||
bx lr
|
||||
|
||||
.global _fini
|
||||
.type _fini,function
|
||||
_fini:
|
||||
BX lr // Return to caller
|
||||
|
||||
/* Workspace for Angel calls. */
|
||||
.data
|
||||
/* Data returned by monitor SWI. */
|
||||
.global __stack_base__
|
||||
HeapBase: .word 0
|
||||
HeapLimit: .word 0
|
||||
__stack_base__: .word 0
|
||||
StackLimit: .word 0
|
||||
+295
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
##############################################################################
|
||||
# Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the MIT License which is available at
|
||||
# https://opensource.org/licenses/MIT.
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
##############################################################################
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# this script builds the ThreadX sample image for the Cortex-A9 SMP port using
|
||||
# GNU toolchain or llvm/clang toolchain (defaults to GNU).
|
||||
: "${TOOLCHAIN:=gnu}"
|
||||
case "${TOOLCHAIN}" in
|
||||
gnu)
|
||||
CC="arm-none-eabi-gcc"
|
||||
TARGET_FLAGS="" # GNU and Clang use different driver syntax for selecting the program's
|
||||
# entry-point symbol.
|
||||
ENTRY_FLAG="-e Vectors"
|
||||
# Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
|
||||
# while ATFE requires a semihost library.
|
||||
SYSCALL_LIB="--specs=nosys.specs"
|
||||
;;
|
||||
atfe)
|
||||
CC="${ATFE_CLANG:-clang}"
|
||||
TARGET_FLAGS="--target=arm-none-eabi"
|
||||
ENTRY_FLAG="-Wl,--entry=Vectors"
|
||||
SYSCALL_LIB="-lsemihost"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a9 sample_threadx.c
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 startup.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 crt0.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_GIC.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_SCU.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_Mutexes.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_PrivateTimer.S
|
||||
"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 v7.S
|
||||
"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a9 -nostartfiles \
|
||||
-T sample_threadx.ld \
|
||||
${ENTRY_FLAG} \
|
||||
${SYSCALL_LIB} \
|
||||
-o sample_threadx.out MP_PrivateTimer.o MP_GIC.o MP_Mutexes.o MP_SCU.o \
|
||||
sample_threadx.o startup.o crt0.o v7.o tx.a \
|
||||
-Wl,-M > sample_threadx.map
|
||||
@@ -0,0 +1,101 @@
|
||||
|
||||
.syntax unified
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb
|
||||
#else
|
||||
.arm
|
||||
#endif
|
||||
|
||||
/* .text is used instead of .section .text so it works with arm-aout too. */
|
||||
.text
|
||||
.align 0
|
||||
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _mainCRTStartup
|
||||
_mainCRTStartup:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global _start
|
||||
_start:
|
||||
#if defined(THUMB_MODE)
|
||||
.thumb_func
|
||||
#endif
|
||||
.global start
|
||||
start:
|
||||
|
||||
/* Start by setting up a stack */
|
||||
/* Set up the stack pointer to a fixed value */
|
||||
ldr r3, .LC0
|
||||
mov sp, r3
|
||||
/* Setup a default stack-limit in case the code has been
|
||||
compiled with "-mapcs-stack-check". Hard-wiring this value
|
||||
is not ideal, since there is currently no support for
|
||||
checking that the heap and stack have not collided, or that
|
||||
this default 64k is enough for the program being executed.
|
||||
However, it ensures that this simple crt0 world will not
|
||||
immediately cause an overflow event: */
|
||||
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
|
||||
mov a2, #0 /* Second arg: fill value */
|
||||
mov fp, a2 /* Null frame pointer */
|
||||
mov r7, a2 /* Null frame pointer for Thumb */
|
||||
|
||||
ldr a1, .LC1 /* First arg: start of memory block */
|
||||
ldr a3, .LC2
|
||||
sub a3, a3, a1 /* Third arg: length of block */
|
||||
|
||||
|
||||
|
||||
bl memset
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
#ifdef __USES_INITFINI__
|
||||
/* Some arm/elf targets use the .init and .fini sections
|
||||
to create constructors and destructors, and for these
|
||||
targets we need to call the _init function and arrange
|
||||
for _fini to be called at program exit. */
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
/* ldr r0, .Lfini */
|
||||
bl atexit
|
||||
/* bl init */
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
#endif
|
||||
bl main
|
||||
|
||||
bl exit /* Should not return. */
|
||||
|
||||
|
||||
/* For Thumb, constants must be after the code since only
|
||||
positive offsets are supported for PC relative addresses. */
|
||||
|
||||
.align 0
|
||||
.LC0:
|
||||
.LC1:
|
||||
.word __bss_start__
|
||||
.LC2:
|
||||
.word __bss_end__
|
||||
/*
|
||||
#ifdef __USES_INITFINI__
|
||||
.Lfini:
|
||||
.word _fini
|
||||
#endif */
|
||||
/* Return ... */
|
||||
bx lr
|
||||
|
||||
.global _fini
|
||||
.type _fini,function
|
||||
_fini:
|
||||
BX lr // Return to caller
|
||||
|
||||
/* Workspace for Angel calls. */
|
||||
.data
|
||||
/* Data returned by monitor SWI. */
|
||||
.global __stack_base__
|
||||
HeapBase: .word 0
|
||||
HeapLimit: .word 0
|
||||
__stack_base__: .word 0
|
||||
StackLimit: .word 0
|
||||
Reference in New Issue
Block a user