Ignore:
Timestamp:
Feb 18, 2015, 4:18:43 PM (9 years ago)
Author:
cfuguet
Message:

preloader: when loading LINUX, copy the DTB in low memory addresses

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/softs/tsar_boot/src/reset_elf_loader.c

    r930 r949  
    1717
    1818extern int blk_buf_idx;
     19extern int dtb_start, dtb_end;
     20
     21addr_t dtb_addr;
    1922
    2023///////////////////////////////////////////////////////////////////////////////
     
    5659     */
    5760    int pseg;
    58     for (pseg = 0; pseg < elf_header.e_phnum; pseg++)
    59     {
     61    for (pseg = 0; pseg < elf_header.e_phnum; pseg++) {
    6062        if(elf_pht[pseg].p_type != PT_LOAD) continue;
    6163
     
    9193    }
    9294
     95    if (pseg == 0) {
     96        reset_puts("\n[RESET ERROR] No loadable segments");
     97        goto error;
     98    }
     99
     100    /* By default, the used device tree is the one in the ROM */
     101    dtb_addr = (addr_t)&dtb_start;
     102
     103#if OS_LINUX
     104    /* When loading a Linux kernel, the device tree should be located in low
     105     * memory addresses before the kernel itself.
     106     * - When the ROM-contained DTB is located before the kernel no need to copy
     107     *   the DTB elsewhere.
     108     * - When the ROM-contained DTB is located after the kernel the DTB is
     109     *   copied before the kernel. */
     110    const int copy_dtb = ((addr_t)&dtb_start > elf_pht[0].p_paddr);
     111    if (copy_dtb) {
     112        size_t dtb_size = (size_t)&dtb_end - (size_t)&dtb_start;
     113        dtb_addr = SEG_RAM_BASE;
     114        if ((dtb_addr + (addr_t)dtb_size) >= elf_pht[0].p_paddr) {
     115            reset_puts("\n[RESET ERROR] Insufficient space to copy the DTB");
     116            goto error;
     117        }
     118
     119        memcpy((void*)dtb_addr, (void*)&dtb_start, dtb_size);
     120        reset_puts("\n[RESET] Device tree blob copied / address = ");
     121        reset_putx(dtb_addr);
     122        reset_puts(" / size = ");
     123        reset_putx(dtb_size);
     124    }
     125#endif
     126
    93127    reset_puts("\n[RESET] Complete reset_elf_loader at cycle ");
    94     reset_putd( proctime() );
     128    reset_putd(proctime());
    95129    reset_puts(" / boot entry = ");
    96     reset_putx( (addr_t)(elf_header.e_entry) );
     130    reset_putx((addr_t)elf_header.e_entry);
    97131    reset_puts("\n");
    98132
    99     return ((void *) elf_header.e_entry);
     133    return ((void*)elf_header.e_entry);
    100134
    101135error:
Note: See TracChangeset for help on using the changeset viewer.