From 672e36f401b8e6d5ce473c904e2863ddd4545331 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:22:13 +0100 Subject: [PATCH] Force the zero page of the kernel to be part of a segment This will be necessary for limine and likely multiboot support. See the comment in the linker scripts. --- linkers/aarch64.ld | 15 ++++++++++++++- linkers/i686.ld | 12 ++++++++++++ linkers/x86_64.ld | 12 ++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/linkers/aarch64.ld b/linkers/aarch64.ld index cce4c9edc9..e3e7b80c66 100644 --- a/linkers/aarch64.ld +++ b/linkers/aarch64.ld @@ -7,6 +7,19 @@ SECTIONS { . = KERNEL_OFFSET; . += SIZEOF_HEADERS; + + /* Force the zero page to be part of a segment by creating a + * dummy section in the zero page. + * Limine will map the segment with the lowest vaddr value at + * 0xFFFFFFFF80000000 even if the segment has a higher vaddr. + * As such without the zero page being part of a segment, the + * kernel would be loaded at an offset from the expected + * location. As the redox kernel is not currently relocatable, + * this would result in a crash. A similar issue likely exists + * with multiboot/multiboot2 and the paddr of the segment. + */ + .dummy ALIGN(8) : AT(ADDR(.dummy) - KERNEL_OFFSET) {} + . = ALIGN(4096); .text : AT(ADDR(.text) - KERNEL_OFFSET) { @@ -21,7 +34,7 @@ SECTIONS { __text_end = .; } - .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { + .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { __rodata_start = .; *(.rodata*) . = ALIGN(4096); diff --git a/linkers/i686.ld b/linkers/i686.ld index 0405e100a2..f7eb9c4295 100644 --- a/linkers/i686.ld +++ b/linkers/i686.ld @@ -8,6 +8,18 @@ SECTIONS { . += SIZEOF_HEADERS; + /* Force the zero page to be part of a segment by creating a + * dummy section in the zero page. + * Limine will map the segment with the lowest vaddr value at + * 0xFFFFFFFF80000000 even if the segment has a higher vaddr. + * As such without the zero page being part of a segment, the + * kernel would be loaded at an offset from the expected + * location. As the redox kernel is not currently relocatable, + * this would result in a crash. A similar issue likely exists + * with multiboot/multiboot2 and the paddr of the segment. + */ + .dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {} + .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) { __text_start = .; *(.text*) diff --git a/linkers/x86_64.ld b/linkers/x86_64.ld index c6c04349d9..6610509aef 100644 --- a/linkers/x86_64.ld +++ b/linkers/x86_64.ld @@ -8,6 +8,18 @@ SECTIONS { . += SIZEOF_HEADERS; + /* Force the zero page to be part of a segment by creating a + * dummy section in the zero page. + * Limine will map the segment with the lowest vaddr value at + * 0xFFFFFFFF80000000 even if the segment has a higher vaddr. + * As such without the zero page being part of a segment, the + * kernel would be loaded at an offset from the expected + * location. As the redox kernel is not currently relocatable, + * this would result in a crash. A similar issue likely exists + * with multiboot/multiboot2 and the paddr of the segment. + */ + .dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {} + .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) { __text_start = .; *(.text*)