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_ */ 363