浏览代码

AArch64: support public linker scripts (#7831)

Signed-off-by: GuEe-GUI <GuEe-GUI@github.com>
GUI 1 年之前
父节点
当前提交
6f119d4ce9

+ 8 - 0
bsp/qemu-virt64-aarch64/.config

@@ -94,6 +94,10 @@ CONFIG_RT_CONSOLEBUF_SIZE=256
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
 CONFIG_RT_VER_NUM=0x50001
 CONFIG_RT_USING_STDC_ATOMIC=y
+
+#
+# RT-Thread Architecture
+#
 CONFIG_ARCH_CPU_64BIT=y
 CONFIG_RT_USING_CACHE=y
 # CONFIG_RT_USING_HW_ATOMIC is not set
@@ -104,6 +108,10 @@ CONFIG_ARCH_MM_MMU=y
 CONFIG_ARCH_ARM=y
 CONFIG_ARCH_ARM_MMU=y
 CONFIG_ARCH_ARMV8=y
+CONFIG_ARCH_TEXT_OFFSET=0x80000
+CONFIG_ARCH_RAM_OFFSET=0x40000000
+CONFIG_ARCH_SECONDARY_CPU_STACK_SIZE=4096
+CONFIG_ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 
 #
 # RT-Thread Components

+ 0 - 4
bsp/qemu-virt64-aarch64/SConstruct

@@ -40,9 +40,5 @@ Export('rtconfig')
 # prepare building environment
 objs = PrepareBuilding(env, RTT_ROOT)
 
-if GetDepend('RT_USING_SMART'):
-    # use smart link.lds
-    env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
-
 # make a building
 DoBuilding(TARGET, objs)

+ 0 - 109
bsp/qemu-virt64-aarch64/link.lds

@@ -1,109 +0,0 @@
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-SECTIONS
-{
-    . = 0x40080000;
-    /* . = 0xffff000000080000; */
-
-    __text_start = .;
-    .text :
-    {
-        KEEP(*(.text.entrypoint))
-        KEEP(*(.vectors))
-        *(.text)
-        *(.text.*)
-
-        /* section information for utest */
-        . = ALIGN(8);
-        __rt_utest_tc_tab_start = .;
-        KEEP(*(UtestTcTab))
-        __rt_utest_tc_tab_end = .;
-
-        /* section information for finsh shell */
-        . = ALIGN(8);
-        __fsymtab_start = .;
-        KEEP(*(FSymTab))
-        __fsymtab_end = .;
-        . = ALIGN(8);
-        __vsymtab_start = .;
-        KEEP(*(VSymTab))
-        __vsymtab_end = .;
-        . = ALIGN(8);
-
-        /* section information for modules */
-        . = ALIGN(8);
-        __rtmsymtab_start = .;
-        KEEP(*(RTMSymTab))
-        __rtmsymtab_end = .;
-
-        /* section information for initialization */
-        . = ALIGN(8);
-        __rt_init_start = .;
-        KEEP(*(SORT(.rti_fn*)))
-        __rt_init_end = .;
-    } =0
-    __text_end = .;
-
-    .ARM.exidx   :
-    {
-        __exidx_start = .;
-        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-        __exidx_end = .;
-    }
-
-    __rodata_start = .;
-    .rodata   : { *(.rodata) *(.rodata.*) }
-    __rodata_end = .;
-
-    . = ALIGN(8);
-    .ctors :
-    {
-        PROVIDE(__ctors_start__ = .);
-        KEEP(*(SORT(.init_array.*)))
-        KEEP(*(.init_array))
-        PROVIDE(__ctors_end__ = .);
-    }
-
-    .dtors :
-    {
-        PROVIDE(__dtors_start__ = .);
-        KEEP(*(SORT(.fini_array.*)))
-        KEEP(*(.fini_array))
-        PROVIDE(__dtors_end__ = .);
-    }
-
-    . = ALIGN(8);
-    __data_start = .;
-    .data :
-    {
-        *(.data)
-        *(.data.*)
-    }
-    __data_end = .;
-
-    . = ALIGN(8);
-    __bss_start = .;
-    .bss       :
-    {
-    *(.bss)
-    *(.bss.*)
-    *(COMMON)
-    . = ALIGN(8);
-    }
-    . = ALIGN(8);
-    __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) }
-
-    __data_size = SIZEOF(.data);
-    __bss_size = SIZEOF(.bss);
-
-    _end = .;
-}

+ 0 - 109
bsp/qemu-virt64-aarch64/link_smart.lds

@@ -1,109 +0,0 @@
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-SECTIONS
-{
-    /* . = 0x40080000; */
-    . = 0xffff000000080000;
-
-    __text_start = .;
-    .text :
-    {
-        KEEP(*(.text.entrypoint))
-        KEEP(*(.vectors))
-        *(.text)
-        *(.text.*)
-
-        /* section information for utest */
-        . = ALIGN(8);
-        __rt_utest_tc_tab_start = .;
-        KEEP(*(UtestTcTab))
-        __rt_utest_tc_tab_end = .;
-
-        /* section information for finsh shell */
-        . = ALIGN(8);
-        __fsymtab_start = .;
-        KEEP(*(FSymTab))
-        __fsymtab_end = .;
-        . = ALIGN(8);
-        __vsymtab_start = .;
-        KEEP(*(VSymTab))
-        __vsymtab_end = .;
-        . = ALIGN(8);
-
-        /* section information for modules */
-        . = ALIGN(8);
-        __rtmsymtab_start = .;
-        KEEP(*(RTMSymTab))
-        __rtmsymtab_end = .;
-
-        /* section information for initialization */
-        . = ALIGN(8);
-        __rt_init_start = .;
-        KEEP(*(SORT(.rti_fn*)))
-        __rt_init_end = .;
-    } =0
-    __text_end = .;
-
-    .ARM.exidx   :
-    {
-        __exidx_start = .;
-        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-        __exidx_end = .;
-    }
-
-    __rodata_start = .;
-    .rodata   : { *(.rodata) *(.rodata.*) }
-    __rodata_end = .;
-
-    . = ALIGN(8);
-    .ctors :
-    {
-        PROVIDE(__ctors_start__ = .);
-        KEEP(*(SORT(.init_array.*)))
-        KEEP(*(.init_array))
-        PROVIDE(__ctors_end__ = .);
-    }
-
-    .dtors :
-    {
-        PROVIDE(__dtors_start__ = .);
-        KEEP(*(SORT(.fini_array.*)))
-        KEEP(*(.fini_array))
-        PROVIDE(__dtors_end__ = .);
-    }
-
-    . = ALIGN(8);
-    __data_start = .;
-    .data :
-    {
-        *(.data)
-        *(.data.*)
-    }
-    __data_end = .;
-
-    . = ALIGN(8);
-    __bss_start = .;
-    .bss       :
-    {
-    *(.bss)
-    *(.bss.*)
-    *(COMMON)
-    . = ALIGN(8);
-    }
-    . = ALIGN(8);
-    __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) }
-
-    __data_size = SIZEOF(.data);
-    __bss_size = SIZEOF(.bss);
-
-    _end = .;
-}

+ 7 - 0
bsp/qemu-virt64-aarch64/rtconfig.h

@@ -61,12 +61,19 @@
 #define RT_CONSOLE_DEVICE_NAME "uart0"
 #define RT_VER_NUM 0x50001
 #define RT_USING_STDC_ATOMIC
+
+/* RT-Thread Architecture */
+
 #define ARCH_CPU_64BIT
 #define RT_USING_CACHE
 #define ARCH_MM_MMU
 #define ARCH_ARM
 #define ARCH_ARM_MMU
 #define ARCH_ARMV8
+#define ARCH_TEXT_OFFSET 0x80000
+#define ARCH_RAM_OFFSET 0x40000000
+#define ARCH_SECONDARY_CPU_STACK_SIZE 4096
+#define ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS
 
 /* RT-Thread Components */
 

+ 3 - 1
bsp/qemu-virt64-aarch64/rtconfig.py

@@ -13,6 +13,7 @@ if PLATFORM == 'gcc':
     PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
+    CPP     = PREFIX + 'cpp'
     AS      = PREFIX + 'gcc'
     AR      = PREFIX + 'ar'
     LINK    = PREFIX + 'gcc'
@@ -25,10 +26,11 @@ if PLATFORM == 'gcc':
     AFPFLAGS = ' '
     DEVICE   = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
 
+    CPPFLAGS= ' -E -P -x assembler-with-cpp'
     CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always'
     CFLAGS  = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always'
     AFLAGS  = ' -c' + AFPFLAGS + ' -x assembler-with-cpp'
-    LFLAGS  = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static'
+    LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static'
     CPATH   = ''
     LPATH   = ''
 

+ 6 - 0
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

+ 1 - 0
libcpu/aarch64/.gitignore

@@ -0,0 +1 @@
+link.lds

+ 19 - 0
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

+ 5 - 0
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'))

+ 2 - 2
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
 

+ 43 - 5
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

+ 191 - 0
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);
+}

+ 17 - 0
tools/building.py

@@ -513,6 +513,23 @@ def AddDepend(option):
     else:
         print('AddDepend arguements are illegal!')
 
+def Preprocessing(input, suffix, output = None, CPPPATH = None):
+    if hasattr(rtconfig, "CPP") and hasattr(rtconfig, "CPPFLAGS"):
+        if output == None:
+            import re
+            output = re.sub(r'[\.]+.*', suffix, input)
+        inc = ' '
+        cpppath = CPPPATH
+        for cpppath_item in cpppath:
+            inc += ' -I' + cpppath_item
+        CPP = rtconfig.EXEC_PATH + '/' + rtconfig.CPP
+        if not os.path.exists(CPP):
+            CPP = rtconfig.CPP
+        CPP += rtconfig.CPPFLAGS
+        path = GetCurrentDir() + '/'
+        os.system(CPP + inc + ' ' + path + input + ' -o ' + path + output)
+    else:
+        print('CPP tool or CPPFLAGS is undefined in rtconfig!')
 
 def MergeGroup(src_group, group):
     src_group['src'] = src_group['src'] + group['src']