Annotation of sys/sys/lkm.h, Revision 1.1
1.1 ! nbrk 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_ */
CVSweb