Changeset 949 for trunk/softs


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

Location:
trunk/softs/tsar_boot
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/softs/tsar_boot/include/defs.h

    r804 r949  
    1313#   define RESET_HARD_CC      0
    1414#endif
     15
     16/**
     17 * Supported OS
     18 */
     19#define OS_LINUX              0
    1520
    1621/**
  • trunk/softs/tsar_boot/preloader.ld.in

    r930 r949  
    2525    {
    2626        *(.reset)
    27         *(.rodata)
    28         *(.rodata.*)
     27        *(.text)
    2928        . = ALIGN(0x4);
    30         dtb_addr = .;
     29        dtb_start = .;
    3130#if USE_DT == 1
    3231        INCLUDE "build/platform.ld";
    3332#endif
     33        dtb_end = .;
     34        *(.rodata)
     35        *(.rodata.*)
    3436    }
    3537
  • trunk/softs/tsar_boot/src/reset.S

    r833 r949  
    3636    .section .reset,"ax",@progbits
    3737
    38     .extern dtb_addr
    3938    .extern reset_putc
    4039    .extern reset_getc
     
    4746    .extern reset_ioc_init
    4847    .extern versionstr
     48    .extern dtb_start
     49    .extern dtb_addr
    4950
    5051    .globl  reset                    /* Makes reset an external symbol */
     
    6263preloader_vector:
    6364    .word   RESET_VERSION            /* 0xbfc0008 */
    64     .word   dtb_addr                 /* 0xbfc000c */
     65    .word   dtb_start                /* 0xbfc000c */
    6566    .word   reset_putc               /* 0xbfc0010 */
    6667    .word   reset_getc               /* 0xbfc0014 */
     
    167168
    168169    la      a0,     preloader_vector
    169     move    a1,     zero
     170    lw      a1,     dtb_addr
    170171    move    a2,     zero
    171172    move    a3,     zero
  • 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.