source: trunk/softs/tsar_boot/src/reset_elf_loader.c @ 817

Last change on this file since 817 was 758, checked in by cfuguet, 10 years ago

tsar_boot: improving configuration infrastructure

  • Using hard_config.h which respects the same sintax that the hard_config.h file of all TSAR platforms. This file can be then generated by the GIET-VM genmap tool or written manually.
  • All peripheral drivers have been moved to a drivers directory and they are compiled as a static library. This allows GCC to only include in the final .ELF the object files of used peripherals and not all of them.
  • Example hard_config.h and ldscripts have been introduced in the conf directory.
  • Improving comments in all files
File size: 2.8 KB
Line 
1/**
2 * \file    : reset_elf_loader.c
3 * \date    : August 2012
4 * \author  : Cesar Fuguet
5 *
6 * This file defines an elf file loader which reads an executable .elf file
7 * starting at a sector passed as argument on a disk and copy the different
8 * ELF program segments in the appropriate memory address using as information
9 * the virtual address read from the .elf file.
10 */
11
12#include <reset_ioc.h>
13#include <elf-types.h>
14#include <reset_tty.h>
15#include <reset_utils.h>
16#include <defs.h>
17
18///////////////////////////////////////////////////////////////////////////////
19void * reset_elf_loader(size_t lba)
20///////////////////////////////////////////////////////////////////////////////
21{
22    size_t file_offset = lba * BLOCK_SIZE;
23
24    reset_puts("\n[RESET] Start reset_elf_loader at cycle ");
25    reset_putd( proctime() );
26    reset_puts("\n");
27
28    /*
29     * Load ELF HEADER
30     */
31    Elf32_Ehdr elf_header;
32    if (pread(file_offset, (void*)&elf_header, sizeof(Elf32_Ehdr), 0) < 0) {
33        goto error;
34    }
35    check_elf_header(&elf_header);
36
37    /*
38     * Load ELF PROGRAM HEADER TABLE
39     */
40    Elf32_Phdr elf_pht[RESET_PHDR_ARRAY_SIZE];
41    size_t phdr_nbyte = sizeof(Elf32_Phdr) * elf_header.e_phnum;
42    size_t phdr_off = elf_header.e_phoff;
43    if (pread(file_offset, (void*)&elf_pht, phdr_nbyte, phdr_off) < 0) {
44        goto error;
45    }
46
47    /*
48     * Search for loadable segments in the ELF file
49     */
50    int pseg;
51    for (pseg = 0; pseg < elf_header.e_phnum; pseg++)
52    {
53        if(elf_pht[pseg].p_type != PT_LOAD) continue;
54
55#if (RESET_DEBUG == 1)
56        reset_puts("[RESET DEBUG] Loadable segment found:\n");
57        reset_print_elf_phdr(&elf_pht[pseg]);
58#endif
59
60        addr_t p_paddr = elf_pht[pseg].p_paddr;
61        size_t p_filesz = elf_pht[pseg].p_filesz;
62        size_t p_memsz = elf_pht[pseg].p_memsz;
63        size_t p_offset = elf_pht[pseg].p_offset;
64
65        /*
66         * Copy program segment from ELF executable into corresponding physical
67         * address
68         */
69        if (pread(file_offset, (void*)p_paddr, p_filesz, p_offset) < 0) {
70            goto error;
71        }
72
73        /*
74         * Fill remaining bytes with zero (filesz < memsz)
75         */
76        char* pseg_ptr = (char*)p_paddr;
77        memset((void*)&pseg_ptr[p_filesz], 0, (p_memsz - p_filesz));
78
79        reset_puts("\n[RESET] Segment loaded : address = ");
80        reset_putx(p_paddr);
81        reset_puts(" / size = ");
82        reset_putx(p_filesz);
83        reset_puts("\n");
84    }
85
86    reset_puts("\n[RESET] Complete reset_elf_loader at cycle ");
87    reset_putd( proctime() );
88    reset_puts(" / boot entry = ");
89    reset_putx( (addr_t)(elf_header.e_entry) );
90    reset_puts("\n");
91
92    return ((void *) elf_header.e_entry);
93
94error:
95    reset_puts("\n[RESET ERROR] Error while loading ELF file");
96    reset_exit();
97    return 0;
98}
99
100// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Note: See TracBrowser for help on using the repository browser.