FreeBSD/Linux Kernel Cross Reference
sys/sys/lkm.h
1 /* $NetBSD: lkm.h,v 1.37 2005/02/03 19:20:01 perry Exp $ */
2
3 /*
4 * Header file used by loadable kernel modules and loadable kernel module
5 * utilities.
6 *
7 * 23 Jan 93 Terry Lambert Original
8 *
9 * Copyright (c) 1992 Terrence R. Lambert.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Terrence R. Lambert.
23 * 4. The name Terrence R. Lambert may not be used to endorse or promote
24 * products derived from this software without specific prior written
25 * permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY
28 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #ifndef _SYS_LKM_H_
41 #define _SYS_LKM_H_
42
43 #include <sys/queue.h>
44
45 /*
46 * Supported module types
47 */
48 typedef enum loadmod {
49 LM_SYSCALL,
50 LM_VFS,
51 LM_DEV,
52 LM_STRMOD,
53 LM_EXEC,
54 LM_COMPAT,
55 LM_MISC,
56 LM_DRV,
57 } MODTYPE;
58
59 /*
60 * Version of module interface. Bump if kernel structures or API affecting
61 * LKM modules change, unless the kernel version is bumped at the
62 * same time too.
63 */
64 #define LKM_VERSION 2
65
66 #define MAXLKMNAME 32
67
68 /****************************************************************************/
69
70 #ifdef _KERNEL
71
72 /*
73 * Any module (to get type and name info without knowing type)
74 */
75 struct lkm_any {
76 MODTYPE lkm_type;
77 const char *lkm_name;
78 u_long lkm_offset;
79 u_int lkm_modver;
80 u_int lkm_sysver;
81 const char *lkm_envver;
82 };
83
84
85 /*
86 * Loadable system call
87 */
88 struct lkm_syscall {
89 struct lkm_any mod;
90 struct sysent *lkm_sysent;
91 struct sysent lkm_oldent; /* save area for unload */
92 };
93
94 /*
95 * Loadable file system
96 */
97 struct lkm_vfs {
98 struct lkm_any mod;
99 struct vfsops *lkm_vfsops;
100 };
101
102 /*
103 * Loadable device driver
104 */
105 struct lkm_dev {
106 struct lkm_any mod;
107 const char *lkm_devname;
108 const struct bdevsw *lkm_bdev;
109 int lkm_bdevmaj;
110 const struct cdevsw *lkm_cdev;
111 int lkm_cdevmaj;
112 };
113
114 #ifdef STREAMS
115 /*
116 * Loadable streams module
117 */
118 struct lkm_strmod {
119 struct lkm_any mod;
120 /*
121 * Removed: future release
122 */
123 };
124 #endif
125
126 /*
127 * Exec loader
128 */
129 struct lkm_exec {
130 struct lkm_any mod;
131 struct execsw *lkm_execsw;
132 const char *lkm_emul;
133 };
134
135 /*
136 * Compat (emulation) loader
137 */
138 struct lkm_compat {
139 struct lkm_any mod;
140 const struct emul *lkm_compat;
141 };
142
143 /*
144 * Miscellaneous module (complex load/unload, potentially complex stat)
145 */
146 struct lkm_misc {
147 struct lkm_any mod;
148 };
149
150 /*
151 * Driver module
152 */
153 struct lkm_drv {
154 struct lkm_any mod;
155 struct cfdriver **lkm_cd;
156 const struct cfattachlkminit *lkm_cai;
157 struct cfdata *lkm_cf;
158 };
159
160 /*
161 * Generic reference ala XEvent to allow single entry point in the xxxinit()
162 * routine.
163 */
164 union lkm_generic {
165 struct lkm_any *lkm_any;
166 struct lkm_syscall *lkm_syscall;
167 struct lkm_vfs *lkm_vfs;
168 struct lkm_dev *lkm_dev;
169 #ifdef STREAMS
170 struct lkm_strmod *lkm_strmod;
171 #endif
172 struct lkm_exec *lkm_exec;
173 struct lkm_compat *lkm_compat;
174 struct lkm_misc *lkm_misc;
175 struct lkm_drv *lkm_drv;
176 };
177
178 /*
179 * Per module information structure
180 */
181 struct lkm_table {
182 char refcnt; /* Reference count */
183 char forced; /* Forced load, skipping compatibility check */
184
185 int (*entry)(struct lkm_table *, int, int);/* entry function */
186 union lkm_generic private; /* module private data */
187
188 u_long size;
189 u_long offset;
190 u_long area;
191
192 /* ddb support */
193 u_long syms; /* start of symbol table */
194 u_long sym_size; /* size of symbol table (syms+strings) */
195 u_long sym_offset; /* offset of next symbol chunk */
196 u_long sym_symsize; /* size of symbol part only */
197
198 int id; /* Identifier */
199 TAILQ_ENTRY(lkm_table) link;
200 };
201
202
203 #define LKM_E_LOAD 1
204 #define LKM_E_UNLOAD 2
205 #define LKM_E_STAT 3
206
207
208 #define MOD_SYSCALL(name,callslot,sysentp) \
209 static struct lkm_syscall _module = { \
210 { LM_SYSCALL, name, callslot, \
211 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
212 sysentp \
213 };
214
215 #define MOD_VFS(name,vfsslot,vfsopsp) \
216 static struct lkm_vfs _module = { \
217 { LM_VFS, name, (u_long)vfsslot, \
218 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
219 vfsopsp \
220 };
221
222 #define MOD_DEV(name,devname,bdevp,bdevm,cdevp,cdevm) \
223 static struct lkm_dev _module = { \
224 { LM_DEV, name, (u_long)-1, \
225 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
226 devname, \
227 bdevp, \
228 bdevm, \
229 cdevp, \
230 cdevm, \
231 };
232
233 #define MOD_COMPAT(name,compatslot,emulp) \
234 static struct lkm_compat _module = { \
235 { LM_COMPAT, name, (u_long)compatslot, \
236 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
237 emulp \
238 };
239
240 #define MOD_EXEC(name,execslot,execsw,emul) \
241 static struct lkm_exec _module = { \
242 { LM_EXEC, name, (u_long)execslot, \
243 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
244 execsw, \
245 emul \
246 };
247
248 #define MOD_MISC(name) \
249 static struct lkm_misc _module = { \
250 { LM_MISC, name, (u_long)-1, \
251 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
252 };
253
254 #define MOD_DRV(name,drvs,atts,cfdata) \
255 static struct lkm_drv _module = { \
256 { LM_DRV, name, (u_long)-1, \
257 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
258 drvs, atts, cfdata \
259 };
260
261 /*
262 * Environment encoding, for LKM<->kernel compatibility check.
263 */
264 #ifdef DIAGNOSTIC
265 #define _LKM_E_DIAGNOSTIC ",DIAGNOSTIC"
266 #else
267 #define _LKM_E_DIAGNOSTIC ""
268 #endif
269
270 #ifdef DEBUG
271 #define _LKM_E_DEBUG ",DEBUG"
272 #else
273 #define _LKM_E_DEBUG ""
274 #endif
275
276 #ifdef LOCKDEBUG
277 #define _LKM_E_LOCKDEBUG ",LOCKDEBUG"
278 #else
279 #define _LKM_E_LOCKDEBUG ""
280 #endif
281
282 #ifdef MULTIPROCESSOR
283 #define _LKM_E_MULTIPROCESSOR ",MULTIPROCESSOR"
284 #else
285 #define _LKM_E_MULTIPROCESSOR ""
286 #endif
287
288 #ifdef MALLOCLOG
289 #define _LKM_E_MALLOCLOG ",MALLOCLOG"
290 #else
291 #define _LKM_E_MALLOCLOG ""
292 #endif
293
294 #define _LKM_ENV_VERSION \
295 _LKM_E_DEBUG _LKM_E_DIAGNOSTIC _LKM_E_LOCKDEBUG \
296 _LKM_E_MULTIPROCESSOR _LKM_E_MALLOCLOG
297
298 int lkm_nofunc(struct lkm_table *, int);
299 int lkmexists(struct lkm_table *);
300 int lkmdispatch(struct lkm_table *, int);
301
302 /*
303 * LKM_DISPATCH -- body function for use in module entry point function;
304 * generally, the function body will consist entirely of a single
305 * LKM_DISPATCH line.
306 *
307 * If load/unload/stat are called on each corresponding entry instance.
308 * If no function is desired for load/stat/unload, lkm_nofunc() should
309 * be specified. "cmd" is passed to each function so that a single
310 * function can be used if desired.
311 */
312 #define LKM_DISPATCH(lkmtp, cmd, envdep, load, unload, stat) \
313 switch (cmd) { \
314 int error; \
315 case LKM_E_LOAD: \
316 lkmtp->private.lkm_any = (void *)&_module; \
317 if ((error = lkmdispatch(lkmtp, cmd)) != 0) \
318 return error; \
319 if ((error = load(lkmtp, cmd)) != 0) \
320 (void)lkmdispatch(lkmtp, LKM_E_UNLOAD); \
321 return error; \
322 break; \
323 case LKM_E_UNLOAD: \
324 if ((error = unload(lkmtp, cmd)) != 0) \
325 return error; \
326 return lkmdispatch(lkmtp, cmd); \
327 break; \
328 case LKM_E_STAT: \
329 if ((error = stat(lkmtp, cmd)) != 0) \
330 return error; \
331 return lkmdispatch(lkmtp, cmd); \
332 break; \
333 } \
334 return (0);
335
336 /* remap the old macro for backward source compatibility */
337 #define DISPATCH(lkmtp, cmd, ver, att, det, stat) \
338 LKM_DISPATCH(lkmtp, cmd, NULL, att, det, stat)
339
340 extern struct vm_map *lkm_map;
341 void lkm_init(void);
342
343 #endif /* _KERNEL */
344
345 /****************************************************************************/
346
347 /*
348 * IOCTL's recognized by /dev/lkm
349 */
350 #define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf)
351 #define LMUNRESRV _IO('K', 2)
352 #define LMREADY _IOW('K', 3, u_long)
353 #define LMRESERV _IOWR('K', 4, struct lmc_resrv)
354
355 #define LMLOAD _IOW('K', 9, struct lmc_load)
356 #define LMUNLOAD _IOWR('K', 10, struct lmc_unload)
357 #define LMSTAT _IOWR('K', 11, struct lmc_stat)
358 #define LMLOADSYMS _IOW('K', 12, struct lmc_loadbuf)
359 #define LMFORCE _IOW('K', 13, u_long)
360
361 #define MODIOBUF 512 /* # of bytes at a time to loadbuf */
362
363 /*
364 * IOCTL arguments
365 */
366
367
368 /*
369 * Reserve a page-aligned block of kernel memory for the module
370 */
371 struct lmc_resrv {
372 u_long size; /* IN: size of module to reserve */
373 char *name; /* IN: name (must be provided */
374 int slot; /* OUT: allocated slot (module ID) */
375 u_long addr; /* OUT: Link-to address */
376 /* ddb support */
377 u_long xxx_unused1; /* unused */
378 u_long sym_size; /* IN: total size of symbol table */
379 u_long xxx_unused2; /* unused */
380 u_long sym_symsize; /* IN: size of symbol portion of symtable */
381 u_long sym_addr; /* OUT: address of symbol table */
382 };
383
384 /*
385 * Copy a buffer at a time into the allocated area in the kernel; writes
386 * are assumed to occur contiguously.
387 */
388 struct lmc_loadbuf {
389 int cnt; /* IN: # of chars pointed to by data */
390 char *data; /* IN: pointer to data buffer */
391 };
392
393
394 /*
395 * Load a module (assumes it's been mmapped to address before call)
396 */
397 struct lmc_load {
398 caddr_t address; /* IN: user space mmap address */
399 int status; /* OUT: status of operation */
400 int id; /* OUT: module ID if loaded */
401 };
402
403 /*
404 * Unload a module (by name/id)
405 */
406 struct lmc_unload {
407 int id; /* IN: module ID to unload */
408 char *name; /* IN: module name to unload if id -1 */
409 int status; /* OUT: status of operation */
410 };
411
412
413 /*
414 * Get module information for a given id (or name if id == -1).
415 */
416 struct lmc_stat {
417 int id; /* IN: module ID to unload */
418 char name[MAXLKMNAME]; /* IN/OUT: name of module */
419 u_long offset; /* OUT: target table offset */
420 MODTYPE type; /* OUT: type of module */
421 u_long area; /* OUT: kernel load addr */
422 u_long size; /* OUT: module size (pages) */
423 u_long private; /* OUT: module private data */
424 int ver; /* OUT: lkm compile version */
425 };
426
427 #define LKM_MAKEMAJOR(b, c) ((((b) & 0xffff) << 16) | ((c) & 0xffff))
428 #define LKM_BLOCK_MAJOR(v) (int)((int16_t)(((v) >> 16) & 0xffff))
429 #define LKM_CHAR_MAJOR(v) (int)((int16_t)((v) & 0xffff))
430
431 #endif /* !_SYS_LKM_H_ */
Cache object: c79ddc65e838404f2de9dfd854469731
|