rpi3: Mark first memory page as reserved

When the kernel is built the build system is responsible for finding
a suitable physical memory location where the kernel can be put on
the given target platform.
This is recorded into the kernel.elf file and read by the elfloader
program when it loads the kernel to that memory address.

In order to find memory blocks to avoid, the build system looks for
the /reserved-memory node in the target platform's device tree dts,
along with other device memory blocks.

The bcm2837 / Raspberry Pi 3 bootloader uses the first memory page
at address 0x0 to load a so called armstub which is used to set up
the ARM processor's initial state. It is also used to "park" the
secondary cores by putting them in a spin loop located within the
armstub from which the boot core can release them when ready.

The rpi3.dts already contains a /memreserve/ node reserving this
page, however as the build system only looks for the standardized
reserved-memory node it promptly disregards it and allow the kernel
to be loaded at physical address 0x0, overwriting the armstub.

A side effect of this is that the spinloop code also is overwritten,
potentially releasing the secondary cores to execute whatever kernel
code is written in the place of their spinloops, causing all kinds
of undefined behavior dependent on both race conditions and kernel
elf layout. It also implies that the kernel SMP boot code would not
be able to release the cores if implemented for the platform.

This patch adds the /reserved-memory node to the overlay-rpi3.dts
file and a child node reserving the memory region for the first
memory page. This in effect causes the kernel to instead be loaded
to 0x1000000 (aligned to a supersection).

Co-authored-by: Axel Heider <axelheider@gmx.de>
Signed-off-by: Viktor Sannum <sannum.viktor@gmail.com>
This commit is contained in:
Viktor Sannum 2021-07-12 09:54:04 +02:00 committed by Kent McLeod
parent fc167441f0
commit e22089d0cc

View file

@ -20,4 +20,25 @@
/* This is configurable in the Pi's config.txt, but we use 128MiB of RAM by default. */
reg = <0x00 0x08000000>;
};
reserved-memory {
#address-cells = <0x01>;
#size-cells = <0x01>;
ranges;
/* Keep the first page of physical memory is reserved for the initial
* bootloader (e.g. armstub). It has parked the secondary cores there,
* they spin until they get released. When SMP is enabled, the kernel
* will release them during boot and this memory can be reused.
* However, we still have to ensure the kernel image itself is not
* placed here. In non-SMP configurations, the cores must keep spinning
* forever. Re-using this memory will cause the secondary cores to
* execute whatever content is placed there, which likely makes them
* run amok.
* See also https://leiradel.github.io/2019/01/20/Raspberry-Pi-Stubs.html#armstub8s
*/
reserved-memory@0{
reg = <0x0 0x1000>;
no-map;
}
};
};