Running RTEMS on a LEON2 from ROM
Jiri Gaisler
jiri at gaisler.se
Wed Jul 26 15:41:24 UTC 2017
On 07/26/2017 04:17 PM, Jiri Gaisler wrote:
>
> On 07/26/2017 03:24 PM, Mike Looijmans wrote:
>> On 26-07-17 13:36, Mike Looijmans wrote:
>>> On 26-07-17 13:10, Mike Looijmans wrote:
>>>> On 26-07-17 10:21, Jiri Gaisler wrote:
>>>>>
>>>>> On 07/26/2017 07:25 AM, Mike Looijmans wrote:
>>>>>>> how you do it with standalone sis:
>>>>>>>
>>>>>>> $ sparc-rtems4.12-sis -leon2 application.exe
>>>>>>>
>>>>>>>> hi 100
>>>>>>>> go
>>>>>>>> hi
>>>>>>>> reg
>>>>>> Doesn't get very far, there's apparently no (working) memory at
>>>>>> 0x40000000 in the simulator, it always reads back as "0", so any
>>>>>> access to RAM results in a crash in the simulator.
>>>>>>
>>>>>>
>>>>>>
>>>>> Are you sure you are building sis and gdb from RSB head? sis in the
>>>>> regular gdb does not support leon2 yet.
>>>>> To advance things, you can send me your application binary and I
>>>>> can run
>>>>> it in the simulator and send you the traces. If you are on 64-bit
>>>>> ubuntu
>>>>> 16.04, I can also provide you with binaries for sis/gdb, or the
>>>>> whole RSB.
>>>> I built the current HEAD of the RSB, and ran using the simulator
>>>> from that. The result is the same.
>>>>
>>>> Did some more digging. The problem appears to be that the simulator
>>>> populates the memory segments using the VMA values instead of the
>>>> LMA values. So it writes the data segment to RAM at 0x40000000,
>>>> instead of in ROM, directly following the text segment, as the boot
>>>> code expects. I can see the data segment contents there just after
>>>> loading the elf.
>>>>
>>>> When the code starts, it copies the data segment from ROM into RAM
>>>> and that will copy the empty ROM part onto the RAM, resulting in the
>>>> all-zero data in RAM that I see.
>>>>
>>>> Can I load a binary image into sis? (so not an elf but a raw ROM image)
>>>>
>>>> I'll try using objdump to concat the text and data into a single
>>>> segment elf for the simulator. Or maybe patch the VMA address to
>>>> match the LMA.
>>> That worked. According to SIS, the crash happens here:
>>>
>>> https://git.rtems.org/rtems/tree/cpukit/score/src/heap.c?h=4.11#n274
>>>
>>> From sis, i can see:
>>>
>>> 18156 0000da3c 81c3e008 retl
>>> 18158 0000da40 01000000 nop
>>> 18159 00006eec c41fbff8 ldd [ %fp + -8 ], %g2
>>> 18162 00006ef0 b406401a add %i1, %i2, %i2
>>> 18163 00006ef4 f020a008 st %i0, [ %g2 + 8 ]
>>> 18166 00006ef8 f020a00c st %i0, [ %g2 + 0xc ]
>>> 18169 00006efc f4208000 st %i2, [ %g2 ]
>>> 18172 00006f00 8220c002 sub %g3, %g2, %g1
>>> 18173 00006f04 88106001 or %g1, 1, %g4
>>> 18174 00006f08 c820a004 st %g4, [ %g2 + 4 ]
>>> 18177 00006f0c c43e2020 std %g2, [ %i0 + 0x20 ]
>>> 18181 00006f10 c4262008 st %g2, [ %i0 + 8 ]
>>> 18184 00006f14 c426200c st %g2, [ %i0 + 0xc ]
>>> 18187 00006f18 f6262010 st %i3, [ %i0 + 0x10 ]
>>> 18190 00006f1c fa262014 st %i5, [ %i0 + 0x14 ]
>>> 18193 00006f20 f2262018 st %i1, [ %i0 + 0x18 ]
>>> 18196 00006f24 f426201c st %i2, [ %i0 + 0x1c ]
>>> 18199 00006f28 c220c000 st %g1, [ %g3 ]
>>> 18203 40000090 91d020ff ta 0xff
>>> sis> reg
>>>
>>> INS LOCALS OUTS GLOBALS
>>> 0: 40002500 91CFE0F0 51CF6D70 00000000
>>> 1: 00000000 00006F28 00000008 51CF6D70
>>> 2: 00000068 00006F2C 0A39EDAF 40007380
>>> 3: 00000010 00000000 00000007 91CFE0F0
>>> 4: 400FFE70 00000000 FFFFFFFF 51CF6D71
>>> 5: 40002568 00000000 00000008 00000000
>>> 6: 400FFE10 00000000 400FFDB0 00000000
>>> 7: 00006EE4 00000000 00006DD0 00000000
>>>
>>> psr: 00400FC3 wim: 00000002 tbr: 40000090 y: 00000000
>>>
>>>
>>> Looked this address up in the "objdump -S" output, and that shows the
>>> following source code and assembly there:
>>>
>>> /* Heap control */
>>> heap->page_size = page_size;
>>> 6f18: f6 26 20 10 st %i3, [ %i0 + 0x10 ]
>>> heap->min_block_size = min_block_size;
>>> 6f1c: fa 26 20 14 st %i5, [ %i0 + 0x14 ]
>>> heap->area_begin = heap_area_begin;
>>> 6f20: f2 26 20 18 st %i1, [ %i0 + 0x18 ]
>>> heap->area_end = heap_area_end;
>>> 6f24: f4 26 20 1c st %i2, [ %i0 + 0x1c ]
>>> heap->last_block = last_block;
>>> _Heap_Free_list_head( heap )->next = first_block;
>>> _Heap_Free_list_tail( heap )->prev = first_block;
>>>
>>> /* Last block */
>>> last_block->prev_size = first_block_size;
>>> 6f28: c2 20 c0 00 st %g1, [ %g3 ]
>>>
>>>
>>> Something's up with the heap initialization. Haven't found out what
>>> exactly though. %g3=91CFE0F0 but should be in the RAM range
>>> (400XXXXX) for that "st" to make sense.
>>>
>> "_Heap_Initialize" is called twice. Once from
>> _Workspace_Handler_initialization with sensible values, and the second
>> time it's called from RTEMS_Malloc_Initialize, with the heap_end set
>> to 0x91CFE0FF which isn't valid and causes the crash.
>>
> _Heap_Initialize is called twice, this is normal. However, the SPARC
> port has a peculiar way of passing the top of memory, it does that by
> writing it to a symbol called rdb_start, which is located at vector
> 0x7c in the trap table. In normal cases, rdb_start is at address
> 400007c0. I guess when the trap table is relocated, the value is lost
> somehow and overwritten with a assembly instruction.
>
> Normal leon2 executable:
>
> (gdb) p /x rdb_start
> $2 = 0x40fffe80
> (gdb)
>
> You binary after boot:
>
> (gdb) p /x rdb_start
> $3 = 0x91d020ff
> (gdb)
>
> If you recreate the trap table in RAM, make sure that the rdb_start is
> properly set to end of RAM.
>
> Jiri.
Let me clarify this. The rdb_start is set by either the prom loader,
grmon or simulator to the top of available RAM (64-byte aligned), RTEMS
then use the value to allocate the stack and heap. So your boot code
must write this value before the system starts initializing. If you have
1 Mbyte of RAM, then set 0x400007c0 = 0x400fffe0 and it should work. The
reason for this is historical, but it allows the same executable to run
on different boards with varying amount of memory.
jiri.
More information about the users
mailing list