Warning, cross-references for /kernel/module/loader.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "types.h"
0019 #include "mem/physical.h"
0020 #include "mem/virtual.h"
0021 #include "module/header.h"
0022 #include "util/debug.h"
0023 #include "arch/i386.h"
0024
0025 #define DEBUG_MODULE
0026
0027 #ifdef DEBUG_MODULE
0028 #define DLOG(fmt,...) DLOG_PREFIX("module",fmt,##__VA_ARGS__)
0029 #else
0030 #define DLOG(fmt,...) ;
0031 #endif
0032
0033 extern const struct module *_module_ptr_list;
0034
0035 typedef struct modruntime {
0036 const struct module *mod;
0037 union {
0038 u32 flags;
0039 struct {
0040 u32 loaded:1;
0041 };
0042 };
0043 } modruntime_t;
0044
0045 typedef struct modsystem {
0046 modruntime_t *mr;
0047 u32 cnt;
0048 } modsystem_t;
0049
0050 static modsystem_t module_system;
0051
0052 static bool module_load_i (const int);
0053
0054
0055
0056 static int
0057 module_load_name (const char *name, int i, int j)
0058 {
0059 bool subtree = FALSE, success = FALSE;
0060 if (name[j-1] == '_' && name[j-2] == '_' && name[j-3] == '_')
0061 subtree = TRUE;
0062 int n;
0063 for (n=0; n<module_system.cnt; n++) {
0064 const char *modname = module_system.mr[n].mod->name;
0065 if ((subtree || strlen (modname) == j - i) &&
0066 strncmp (modname, name + i, j - i) == 0) {
0067 success |= module_load_i (n);
0068 if (!subtree) return success;
0069 }
0070 }
0071 return success;
0072 }
0073
0074
0075
0076 static bool
0077 module_load_disj (const char *names)
0078 {
0079 int i, j;
0080 bool success = FALSE;
0081 for (i=0, j=0; names[j]; i=j+1) {
0082 j=i;
0083 while (names[j] && names[j]!='|') j++;
0084 success |= module_load_name (names, i, j);
0085 }
0086 return success;
0087 }
0088
0089
0090 static bool
0091 module_load_i (const int modi)
0092 {
0093 int depi;
0094 modruntime_t *mr = module_system.mr;
0095
0096 if (modi < 0) return FALSE;
0097 if (mr[modi].loaded) return TRUE;
0098 for (depi=0; depi<mr[modi].mod->num_dependencies; depi++)
0099 if (!module_load_disj (mr[modi].mod->dependencies[depi]))
0100 return FALSE;
0101 if (mr[modi].mod->ops->init ()) {
0102 mr[modi].loaded = 1;
0103 DLOG ("initialized module \"%s\"", mr[modi].mod->name);
0104 return TRUE;
0105 } else {
0106 DLOG ("failed to initialize module \"%s\"", mr[modi].mod->name);
0107 return FALSE;
0108 }
0109 }
0110
0111
0112 extern bool
0113 module_load_all (void)
0114 {
0115 u32 count = 0, pages = 0, i;
0116 u32 phys;
0117 modruntime_t *mr;
0118 DLOG ("loading all modules");
0119 const struct module **mod;
0120 for (mod = &_module_ptr_list; *mod; mod++) {
0121 DLOG ("found name=\"%s\" desc: %s", (*mod)->name, (*mod)->desc);
0122 count++;
0123 }
0124 if (!count) return TRUE;
0125 pages = ((count * sizeof (modruntime_t) - 1) >> 12) + 1;
0126 phys = alloc_phys_frames (pages);
0127 if (phys == (u32) -1) goto abort;
0128 mr = map_contiguous_virtual_pages (phys | 3, pages);
0129 if (!mr) goto abort_phys;
0130 memset (mr, 0, pages << 12);
0131
0132 module_system.mr = mr;
0133 module_system.cnt = count;
0134 for (i=0, mod = &_module_ptr_list; *mod; i++, mod++) {
0135 mr[i].mod = *mod;
0136 }
0137
0138 for (i=0; i<count; i++)
0139 module_load_i (i);
0140
0141 return TRUE;
0142 abort_phys:
0143 free_phys_frames (phys, pages);
0144 abort:
0145 return FALSE;
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157