#ifndef __ASM_KERNEL_PGTABLE_H
 #define __ASM_KERNEL_PGTABLE_H
 
+#include <asm/boot.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/sparsemem.h>
 
 
 /* the initial ID map may need two extra pages if it needs to be extended */
 #if VA_BITS < 48
-#define INIT_IDMAP_DIR_SIZE    (INIT_DIR_SIZE + (2 * PAGE_SIZE))
+#define INIT_IDMAP_DIR_SIZE    ((INIT_IDMAP_DIR_PAGES + 2) * PAGE_SIZE)
 #else
-#define INIT_IDMAP_DIR_SIZE    INIT_DIR_SIZE
+#define INIT_IDMAP_DIR_SIZE    (INIT_IDMAP_DIR_PAGES * PAGE_SIZE)
 #endif
+#define INIT_IDMAP_DIR_PAGES   EARLY_PAGES(KIMAGE_VADDR, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE)
 
 /* Initial memory map size */
 #if ARM64_KERNEL_USES_PMD_MAPS
 
         *
         *  Register   Scope                      Purpose
         *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
+        *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
         *  x23        primary_entry() .. start_kernel()        physical misalignment/KASLR offset
         *  x28        clear_page_tables()                      callee preserved temp register
         *  x19/x20    __primary_switch()                       callee preserved temp registers
 #endif
        adrp    x0, init_idmap_pg_dir
        adrp    x3, _text
-       adrp    x6, _end
+       adrp    x6, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
        mov     x7, SWAPPER_RX_MMUFLAGS
 
        map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
        mov     x6, #SWAPPER_BLOCK_SHIFT
        bl      remap_region
 
+       /* Remap the FDT after the kernel image */
+       adrp    x1, _text
+       adrp    x22, _end + SWAPPER_BLOCK_SIZE
+       bic     x2, x22, #SWAPPER_BLOCK_SIZE - 1
+       bfi     x22, x21, #0, #SWAPPER_BLOCK_SHIFT              // remapped FDT address
+       add     x3, x2, #MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
+       bic     x4, x21, #SWAPPER_BLOCK_SIZE - 1
+       mov     x5, SWAPPER_RW_MMUFLAGS
+       mov     x6, #SWAPPER_BLOCK_SHIFT
+       bl      remap_region
+
        /*
         * Since the page tables have been populated with non-cacheable
         * accesses (MMU disabled), invalidate those tables again to