Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * @(#)$Id: cmod.c,v 1.4 2007/05/28 16:22:15 bg- Exp $ 00030 */ 00031 00032 #include <stdio.h> 00033 #include <string.h> 00034 00035 #include "contiki.h" 00036 00037 #include "loader/elf32.h" 00038 #include "loader/cle.h" 00039 #include "loader/cmod.h" 00040 00041 #include "lib/malloc.h" 00042 00043 #include "lib/assert.h" 00044 00045 #if 1 00046 #define PRINTF(...) do {} while (0) 00047 #else 00048 #define PRINTF(...) printf(__VA_ARGS__) 00049 #endif 00050 00051 #ifndef CMOD_NMODULES 00052 #define CMOD_NMODULES 4 00053 #endif 00054 struct cmod_info cmod_module[CMOD_NMODULES]; 00055 00056 int 00057 cmod_load(unsigned imod, 00058 cle_scratch scratch, 00059 int (*pread)(void *, int, off_t), 00060 off_t off) 00061 { 00062 struct cle_info h; 00063 int ret; 00064 void (*init)(void); 00065 00066 if(imod >= CMOD_NMODULES) { 00067 PRINTF("imod to large"); 00068 return 100; 00069 } 00070 00071 if(cmod_module[imod].ram != NULL || cmod_module[imod].fini != NULL) { 00072 PRINTF("module busy\n"); 00073 return 101; 00074 } 00075 00076 /* The (ELF) header is located at the start of the buffer. */ 00077 ret = cle_read_info(&h, pread, off); 00078 00079 if(ret != CLE_OK) { 00080 strcpy(scratch, h.name); 00081 return ret; 00082 } 00083 00084 cmod_module[imod].ram = malloc(h.datasize + h.bsssize + h.textsize); 00085 if(cmod_module[imod].ram == NULL) { 00086 return CMOD_DATA_TO_LARGE; 00087 } 00088 00089 /* 00090 * Here we specify where we want to relocate to. 00091 */ 00092 h.data = cmod_module[imod].ram; 00093 h.bss = h.data + h.datasize; 00094 h.text = (cle_addr)h.bss + h.bsssize; 00095 00096 PRINTF("cmod: copy text segment to RAM %p %p\n", 00097 h.text, h.text + h.textsize); 00098 ret = pread((void *)h.text, h.textsize, off + h.textoff); 00099 assert(ret > 0); 00100 if(h.textrelasize > 0) { 00101 PRINTF("cmod: relocate text in RAM\n"); 00102 ret = cle_relocate(&h, 00103 pread, 00104 off, 00105 (void *)h.text, 00106 h.textrelaoff, h.textrelasize); 00107 if(ret != CLE_OK) { 00108 strcpy(scratch, h.name); 00109 return ret; 00110 } 00111 } 00112 00113 PRINTF("cmod: copy data segment to RAM %p %p\n", 00114 h.data, h.data + h.datasize); 00115 ret = pread(h.data, h.datasize, off + h.dataoff); 00116 assert(ret >= 0); 00117 if(h.datarelasize > 0) { 00118 PRINTF("cmod: relocate data segment\n"); 00119 ret = cle_relocate(&h, 00120 pread, 00121 off, 00122 h.data, 00123 h.datarelaoff, h.datarelasize); 00124 if(ret != CLE_OK) { 00125 strcpy(scratch, h.name); 00126 return ret; 00127 } 00128 } 00129 00130 PRINTF("cmod: zero bss %p %p\n", h.bss, h.bss + h.bsssize); 00131 memset(h.bss, 0, h.bsssize); 00132 00133 cmod_module[imod].fini = cle_lookup(&h, pread, off, "_fini"); 00134 init = cle_lookup(&h, pread, off, "_init"); 00135 00136 if(init != NULL) { 00137 PRINTF("init=%p fini=%p\n", init, cmod_module[imod].fini); 00138 (*init)(); 00139 return CLE_OK; 00140 } else 00141 return CMOD_NO_STARTPOINT; 00142 } 00143 00144 void 00145 cmod_unload(int imod) 00146 { 00147 if(cmod_module[imod].fini != NULL) { 00148 (*cmod_module[imod].fini)(); 00149 cmod_module[imod].fini = NULL; 00150 } 00151 if(cmod_module[imod].ram != NULL) { 00152 free(cmod_module[imod].ram); 00153 cmod_module[imod].ram = NULL; 00154 } 00155 } 00156 00157 #if 0 00158 void 00159 cmod_status(void) 00160 { 00161 unsigned i; 00162 PRINTF("Id Module Address Fini\n"); 00163 for(i = 0; i < CMOD_NMODULES; i++) 00164 if(cmod_module[i].ram != NULL) 00165 PRINTF("%2d %-8s %7p %4p\n", i, 00166 cmod_module[i].name, cmod_module[i].ram, cmod_module[i].fini); 00167 } 00168 #endif