Booting L4Re on the CI20: Panic in sigma0
Paul Boddie
paul at boddie.org.uk
Fri Jul 14 01:11:38 CEST 2017
Following up to myself...
On Thursday 13. July 2017 19.22.32 Paul Boddie wrote:
>
> But now I appear to experience a panic in sigma0 as it starts up, with the
> message...
>
> Warning: Sigma0 raised an exception --> HALT
[...]
> The EPC indeed appears to reference sigma0, with the Cause indicating an
> erroneous data or instruction fetch operation. Looking at the disassembly
> of sigma0...
>
> 002000e0 <__start>:
> 2000e0: 3c1c0001 lui gp,0x1
> 2000e4: 279c7f80 addiu gp,gp,32640
> 2000e8: 0399e021 addu gp,gp,t9
> 2000ec: 8f9d8018 lw sp,-32744(gp)
> 2000f0: 8f99801c lw t9,-32740(gp)
> 2000f4: 27bdfff0 addiu sp,sp,-16
> 2000f8: 0320f809 jalr t9
> 2000fc: 00000000 nop
>
> ...it appears that the problem occurs when the global offset table is
> accessed. The global pointer gets computed as...
>
> 0x10000 + 32640 + 0x800a0000 = 0x800b7f80
>
> ...with the load-relative operation accessing...
>
> 0x800b7f80 - 32744 = 0x800aff98
Of course, t9, which was set to 0x800a0000 (if the register dump can be
believed), is completely wrong according to the way it is used conventionally
(as a reference to the current routine). So I investigated the initialisation
code for sigma0 in the following place:
pkg/l4re-core/sigma0/server/src/ARCH-mips/crt0.S
This is what it looks like:
__start:
.cpload $25 /* load GP */
SETUP_GPX64($25, $0)
PTR_LA $29, crt0_stack_high
PTR_LA $25, init
PTR_SUBU $29, (NARGSAVE * SZREG)
jalr $25
nop
The problem here is that the .cpload directive (operating on t9/$25) doesn't
have a known value of t9 to work with, it would seem. Consequently, the
calculations in the generated code work with a value that isn't initialised.
I tried to add the initialisation of t9 before the .cpload directive, but this
actually caused the computed offsets to the gp/$28 register to be eight bytes
out, thus causing the accessed table addresses to be eight bytes too low. Here
is what I tried:
__start:
lui $25, %hi(__start)
ori $25, $25, %lo(__start)
.cpload $25 /* load GP */
Clearly, the two extra instructions were confusing the .cpload directive. So I
then introduced another label as follows, making the .cpload directive operate
at exactly the referenced place in the program:
__start:
lui $25, %hi(__realstart)
ori $25, $25, %lo(__realstart)
__realstart:
.cpload $25 /* load GP */
Now, the value of t9 is correct for the gp operations. At this point, I get
the following output:
SIGMA0: Hello!
KIP @ 10000
allocated 4KB for maintenance structures
SIGMA0: Dump of all resource maps
RAM:------------------------
[4:1000;1fff]
[4:140000;184fff]
[4:190000;197fff]
[4:1100000;1164fff]
[0:2155000;3fffffff]
IOMEM:----------------------
[0:40000000;ffffffff]
I'm guessing that there should be more output after that, but it either isn't
produced on UART0 or something is hanging somewhere. Looking at similar code
in moe, it appears that a similar measure is required to set up t9. Here is
where that code lives:
pkg/l4re-core/moe/server/src/ARCH-mips/crt0.S
Making a similar change in the "_real_start" routine there yields the
following additional output:
MOE: Hello world
And that is then the end of output. Maybe I've stumbled across a difference in
the way the compilers work here. I'm using the mipsel-linux-gnu cross-
compilers in Debian unstable, whereas I imagine that the people who ported the
code to MIPS used proprietary toolchains with different characteristics.
Anyway, I guess I'll investigate other places where this might be occurring
and hopefully get the "hello" program to do its thing.
Paul
More information about the l4-hackers
mailing list