Index: /trunk/softs/tsar_boot/include/defs.h
===================================================================
--- /trunk/softs/tsar_boot/include/defs.h	(revision 948)
+++ /trunk/softs/tsar_boot/include/defs.h	(revision 949)
@@ -13,4 +13,9 @@
 #   define RESET_HARD_CC      0
 #endif
+
+/**
+ * Supported OS
+ */
+#define OS_LINUX              0
 
 /**
Index: /trunk/softs/tsar_boot/preloader.ld.in
===================================================================
--- /trunk/softs/tsar_boot/preloader.ld.in	(revision 948)
+++ /trunk/softs/tsar_boot/preloader.ld.in	(revision 949)
@@ -25,11 +25,13 @@
     {
         *(.reset)
-        *(.rodata)
-        *(.rodata.*)
+        *(.text)
         . = ALIGN(0x4);
-        dtb_addr = .;
+        dtb_start = .;
 #if USE_DT == 1
         INCLUDE "build/platform.ld";
 #endif
+        dtb_end = .;
+        *(.rodata)
+        *(.rodata.*)
     }
 
Index: /trunk/softs/tsar_boot/src/reset.S
===================================================================
--- /trunk/softs/tsar_boot/src/reset.S	(revision 948)
+++ /trunk/softs/tsar_boot/src/reset.S	(revision 949)
@@ -36,5 +36,4 @@
     .section .reset,"ax",@progbits
 
-    .extern dtb_addr
     .extern reset_putc
     .extern reset_getc
@@ -47,4 +46,6 @@
     .extern reset_ioc_init
     .extern versionstr
+    .extern dtb_start
+    .extern dtb_addr
 
     .globl  reset                    /* Makes reset an external symbol */
@@ -62,5 +63,5 @@
 preloader_vector:
     .word   RESET_VERSION            /* 0xbfc0008 */
-    .word   dtb_addr                 /* 0xbfc000c */
+    .word   dtb_start                /* 0xbfc000c */
     .word   reset_putc               /* 0xbfc0010 */
     .word   reset_getc               /* 0xbfc0014 */
@@ -167,5 +168,5 @@
 
     la      a0,     preloader_vector
-    move    a1,     zero
+    lw      a1,     dtb_addr
     move    a2,     zero
     move    a3,     zero
Index: /trunk/softs/tsar_boot/src/reset_elf_loader.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_elf_loader.c	(revision 948)
+++ /trunk/softs/tsar_boot/src/reset_elf_loader.c	(revision 949)
@@ -17,4 +17,7 @@
 
 extern int blk_buf_idx;
+extern int dtb_start, dtb_end;
+
+addr_t dtb_addr;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -56,6 +59,5 @@
      */
     int pseg;
-    for (pseg = 0; pseg < elf_header.e_phnum; pseg++)
-    {
+    for (pseg = 0; pseg < elf_header.e_phnum; pseg++) {
         if(elf_pht[pseg].p_type != PT_LOAD) continue;
 
@@ -91,11 +93,43 @@
     }
 
+    if (pseg == 0) {
+        reset_puts("\n[RESET ERROR] No loadable segments");
+        goto error;
+    }
+
+    /* By default, the used device tree is the one in the ROM */
+    dtb_addr = (addr_t)&dtb_start;
+
+#if OS_LINUX
+    /* When loading a Linux kernel, the device tree should be located in low
+     * memory addresses before the kernel itself.
+     * - When the ROM-contained DTB is located before the kernel no need to copy
+     *   the DTB elsewhere.
+     * - When the ROM-contained DTB is located after the kernel the DTB is
+     *   copied before the kernel. */
+    const int copy_dtb = ((addr_t)&dtb_start > elf_pht[0].p_paddr);
+    if (copy_dtb) {
+        size_t dtb_size = (size_t)&dtb_end - (size_t)&dtb_start;
+        dtb_addr = SEG_RAM_BASE;
+        if ((dtb_addr + (addr_t)dtb_size) >= elf_pht[0].p_paddr) {
+            reset_puts("\n[RESET ERROR] Insufficient space to copy the DTB");
+            goto error;
+        }
+
+        memcpy((void*)dtb_addr, (void*)&dtb_start, dtb_size);
+        reset_puts("\n[RESET] Device tree blob copied / address = ");
+        reset_putx(dtb_addr);
+        reset_puts(" / size = ");
+        reset_putx(dtb_size);
+    }
+#endif
+
     reset_puts("\n[RESET] Complete reset_elf_loader at cycle ");
-    reset_putd( proctime() );
+    reset_putd(proctime());
     reset_puts(" / boot entry = ");
-    reset_putx( (addr_t)(elf_header.e_entry) );
+    reset_putx((addr_t)elf_header.e_entry);
     reset_puts("\n");
 
-    return ((void *) elf_header.e_entry);
+    return ((void*)elf_header.e_entry);
 
 error:
