POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/core/loader.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Thu Jan 15 23:34:13 2009 
00015  */
00016 
00029 #ifdef POK_NEEDS_PARTITIONS
00030 
00031 #include <errno.h>
00032 #include <types.h>
00033 #include <libc.h>
00034 #include <core/cpio.h>
00035 #include <core/error.h>
00036 #include <core/partition.h>
00037 #include <elf.h>
00038 
00043 extern uint32_t part_sizes[];
00044 
00049 static pok_ret_t pok_loader_elf_load   (char* file,
00050                                         uint32_t offset,
00051                                         void** entry)
00052 {
00053    Elf32_Ehdr*  elf_header;
00054    Elf32_Phdr*  elf_phdr;
00055    unsigned int i;
00056    char*        dest;
00057 
00058    elf_header = (Elf32_Ehdr*)file;
00059 
00060    if (elf_header->e_ident[0] != 0x7f ||
00061        elf_header->e_ident[1] != 'E' ||
00062        elf_header->e_ident[2] != 'L' ||
00063        elf_header->e_ident[3] != 'F')
00064    {
00065       return POK_ERRNO_NOTFOUND;
00066    }
00067 
00068    *entry = (void*)elf_header->e_entry;
00069 
00070    elf_phdr = (Elf32_Phdr*)(file + elf_header->e_phoff);
00071 
00072    for (i = 0; i < elf_header->e_phnum; ++i)
00073    {
00074       dest = (char *)elf_phdr[i].p_vaddr + offset;
00075 
00076       memcpy (dest, elf_phdr[i].p_offset + file, elf_phdr[i].p_filesz);
00077       memset (dest + elf_phdr[i].p_filesz, 0, elf_phdr[i].p_memsz - elf_phdr[i].p_filesz);
00078    }
00079 
00080    return POK_ERRNO_OK;
00081 }
00082 
00083 
00084 
00085 void pok_loader_load_partition (const uint8_t part_id,
00086                                 uint32_t offset,
00087                                 uint32_t *entry)
00088 {
00089    void*       elf_entry = NULL;
00090    extern char __archive2_begin;
00091    uint32_t    size;
00092    uint8_t     t;
00093 
00094    size = 0;
00095    t    = 0;
00096 
00097    while (t < part_id)
00098    {
00099       size += part_sizes[t];
00100       t++;
00101    }
00102 
00103    if (pok_partitions[part_id].size < part_sizes[part_id])
00104    {
00105 #ifdef POK_NEEDS_ERROR_HANDLING
00106       pok_partition_error (part_id, POK_ERROR_KIND_PARTITION_CONFIGURATION);
00107 #else
00108 #ifdef POK_NEEDS_DEBUG
00109       /* We consider that even if errors are not raised, we must print an error
00110        * for such error
00111        * So, when we are using the debug mode, we print a fatal error.
00112        */
00113 #include <core/debug.h>
00114 #include <libc.h>
00115       printf("Declared size for partition %d : %d\n", part_id, pok_partitions[part_id].size);
00116       printf("Real size for partition %d     : %d\n", part_id, part_sizes[part_id]);
00117       pok_fatal ("Partition size is not correct\n");
00118 #endif
00119 #endif
00120    }
00121    /*
00122     *  FIXME : current debug session about exceptions-handled
00123    printf ("Will load partition at offset 0x%x\n", offset);
00124    */
00125    pok_loader_elf_load ((&__archive2_begin) + size , offset, &elf_entry);
00126 
00127    *entry = (uint32_t)elf_entry;
00128 }
00129 
00130 #endif /* POK_NEEDS_PARTITIONS */