1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 *
| 1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 *
|
26 * $Id: bootstrap.h,v 1.3 1998/09/03 02:10:07 msmith Exp $
| 26 * $Id: bootstrap.h,v 1.4 1998/09/04 02:43:26 msmith Exp $
|
27 */ 28 29#include <sys/types.h> 30 31/* XXX debugging */ 32extern struct console vidconsole; 33#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();} 34 35/* 36 * Generic device specifier; architecture-dependant 37 * versions may be larger, but should be allowed to 38 * overlap. 39 */ 40struct devdesc 41{ 42 struct devsw *d_dev; 43 int d_type; 44#define DEVT_NONE 0 45#define DEVT_DISK 1 46#define DEVT_NET 2 47}; 48 49/* Commands and return values; nonzero return sets command_errmsg != NULL */ 50typedef int (bootblk_cmd_t)(int argc, char *argv[]); 51extern char *command_errmsg; 52extern char command_errbuf[]; /* XXX blah, length */ 53#define CMD_OK 0 54#define CMD_ERROR 1 55 56/* interp.c */ 57extern void interact(void); 58extern void source(char *filename); 59
| 27 */ 28 29#include <sys/types.h> 30 31/* XXX debugging */ 32extern struct console vidconsole; 33#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();} 34 35/* 36 * Generic device specifier; architecture-dependant 37 * versions may be larger, but should be allowed to 38 * overlap. 39 */ 40struct devdesc 41{ 42 struct devsw *d_dev; 43 int d_type; 44#define DEVT_NONE 0 45#define DEVT_DISK 1 46#define DEVT_NET 2 47}; 48 49/* Commands and return values; nonzero return sets command_errmsg != NULL */ 50typedef int (bootblk_cmd_t)(int argc, char *argv[]); 51extern char *command_errmsg; 52extern char command_errbuf[]; /* XXX blah, length */ 53#define CMD_OK 0 54#define CMD_ERROR 1 55 56/* interp.c */ 57extern void interact(void); 58extern void source(char *filename); 59
|
| 60/* interp_parse.c */ 61extern int parse(int *argc, char ***argv, char *str); 62
|
60/* boot.c */ 61extern int autoboot(int delay, char *prompt); 62 63/* misc.c */ 64extern char *unargv(int argc, char *argv[]); 65extern size_t strlenout(vm_offset_t str); 66extern char *strdupout(vm_offset_t str); 67 68/* 69 * Modular console support. 70 */ 71struct console 72{ 73 char *c_name; 74 char *c_desc; 75 int c_flags; 76#define C_PRESENTIN (1<<0) 77#define C_PRESENTOUT (1<<1) 78#define C_ACTIVEIN (1<<2) 79#define C_ACTIVEOUT (1<<3) 80 void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 81 int (* c_init)(int arg); /* reinit XXX may need more args */ 82 void (* c_out)(int c); /* emit c */ 83 int (* c_in)(void); /* wait for and return input */ 84 int (* c_ready)(void); /* return nonzer if input waiting */ 85}; 86extern struct console *consoles[]; 87extern void cons_probe(void); 88 89/* 90 * Plug-and-play enumerator/configurator interface. 91 */
| 63/* boot.c */ 64extern int autoboot(int delay, char *prompt); 65 66/* misc.c */ 67extern char *unargv(int argc, char *argv[]); 68extern size_t strlenout(vm_offset_t str); 69extern char *strdupout(vm_offset_t str); 70 71/* 72 * Modular console support. 73 */ 74struct console 75{ 76 char *c_name; 77 char *c_desc; 78 int c_flags; 79#define C_PRESENTIN (1<<0) 80#define C_PRESENTOUT (1<<1) 81#define C_ACTIVEIN (1<<2) 82#define C_ACTIVEOUT (1<<3) 83 void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 84 int (* c_init)(int arg); /* reinit XXX may need more args */ 85 void (* c_out)(int c); /* emit c */ 86 int (* c_in)(void); /* wait for and return input */ 87 int (* c_ready)(void); /* return nonzer if input waiting */ 88}; 89extern struct console *consoles[]; 90extern void cons_probe(void); 91 92/* 93 * Plug-and-play enumerator/configurator interface. 94 */
|
| 95struct pnpident 96{ 97 char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 98 struct pnpident *id_next; /* the next identifier */ 99}; 100 101struct pnphandler;
|
92struct pnpinfo 93{
| 102struct pnpinfo 103{
|
94 char *pi_ident; /* ASCII identifier, actual format varies with bus/handler */
| 104 struct pnpident *pi_ident; /* list of identifiers */
|
95 int pi_revision; /* optional revision (or -1) if not supported */ 96 char *pi_module; /* module/args nominated to handle device */ 97 int pi_argc; /* module arguments */ 98 char **pi_argv;
| 105 int pi_revision; /* optional revision (or -1) if not supported */ 106 char *pi_module; /* module/args nominated to handle device */ 107 int pi_argc; /* module arguments */ 108 char **pi_argv;
|
99 int pi_handler; /* handler which detected this device */
| 109 struct pnphandler *pi_handler; /* handler which detected this device */
|
100 struct pnpinfo *pi_next;
| 110 struct pnpinfo *pi_next;
|
101}
| 111};
|
102 103struct pnphandler 104{
| 112 113struct pnphandler 114{
|
105 char *pp_name; /* handler/bus name */ 106 struct pnpinfo *(pp_enumerate *)(int index); /* return a string identifying device (index) */
| 115 char *pp_name; /* handler/bus name */ 116 void (* pp_enumerate)(struct pnpinfo **); /* add detected devices to chain */
|
107}; 108
| 117}; 118
|
109extern struct pnphandler *pnphandlers[]; /* provided by MD code */ 110
| 119extern struct pnphandler *pnphandlers[]; /* provided by MD code */
|
111
| 120
|
| 121extern void pnp_addident(struct pnpinfo *pi, char *ident); 122
|
112/* 113 * Module metadata header. 114 * 115 * Metadata are allocated on our heap, and copied into kernel space 116 * before executing the kernel. 117 */ 118struct module_metadata 119{ 120 size_t md_size; 121 u_int16_t md_type; 122 struct module_metadata *md_next; 123 char md_data[0]; /* data are immediately appended */ 124}; 125 126/* 127 * Loaded module information. 128 * 129 * At least one module (the kernel) must be loaded in order to boot. 130 * The kernel is always loaded first. 131 * 132 * String fields (m_name, m_type) should be dynamically allocated. 133 */ 134struct loaded_module 135{ 136 char *m_name; /* module name */ 137 char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */ 138 char *m_args; /* arguments for the module */ 139 struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */ 140 int m_loader; /* index of the loader that read the file */ 141 vm_offset_t m_addr; /* load address */ 142 size_t m_size; /* module size */ 143 struct loaded_module *m_next; /* next module */ 144}; 145 146struct module_format 147{ 148 /* Load function must return EFTYPE if it can't handle the module supplied */ 149 int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result); 150 /* Only a loader that will load a kernel (first module) should have an exec handler */ 151 int (* l_exec)(struct loaded_module *mp); 152}; 153extern struct module_format *module_formats[]; /* supplied by consumer */ 154extern struct loaded_module *loaded_modules; 155extern int mod_load(char *name, int argc, char *argv[]); 156extern int mod_loadobj(char *type, char *name); 157extern struct loaded_module *mod_findmodule(char *name, char *type); 158extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p); 159extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type); 160extern void mod_discard(struct loaded_module *mp);
| 123/* 124 * Module metadata header. 125 * 126 * Metadata are allocated on our heap, and copied into kernel space 127 * before executing the kernel. 128 */ 129struct module_metadata 130{ 131 size_t md_size; 132 u_int16_t md_type; 133 struct module_metadata *md_next; 134 char md_data[0]; /* data are immediately appended */ 135}; 136 137/* 138 * Loaded module information. 139 * 140 * At least one module (the kernel) must be loaded in order to boot. 141 * The kernel is always loaded first. 142 * 143 * String fields (m_name, m_type) should be dynamically allocated. 144 */ 145struct loaded_module 146{ 147 char *m_name; /* module name */ 148 char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */ 149 char *m_args; /* arguments for the module */ 150 struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */ 151 int m_loader; /* index of the loader that read the file */ 152 vm_offset_t m_addr; /* load address */ 153 size_t m_size; /* module size */ 154 struct loaded_module *m_next; /* next module */ 155}; 156 157struct module_format 158{ 159 /* Load function must return EFTYPE if it can't handle the module supplied */ 160 int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result); 161 /* Only a loader that will load a kernel (first module) should have an exec handler */ 162 int (* l_exec)(struct loaded_module *mp); 163}; 164extern struct module_format *module_formats[]; /* supplied by consumer */ 165extern struct loaded_module *loaded_modules; 166extern int mod_load(char *name, int argc, char *argv[]); 167extern int mod_loadobj(char *type, char *name); 168extern struct loaded_module *mod_findmodule(char *name, char *type); 169extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p); 170extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type); 171extern void mod_discard(struct loaded_module *mp);
|
| 172extern struct loaded_module *mod_allocmodule(void);
|
161
| 173
|
| 174 175/* MI module loaders */ 176extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); 177extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); 178 179/* extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */ 180
|
162/* 163 * Module information subtypes
| 181/* 182 * Module information subtypes
|
| 183 * 184 * XXX these are copies of the defines in <sys/linker.h>, and should be nuked 185 * XXX before being committed.
|
164 */
| 186 */
|
165/* XXX these belong in <machine/bootinfo.h> */
| |
166#define MODINFO_NAME 0x0000 167#define MODINFO_TYPE 0x0001 168#define MODINFO_ADDR 0x0002 169#define MODINFO_SIZE 0x0003 170#define MODINFO_METADATA 0x8000 171 172#define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ 173#define MODINFOMD_ELFHDR 0x0002 /* ELF header */ 174#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ 175
| 187#define MODINFO_NAME 0x0000 188#define MODINFO_TYPE 0x0001 189#define MODINFO_ADDR 0x0002 190#define MODINFO_SIZE 0x0003 191#define MODINFO_METADATA 0x8000 192 193#define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ 194#define MODINFOMD_ELFHDR 0x0002 /* ELF header */ 195#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ 196
|
176/* MI module loaders */ 177extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); 178extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); 179 180/* extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */ 181
| |
182#define KLD_IDENT_SYMNAME "kld_identifier_" 183#define MODINFOMD_KLDIDENT (MODINFOMD_NOCOPY | 0x4000) 184#define MODINFOMD_KLDDEP (MODINFOMD_NOCOPY | 0x4001) 185
| 197#define KLD_IDENT_SYMNAME "kld_identifier_" 198#define MODINFOMD_KLDIDENT (MODINFOMD_NOCOPY | 0x4000) 199#define MODINFOMD_KLDDEP (MODINFOMD_NOCOPY | 0x4001) 200
|
| 201 202
|
186#if defined(__ELF__) 187 188/* 189 * Alpha GAS needs an align before the section change. It seems to assume 190 * that after the .previous, it is aligned, so the following .align 3 is 191 * ignored. Since the previous instructions often contain strings, this is 192 * a problem. 193 */ 194 195#ifdef __alpha__ 196#define MAKE_SET(set, sym) \ 197 __asm(".align 3"); \ 198 __asm(".section .set." #set ",\"aw\""); \ 199 __asm(".quad " #sym); \ 200 __asm(".previous") 201#else 202#define MAKE_SET(set, sym) \ 203 __asm(".section .set." #set ",\"aw\""); \ 204 __asm(".long " #sym); \ 205 __asm(".previous") 206#endif 207#define TEXT_SET(set, sym) MAKE_SET(set, sym) 208#define DATA_SET(set, sym) MAKE_SET(set, sym) 209#define BSS_SET(set, sym) MAKE_SET(set, sym) 210#define ABS_SET(set, sym) MAKE_SET(set, sym) 211 212#else 213 214/* 215 * Linker set support, directly from <sys/kernel.h> 216 * 217 * NB: the constants defined below must match those defined in 218 * ld/ld.h. Since their calculation requires arithmetic, we 219 * can't name them symbolically (e.g., 23 is N_SETT | N_EXT). 220 */ 221#define MAKE_SET(set, sym, type) \ 222 static void const * const __set_##set##_sym_##sym = &sym; \ 223 __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym) 224#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23) 225#define DATA_SET(set, sym) MAKE_SET(set, sym, 25) 226#define BSS_SET(set, sym) MAKE_SET(set, sym, 27) 227#define ABS_SET(set, sym) MAKE_SET(set, sym, 21) 228 229#endif 230 231struct linker_set { 232 int ls_length; 233 const void *ls_items[1]; /* really ls_length of them, trailing NULL */ 234}; 235 236/* 237 * Support for commands 238 */ 239struct bootblk_command 240{ 241 const char *c_name; 242 const char *c_desc; 243 bootblk_cmd_t *c_fn; 244}; 245 246#define COMMAND_SET(tag, key, desc, func) \ 247 static bootblk_cmd_t func; \ 248 static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ 249 DATA_SET(Xcommand_set, _cmd_ ## tag); 250 251extern struct linker_set Xcommand_set; 252 253/* 254 * The intention of the architecture switch is to provide a convenient 255 * encapsulation of the interface between the bootstrap MI and MD code. 256 * MD code may selectively populate the switch at runtime based on the 257 * actual configuration of the target system. 258 */ 259struct arch_switch 260{ 261 /* Automatically load modules as required by detected hardware */ 262 int (* arch_autoload)(); 263 /* Locate the device for (name), return pointer to tail in (*path) */ 264 int (*arch_getdev)(void **dev, char *name, char **path); 265 /* Copy from local address space to module address space, similar to bcopy() */ 266 int (*arch_copyin)(void *src, vm_offset_t dest, size_t len); 267 /* Copy to local address space from module address space, similar to bcopy() */ 268 int (*arch_copyout)(vm_offset_t src, void *dest, size_t len); 269 /* Read from file to module address space, same semantics as read() */ 270 int (*arch_readin)(int fd, vm_offset_t dest, size_t len);
| 203#if defined(__ELF__) 204 205/* 206 * Alpha GAS needs an align before the section change. It seems to assume 207 * that after the .previous, it is aligned, so the following .align 3 is 208 * ignored. Since the previous instructions often contain strings, this is 209 * a problem. 210 */ 211 212#ifdef __alpha__ 213#define MAKE_SET(set, sym) \ 214 __asm(".align 3"); \ 215 __asm(".section .set." #set ",\"aw\""); \ 216 __asm(".quad " #sym); \ 217 __asm(".previous") 218#else 219#define MAKE_SET(set, sym) \ 220 __asm(".section .set." #set ",\"aw\""); \ 221 __asm(".long " #sym); \ 222 __asm(".previous") 223#endif 224#define TEXT_SET(set, sym) MAKE_SET(set, sym) 225#define DATA_SET(set, sym) MAKE_SET(set, sym) 226#define BSS_SET(set, sym) MAKE_SET(set, sym) 227#define ABS_SET(set, sym) MAKE_SET(set, sym) 228 229#else 230 231/* 232 * Linker set support, directly from <sys/kernel.h> 233 * 234 * NB: the constants defined below must match those defined in 235 * ld/ld.h. Since their calculation requires arithmetic, we 236 * can't name them symbolically (e.g., 23 is N_SETT | N_EXT). 237 */ 238#define MAKE_SET(set, sym, type) \ 239 static void const * const __set_##set##_sym_##sym = &sym; \ 240 __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym) 241#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23) 242#define DATA_SET(set, sym) MAKE_SET(set, sym, 25) 243#define BSS_SET(set, sym) MAKE_SET(set, sym, 27) 244#define ABS_SET(set, sym) MAKE_SET(set, sym, 21) 245 246#endif 247 248struct linker_set { 249 int ls_length; 250 const void *ls_items[1]; /* really ls_length of them, trailing NULL */ 251}; 252 253/* 254 * Support for commands 255 */ 256struct bootblk_command 257{ 258 const char *c_name; 259 const char *c_desc; 260 bootblk_cmd_t *c_fn; 261}; 262 263#define COMMAND_SET(tag, key, desc, func) \ 264 static bootblk_cmd_t func; \ 265 static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ 266 DATA_SET(Xcommand_set, _cmd_ ## tag); 267 268extern struct linker_set Xcommand_set; 269 270/* 271 * The intention of the architecture switch is to provide a convenient 272 * encapsulation of the interface between the bootstrap MI and MD code. 273 * MD code may selectively populate the switch at runtime based on the 274 * actual configuration of the target system. 275 */ 276struct arch_switch 277{ 278 /* Automatically load modules as required by detected hardware */ 279 int (* arch_autoload)(); 280 /* Locate the device for (name), return pointer to tail in (*path) */ 281 int (*arch_getdev)(void **dev, char *name, char **path); 282 /* Copy from local address space to module address space, similar to bcopy() */ 283 int (*arch_copyin)(void *src, vm_offset_t dest, size_t len); 284 /* Copy to local address space from module address space, similar to bcopy() */ 285 int (*arch_copyout)(vm_offset_t src, void *dest, size_t len); 286 /* Read from file to module address space, same semantics as read() */ 287 int (*arch_readin)(int fd, vm_offset_t dest, size_t len);
|
| 288 /* Perform ISA byte port I/O (only for systems with ISA) */ 289 int (*arch_isainb)(int port); 290 void (*arch_isaoutb)(int port, int value);
|
271}; 272extern struct arch_switch archsw; 273
| 291}; 292extern struct arch_switch archsw; 293
|
| 294/* This must be provided by the MD code, but should it be in the archsw? */ 295extern void delay(int delay); 296
|
274/* 275 * XXX these belong in a system header 276 */ 277#define KLD_NAMELEN 32 278 279struct kld_module_dependancy 280{ 281 char kd_name[KLD_NAMELEN]; 282 u_int32_t kd_version; 283}; 284 285struct kld_module_identifier 286{ 287 u_int32_t ki_kldversion; 288 char ki_name[KLD_NAMELEN]; 289 u_int32_t ki_version; 290 struct kld_module_dependancy *ki_deps; 291 int ki_ndeps; 292 size_t ki_depsize; 293}; 294 295/* 296 * Use the depsize field in the identifier to correctly index a 297 * dependancy. 298 */ 299#define KLD_GETDEP(ki, kd, n) (struct kld_module_dependancy *)((char *)(kd) + ((ki)->ki_depsize * (n)))
| 297/* 298 * XXX these belong in a system header 299 */ 300#define KLD_NAMELEN 32 301 302struct kld_module_dependancy 303{ 304 char kd_name[KLD_NAMELEN]; 305 u_int32_t kd_version; 306}; 307 308struct kld_module_identifier 309{ 310 u_int32_t ki_kldversion; 311 char ki_name[KLD_NAMELEN]; 312 u_int32_t ki_version; 313 struct kld_module_dependancy *ki_deps; 314 int ki_ndeps; 315 size_t ki_depsize; 316}; 317 318/* 319 * Use the depsize field in the identifier to correctly index a 320 * dependancy. 321 */ 322#define KLD_GETDEP(ki, kd, n) (struct kld_module_dependancy *)((char *)(kd) + ((ki)->ki_depsize * (n)))
|