Ignore:
Timestamp:
Jun 30, 2013, 8:28:58 PM (11 years ago)
Author:
cfuguet
Message:

Modifications in tsar_boot:

  • Creating new files boot_utils.[c h] containing the memcpy, memset and some ELF format debug functions
  • Introducing assert in the boot_elf_loader to show an error when some of segments to load conflicts with some of the pre-loader segments
  • Cosmetic changes in boot_elf_loader to improve code readibility
  • Fixing bug in dcache_buf_invalidate function used by boot_ioc_read when cache coherence not supported. The condition in the for loop was erroneous.
  • Modification in Makefile: The SYSCLK_FREQ parameter is not passed anymore

as a Makefile parameter but it is definesd in the defs_platform.h file

File:
1 edited

Legend:

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

    r415 r425  
    11/**
    2  * \file    : boot_loader_entry.c
     2 * \file    : boot_elf_loader.c
    33 * \date    : August 2012
    44 * \author  : Cesar Fuguet
     
    1313#include <elf-types.h>
    1414#include <boot_tty.h>
    15 #include <boot_memcpy.h>
     15#include <boot_utils.h>
    1616#include <defs.h>
     17
     18#if (BOOT_DEBUG == 1)
     19static char* init_state_str[] = {
     20    "ELF_HEADER_STATE",
     21    "ELF_PROGRAM_HEADER_STATE",
     22    "ELF_OFFSET_STATE",
     23    "ELF_SEGMENT_STATE",
     24    "ELF_END_STATE"
     25};
     26#endif
    1727
    1828void * boot_elf_loader(unsigned int lba)
    1929{
    20     /**
     30    /*
    2131     * Temporary variables used by the boot loader
    2232     */
     
    2636
    2737    unsigned char * buffer_ptr;
    28     Elf32_Ehdr    * elf_header_ptr;
    29     Elf32_Phdr    * elf_pht_ptr;
     38    Elf32_Ehdr    * elf_ehdr_ptr;
     39    Elf32_Phdr    * elf_phdr_ptr;
    3040
    3141    unsigned int nb_available;
     
    3444    unsigned int nb_block;
    3545    unsigned int offset;
     46
     47    unsigned char * pseg_ptr;
     48    unsigned int pseg_start;
     49    unsigned int pseg_end;
     50    unsigned int pseg_remainder;
    3651    unsigned int pseg;
    37     unsigned int i;
    38     unsigned int segment_req;
    3952
    4053    /*
    4154     * Loader state machine definition
    4255     */
    43     enum
     56    typedef enum
    4457    {
    4558        ELF_HEADER_STATE,
     
    4861        ELF_SEGMENT_STATE,
    4962        ELF_END_STATE
    50     } init_state
    51 #if (BOOT_DEBUG ==1)
    52     , init_state_debug
    53 #endif
    54         ;
    55 
    56 #if (BOOT_DEBUG == 1)
    57     char* init_state_str[] = {
    58         "ELF_HEADER_STATE",
    59         "ELF_PROGRAM_HEADER_STATE",
    60         "ELF_OFFSET_STATE",
    61         "ELF_SEGMENT_STATE",
    62         "ELF_END_STATE"
    63     };
    64 #endif
    65 
     63    } elf_loader_t;
     64
     65    elf_loader_t init_state;
     66    init_state = ELF_HEADER_STATE;
     67
     68#if (BOOT_DEBUG == 1)
     69    elf_loader_t init_state_debug;
     70    init_state_debug = ELF_END_STATE;
     71#endif
    6672
    6773    boot_puts("Starting boot_elf_loader function...\n\r");
    6874
    69     nb_block           = lba;
    70 
    71     pseg               = 0;
    72     nb_available       = 0;
    73     nb_rest            = sizeof(Elf32_Ehdr);
    74     offset             = 0;
    75 
    76     elf_header_ptr     = (Elf32_Ehdr *) &elf_header;
    77     elf_pht_ptr        = (Elf32_Phdr *) &elf_pht[0];
    78 
    79     init_state         = ELF_HEADER_STATE;
    80 #if (BOOT_DEBUG == 1)
    81     init_state_debug   = ELF_END_STATE;
    82 #endif
     75    nb_block     = lba;
     76    nb_available = 0;
     77    nb_rest      = sizeof(Elf32_Ehdr);
     78    pseg         = 0;
     79    offset       = 0;
     80    elf_ehdr_ptr = (Elf32_Ehdr *) &elf_header;
     81    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
    8382
    8483    while(init_state != ELF_END_STATE)
    8584    {
    86         if (nb_available == 0)
     85        if (nb_available == 0 )
    8786        {
    8887            buffer_ptr = &boot_elf_loader_buffer[0];
    8988
    90             if ( boot_ioc_read(nb_block , buffer_ptr, 1) )
     89            if (boot_ioc_read(nb_block , buffer_ptr, 1))
    9190            {
    9291                boot_puts (
    9392                    "ERROR: "
    94                     "IOC_FAILED"
     93                    "boot_ioc_read() failed"
    9594                    "\n"
    9695                );
     
    118117        switch(init_state)
    119118        {
    120             /**
     119            /*
    121120             * Reading ELF executable header
    122121             */
    123122            case ELF_HEADER_STATE:
    124                 boot_memcpy(elf_header_ptr, buffer_ptr, nb_read);
     123                memcpy(elf_ehdr_ptr, buffer_ptr, nb_read);
    125124
    126125                nb_rest -= nb_read;
     
    128127                if(nb_rest == 0)
    129128                {
    130                     nb_rest = elf_header_ptr->e_phnum * elf_header_ptr->e_phentsize;
    131 
    132                     /* Verification of ELF Magic Number */
    133                     if (
    134                         (elf_header_ptr->e_ident[EI_MAG0] != ELFMAG0) ||
    135                         (elf_header_ptr->e_ident[EI_MAG1] != ELFMAG1) ||
    136                         (elf_header_ptr->e_ident[EI_MAG2] != ELFMAG2) ||
    137                         (elf_header_ptr->e_ident[EI_MAG3] != ELFMAG3) )
     129                    nb_rest = elf_ehdr_ptr->e_phnum * elf_ehdr_ptr->e_phentsize;
     130
     131                    /*
     132                     * Verification of ELF Magic Number
     133                     */
     134                    if ( (elf_ehdr_ptr->e_ident[EI_MAG0] != ELFMAG0) ||
     135                         (elf_ehdr_ptr->e_ident[EI_MAG1] != ELFMAG1) ||
     136                         (elf_ehdr_ptr->e_ident[EI_MAG2] != ELFMAG2) ||
     137                         (elf_ehdr_ptr->e_ident[EI_MAG3] != ELFMAG3) )
    138138                    {
    139139                        boot_puts(
     
    150150                     * smaller than the work size allocated for the
    151151                     * elf_pht[PHDR_ARRAY_SIZE] array
    152                      **/
    153                     if (elf_header_ptr->e_phnum > PHDR_ARRAY_SIZE)
     152                     */
     153                    if (elf_ehdr_ptr->e_phnum > PHDR_ARRAY_SIZE)
    154154                    {
    155155                        boot_puts(
    156156                            "ERROR: "
    157                             "ELF PHDR table size is bigger than "
    158                             "the allocated work space"
     157                            "ELF PHDR table size is bigger than the allocated"
     158                            "work space"
    159159                            "\n"
    160160                        );
     
    168168                break;
    169169
    170             /**
     170            /*
    171171             * Reading ELF program headers
    172172             */
    173173            case ELF_PROGRAM_HEADER_STATE:
    174                 boot_memcpy(elf_pht_ptr, buffer_ptr, nb_read);
    175 
    176                 elf_pht_ptr = (Elf32_Phdr *)((unsigned char *) elf_pht_ptr + nb_read);
    177                 nb_rest    -= nb_read;
     174                memcpy(elf_phdr_ptr, buffer_ptr, nb_read);
     175
     176                elf_phdr_ptr =
     177                    (Elf32_Phdr *)((unsigned char *) elf_phdr_ptr + nb_read);
     178
     179                nb_rest -= nb_read;
    178180
    179181                if(nb_rest == 0)
    180182                {
    181                     elf_pht_ptr = (Elf32_Phdr *) &elf_pht[0];
     183                    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
    182184
    183185                    /*
    184186                     * Search the first not NULL segment in the ELF file
    185187                     */
    186                     for (pseg = 0; pseg < elf_header_ptr->e_phnum; pseg++)
    187                     {
    188                         if(elf_pht_ptr[pseg].p_type == PT_LOAD)
     188                    for (pseg = 0; pseg < elf_ehdr_ptr->e_phnum; pseg++)
     189                    {
     190                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
    189191                        {
    190192#if (BOOT_DEBUG == 1)
    191                             boot_puts("found a loadable segment:");
    192                             boot_puts("\n- type   : "); boot_putx(elf_pht_ptr[pseg].p_type);
    193                             boot_puts("\n- offset : "); boot_putx(elf_pht_ptr[pseg].p_offset);
    194                             boot_puts("\n- vaddr  : "); boot_putx(elf_pht_ptr[pseg].p_vaddr);
    195                             boot_puts("\n- paddr  : "); boot_putx(elf_pht_ptr[pseg].p_paddr);
    196                             boot_puts("\n- filesz : "); boot_putx(elf_pht_ptr[pseg].p_filesz);
    197                             boot_puts("\n- memsz  : "); boot_putx(elf_pht_ptr[pseg].p_memsz);
    198                             boot_puts("\n- flags  : "); boot_putx(elf_pht_ptr[pseg].p_flags);
    199                             boot_puts("\n- align  : "); boot_putx(elf_pht_ptr[pseg].p_align);
    200 #endif
    201                             if (elf_pht_ptr[pseg].p_offset < offset)
     193                            boot_puts("loadable segment found:\n");
     194                            boot_print_elf_phdr(&elf_phdr_ptr[pseg]);
     195#endif
     196                            if (elf_phdr_ptr[pseg].p_offset < offset)
    202197                            {
    203198                                /*
    204                                  * Case where the segment to load includes the elf
    205                                  * and program headers
    206                                  * */
    207                                 nb_rest = elf_pht_ptr[pseg].p_filesz - offset;
     199                                 * Case where the segment to load includes the
     200                                 * elf and program headers
     201                                 */
     202                                nb_rest = elf_phdr_ptr[pseg].p_filesz - offset;
    208203                                init_state = ELF_SEGMENT_STATE;
    209204                            }
     
    212207                                /*
    213208                                 * Segment to load is further away in ELF file
    214                                  * */
    215                                 nb_rest = elf_pht_ptr[pseg].p_offset - offset;
     209                                 */
     210                                nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
    216211                                init_state = ELF_OFFSET_STATE;
    217212                            }
     
    220215                    }
    221216
    222                     if (pseg == elf_header_ptr->e_phnum)
     217                    if (pseg == elf_ehdr_ptr->e_phnum)
    223218                    {
    224219                        boot_puts(
     
    234229                break;
    235230
    236             /**
     231            /*
    237232             * Go to the offset of the first not null program segment in the
    238233             * ELF file
     234             *
     235             * TODO:
     236             * No need to read from the disk the useless bytes. Try to compute
     237             * the next usefull lba
    239238             */
    240239            case ELF_OFFSET_STATE:
     
    243242                if (nb_rest == 0)
    244243                {
    245                     nb_rest    = elf_pht_ptr[pseg].p_filesz;
     244                    nb_rest    = elf_phdr_ptr[pseg].p_filesz;
    246245                    init_state = ELF_SEGMENT_STATE;
    247246                }
     
    249248                break;
    250249
    251             /**
     250            /*
    252251             * Reading ELF segments
     252             *
     253             * TODO:
     254             * Do not pass by block buffer but write directly in target memory
     255             * address
    253256             */
    254257            case ELF_SEGMENT_STATE:
    255                 /**
    256                  * Copying ELF segment data in memory segments using the virtual
    257                  * address got from the ELF file
     258                /*
     259                 * Verify that loadable segment does not conflict with
     260                 * pre-loader memory space
    258261                 */
    259                 segment_req = ((elf_pht_ptr[pseg].p_vaddr & 0xBFC00000) != 0xBFC00000);
    260 
    261                 if ( segment_req )
    262                 {
    263                     boot_memcpy((unsigned char *) elf_pht_ptr[pseg].p_vaddr +
    264                                 (elf_pht_ptr[pseg].p_filesz - nb_rest),
    265                                 buffer_ptr,
    266                                 nb_read);
    267                 }
     262                pseg_start = elf_phdr_ptr[pseg].p_vaddr;
     263
     264                pseg_end   = elf_phdr_ptr[pseg].p_vaddr +
     265                             elf_phdr_ptr[pseg].p_memsz;
     266
     267                if ((pseg_start >= 0xBFC00000 && pseg_start <= 0xBFC10000) ||
     268                    (pseg_end   >= 0xBFC00000 && pseg_end   <= 0xBFC10000) ||
     269                    (pseg_start <  0xBFC00000 && pseg_end   >  0xBFC10000))
     270                {
     271                    boot_puts(
     272                        "ERROR: "
     273                        "Program segment conflits with pre-loader memory space"
     274                        "\n"
     275                    );
     276                    boot_exit();
     277                }
     278
     279                /*
     280                 * Copy the ELF segment data in memory using the
     281                 * virtual address obtained from the ELF file
     282                 */
     283                pseg_ptr = (unsigned char *)
     284                    elf_phdr_ptr[pseg].p_vaddr  +
     285                    elf_phdr_ptr[pseg].p_filesz -
     286                    nb_rest;
     287
     288                memcpy(pseg_ptr, buffer_ptr, nb_read);
    268289
    269290                nb_rest -= nb_read;
    270291
    271                 if ( nb_rest == 0 )
    272                 {
    273                     if ( segment_req )
    274                     {
    275                         boot_puts("Copied segment at address ");
    276                         boot_putx(elf_pht_ptr[pseg].p_vaddr);
    277                         boot_puts("\n");
    278 
    279                         /*
    280                          * Fill remaining bytes with zeros (filesz < memsz)
    281                          */
    282                         for ( i = 0                                                        ;
    283                               i < (elf_pht_ptr[pseg].p_memsz - elf_pht_ptr[pseg].p_filesz) ;
    284                               i--                                                          )
     292                if (nb_rest == 0)
     293                {
     294                    /*
     295                     * Fill remaining bytes with zeros (filesz < memsz)
     296                     */
     297                    pseg_remainder =
     298                        elf_phdr_ptr[pseg].p_memsz  -
     299                        elf_phdr_ptr[pseg].p_filesz ;
     300
     301                    pseg_ptr = (unsigned char *)
     302                        elf_phdr_ptr[pseg].p_vaddr  +
     303                        elf_phdr_ptr[pseg].p_filesz ;
     304
     305                    memset(pseg_ptr, 0, pseg_remainder);
     306
     307                    boot_puts("Copied segment at address ");
     308                    boot_putx(elf_phdr_ptr[pseg].p_vaddr);
     309                    boot_puts("\n");
     310
     311                    /*
     312                     * Search the next first not NULL segment in the ELF file
     313                     */
     314                    for (pseg += 1; pseg < elf_ehdr_ptr->e_phnum; pseg++)
     315                    {
     316                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
    285317                        {
    286                             *(unsigned char *)
    287                             (elf_pht_ptr[pseg].p_vaddr + elf_pht_ptr[pseg].p_filesz + i) = 0;
    288                         }
    289                     }
    290 
    291                     /*
    292                      * Search the first not NULL segment in the ELF file
    293                      */
    294                     for ( pseg = pseg + 1; pseg < elf_header_ptr->e_phnum; pseg++) {
    295                         if(elf_pht_ptr[pseg].p_type == PT_LOAD)
    296                         {
    297                             nb_rest = elf_pht_ptr[pseg].p_offset - offset;
     318#if (BOOT_DEBUG == 1)
     319                            boot_puts("loadable segment found:\n");
     320                            boot_print_elf_phdr(&elf_phdr_ptr[pseg]);
     321#endif
     322                            nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
    298323                            break;
    299324                        }
     
    303328                     * Program loading finished
    304329                     */
    305                     if(pseg == elf_header_ptr->e_phnum)
     330                    if(pseg == elf_ehdr_ptr->e_phnum)
    306331                    {
    307332                        init_state = ELF_END_STATE;
     
    317342        }
    318343
    319         buffer_ptr              += nb_read;
    320         nb_available            -= nb_read;
     344        buffer_ptr   += nb_read;
     345        nb_available -= nb_read;
    321346    }
    322347
     
    325350        "Entry point address: "
    326351    );
    327     boot_putx(elf_header_ptr->e_entry);
     352
     353    boot_putx(elf_ehdr_ptr->e_entry);
    328354    boot_puts("\n");
    329355
    330     return ((void *) elf_header_ptr->e_entry);
     356    return ((void *) elf_ehdr_ptr->e_entry);
    331357}
     358
     359// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Note: See TracChangeset for help on using the changeset viewer.