Rockbox Development > Starting Development and Compiling

Ingenic MIPS GCC 7.2.0 Toolchain to compile m3k native port

<< < (2/5) > >>

vitt13:
It seems I "fixed" that problem, but it leads to another.
I added to plugin.lds after data section

--- Code: ---    . = .;
    _gp = ALIGN(16);
    .got ALIGN(4) :
    {
        *(.got.plt) *(.got)
        . = ALIGN(4) ;
    } > PLUGIN_RAM
--- End code ---
but it leads to section overflow for 264bytes for two cases, and 'not fit to PLUGIN_RAM' for apps/plugins/sdl/duke3d.*

amachronic:
Hmm, I guess it makes sense we need to support GOT in the linker scripts. I never thought of that! ::) I hope you get it worked out -- I'm no expert on sorting out weird linker issues, so I don't have any specific suggestions. Perhaps you should compare with the default linker scripts (shipped with the toolchain) for more hints?

Anyhow, there's a copy of the 'mxu_as' script here: https://github.com/OpenNoahEdu/ingenic-jz-crosstools-src. I don't remember finding it on Ingenic's FTP site. If your goal here is to experiment with MXU this might be a lot easier than fighting the linker; all you'd have to do is set up special make rules.

vitt13:

--- Quote from: amachronic on December 14, 2021, 06:39:10 AM ---Perhaps you should compare with the default linker scripts (shipped with the toolchain) for more hints?
--- End quote ---
Thanks! It's best advice that has helped me.
I reviewed linker script from toolchain mips-linux-gnu-ingenic-gcc7.2.0/mips-linux-gnu/lib/ldscripts/elf32ltsmip.x and found how fix the problem with GOT and section overfill (just grabbed few strings basically).
And it works! All plugins, demo and games run without errors usung newest Ingenic GCC 7.2.0 TC and with same GCCOPTS flags that generated with Rockbox configure and its GCC4.9.2 TC.
But with my horrific additional flags that I added during fighting with linker, only 3D games (quake, doom, wolf3d, duke3d) failed and demo/fft ("TLB refill handler at ..."). So it's all can be fixed with right flags.
So here are patchs. Those sorts are not necessary but why not use it.
I use -DGCC720 in GCCOPTS, it's not perfect platform check.


--- Code: ------ rockbox/apps/plugins/plugin.lds 2021-11-30 23:15:20.509125218 +0300
+++ rockbox_new/apps/plugins/plugin.lds 2021-12-14 22:22:27.354083567 +0300
@@ -7,7 +7,11 @@
 #elif defined(CPU_ARM)
 OUTPUT_FORMAT(elf32-littlearm)
 #elif defined(CPU_MIPS)
+#ifdef GCC720
+OUTPUT_FORMAT(elf32-tradlittlemips)
+#else
 OUTPUT_FORMAT(elf32-littlemips)
+#endif
 #else
 /* We can have an #error here we don't use this file when build sims! */
 #error Unknown CPU architecture
@@ -266,20 +270,51 @@
 
     .rodata :
     {
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
 #if defined(IRAMSIZE) && IRAMSIZE == 0
-        *(.irodata)
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.irodata)))
 #endif
     } > PLUGIN_RAM
-
+#ifdef GCC720
+    .got.plt        : { *(.got.plt) }
+#endif
     .data :
     {
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.data*)))
 #if defined(IRAMSIZE) && IRAMSIZE == 0
-        *(.idata)
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.idata)))
 #endif
     } > PLUGIN_RAM
 
+#ifdef GCC720
+    . = .;
+    . = .;
+    HIDDEN (_gp = ALIGN (16) + 0x7ff0);
+    .got :
+    {
+        *(.got)
+    } > PLUGIN_RAM
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+    .sdata          :
+    {
+        *(.sdata .sdata.* .gnu.linkonce.s.*)
+    } > PLUGIN_RAM
+    .lit8           : { *(.lit8) }
+    .lit4           : { *(.lit4) }
+    _edata = .; PROVIDE (edata = .);
+    . = .;
+    __bss_start = .;
+    _fbss = .;
+    .sbss           :
+    {
+       *(.dynsbss)
+       *(.sbss .sbss.* .gnu.linkonce.sb.*)
+       *(.scommon)
+    } > PLUGIN_RAM
+#endif
+
 #if NOCACHE_BASE != 0
     .ncdata . + NOCACHE_BASE :
     {
@@ -320,8 +355,20 @@
         *(.ibss)
 #endif
         *(COMMON)
+#ifdef GCC720
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 32 / 8 : 1);
+#else
         . = ALIGN(0x4);
+#endif
     } > PLUGIN_RAM
+#ifdef GCC720
+      . = ALIGN(32 / 8);
+#endif
 
 #if NOCACHE_BASE != 0
     .ncbss . + NOCACHE_BASE (NOLOAD) :
--- End code ---


--- Code: ------ rockbox/firmware/target/mips/ingenic_x1000/spl.lds 2021-11-30 23:15:21.424138771 +0300
+++ rockbox_new/firmware/target/mips/ingenic_x1000/spl.lds 2021-12-12 19:41:03.927982128 +0300
@@ -1,7 +1,11 @@
 #include "config.h"
 #include "cpu.h"
 
-OUTPUT_FORMAT("elf32-littlemips")
+#ifdef GCC720
+OUTPUT_FORMAT(elf32-tradlittlemips)
+#else
+OUTPUT_FORMAT(elf32-littlemips)
+#endif
 OUTPUT_ARCH(MIPS)
 ENTRY(_spl_start)
 STARTUP(target/mips/ingenic_x1000/spl-start.o)
--- End code ---


--- Code: ------ rockbox/firmware/target/mips/ingenic_x1000/app.lds 2021-11-30 23:15:21.417138667 +0300
+++ rockbox_new/firmware/target/mips/ingenic_x1000/app.lds 2021-12-13 21:23:24.324047688 +0300
@@ -1,7 +1,11 @@
 #include "config.h"
 #include "cpu.h"
 
-OUTPUT_FORMAT("elf32-littlemips")
+#ifdef GCC720
+OUTPUT_FORMAT(elf32-tradlittlemips)
+#else
+OUTPUT_FORMAT(elf32-littlemips)
+#endif
 OUTPUT_ARCH(MIPS)
 ENTRY(_start)
 STARTUP(target/mips/ingenic_x1000/crt0.o)
@@ -31,14 +35,14 @@
     . = ALIGN(4);
     .rodata :
     {
-        *(.rodata*);
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)));
     } > DRAM
 
     . = ALIGN(4);
     .data :
     {
-        *(.data*);
-        *(.sdata*);
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.data*)));
+        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.sdata*)));
     } > DRAM
 
     .iram X1000_IRAM_BASE: AT (_bssbegin)
--- End code ---

amachronic:
Nice work! It turns out the GOT/PIC stuff is all specified in the System V ABI (http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf), now that I know what to look for. There's one thing I don't understand: how can this work without changing the startup code? I'd imagine it at least needs to initialize register t9 before jumping to PIC code?

I'm basically happy to merge this, though I'd like to experiment a bit to find just the minimum needed to make PIC work, rather than blindly copying from GCC/binutils. For example I see no need for that .bss alignment voodoo, but perhaps they do it for a good reason. Aside from PIC, it seems the only thing necessary to support the Ingenic toolchain is using elf32-tradlittlemips instead of elf32-littlemips.

vitt13:
Also found this linker script from jz4730 sources with similar "trick" for small data.

--- Code: ---*   DESCRIPTION :                                                         *
*   Linker script file                                                    *
*                                                                         *
**************************************************************************/

OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(mips)

/**** Start point ****/
ENTRY(_start) /* Entry point of application */

MEMORY
{
    ram (wx) : ORIGIN = 0x80000000, LENGTH = 32M
}

SECTIONS
{
  /**** Code and read-only data ****/

  .text 0x80100000 :
  {
    _ftext = ABSOLUTE(.) ; /* Start of code and read-only data */
    *(.text*)
    *(.gnu.linkonce.*)
    *(__libc*)
    _ecode = ABSOLUTE(.) ; /* End of code */

    *(.rodata*)

    . = ALIGN(8);
    _etext = ABSOLUTE(.); /* End of code and read-only data */
  } > ram

  /**** Initialised data ****/

  .data :
  {
    _fdata = ABSOLUTE(.); /* Start of initialised data */
    *(.data*)
    *(.eh_frame*)
    *(.gcc_except_table*)
   
    . = ALIGN(8);
    __CTOR_LIST__ = ABSOLUTE(.);
    KEEP(*(SORT(.ctors*)))
    __CTOR_END__ = ABSOLUTE(.);
    __DTOR_LIST__ = ABSOLUTE(.);
    KEEP(*(SORT(.dtors*)))
    __DTOR_END__ = ABSOLUTE(.);

    _gp = ABSOLUTE(. + 0x7ff0); /* Base of small data */

    *(.lit8)
    *(.lit4)
    *(.sdata)

    . = ALIGN(8);

    _edata  = ABSOLUTE(.); /* End of initialised data */
  } > ram

  /**** Uninitialised data ****/

  _fbss = .; /* Start of uninitialised data */

  .sbss :
  {
    *(.sbss)
    *(.scommon)
  }
  .bss :
  {
    *(.bss)
    *(COMMON)

    /* Allocate room for stack */
    .   =  ALIGN(8) ;
    _freemem = .;
  }

  _end = . ; /* End of unitialised data */

  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }

  /DISCARD/ :
  {
    *(.reginfo)
  }

  PROVIDE(etext = _etext);
  PROVIDE (edata = .);
  PROVIDE (end = .);
}
--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version