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