rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

Linker problems with ARM926 core / AT91SAM9260 BSP

Open WebDust21 opened this issue 2 years ago • 1 comments

SYSTEM SETUP:

  • Ubuntu 22.04 LTS x64
  • utilizing arm-none-eabi toolchain

I have recently started modifying the AT91SAM9260 RT-Thread BSP for an AT91SAM9263, and came across some fatal issues that will prevent use of the AT91SAM9260 RT-Thread BSP. I am not very good at GitHub, nor do I know the proper way to fix the problems, so I am creating an issue instead of a pull request.

The major problem has to do with the linker script, as well as the ARM926 CPU defs. After successfully compiling the project, I checked the disassembly with:

arm-none-eabi-objdump -d -g rtthread.elf > rtthread.lst

An ARM binary must start with a vector interrupt table. The RT-Thread AT91SAM9260 binary file does not, check this disassembly:

./rtthread-at91sam9260.elf:     file format elf32-littlearm


Disassembly of section .text:

20000000 <_init>:
20000000:	e1a0c00d 	mov	ip, sp
20000004:	e92ddff8 	push	{r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
20000008:	e24cb004 	sub	fp, ip, #4

2000000c <list_fd>:
2000000c:	e92d4ff8 	push	{r3, r4, r5, r6, r7, r8, r9, sl, fp, lr}
20000010:	eb003da5 	bl	2000f6ac <rt_enter_critical>
20000014:	e59f515c 	ldr	r5, [pc, #348]	; 20000178 <list_fd+0x16c>
20000018:	e59f015c 	ldr	r0, [pc, #348]	; 2000017c <list_fd+0x170>
2000001c:	eb003795 	bl	2000de78 <rt_kprintf>
20000020:	e59f0158 	ldr	r0, [pc, #344]	; 20000180 <list_fd+0x174>
20000024:	eb003793 	bl	2000de78 <rt_kprintf>
20000028:	e5953000 	ldr	r3, [r5]
2000002c:	e3530000 	cmp	r3, #0

Perhaps unsurprisingly, the binary will not work.

I did check the output of the "qemu-vexpress-a9" (as an example that works perfectly in QEMU), and as expected, it starts with a vector table:

./rtthread.elf:     file format elf32-littlearm


Disassembly of section .text:

60010000 <__text_start>:
60010000:	e59ff018 	ldr	pc, [pc, #24]	; 60010020 <_vector_reset>
60010004:	e59ff018 	ldr	pc, [pc, #24]	; 60010024 <_vector_undef>
60010008:	e59ff018 	ldr	pc, [pc, #24]	; 60010028 <_vector_swi>
6001000c:	e59ff018 	ldr	pc, [pc, #24]	; 6001002c <_vector_pabt>
60010010:	e59ff018 	ldr	pc, [pc, #24]	; 60010030 <_vector_dabt>
60010014:	e59ff018 	ldr	pc, [pc, #24]	; 60010034 <_vector_resv>
60010018:	e59ff018 	ldr	pc, [pc, #24]	; 60010038 <_vector_irq>
6001001c:	e59ff018 	ldr	pc, [pc, #24]	; 6001003c <_vector_fiq>

60010020 <_vector_reset>:
60010020:	6005f280 	.word	0x6005f280

60010024 <_vector_undef>:
60010024:	60116fe0 	.word	0x60116fe0

60010028 <_vector_swi>:
60010028:	6002d1e4 	.word	0x6002d1e4

6001002c <_vector_pabt>:
6001002c:	60117040 	.word	0x60117040

60010030 <_vector_dabt>:
60010030:	601170a0 	.word	0x601170a0

60010034 <_vector_resv>:
60010034:	60117100 	.word	0x60117100

Digging into the issue, I found multiple problems.

The vector table for the ARM926 core is found in "rt-thread-master/libcpu/arm/arm926/start_gcc.S" Checking the build messages, we do see that "start_gcc.S" is being compiled:

CC build/kernel/libcpu/arm/arm926/mmu.o
CC build/kernel/libcpu/arm/arm926/stack.o
**AS build/kernel/libcpu/arm/arm926/start_gcc.o**
CC build/kernel/libcpu/arm/arm926/trap.o
CC build/kernel/libcpu/arm/common/backtrace.o

Looking into "start_gcc.S", we find the linker points:

 /*
 ***************************************
 * Interrupt vector table
 ***************************************
 */
.section .vectors
.code 32

.global start		//.global system_vectors
start: //system_vectors:
    ldr pc, _vector_reset
    ldr pc, _vector_undef
    ldr pc, _vector_swi
    ldr pc, _vector_pabt
    ldr pc, _vector_dabt
    ldr pc, _vector_resv
    ldr pc, _vector_irq
    ldr pc, _vector_fiq

Of particular interest is the line, ".section .vectors". Time to look into the BSP linker script, "rt-thread-master/bsp/at91/at91sam9260/link_scripts/at91sam9260_ram.ld":

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(start)
SECTIONS
{
    . = 0x20000000;

    . = ALIGN(4);
    .text : 
    {
        *(.init)
        *(.text)
        *(.gnu.linkonce.t*)

Wait a minute, the first entry is a vector titled ".init". But in "start_gcc.S", it's supposed to be ".vectors".

So we fix the linker script to read as follows:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(start)
SECTIONS
{
    . = 0x20000000;

    . = ALIGN(4);
    .text : 
    {
        *(.vectors)
        *(.text)
        *(.gnu.linkonce.t*)

Compiling now returns some errors:

LINK rtthread-at91sam9260.elf
build/kernel/libcpu/arm/arm926/start_gcc.o: In function `vector_resv':
(.text+0x220): undefined reference to `__bss_start'
build/kernel/libcpu/arm/arm926/start_gcc.o: In function `vector_resv':
(.text+0x224): undefined reference to `__bss_end'
collect2: error: ld returned 1 exit status
scons: *** [rtthread-at91sam9260.elf] Error 1
scons: building terminated because of errors.

It turns out that this is a nomenclature difference between "start_gcc.S" lines 135-136 and the linker script:

    /* clear bss */
    mov     r0, #0
    ldr     r1, =__bss_start
    ldr     r2, =__bss_end

and the linker script (lines 78-80):

    . = ALIGN(4);
    __bss_start__ = .;
    .bss : { *(.bss)}
    __bss_end__ = .;

Editing the "start_gcc.S" lines 135-136 to match the linker script solves the problem. I am not sure whether "start_gcc.S" or the linker script is wrong here...but after making them match, now it compiles successfully without errors:

LINK rtthread-at91sam9260.elf
arm-none-eabi-objcopy -O binary rtthread-at91sam9260.elf rtthread.bin
arm-none-eabi-objdump -d -g rtthread-at91sam9260.elf > rtthread.lst
arm-none-eabi-size rtthread-at91sam9260.elf
   text    data     bss     dec     hex filename
  99009    4332   35584  138925   21ead rtthread-at91sam9260.elf
scons: done building targets.

And better yet, checking the disassembly LST file, we find the following:

rtthread-at91sam9260.elf:     file format elf32-littlearm


Disassembly of section .text:

20000000 <start>:
20000000:	e59ff018 	ldr	pc, [pc, #24]	; 20000020 <_vector_reset>
20000004:	e59ff018 	ldr	pc, [pc, #24]	; 20000024 <_vector_undef>
20000008:	e59ff018 	ldr	pc, [pc, #24]	; 20000028 <_vector_swi>
2000000c:	e59ff018 	ldr	pc, [pc, #24]	; 2000002c <_vector_pabt>
20000010:	e59ff018 	ldr	pc, [pc, #24]	; 20000030 <_vector_dabt>
20000014:	e59ff018 	ldr	pc, [pc, #24]	; 20000034 <_vector_resv>
20000018:	e59ff018 	ldr	pc, [pc, #24]	; 20000038 <_vector_irq>
2000001c:	e59ff018 	ldr	pc, [pc, #24]	; 2000003c <_vector_fiq>

20000020 <_vector_reset>:
20000020:	20008e44 	.word	0x20008e44

20000024 <_vector_undef>:
20000024:	20008fbc 	.word	0x20008fbc

20000028 <_vector_swi>:
20000028:	20008f94 	.word	0x20008f94

The binary starts with ARM vectors! Now it can actually run!

My port of the AT91SAM9260 BSP to the AT91SAM9263 with these fixes (as well as hundreds of other changes to fix the register differences between the 2 CPU types) booted and ran perfectly on target hardware:

U-Boot> tftp 0x20000000 "rtthread.bin"
macb0: link up, 100Mbps full-duplex (lpa: 0xcde1)
Using macb0 device
TFTP from server 192.168.1.102; our IP address is 192.168.1.250
Filename 'rtthread.bin'.
Load address: 0x20000000
Loading: *########
done
Bytes transferred = 103364 (193c4 hex)
U-Boot> go 0x20000000
## Starting application at 0x20000000 ...
pit_rate=6221647HZ
PIT_MR=0x0300184d

 \ | /
- RT -     Thread Operating System
 / | \     5.0.0 build Nov  4 2022 19:45:44
 2006 - 2022 Copyright by RT-Thread team
msh />help
RT-Thread shell commands:
list_fd          - list file descriptor
pin              - pin [option]
list             - list objects
list_device      - list device in system
list_timer       - list timer in system
list_mempool     - list memory pool in system
list_msgqueue    - list message queue in system
list_mailbox     - list mail box in system
list_mutex       - list mutex in system
list_event       - list event in system
list_sem         - list semaphore in system
list_thread      - list thread
version          - show RT-Thread version information
clear            - clear the terminal screen
free             - Show the memory usage in the system.
ps               - List threads in the system.
help             - RT-Thread shell help.
tail             - print the last N - lines data of the given file
echo             - echo string to file
df               - disk free
umount           - Unmount device from file system
mount            - mount <device> <mountpoint> <fstype>
mkfs             - format disk with file system
mkdir            - Create the DIRECTORY.
pwd              - Print the name of the current working directory.
cd               - Change the shell working directory.
rm               - Remove(unlink) the FILE(s).
cat              - Concatenate FILE(s)
mv               - Rename SOURCE to DEST.
cp               - Copy SOURCE to DEST.
ls               - List information about the FILEs.
shutdown         - shutdown the system
reset            - restart the system

I am presenting these findings in hope that they will be valuable to the developer team, for diagnostics and fixing the BSP issues.

WebDust21 avatar Nov 05 '22 14:11 WebDust21

Thank you for your feed back and correct ld script. I will fix it soon.

BernardXiong avatar Nov 07 '22 21:11 BernardXiong