Activating the sigma0 thread in the Fiasco kernel
Paul Boddie
paul at boddie.org.uk
Sun Mar 4 22:25:12 CET 2018
Hello,
I've been trying to coerce L4Re and Fiasco.OC to work with the Ben NanoNote,
which is related to the MIPS Creator CI20 that is (mostly - see earlier
discussions) supported by this software. There are a few challenges involved,
such as avoiding MIPS32r2 instructions that the NanoNote's SoC doesn't support
(JZ4740 in the NanoNote versus JZ4780 in the CI20), and positioning things
appropriately to avoid upsetting the installed bootloader.
Since I last posted anything about this, I've managed to get Fiasco to go
about its bootstrapping business, proceeding from the bootstrap package,
entering the kernel, running kernel_main, doing various initialisation tasks,
enabling interrupts, and ending up in the init_workload method where a sigma0
thread and a boot thread are created and activated.
It is at this point that I seem to have encountered a particularly stubborn
problem: how to get the sigma0 thread to activate and return control to
init_workload for the boot thread to be activated, then going on to finish
what little remains of the bootstrapping process. Strangely, the boot thread
has no difficulty in being activated and returning control if I put it first
in the sequence, but sigma0 seems to cause something different to happen.
Now, for this activation, it seems that the real action begins in
Context::switch_cpu, where an exchange of stack pointers occurs and a branch
is made to the Context::switchin_context method, with the old context
presumably being made to resume after the branchpoint. As far as I can tell,
both threads manage to set this up correctly. I see that the new context then
causes Thread::user_invoke to be called, with execution proceeding via the
ret_from_user_invoke routine and ultimately into the user task. Looking at the
address to which the CPU will "return" to in user mode, all seems reasonable
and consistent with the configuration of sigma0.
However, one thing that baffles me somewhat is the way that interrupts are
disabled in Thread::user_invoke. Given that the CPU ends up in the task in
user mode, it would surely need some kind of exception or interrupt for the
kernel to be re-entered, yet I don't see any operation that re-enables
interrupts anywhere. Maybe this is the cause of my problem, but I don't
understand how sigma0 would be different from anything else.
I have needed to change some CPU-level operations to adapt the code to the
earlier microarchitecture revision, but I don't think I've made any obvious
mistakes, and I have seemingly figured out how to describe the interrupt
system because for a while I couldn't get past the Delay::init invocation in
the bootstrap process which relies on interrupts working. (Some comments in
the code would have helped me guess what numbers to use in certain
invocations.)
Does anyone have any thoughts or guidance about what I should be looking at?
Thanks in advance and sorry for the wall of text!
Paul
More information about the l4-hackers
mailing list