Fiasco.OC-UX on MIPS?
paul at boddie.org.uk
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
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
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