On Tue, 26 Aug 2025 at 11:50, Mark Rutland mark.rutland@arm.com wrote:
On Sat, Aug 23, 2025 at 04:55:44PM -0700, Sam Edwards wrote:
On Sat, Aug 23, 2025 at 3:25 PM Ard Biesheuvel ardb@kernel.org wrote:
Hi Sam,
On Fri, 22 Aug 2025 at 14:15, Sam Edwards cfsworks@gmail.com wrote:
In early boot, Linux creates identity virtual->physical address mappings so that it can enable the MMU before full memory management is ready. To ensure some available physical memory to back these structures, vmlinux.lds reserves some space (and defines marker symbols) in the middle of the kernel image. However, because they are defined outside of PROGBITS sections, they aren't pre-initialized -- at least as far as ELF is concerned.
In the typical case, this isn't actually a problem: the boot image is prepared with objcopy, which zero-fills the gaps, so these structures are incidentally zero-initialized (an all-zeroes entry is considered absent, so zero-initialization is appropriate).
However, that is just a happy accident: the `vmlinux` ELF output authoritatively represents the state of memory at entry. If the ELF says a region of memory isn't initialized, we must treat it as uninitialized. Indeed, certain bootloaders (e.g. Broadcom CFE) ingest the ELF directly -- sidestepping the objcopy-produced image entirely -- and therefore do not initialize the gaps. This results in the early boot code crashing when it attempts to create identity mappings.
Therefore, add boot-time zero-initialization for the following:
- __pi_init_idmap_pg_dir..__pi_init_idmap_pg_end
- idmap_pg_dir
- reserved_pg_dir
I don't think this is the right approach.
If the ELF representation is inaccurate, it should be fixed, and this should be achievable without impacting the binary image at all.
Hi Ard,
I don't believe I can declare the ELF output "inaccurate" per se, since it's the linker's final determination about the state of memory at kernel entry -- including which regions are not the loader's responsibility to initialize (and should therefore be initialized at runtime, e.g. .bss). But, I think I understand your meaning: you would prefer consistent load-time zero-initialization over run-time. I'm open to that approach if that's the consensus here, but it will make `vmlinux` dozens of KBs larger (even though it keeps `Image` the same size).
Our intent was that these are zeroed at build time in the Image. If the vmlinux isn't consistent with that, that's a problem with the way we generate the vmlinux, and hence "the ELF representation is inaccurate".
I agree with Ard that it's better to bring the vmlinux into line with that (if we need to handlr this at all), even if that means making the vmlinux a few KB bigger.
Indeed. And actually, it should still be the ELF loader's job to zero-initialize NOBITS sections, so ideally, we'd make these NOBITS rather than PROGBITS, and the bloat issue should go away.
If the ELF loader in question relies on the executable's startup code to clear NOBITS sections, it needs to be fixed in any case. Clearing BSS like we do at startup time is really only appropriate for bare-metal images such as arm64's Image, but a platform that elects to use an ELF loader instead (even though that is not a supported bootable format for arm64 Linux) should at least adhere to the ELF spec.