Fiasco.OC-UX on MIPS?

Paul Boddie paul at
Fri Aug 30 13:43:10 CEST 2019

On Thursday 29. August 2019 12.31.49 Paul Boddie wrote:
> On Wednesday 28. August 2019 16.47.31 Sarah Hoffmann wrote:
> > On 8/28/19 4:07 PM, Paul Boddie wrote:
> > > make O=mybuild qemu E=hello QEMU_OPTIONS='-nographic -M malta'
> > 
> > You must also add the CPU type for Mips QEMU. For Mips 32 R2 this would
> > be:
> >   -M malta -cpu P5600
> > 
> > (Unrelated, I usually also set: -nographic -monitor none -serial stdio
> > That gives you the output directly on the console, no extra windows.)
> This is very useful to know. I will give it a try and report back on the
> outcome.

Well, the short story is that I got it to work, so many thanks are due for the 
help. Of course, had I looked at the Makeconf.boot.example file, I would have 
learned about the necessary -cpu option, but that was not the only obstacle 

(The -serial stdio option is apparently the default, but with qemu having so 
many options and switches, I imagine that it is worth specifying in case 
defaults change or option combinations have side-effects.)

What I found was that the bootstrap code was not completing. I added the -S 
option to qemu to stop the CPU at start-up time, and I used the -s option to 
set up remote debugging. Then, I ran gdb in another terminal, using the 
following commands in the gdb session:

target remote localhost:1234
set architecture mips:isa32r2
hbreak *0x802d0000

Using the si command to step through the code, it appeared that execution 
failed at the point where a load was first made relative to the gp register. 
Using the info registers command, I could see that the initialisation of this 
register was not done properly. And looking at the registers at the start of 
bootstrap routine execution, I could see that t9 was being used to initialise 
gp but had not been set up.

If this sounds familiar it is because there were similar issues with other 
assembly language routines that I ended up patching to run L4Re on the 
different Ingenic devices I have been using. However, I never needed to patch 
this code. An explanation for this might be that on the actual hardware, U-
Boot is involved and it might well initialise t9 when jumping to the bootstrap 
code. Here, the CPU firmware does not set up t9.

Previously, it was noted that other compilers had been used to develop L4Re 
for MIPS platforms, and I suspect that there must be a difference in the 
behaviour of the .cpload macro between the assemblers employed by these 
compilers. With my Debian-provided GCC toolchains, .cpload doesn't seem to be 
setting up t9, and it may be that it will only do so if there is a frame 
declared, which is not the case in the code affected by this problem (in the 
different places in L4Re).

(I would have to remind myself about what the .cp* macros actually do because 
I don't remember at this point in time.)

So maybe the approach for initialising t9 could be reviewed so that it is not 
toolchain-specific. Here, as before, I ended up doing something like this:

    lui $25, %hi(_realstart)
    ori $25, $25, %lo(_realstart)

As for the eventual outcome, I managed to get the payload working with qemu 
which is encouraging, although the performance didn't seem particularly great. 
I imagine that the performance might improve if and when qemu realises that 
most of the code can just run directly on the hardware, and the just-in-time 
compilation should figure this out, so perhaps more testing is needed.

Thanks once again for the help!


More information about the l4-hackers mailing list