summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorGUI <[email protected]>2023-07-25 21:31:44 +0800
committerGitHub <[email protected]>2023-07-25 21:31:44 +0800
commit6f119d4ce90a1a4f3b491f21d50a286662f79480 (patch)
tree1e1c2824aa04cabe193a43304b21469caadd2924 /libcpu
parentef91876ee71a63208aec706147a68f60eae8a2fe (diff)
AArch64: support public linker scripts (#7831)
Signed-off-by: GuEe-GUI <[email protected]>
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/Kconfig6
-rwxr-xr-xlibcpu/aarch64/.gitignore1
-rw-r--r--libcpu/aarch64/Kconfig19
-rw-r--r--libcpu/aarch64/SConscript5
-rw-r--r--libcpu/aarch64/common/mmu.c4
-rw-r--r--libcpu/aarch64/cortex-a/entry_point.S48
-rw-r--r--libcpu/aarch64/link.lds.S191
7 files changed, 267 insertions, 7 deletions
diff --git a/libcpu/Kconfig b/libcpu/Kconfig
index 0a667f6281..897ce60555 100644
--- a/libcpu/Kconfig
+++ b/libcpu/Kconfig
@@ -1,3 +1,5 @@
+menu "RT-Thread Architecture"
+
config ARCH_CPU_64BIT
bool
@@ -231,3 +233,7 @@ config ARCH_HOST_SIMULATOR
config ARCH_CPU_STACK_GROWS_UPWARD
bool
default n
+
+source "$RTT_DIR/libcpu/aarch64/Kconfig"
+
+endmenu
diff --git a/libcpu/aarch64/.gitignore b/libcpu/aarch64/.gitignore
new file mode 100755
index 0000000000..feb550d190
--- /dev/null
+++ b/libcpu/aarch64/.gitignore
@@ -0,0 +1 @@
+link.lds
diff --git a/libcpu/aarch64/Kconfig b/libcpu/aarch64/Kconfig
new file mode 100644
index 0000000000..4bb9f1ffe7
--- /dev/null
+++ b/libcpu/aarch64/Kconfig
@@ -0,0 +1,19 @@
+if ARCH_ARMV8 && ARCH_CPU_64BIT
+
+config ARCH_TEXT_OFFSET
+ hex "Text offset"
+ default 0x200000
+
+config ARCH_RAM_OFFSET
+ hex "RAM offset"
+ default 0
+
+config ARCH_SECONDARY_CPU_STACK_SIZE
+ int "Secondary CPU stack size"
+ default 4096
+
+config ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ bool
+ default y
+
+endif
diff --git a/libcpu/aarch64/SConscript b/libcpu/aarch64/SConscript
index 5fca2b473b..d726d2d1f2 100644
--- a/libcpu/aarch64/SConscript
+++ b/libcpu/aarch64/SConscript
@@ -8,6 +8,11 @@ Import('rtconfig')
cwd = GetCurrentDir()
group = []
list = os.listdir(cwd)
+bsp_path = Dir('#').abspath
+
+if not os.path.exists(bsp_path + "/link.lds"):
+ Env['LINKFLAGS'] = Env['LINKFLAGS'].replace('link.lds', cwd + "/link.lds")
+ Preprocessing("link.lds.S", ".lds", CPPPATH=[bsp_path])
# add common code files
group = group + SConscript(os.path.join('common', 'SConscript'))
diff --git a/libcpu/aarch64/common/mmu.c b/libcpu/aarch64/common/mmu.c
index cd55948729..88df1f89ff 100644
--- a/libcpu/aarch64/common/mmu.c
+++ b/libcpu/aarch64/common/mmu.c
@@ -777,8 +777,8 @@ void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1,
#ifdef RT_USING_SMART
unsigned long va = KERNEL_VADDR_START;
#else
- extern unsigned char __start;
- unsigned long va = (unsigned long) &__start;
+ extern unsigned char _start;
+ unsigned long va = (unsigned long) &_start;
va = RT_ALIGN_DOWN(va, 0x200000);
#endif
diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S
index e7e5650ea2..3bdca7b81c 100644
--- a/libcpu/aarch64/cortex-a/entry_point.S
+++ b/libcpu/aarch64/cortex-a/entry_point.S
@@ -6,13 +6,51 @@
* Date Author Notes
* 2020-01-15 bigmagic the first version
* 2020-08-10 SummerGift support clang compiler
+ * 2023-04-29 GuEe-GUI support kernel's ARM64 boot header
*/
#include "rtconfig.h"
-.section ".text.entrypoint","ax"
-.global __start
-__start:
+ .section ".text.entrypoint","ax"
+
+#ifdef RT_USING_OFW
+/*
+ * Our goal is to boot the rt-thread as possible without modifying the
+ * bootloader's config, so we use the kernel's boot header for ARM64:
+ * https://www.kernel.org/doc/html/latest/arm64/booting.html#call-the-kernel-image
+ */
+_head:
+ b _start /* Executable code */
+ .long 0 /* Executable code */
+ .quad _text_offset /* Image load offset from start of RAM, little endian */
+ .quad _end - _head /* Effective Image size, little endian (_end defined in link.lds) */
+ .quad 0xa /* Kernel flags, little endian */
+ .quad 0 /* Reserved */
+ .quad 0 /* Reserved */
+ .quad 0 /* Reserved */
+ .ascii "ARM\x64" /* Magic number */
+ .long 0 /* Reserved (used for PE COFF offset) */
+#endif
+/* Variable registers: x21~x28 */
+dtb_paddr .req x21
+boot_arg0 .req x22
+boot_arg1 .req x23
+boot_arg2 .req x24
+stack_top .req x25
+
+ .global _start
+_start:
+/*
+ * Boot CPU general-purpose register settings:
+ * x0 = physical address of device tree blob (dtb) in system RAM.
+ * x1 = 0 (reserved for future use)
+ * x2 = 0 (reserved for future use)
+ * x3 = 0 (reserved for future use)
+ */
+ mov dtb_paddr, x0
+ mov boot_arg0, x1
+ mov boot_arg1, x2
+ mov boot_arg2, x3
#ifdef ARCH_ARM_BOOTWITH_FLUSH_CACHE
bl __asm_flush_dcache_all
#endif
@@ -127,8 +165,8 @@ __start:
dsb sy
#ifdef RT_USING_SMART
- ldr x2, =__start
- GET_PHY x3, __start
+ ldr x2, =_start
+ GET_PHY x3, _start
sub x3, x3, x2
#else
mov x3,0
diff --git a/libcpu/aarch64/link.lds.S b/libcpu/aarch64/link.lds.S
new file mode 100644
index 0000000000..f3528c6e3a
--- /dev/null
+++ b/libcpu/aarch64/link.lds.S
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date Author Notes
+ * 2017-5-30 bernard first version
+ */
+
+#include "rtconfig.h"
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+#ifndef ARCH_TEXT_OFFSET
+#define ARCH_TEXT_OFFSET 0x200000 /* We always boot in address where is 2MB aligned */
+#endif
+
+#ifndef ARCH_RAM_OFFSET
+#define ARCH_RAM_OFFSET 0
+#endif
+
+SECTIONS
+{
+ _text_offset = ARCH_TEXT_OFFSET;
+
+#ifdef RT_USING_SMART
+ . = KERNEL_VADDR_START + _text_offset;
+#else
+ . = ARCH_RAM_OFFSET + _text_offset;
+#endif
+
+ .text :
+ {
+ PROVIDE(__text_start = .);
+
+ KEEP(*(.text.entrypoint)) /* The entry point */
+ *(.vectors)
+ *(.text) /* remaining code */
+ *(.text.*) /* remaining code */
+
+ *(.rodata) /* read-only data (constants) */
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gnu.linkonce.t*)
+
+ /* section information for utest */
+ . = ALIGN(8);
+ PROVIDE(__rt_utest_tc_tab_start = .);
+ KEEP(*(UtestTcTab))
+ PROVIDE(__rt_utest_tc_tab_end = .);
+
+ /* section information for finsh shell */
+ . = ALIGN(8);
+ PROVIDE(__fsymtab_start = .);
+ KEEP(*(FSymTab))
+ PROVIDE(__fsymtab_end = .);
+ . = ALIGN(8);
+ PROVIDE(__vsymtab_start = .);
+ KEEP(*(VSymTab))
+ PROVIDE(__vsymtab_end = .);
+ . = ALIGN(8);
+
+ /* section information for modules */
+ . = ALIGN(8);
+ PROVIDE(__rtmsymtab_start = .);
+ KEEP(*(RTMSymTab))
+ PROVIDE(__rtmsymtab_end = .);
+
+ /* section information for initialization */
+ . = ALIGN(8);
+ PROVIDE(__rt_init_start = .);
+ KEEP(*(SORT(.rti_fn*)))
+ PROVIDE(__rt_init_end = .);
+
+ /* section information for rt_ofw. */
+ . = ALIGN(16);
+ PROVIDE(__rt_ofw_data_start = .);
+ KEEP(*(SORT(.rt_ofw_data.*)))
+ PROVIDE(__rt_ofw_data_end = .);
+ . = ALIGN(16);
+
+ PROVIDE(__text_end = .);
+ }
+
+ .eh_frame_hdr :
+ {
+ *(.eh_frame_hdr)
+ *(.eh_frame_entry)
+ }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+
+ . = ALIGN(8);
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+
+ *(.data1)
+ *(.data1.*)
+
+ . = ALIGN(16);
+ _gp = ABSOLUTE(.); /* Base of small data */
+
+ *(.sdata)
+ *(.sdata.*)
+ *(.rel.local)
+ }
+
+ . = ALIGN(8);
+ .ctors :
+ {
+ PROVIDE(__ctors_start = .);
+ /* new GCC version uses .init_array */
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE(__ctors_end = .);
+ }
+
+ .dtors :
+ {
+ PROVIDE(__dtors_start = .);
+ KEEP(*(SORT(.dtors.*)))
+ KEEP(*(.dtors))
+ PROVIDE(__dtors_end = .);
+ }
+
+ . = ALIGN(16);
+ .bss :
+ {
+ /*
+ * We need some free space to page or cpu stack, move .bss.noclean.*
+ * to optimize size.
+ */
+ PROVIDE(__bss_noclean_start = .);
+ *(.bss.noclean.*)
+ PROVIDE(__bss_noclean_end = .);
+ . = ALIGN(8);
+ PROVIDE(__bss_start = .);
+ *(.bss)
+ *(.bss.*)
+ *(.dynbss)
+ *(COMMON)
+ . = ALIGN(8);
+ PROVIDE(__bss_end = .);
+ }
+
+ /*
+ * We should make the bootloader know the size of memory we need,
+ * so we MUST calc the image's size with section '.bss'.
+ */
+ _end = .;
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ __data_size = SIZEOF(.data);
+ __bss_size = SIZEOF(.bss);
+}