|
|
1.1 ! root 1: /* tag: openbios plugin loader ! 2: * ! 3: * Copyright (C) 2003 Stefan Reinauer ! 4: * ! 5: * See the file "COPYING" for further information about ! 6: * the copyright and warranty status of this work. ! 7: */ ! 8: ! 9: /* This is a simple plugin loader. OpenBIOS duplicates some ! 10: * of this code in kernel/arch/unix/plugins.c. This code is ! 11: * here for reference and simple testing. ! 12: */ ! 13: ! 14: #include <stdio.h> ! 15: #include <stdlib.h> ! 16: #include <string.h> ! 17: #include <dlfcn.h> ! 18: #include <unistd.h> // sleep ! 19: ! 20: #include "unix/plugins.h" ! 21: ! 22: #define PLUGINDIR "/usr/share/OpenBIOS/plugins" ! 23: #define PATHSIZE 256 ! 24: ! 25: #define DEBUG_PLUGINS ! 26: ! 27: typedef struct iorange iorange_t; ! 28: struct iorange { ! 29: const char *name; ! 30: unsigned int start; ! 31: unsigned int end; ! 32: io_ops_t *ops; ! 33: iorange_t *next; ! 34: }; ! 35: ! 36: iorange_t *ioranges = NULL; ! 37: ! 38: typedef struct plugin plugin_t; ! 39: struct plugin { ! 40: const char *name; ! 41: plugin_t *next; ! 42: }; ! 43: ! 44: plugin_t *plugins = NULL; ! 45: ! 46: int register_iorange(const char *name, io_ops_t * ops, unsigned int rstart, ! 47: unsigned int rend) ! 48: { ! 49: iorange_t *newrange; ! 50: ! 51: /* intersection check */ ! 52: newrange = ioranges; ! 53: while (newrange) { ! 54: int fail = 0; ! 55: /* new section swallows old section */ ! 56: if (newrange->start >= rstart && newrange->end <= rend) ! 57: fail = -1; ! 58: /* new section start or end point are within range */ ! 59: if (newrange->start <= rstart && newrange->end >= rstart) ! 60: fail = -1; ! 61: if (newrange->start <= rend && newrange->end >= rend) ! 62: fail = -1; ! 63: if (fail) { ! 64: printf("Error: overlapping IO regions: %s and %s\n", ! 65: newrange->name, name); ! 66: return -1; ! 67: } ! 68: newrange = newrange->next; ! 69: } ! 70: ! 71: newrange = malloc(sizeof(iorange_t)); ! 72: ! 73: newrange->name = name; ! 74: newrange->ops = ops; ! 75: newrange->start = rstart; ! 76: newrange->end = rend; ! 77: newrange->next = ioranges; ! 78: ! 79: ioranges = newrange; ! 80: ! 81: return 0; ! 82: } ! 83: ! 84: int is_loaded(const char *plugin_name) ! 85: { ! 86: plugin_t *p = plugins; ! 87: while (p) { ! 88: if (!strcmp(plugin_name, p->name)) ! 89: return -1; ! 90: p = p->next; ! 91: } ! 92: return 0; ! 93: } ! 94: ! 95: int load_plugin(const char *plugin_name) ! 96: { ! 97: void *handle; ! 98: char *error; ! 99: char path[PATHSIZE]; ! 100: ! 101: int (*init_plugin) (void); ! 102: char **deps; ! 103: char **plugin_info; ! 104: plugin_t *p; ! 105: ! 106: if (is_loaded(plugin_name)) { ! 107: printf("Plugin %s already loaded.\n", plugin_name); ! 108: return 0; ! 109: } ! 110: ! 111: strncpy(path, PLUGINDIR, PATHSIZE); ! 112: strncat(path, "/plugin_", PATHSIZE); ! 113: strncat(path, plugin_name, PATHSIZE); ! 114: strncat(path, ".so", PATHSIZE); ! 115: ! 116: #if DEBUG ! 117: printf("Opening plugin %s\n", path); ! 118: #endif ! 119: ! 120: handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); ! 121: if (!handle) { ! 122: error = dlerror(); ! 123: printf("Error: Could not open plugin \"%s\": %s\n", ! 124: plugin_name, error); ! 125: exit(1); ! 126: } ! 127: #ifdef DEBUG_PLUGINS ! 128: plugin_info = dlsym(handle, "plugin_author"); ! 129: if ((error = dlerror()) == NULL) ! 130: printf("Plugin %s author: %s\n", plugin_name, *plugin_info); ! 131: plugin_info = dlsym(handle, "plugin_license"); ! 132: if ((error = dlerror()) == NULL) ! 133: printf("Plugin %s license: %s\n", plugin_name, *plugin_info); ! 134: plugin_info = dlsym(handle, "plugin_description"); ! 135: if ((error = dlerror()) == NULL) ! 136: printf("Plugin %s descr.: %s\n", plugin_name, *plugin_info); ! 137: #endif ! 138: p = malloc(sizeof(plugin_t)); ! 139: p->next = plugins; ! 140: p->name = plugin_name; ! 141: plugins = p; ! 142: ! 143: deps = dlsym(handle, "plugin_deps"); ! 144: if ((error = dlerror()) != NULL) ! 145: deps = NULL; ! 146: ! 147: ! 148: strncpy(path, "plugin_", PATHSIZE); ! 149: strncat(path, plugin_name, PATHSIZE); ! 150: strncat(path, "_init", PATHSIZE); ! 151: ! 152: init_plugin = dlsym(handle, path); ! 153: if ((error = dlerror()) != NULL) { ! 154: printf("error: %s\n", error); ! 155: exit(1); ! 156: } ! 157: ! 158: if (deps) { ! 159: int i = 0; ! 160: char *walk = deps[0]; ! 161: #ifdef DEBUG_PLUGINS ! 162: printf("\nPlugin %s dependencies:", plugin_name); ! 163: #endif ! 164: while (walk) { ! 165: printf(" %s", walk); ! 166: if (!is_loaded(walk)) { ! 167: #ifdef DEBUG_PLUGINS ! 168: printf("(loading)\n"); ! 169: #endif ! 170: load_plugin(walk); ! 171: } ! 172: #ifdef DEBUG_PLUGINS ! 173: else { ! 174: printf("(loaded)"); ! 175: } ! 176: #endif ! 177: walk = deps[++i]; ! 178: } ! 179: } ! 180: ! 181: printf("\n"); ! 182: #if DEBUG ! 183: printf("Initializing module:\n"); ! 184: #endif ! 185: ! 186: return init_plugin(); ! 187: ! 188: // We don't dlclose the handle here since ! 189: // we want to keep our symbols for later use. ! 190: } ! 191: ! 192: int main(void) ! 193: { ! 194: iorange_t *r; ! 195: ! 196: // load_plugin("kbd"); ! 197: // load_plugin("pci"); ! 198: load_plugin("qt"); ! 199: ! 200: printf("\nRegistered IO Ranges:\n"); ! 201: r = ioranges; ! 202: while (r) { ! 203: printf(" %s: %x-%x\n", r->name, r->start, r->end); ! 204: r = r->next; ! 205: } ! 206: ! 207: sleep(10); ! 208: return 0; ! 209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.