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:
parent
fc167441f0
commit
e22089d0cc
1 changed files with 21 additions and 0 deletions
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue