FreeBSD/Linux Kernel Cross Reference
sys/sys/lkm.h
1 /* $NetBSD: lkm.h,v 1.43 2008/01/02 17:52:02 ad 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 #define MODTYPE_NAMES \
60 "SYSCALL", \
61 "VFS", \
62 "DEV", \
63 "STRMOD", \
64 "EXEC", \
65 "COMPAT", \
66 "MISC", \
67 "DRV"
68
69 /*
70 * Version of module interface. Bump if kernel structures or API affecting
71 * LKM modules change, unless the kernel version is bumped at the
72 * same time too.
73 */
74 #define LKM_VERSION 2
75
76 #define MAXLKMNAME 32
77
78 /****************************************************************************/
79
80 #ifdef _KERNEL
81
82 /*
83 * Any module (to get type and name info without knowing type)
84 */
85 struct lkm_any {
86 MODTYPE lkm_type;
87 const char *lkm_name;
88 u_long lkm_offset;
89 u_int lkm_modver;
90 u_int lkm_sysver;
91 const char *lkm_envver;
92 };
93
94
95 /*
96 * Loadable system call
97 */
98 struct lkm_syscall {
99 struct lkm_any mod;
100 struct sysent *lkm_sysent;
101 struct sysent lkm_oldent; /* save area for unload */
102 };
103
104 /*
105 * Loadable file system
106 */
107 struct lkm_vfs {
108 struct lkm_any mod;
109 struct vfsops *lkm_vfsops;
110 };
111
112 /*
113 * Loadable device driver
114 */
115 struct lkm_dev {
116 struct lkm_any mod;
117 const char *lkm_devname;
118 const struct bdevsw *lkm_bdev;
119 int lkm_bdevmaj;
120 const struct cdevsw *lkm_cdev;
121 int lkm_cdevmaj;
122 };
123
124 #ifdef STREAMS
125 /*
126 * Loadable streams module
127 */
128 struct lkm_strmod {
129 struct lkm_any mod;
130 /*
131 * Removed: future release
132 */
133 };
134 #endif
135
136 /*
137 * Exec loader
138 */
139 struct lkm_exec {
140 struct lkm_any mod;
141 struct execsw *lkm_execsw;
142 const char *lkm_emul;
143 };
144
145 /*
146 * Compat (emulation) loader
147 */
148 struct lkm_compat {
149 struct lkm_any mod;
150 const struct emul *lkm_compat;
151 };
152
153 /*
154 * Miscellaneous module (complex load/unload, potentially complex stat)
155 */
156 struct lkm_misc {
157 struct lkm_any mod;
158 };
159
160 /*
161 * Driver module
162 */
163 struct lkm_drv {
164 struct lkm_any mod;
165 struct cfdriver **lkm_cd;
166 const struct cfattachlkminit *lkm_cai;
167 struct cfdata *lkm_cf;
168 };
169
170 /*
171 * Generic reference ala XEvent to allow single entry point in the xxxinit()
172 * routine.
173 */
174 union lkm_generic {
175 struct lkm_any *lkm_any;
176 struct lkm_syscall *lkm_syscall;
177 struct lkm_vfs *lkm_vfs;
178 struct lkm_dev *lkm_dev;
179 #ifdef STREAMS
180 struct lkm_strmod *lkm_strmod;
181 #endif
182 struct lkm_exec *lkm_exec;
183 struct lkm_compat *lkm_compat;
184 struct lkm_misc *lkm_misc;
185 struct lkm_drv *lkm_drv;
186 };
187
188 /*
189 * Per module information structure
190 */
191 struct lkm_table {
192 char refcnt; /* Reference count */
193 char forced; /* Forced load, skipping compatibility check */
194
195 int (*entry)(struct lkm_table *, int, int);/* entry function */
196 union lkm_generic private; /* module private data */
197
198 u_long size;
199 u_long offset;
200 u_long area;
201
202 /* ddb support */
203 u_long syms; /* start of symbol table */
204 u_long sym_size; /* size of symbol table (syms+strings) */
205 u_long sym_offset; /* offset of next symbol chunk */
206 u_long sym_symsize; /* size of symbol part only */
207
208 int id; /* Identifier */
209 TAILQ_ENTRY(lkm_table) link;
210 };
211
212
213 #define LKM_E_LOAD 1
214 #define LKM_E_UNLOAD 2
215 #define LKM_E_STAT 3
216
217
218 #define MOD_SYSCALL(name,callslot,sysentp) \
219 static struct lkm_syscall _module = { \
220 { LM_SYSCALL, name, callslot, \
221 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
222 sysentp \
223 };
224
225 #define MOD_VFS(name,vfsslot,vfsopsp) \
226 static struct lkm_vfs _module = { \
227 { LM_VFS, name, (u_long)vfsslot, \
228 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
229 vfsopsp \
230 };
231
232 #define MOD_DEV(name,devname,bdevp,bdevm,cdevp,cdevm) \
233 static struct lkm_dev _module = { \
234 { LM_DEV, name, (u_long)-1, \
235 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
236 devname, \
237 bdevp, \
238 bdevm, \
239 cdevp, \
240 cdevm, \
241 };
242
243 #define MOD_COMPAT(name,compatslot,emulp) \
244 static struct lkm_compat _module = { \
245 { LM_COMPAT, name, (u_long)compatslot, \
246 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
247 emulp \
248 };
249
250 #define MOD_EXEC(name,execslot,execsw,emul) \
251 static struct lkm_exec _module = { \
252 { LM_EXEC, name, (u_long)execslot, \
253 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
254 execsw, \
255 emul \
256 };
257
258 #define MOD_MISC(name) \
259 static struct lkm_misc _module = { \
260 { LM_MISC, name, (u_long)-1, \
261 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
262 };
263
264 #define MOD_DRV(name,drvs,atts,cfdata) \
265 static struct lkm_drv _module = { \
266 { LM_DRV, name, (u_long)-1, \
267 LKM_VERSION, __NetBSD_Version__, _LKM_ENV_VERSION }, \
268 drvs, atts, cfdata \
269 };
270
271 /*
272 * Environment encoding, for LKM<->kernel compatibility check.
273 */
274 #ifdef DEBUG
275 #define _LKM_E_DEBUG ",DEBUG"
276 #else
277 #define _LKM_E_DEBUG ""
278 #endif
279
280 #ifdef MALLOCLOG
281 #define _LKM_E_MALLOCLOG ",MALLOCLOG"
282 #else
283 #define _LKM_E_MALLOCLOG ""
284 #endif
285
286 #define _LKM_ENV_VERSION _LKM_E_DEBUG _LKM_E_MALLOCLOG
287
288 int lkm_nofunc(struct lkm_table *, int);
289 int lkmexists(struct lkm_table *);
290 int lkmdispatch(struct lkm_table *, int);
291
292 /*
293 * LKM_DISPATCH -- body function for use in module entry point function;
294 * generally, the function body will consist entirely of a single
295 * LKM_DISPATCH line.
296 *
297 * If load/unload/stat are called on each corresponding entry instance.
298 * If no function is desired for load/stat/unload, lkm_nofunc() should
299 * be specified. "cmd" is passed to each function so that a single
300 * function can be used if desired.
301 */
302 #define LKM_DISPATCH(lkmtp, cmd, envdep, load, unload, stat) \
303 switch (cmd) { \
304 int error; \
305 case LKM_E_LOAD: \
306 lkmtp->private.lkm_any = (void *)&_module; \
307 if ((error = lkmdispatch(lkmtp, cmd)) != 0) \
308 return error; \
309 if ((error = load(lkmtp, cmd)) != 0) \
310 (void)lkmdispatch(lkmtp, LKM_E_UNLOAD); \
311 return error; \
312 break; \
313 case LKM_E_UNLOAD: \
314 if ((error = unload(lkmtp, cmd)) != 0) \
315 return error; \
316 return lkmdispatch(lkmtp, cmd); \
317 break; \
318 case LKM_E_STAT: \
319 if ((error = stat(lkmtp, cmd)) != 0) \
320 return error; \
321 return lkmdispatch(lkmtp, cmd); \
322 break; \
323 } \
324 return (0);
325
326 /* remap the old macro for backward source compatibility */
327 #define DISPATCH(lkmtp, cmd, ver, att, det, stat) \
328 LKM_DISPATCH(lkmtp, cmd, NULL, att, det, stat)
329
330 extern struct vm_map *lkm_map;
331
332 #endif /* _KERNEL */
333
334 /****************************************************************************/
335
336 /*
337 * IOCTL's recognized by /dev/lkm
338 */
339 #define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf)
340 #define LMUNRESRV _IO('K', 2)
341 #define LMREADY _IOW('K', 3, u_long)
342 #define LMRESERV _IOWR('K', 4, struct lmc_resrv)
343
344 #define LMLOAD _IOW('K', 9, struct lmc_load)
345 #define LMUNLOAD _IOWR('K', 10, struct lmc_unload)
346 #define LMSTAT _IOWR('K', 11, struct lmc_stat)
347 #define LMLOADSYMS _IOW('K', 12, struct lmc_loadbuf)
348 #define LMFORCE _IOW('K', 13, u_long)
349
350 #define MODIOBUF 512 /* # of bytes at a time to loadbuf */
351
352 /*
353 * IOCTL arguments
354 */
355
356
357 /*
358 * Reserve a page-aligned block of kernel memory for the module
359 */
360 struct lmc_resrv {
361 u_long size; /* IN: size of module to reserve */
362 char *name; /* IN: name (must be provided */
363 int slot; /* OUT: allocated slot (module ID) */
364 u_long addr; /* OUT: Link-to address */
365 /* ddb support */
366 u_long xxx_unused1; /* unused */
367 u_long sym_size; /* IN: total size of symbol table */
368 u_long xxx_unused2; /* unused */
369 u_long sym_symsize; /* IN: size of symbol portion of symtable */
370 u_long sym_addr; /* OUT: address of symbol table */
371 };
372
373 /*
374 * Copy a buffer at a time into the allocated area in the kernel; writes
375 * are assumed to occur contiguously.
376 */
377 struct lmc_loadbuf {
378 int cnt; /* IN: # of chars pointed to by data */
379 char *data; /* IN: pointer to data buffer */
380 };
381
382
383 /*
384 * Load a module (assumes it's been mmapped to address before call)
385 */
386 struct lmc_load {
387 void * address; /* IN: user space mmap address */
388 int status; /* OUT: status of operation */
389 int id; /* OUT: module ID if loaded */
390 };
391
392 /*
393 * Unload a module (by name/id)
394 */
395 struct lmc_unload {
396 int id; /* IN: module ID to unload */
397 char *name; /* IN: module name to unload if id -1 */
398 int status; /* OUT: status of operation */
399 };
400
401
402 /*
403 * Get module information for a given id (or name if id == -1).
404 */
405 struct lmc_stat {
406 int id; /* IN: module ID to unload */
407 char name[MAXLKMNAME]; /* IN/OUT: name of module */
408 u_long offset; /* OUT: target table offset */
409 MODTYPE type; /* OUT: type of module */
410 u_long area; /* OUT: kernel load addr */
411 u_long size; /* OUT: module size (pages) */
412 u_long private; /* OUT: module private data */
413 int ver; /* OUT: lkm compile version */
414 };
415
416 #define LKM_MAKEMAJOR(b, c) ((((b) & 0xffff) << 16) | ((c) & 0xffff))
417 #define LKM_BLOCK_MAJOR(v) (int)((int16_t)(((uint32_t)(v) >> 16) & 0xffff))
418 #define LKM_CHAR_MAJOR(v) (int)((int16_t)((v) & 0xffff))
419
420 #endif /* !_SYS_LKM_H_ */
Cache object: dbf218f4a79cbe0307e34d11a5975281
|