cmod.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
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