[SLOF] [PATCH] OF: Add a separate direct kernel loading word
segher at kernel.crashing.org
Tue Jul 12 23:48:19 AEST 2022
On Tue, Jul 12, 2022 at 10:46:24AM +1000, Jordan Niethe wrote:
> Currently, go-64 is used for booting a kernel from qemu (i.e. -kernel).
> However, there is an expectation from users that this should be able to
> boot not just vmlinux kernels but things like Zimages too.
> The bootwrapper of a BE zImage is a 32-bit ELF. Attempting to load that
> with go-64 means that it will be ran with MSR_SF set (64-bit mode). This
> crashes early in boot (usually due to what should be 32-bit operations
> being done with 64-bit registers eventually leading to an incorrect
> address being generated and branched to).
In PowerPC, all operations are done the same in SF=0 and SF=1 modes,
- For addressing storage, the high 32 bits are ignored if SF=0;
- For bdz and bdnz (bc with BO=1) the high 32 bits are ignored;
- For integer record form instructions ("dot instructions"), the high
32 bits are ignored.
Everything else is done exactly the same with SF=0 -- the high 32 bits
of everything are set in exactly the same way, for example.
In practice, what bites you is the first item, when doing table jumps:
it ends up jumping to 0xffffffff12345678 instead of 0x0000000012345678
when running 32-bit code with SF=1. You get about two million
instructions into yaboot before it blows up, for example :-) Dot insns
are very common, but you do end up with the result properly (sign-)
extended most of the time :-)
> Note that our 64-bit payloads are prepared to enter with MSR_SF cleared
> and set it themselves very early.
> Add a new word named go-direct that will execute any simple payload
> in-place and will enter with MSR_SF cleared. This allows booting a BE
> zImage from qemu with -machine kernel-addr=0.
Ouch. So you run 64-bit programs in 32-bit mode as well, just hoping
they will deal with it? Not a good idea :-( Current Linux is fine with
it, but are other payloads, including future Linux?
"init-program" is supposed to set the MSR state correctly (in ciregs
>srr1), based on the ELF headers (and btw the same is true for the LE
flag etc). A little ELF parsing is needed.
Hope this helps,
More information about the SLOF