1 /* $OpenBSD: lkm.h,v 1.11 2002/01/09 18:20:52 ericj Exp $ */
2 /* $NetBSD: lkm.h,v 1.12 1996/02/09 18:25:13 christos Exp $ */
3
4 /*
5 * Header file used by loadable kernel modules and loadable kernel module
6 * utilities.
7 *
8 * 23 Jan 93 Terry Lambert Original
9 *
10 * Copyright (c) 1996 Michael Shalayeff
11 * Copyright (c) 1992 Terrence R. Lambert.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by Terrence R. Lambert.
25 * 4. The name Terrence R. Lambert may not be used to endorse or promote
26 * products derived from this software without specific prior written
27 * permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY
30 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 */
41
42 #ifndef _SYS_LKM_H_
43 #define _SYS_LKM_H_
44
45 #include <sys/queue.h>
46
47 /*
48 * Supported module types
49 */
50 typedef enum loadmod {
51 LM_SYSCALL,
52 LM_VFS,
53 LM_DEV,
54 LM_EXEC,
55 LM_MISC
56 } MODTYPE;
57
58
59 #define LKM_OLDVERSION 1 /* version of module loader */
60 #define LKM_VERSION 2 /* version of module loader */
61 #define MAXLKMNAME 32
62
63 /****************************************************************************/
64
65 #ifdef _KERNEL
66
67 /*
68 * Loadable system call
69 */
70 struct lkm_syscall {
71 MODTYPE lkm_type;
72 int lkm_ver;
73 char *lkm_name;
74 u_long lkm_offset; /* save/assign area */
75 struct sysent *lkm_sysent;
76 struct sysent lkm_oldent; /* save area for unload */
77 };
78
79 /*
80 * Loadable file system
81 */
82 struct lkm_vfs {
83 MODTYPE lkm_type;
84 int lkm_ver;
85 char *lkm_name;
86 u_long lkm_offset;
87 struct vfsconf *lkm_vfsconf;
88 };
89
90 /*
91 * Supported device module types
92 */
93 typedef enum devtype {
94 LM_DT_BLOCK,
95 LM_DT_CHAR
96 } DEVTYPE;
97
98 /*
99 * Loadable device driver
100 */
101 struct lkm_dev {
102 MODTYPE lkm_type;
103 int lkm_ver;
104 char *lkm_name;
105 u_long lkm_offset;
106 DEVTYPE lkm_devtype;
107 union {
108 void *anon;
109 struct bdevsw *bdev;
110 struct cdevsw *cdev;
111 } lkm_dev;
112 union {
113 struct bdevsw bdev;
114 struct cdevsw cdev;
115 } lkm_olddev;
116 };
117
118 /*
119 * Exec loader
120 */
121 struct lkm_exec {
122 MODTYPE lkm_type;
123 int lkm_ver;
124 char *lkm_name;
125 u_long lkm_offset;
126 struct execsw *lkm_exec;
127 struct execsw lkm_oldexec;
128 };
129
130 /*
131 * Miscellaneous module (complex load/unload, potentially complex stat
132 */
133 struct lkm_misc {
134 MODTYPE lkm_type;
135 int lkm_ver;
136 char *lkm_name;
137 u_long lkm_offset;
138 };
139
140 /*
141 * Any module (to get type and name info without knowing type)
142 */
143 struct lkm_any {
144 MODTYPE lkm_type;
145 int lkm_ver;
146 char *lkm_name;
147 u_long lkm_offset;
148 };
149
150
151 /*
152 * Generic reference ala XEvent to allow single entry point in the xxxinit()
153 * routine.
154 */
155 union lkm_generic {
156 struct lkm_any *lkm_any;
157 struct lkm_syscall *lkm_syscall;
158 struct lkm_vfs *lkm_vfs;
159 struct lkm_dev *lkm_dev;
160 struct lkm_exec *lkm_exec;
161 struct lkm_misc *lkm_misc;
162 };
163
164 /*
165 * Per module information structure
166 */
167 struct lkm_table {
168 TAILQ_ENTRY(lkm_table) list;
169 int type;
170 u_long size;
171 u_long offset;
172 u_long area;
173
174 int ver; /* version (INIT) */
175 int refcnt; /* reference count (INIT) */
176 int depcnt; /* dependency count (INIT) */
177 int id; /* identifier (INIT) */
178
179 int (*entry)(struct lkm_table *, int, int); /* entry function */
180 union lkm_generic private; /* module private data */
181
182 /* ddb support */
183 char *syms; /* ? start of symbol table */
184 u_long sym_size; /* ? size of symbol table */
185 u_long sym_offset; /* ? offset */
186 u_long sym_symsize; /* ? symsize */
187 char *sym_addr; /* ? addr */
188 int sym_id; /* ? symtab id from ddb */
189 };
190
191
192 #define LKM_E_LOAD 1
193 #define LKM_E_UNLOAD 2
194 #define LKM_E_STAT 3
195
196
197 #define MOD_SYSCALL(name,callslot,sysentp) \
198 static struct lkm_syscall _module = { \
199 LM_SYSCALL, \
200 LKM_VERSION, \
201 name, \
202 callslot, \
203 sysentp \
204 };
205
206 #define MOD_VFS(name,vfsslot,vfsconf) \
207 static struct lkm_vfs _module = { \
208 LM_VFS, \
209 LKM_VERSION, \
210 name, \
211 vfsslot, \
212 vfsconf \
213 };
214
215 #define MOD_DEV(name,devtype,devslot,devp) \
216 static struct lkm_dev _module = { \
217 LM_DEV, \
218 LKM_VERSION, \
219 name, \
220 devslot, \
221 devtype, \
222 {(void *)devp} \
223 };
224
225 #define MOD_EXEC(name,execslot,execsw) \
226 static struct lkm_exec _module = { \
227 LM_EXEC, \
228 LKM_VERSION, \
229 name, \
230 execslot, \
231 execsw \
232 };
233
234 #define MOD_MISC(name) \
235 static struct lkm_misc _module = { \
236 LM_MISC, \
237 LKM_VERSION, \
238 name \
239 };
240
241
242 extern int lkm_nofunc(struct lkm_table *lkmtp, int cmd);
243 extern struct lkm_table *lkm_list(struct lkm_table *);
244 extern int lkmdispatch(struct lkm_table *, int);
245
246 /*
247 * DISPATCH -- body function for use in module entry point function;
248 * generally, the function body will consist entirely of a single
249 * DISPATCH line.
250 *
251 * If load/unload/stat are called on each corresponding entry instance.
252 * If no function is desired for load/stat/unload, lkm_nofunc() should
253 * be specified. "cmd" is passed to each function so that a single
254 * function can be used if desired.
255 */
256 #define DISPATCH(lkmtp,cmd,ver,load,unload,stat) \
257 if (ver != LKM_VERSION) \
258 return EINVAL; /* version mismatch */ \
259 switch (cmd) { \
260 int error; \
261 case LKM_E_LOAD: \
262 lkmtp->private.lkm_any = (struct lkm_any *)&_module; \
263 if ((error = load(lkmtp, cmd)) != 0) \
264 return error; \
265 break; \
266 case LKM_E_UNLOAD: \
267 if ((error = unload(lkmtp, cmd)) != 0) \
268 return error; \
269 break; \
270 case LKM_E_STAT: \
271 if ((error = stat(lkmtp, cmd)) != 0) \
272 return error; \
273 break; \
274 } \
275 return lkmdispatch(lkmtp, cmd);
276
277 #endif /* _KERNEL */
278
279 /****************************************************************************/
280
281 /*
282 * IOCTL's recognized by /dev/lkm
283 */
284 #define LMRESERV_O _IOWR('K', 0, struct lmc_resrv)
285 #define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf)
286 #define LMUNRESRV _IO('K', 2)
287 #define LMREADY _IOW('K', 3, u_long)
288 #define LMRESERV _IOWR('K', 4, struct lmc_resrv)
289
290 #define LMLOAD _IOW('K', 9, struct lmc_load)
291 #define LMUNLOAD _IOWR('K', 10, struct lmc_unload)
292 #define LMSTAT _IOWR('K', 11, struct lmc_stat)
293 #define LMLOADSYMS _IOW('K', 12, struct lmc_loadbuf)
294
295 #define MODIOBUF 512 /* # of bytes at a time to loadbuf */
296
297 /*
298 * IOCTL arguments
299 */
300
301
302 /*
303 * Reserve a page-aligned block of kernel memory for the module
304 */
305 struct lmc_resrv {
306 u_long size; /* IN: size of module to reserve */
307 char *name; /* IN: name (must be provided */
308 int slot; /* OUT: allocated slot (module ID) */
309 u_long addr; /* OUT: Link-to address */
310 /* ddb support */
311 char *syms; /* ? start of symbol table */
312 u_long sym_size; /* ? size of symbol table */
313 u_long sym_offset; /* ? offset */
314 u_long sym_symsize; /* ? symsize */
315 char *sym_addr; /* ? addr */
316 };
317
318
319 /*
320 * Copy a buffer at a time into the allocated area in the kernel; writes
321 * are assumed to occur contiguously.
322 */
323 struct lmc_loadbuf {
324 int cnt; /* IN: # of chars pointed to by data */
325 char *data; /* IN: pointer to data buffer */
326 };
327
328
329 /*
330 * Load a module (assumes it's been mmapped to address before call)
331 */
332 struct lmc_load {
333 caddr_t address; /* IN: user space mmap address */
334 int status; /* OUT: status of operation */
335 int id; /* OUT: module ID if loaded */
336 };
337
338 /*
339 * Unload a module (by name/id)
340 */
341 struct lmc_unload {
342 int id; /* IN: module ID to unload */
343 char *name; /* IN: module name to unload if id -1 */
344 int status; /* OUT: status of operation */
345 };
346
347
348 /*
349 * Get module information for a given id (or name if id == -1).
350 */
351 struct lmc_stat {
352 int id; /* IN: module ID to unload */
353 char *name; /* IN/OUT: name of module */
354 u_long offset; /* OUT: target table offset */
355 MODTYPE type; /* OUT: type of module */
356 u_long area; /* OUT: kernel load addr */
357 u_long size; /* OUT: module size (pages) */
358 u_long private; /* OUT: module private data */
359 int ver; /* OUT: lkm compile version */
360 };
361
362 #endif /* !_SYS_LKM_H_ */