|
|
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.