Index: kernel/arch/abs32le/_link.ld.in
===================================================================
--- kernel/arch/abs32le/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/abs32le/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -1,4 +1,5 @@
 SECTIONS {
 	.text : {
+		kernel_load_address = .;
 		ktext_start = .;
 		*(.text);
@@ -8,10 +9,4 @@
 		kdata_start = .;
 		*(.data);                       /* initialized data */
-		hardcoded_ktext_size = .;
-		LONG(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		LONG(kdata_end - kdata_start);
-		hardcoded_load_address = .;
-		LONG(hardcoded_load_address);
 		*(.bss);                        /* uninitialized static variables */
 		*(COMMON);                      /* global variables */
Index: kernel/arch/abs32le/src/mm/frame.c
===================================================================
--- kernel/arch/abs32le/src/mm/frame.c	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/abs32le/src/mm/frame.c	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -42,7 +42,4 @@
 #include <print.h>
 
-size_t hardcoded_unmapped_ktext_size = 0;
-size_t hardcoded_unmapped_kdata_size = 0;
-
 void physmem_print(void)
 {
Index: kernel/arch/amd64/_link.ld.in
===================================================================
--- kernel/arch/amd64/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/amd64/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -13,4 +13,6 @@
 
 SECTIONS {
+	kernel_load_address = PA2KA(BOOT_OFFSET);
+
 	.unmapped BOOT_OFFSET: AT (0) {
 		unmapped_ktext_start = .;
@@ -32,14 +34,4 @@
 		*(.data);              /* initialized data */
 		*(.rodata .rodata.*);  /* string literals */
-		hardcoded_load_address = .;
-		QUAD(PA2KA(BOOT_OFFSET));
-		hardcoded_ktext_size = .;
-		QUAD(ktext_end - ktext_start + (unmapped_ktext_end - unmapped_ktext_start));
-		hardcoded_kdata_size = .;
-		QUAD(kdata_end - kdata_start + (unmapped_kdata_end - unmapped_kdata_start));
-		hardcoded_unmapped_ktext_size = .;
-		QUAD(unmapped_ktext_end - unmapped_ktext_start);
-		hardcoded_unmapped_kdata_size = .;
-		QUAD(unmapped_kdata_end - unmapped_kdata_start);
 		*(COMMON);      /* global variables */
 
@@ -71,5 +63,4 @@
 
 #ifdef CONFIG_SMP
-	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
 	ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
 	ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
Index: kernel/arch/amd64/include/arch/boot/boot.h
===================================================================
--- kernel/arch/amd64/include/arch/boot/boot.h	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/amd64/include/arch/boot/boot.h	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -42,10 +42,5 @@
 #ifndef __ASSEMBLER__
 
-#ifdef CONFIG_SMP
-
-/* This is only a symbol so the type is dummy. Obtain the value using &. */
-extern int _hardcoded_unmapped_size;
-
-#endif /* CONFIG_SMP */
+extern uint8_t unmapped_kdata_end[];
 
 #endif /* __ASSEMBLER__ */
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/amd64/src/amd64.c	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -94,7 +94,7 @@
 
 #ifdef CONFIG_SMP
+	size_t unmapped_size = (uintptr_t) unmapped_kdata_end - BOOT_OFFSET;
 	/* Copy AP bootstrap routines below 1 MB. */
-	memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
-	    (size_t) &_hardcoded_unmapped_size);
+	memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, unmapped_size);
 #endif
 }
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/arm32/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -24,4 +24,5 @@
 SECTIONS {
 	. = KERNEL_LOAD_ADDRESS;
+	kernel_load_address = .;
 	.text : {
 		ktext_start = .;
@@ -32,10 +33,4 @@
 		kdata_start = .;
 		*(.data);                       /* initialized data */
-		hardcoded_ktext_size = .;
-		LONG(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		LONG(kdata_end - kdata_start);
-		hardcoded_load_address = .;
-		LONG(KERNEL_LOAD_ADDRESS);
 		*(.bss);                        /* uninitialized static variables */
 		*(COMMON);                      /* global variables */
Index: kernel/arch/ia32/_link.ld.in
===================================================================
--- kernel/arch/ia32/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia32/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -13,4 +13,6 @@
 
 SECTIONS {
+	kernel_load_address = PA2KA(BOOT_OFFSET);
+
 	.unmapped BOOT_OFFSET: AT (0) {
 		unmapped_ktext_start = .;
@@ -32,14 +34,4 @@
 		*(.rodata .rodata.*);   /* string literals */
 		*(COMMON);              /* global variables */
-		hardcoded_load_address = .;
-		LONG(PA2KA(BOOT_OFFSET));
-		hardcoded_ktext_size = .;
-		LONG((ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start));
-		hardcoded_kdata_size = .;
-		LONG((kdata_end - kdata_start) + (unmapped_kdata_end - unmapped_kdata_start));
-		hardcoded_unmapped_ktext_size = .;
-		LONG(unmapped_ktext_end - unmapped_ktext_start);
-		hardcoded_unmapped_kdata_size = .;
-		LONG(unmapped_kdata_end - unmapped_kdata_start);
 		. = ALIGN(8);
 		symbol_table = .;
@@ -68,5 +60,4 @@
 #ifdef CONFIG_SMP
 
-	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
 	ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
 	ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
Index: kernel/arch/ia32/include/arch/boot/boot.h
===================================================================
--- kernel/arch/ia32/include/arch/boot/boot.h	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia32/include/arch/boot/boot.h	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -44,6 +44,5 @@
 #ifdef CONFIG_SMP
 
-/* This is only a symbol so the type is dummy. Obtain the value using &. */
-extern int _hardcoded_unmapped_size;
+extern uint8_t unmapped_kdata_end[];
 
 #endif /* CONFIG_SMP */
Index: kernel/arch/ia32/src/boot/multiboot.S
===================================================================
--- kernel/arch/ia32/src/boot/multiboot.S	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia32/src/boot/multiboot.S	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -285,17 +285,6 @@
 /** Calculate unmapped address of the end of the kernel. */
 calc_kernel_end:
-	movl $KA2PA(hardcoded_load_address), %edi
-	movl (%edi), %esi
-	leal KA2PA(0)(%esi), %esi
-
-	movl $KA2PA(hardcoded_ktext_size), %edi
-	addl (%edi), %esi
-	leal KA2PA(0)(%esi), %esi
-
-	movl $KA2PA(hardcoded_kdata_size), %edi
-	addl (%edi), %esi
-	leal KA2PA(0)(%esi), %esi
-	movl %esi, kernel_end
-
+	movl $KA2PA(kdata_end), %edi
+	movl %edi, kernel_end
 	ret
 
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia32/src/ia32.c	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -94,7 +94,7 @@
 
 #ifdef CONFIG_SMP
+	size_t unmapped_size = (uintptr_t) unmapped_kdata_end - BOOT_OFFSET;
 	/* Copy AP bootstrap routines below 1 MB. */
-	memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
-	    (size_t) &_hardcoded_unmapped_size);
+	memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, unmapped_size);
 #endif
 }
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -47,7 +47,4 @@
 
 #define PHYSMEM_LIMIT32  UINT64_C(0x100000000)
-
-size_t hardcoded_unmapped_ktext_size = 0;
-size_t hardcoded_unmapped_kdata_size = 0;
 
 static void init_e820_memory(pfn_t minconf, bool low)
@@ -155,7 +152,9 @@
 
 #ifdef CONFIG_SMP
+		size_t unmapped_size =
+		    (uintptr_t) unmapped_kdata_end - BOOT_OFFSET;
+
 		minconf = max(minconf,
-		    ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size +
-		    hardcoded_unmapped_kdata_size));
+		    ADDR2PFN(AP_BOOT_OFFSET + unmapped_size));
 #endif
 
@@ -168,6 +167,5 @@
 		/* Reserve AP real mode bootstrap memory */
 		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
-		    (hardcoded_unmapped_ktext_size +
-		    hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
+		    unmapped_size >> FRAME_WIDTH);
 #endif
 	}
Index: kernel/arch/ia64/_link.ld.in
===================================================================
--- kernel/arch/ia64/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ia64/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -13,4 +13,6 @@
 
 SECTIONS {
+	kernel_load_address = LOAD_ADDRESS_V;
+
 	.image LOAD_ADDRESS_V: AT (LOAD_ADDRESS_P) {
 		ktext_start = .;
@@ -24,10 +26,4 @@
 		*(.opd)
 		*(.data .data.*)
-		hardcoded_load_address = .;
-		QUAD(LOAD_ADDRESS_V);
-		hardcoded_ktext_size = .;
-		QUAD(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		QUAD(kdata_end - kdata_start);
 		__gp = .;
 		*(.got .got.*)
Index: kernel/arch/mips32/_link.ld.in
===================================================================
--- kernel/arch/mips32/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/mips32/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -23,4 +23,6 @@
 SECTIONS {
 	. = KERNEL_LOAD_ADDRESS;
+	kernel_load_address = .;
+
 	.text : {
 		ktext_start = .;
@@ -31,10 +33,4 @@
 		kdata_start = .;
 		*(.data);                       /* initialized data */
-		hardcoded_ktext_size = .;
-		LONG(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		LONG(kdata_end - kdata_start);
-		hardcoded_load_address = .;
-		LONG(KERNEL_LOAD_ADDRESS);
 		*(.rodata*);
 		*(.sdata);
Index: kernel/arch/ppc32/_link.ld.in
===================================================================
--- kernel/arch/ppc32/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/ppc32/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -18,4 +18,6 @@
 
 SECTIONS {
+	kernel_load_address = PA2KA(0);
+
 	.unmapped 0: AT (0) {
 		unmapped_ktext_start = .;
@@ -41,10 +43,4 @@
 		*(.sdata2);
 		*(.sbss);
-		hardcoded_ktext_size = .;
-		LONG(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		LONG(kdata_end - kdata_start);
-		hardcoded_load_address = .;
-		LONG(PA2KA(BOOT_OFFSET));
 		*(.bss);        /* uninitialized static variables */
 		*(COMMON);      /* global variables */
Index: kernel/arch/riscv64/_link.ld.in
===================================================================
--- kernel/arch/riscv64/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/riscv64/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -14,4 +14,6 @@
 
 SECTIONS {
+	kernel_load_address = PA2KA(BOOT_OFFSET);
+
 	.image (PA2KA(BOOT_OFFSET)) : AT (0) {
 		ktext_start = .;
@@ -23,10 +25,4 @@
 		*(.data);                       /* initialized data */
 		*(.rodata*);
-		hardcoded_load_address = .;
-		QUAD(PA2KA(BOOT_OFFSET));
-		hardcoded_ktext_size = .;
-		QUAD(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		QUAD(kdata_end - kdata_start);
 		*(.sdata);
 		*(.reginfo);
Index: kernel/arch/sparc64/_link.ld.in
===================================================================
--- kernel/arch/sparc64/_link.ld.in	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/arch/sparc64/_link.ld.in	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -13,4 +13,6 @@
 SECTIONS {
 	.image VMA: AT (LMA) {
+		kernel_load_address = .;
+
 		ktext_start = .;
 		*(K_TEXT_START)
@@ -26,10 +28,4 @@
 		*(.sbss);
 		. = ALIGN(8);
-		hardcoded_ktext_size = .;
-		QUAD(ktext_end - ktext_start);
-		hardcoded_kdata_size = .;
-		QUAD(kdata_end - kdata_start);
-		hardcoded_load_address = .;
-		QUAD(VMA);
 		*(.bss);                    /* uninitialized static variables */
 		*(COMMON);                  /* global variables */
Index: kernel/generic/include/main/main.h
===================================================================
--- kernel/generic/include/main/main.h	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/generic/include/main/main.h	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -38,7 +38,9 @@
 #include <typedefs.h>
 
-extern size_t hardcoded_kdata_size;
-extern size_t hardcoded_ktext_size;
-extern uintptr_t hardcoded_load_address;
+/* Address of the start of the kernel image. */
+extern uint8_t kernel_load_address[];
+/* Address of the end of kernel. */
+extern uint8_t kdata_end[];
+
 extern uintptr_t stack_safe;
 
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 7900e5dd9692cec40a7b95a02e09774b85117354)
+++ kernel/generic/src/main/main.c	(revision 8a1afd26eb90be3d715d4ce522280cbbf475f0a9)
@@ -168,7 +168,8 @@
 	config.cpu_active = 1;
 
-	config.base = hardcoded_load_address;
-	config.kernel_size = ALIGN_UP(hardcoded_ktext_size +
-	    hardcoded_kdata_size, PAGE_SIZE);
+	config.base = (uintptr_t) kernel_load_address;
+
+	config.kernel_size =
+	    ALIGN_UP((uintptr_t) kdata_end - config.base, PAGE_SIZE);
 	config.stack_size = STACK_SIZE;
 
