| @@ -1,612 +1,612 @@ | | | @@ -1,612 +1,612 @@ |
1 | .\" $NetBSD: module.9,v 1.52 2019/04/07 22:32:10 pgoyette Exp $ | | 1 | .\" $NetBSD: module.9,v 1.53 2021/07/22 01:38:45 pgoyette Exp $ |
2 | .\" | | 2 | .\" |
3 | .\" Copyright (c) 2010 The NetBSD Foundation, Inc. | | 3 | .\" Copyright (c) 2010 The NetBSD Foundation, Inc. |
4 | .\" All rights reserved. | | 4 | .\" All rights reserved. |
5 | .\" | | 5 | .\" |
6 | .\" This code is derived from software contributed to The NetBSD Foundation | | 6 | .\" This code is derived from software contributed to The NetBSD Foundation |
7 | .\" by Andrew Doran. | | 7 | .\" by Andrew Doran. |
8 | .\" | | 8 | .\" |
9 | .\" Redistribution and use in source and binary forms, with or without | | 9 | .\" Redistribution and use in source and binary forms, with or without |
10 | .\" modification, are permitted provided that the following conditions | | 10 | .\" modification, are permitted provided that the following conditions |
11 | .\" are met: | | 11 | .\" are met: |
12 | .\" 1. Redistributions of source code must retain the above copyright | | 12 | .\" 1. Redistributions of source code must retain the above copyright |
13 | .\" notice, this list of conditions and the following disclaimer. | | 13 | .\" notice, this list of conditions and the following disclaimer. |
14 | .\" 2. Redistributions in binary form must reproduce the above copyright | | 14 | .\" 2. Redistributions in binary form must reproduce the above copyright |
15 | .\" notice, this list of conditions and the following disclaimer in the | | 15 | .\" notice, this list of conditions and the following disclaimer in the |
16 | .\" documentation and/or other materials provided with the distribution. | | 16 | .\" documentation and/or other materials provided with the distribution. |
17 | .\" | | 17 | .\" |
18 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 18 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
19 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 19 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
20 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 20 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
21 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 21 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
22 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 22 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
23 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 23 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
24 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 24 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
25 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 25 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
26 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 26 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
27 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 27 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
28 | .\" POSSIBILITY OF SUCH DAMAGE. | | 28 | .\" POSSIBILITY OF SUCH DAMAGE. |
29 | .\" | | 29 | .\" |
30 | .Dd April 8, 2019 | | 30 | .Dd July 21, 2021 |
31 | .Dt MODULE 9 | | 31 | .Dt MODULE 9 |
32 | .Os | | 32 | .Os |
33 | .Sh NAME | | 33 | .Sh NAME |
34 | .Nm module , | | 34 | .Nm module , |
35 | .Nm module_load , | | 35 | .Nm module_load , |
36 | .Nm module_autoload , | | 36 | .Nm module_autoload , |
37 | .Nm module_unload , | | 37 | .Nm module_unload , |
38 | .Nm module_init_class , | | 38 | .Nm module_init_class , |
39 | .Nm module_hold , | | 39 | .Nm module_hold , |
40 | .Nm module_rele , | | 40 | .Nm module_rele , |
41 | .Nm module_find_section , | | 41 | .Nm module_find_section , |
42 | .Nm module_kernel , | | 42 | .Nm module_kernel , |
43 | .Nm module_name , | | 43 | .Nm module_name , |
44 | .Nm module_source , | | 44 | .Nm module_source , |
45 | .Nm module_register_callbacks , | | 45 | .Nm module_register_callbacks , |
46 | .Nm module_unregister_callbacks , | | 46 | .Nm module_unregister_callbacks , |
47 | .Nm module_specific_key_create , | | 47 | .Nm module_specific_key_create , |
48 | .Nm module_specific_key_delete , | | 48 | .Nm module_specific_key_delete , |
49 | .Nm module_getspecific , | | 49 | .Nm module_getspecific , |
50 | .Nm module_setspecific | | 50 | .Nm module_setspecific |
51 | .Nd kernel module loader | | 51 | .Nd kernel module loader |
52 | .Sh SYNOPSIS | | 52 | .Sh SYNOPSIS |
53 | .In sys/module.h | | 53 | .In sys/module.h |
54 | .Fn MODULE "class" "name" "required" | | 54 | .Fn MODULE "class" "name" "required" |
55 | .Ft int | | 55 | .Ft int |
56 | .Fn module_load "const char *name" "int flags" "prop_dictionary_t props" \ | | 56 | .Fn module_load "const char *name" "int flags" "prop_dictionary_t props" \ |
57 | "modclass_t class" | | 57 | "modclass_t class" |
58 | .Ft int | | 58 | .Ft int |
59 | .Fn module_autoload "const char *name" "modclass_t class" | | 59 | .Fn module_autoload "const char *name" "modclass_t class" |
60 | .Ft int | | 60 | .Ft int |
61 | .Fn module_unload "const char *name" | | 61 | .Fn module_unload "const char *name" |
62 | .Ft void | | 62 | .Ft void |
63 | .Fn module_init_class "modclass_t class" | | 63 | .Fn module_init_class "modclass_t class" |
64 | .Ft int | | 64 | .Ft void |
65 | .Fn module_hold "module_t *module" | | 65 | .Fn module_hold "module_t *module" |
66 | .Ft void | | 66 | .Ft void |
67 | .Fn module_rele "module_t *module" | | 67 | .Fn module_rele "module_t *module" |
68 | .Ft int | | 68 | .Ft int |
69 | .Fn module_find_section "const char *" "void **" "size_t *" | | 69 | .Fn module_find_section "const char *" "void **" "size_t *" |
70 | .Ft "module_t *" | | 70 | .Ft "module_t *" |
71 | .Fn module_kernel "void" | | 71 | .Fn module_kernel "void" |
72 | .Ft "const char *" | | 72 | .Ft "const char *" |
73 | .Fn module_name "struct module *module" | | 73 | .Fn module_name "struct module *module" |
74 | .Ft modsrc_t | | 74 | .Ft modsrc_t |
75 | .Fn module_source "struct module *module" | | 75 | .Fn module_source "struct module *module" |
76 | .Ft void | | 76 | .Ft void |
77 | .Fn module_init "void" | | 77 | .Fn module_init "void" |
78 | .Ft void | | 78 | .Ft void |
79 | .Fn module_start_unload_thread "void" | | 79 | .Fn module_start_unload_thread "void" |
80 | .Ft void | | 80 | .Ft void |
81 | .Fn module_builtin_require_force "void" | | 81 | .Fn module_builtin_require_force "void" |
82 | .Ft void | | 82 | .Ft void |
83 | .Fn module_load_vfs_init "void" | | 83 | .Fn module_load_vfs_init "void" |
84 | .Ft "void *" | | 84 | .Ft "void *" |
85 | .Fn module_register_callbacks "void (*)(struct module *)" \ | | 85 | .Fn module_register_callbacks "void (*)(struct module *)" \ |
86 | "void (*unload)(struct module *)" | | 86 | "void (*unload)(struct module *)" |
87 | .Ft void | | 87 | .Ft void |
88 | .Fn module_unregister_callbacks "void *" | | 88 | .Fn module_unregister_callbacks "void *" |
89 | .Ft specificdata_key_t | | 89 | .Ft specificdata_key_t |
90 | .Fn module_specific_key_create "specificdata_key_t *keyp" \ | | 90 | .Fn module_specific_key_create "specificdata_key_t *keyp" \ |
91 | "specificdata_dtor_t dtor" | | 91 | "specificdata_dtor_t dtor" |
92 | .Ft void | | 92 | .Ft void |
93 | .Fn module_specific_key_delete "specificdata_key_t key" | | 93 | .Fn module_specific_key_delete "specificdata_key_t key" |
94 | .Ft "void *" | | 94 | .Ft "void *" |
95 | .Fn module_getspecific "module_t *mod" "specificdata_key_t key" | | 95 | .Fn module_getspecific "module_t *mod" "specificdata_key_t key" |
96 | .Ft "void *" | | 96 | .Ft "void *" |
97 | .Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data" | | 97 | .Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data" |
98 | .Sh DESCRIPTION | | 98 | .Sh DESCRIPTION |
99 | Modules are sections of code that can be independently linked and selectively | | 99 | Modules are sections of code that can be independently linked and selectively |
100 | loaded into or unloaded from a running kernel. | | 100 | loaded into or unloaded from a running kernel. |
101 | This provides a mechanism to update the module without having to relink | | 101 | This provides a mechanism to update the module without having to relink |
102 | the kernel and reboot. | | 102 | the kernel and reboot. |
103 | Modules can be loaded from within the kernel image, provided by the boot | | 103 | Modules can be loaded from within the kernel image, provided by the boot |
104 | loader, or loaded from the file system. | | 104 | loader, or loaded from the file system. |
105 | .Pp | | 105 | .Pp |
106 | The | | 106 | The |
107 | .Nm | | 107 | .Nm |
108 | subsystem includes two data types: | | 108 | subsystem includes two data types: |
109 | .Bl -enum -offset indent | | 109 | .Bl -enum -offset indent |
110 | .It | | 110 | .It |
111 | The | | 111 | The |
112 | .Vt module_t | | 112 | .Vt module_t |
113 | type provides storage to describe a module. | | 113 | type provides storage to describe a module. |
114 | .It | | 114 | .It |
115 | The | | 115 | The |
116 | .Vt modinfo_t | | 116 | .Vt modinfo_t |
117 | type resides within | | 117 | type resides within |
118 | .Vt module_t | | 118 | .Vt module_t |
119 | and contains module header info. | | 119 | and contains module header info. |
120 | .El | | 120 | .El |
121 | .Pp | | 121 | .Pp |
122 | The module subsystem is protected by the global | | 122 | The module subsystem is protected by the global |
123 | .Va kernconfig_mutex . | | 123 | .Va kernconfig_mutex . |
124 | .Sh FUNCTIONS | | 124 | .Sh FUNCTIONS |
125 | .Bl -tag -width abcd | | 125 | .Bl -tag -width abcd |
126 | .It Fn MODULE "class" "name" "required" | | 126 | .It Fn MODULE "class" "name" "required" |
127 | The | | 127 | The |
128 | .Fn MODULE | | 128 | .Fn MODULE |
129 | macro creates and initializes a | | 129 | macro creates and initializes a |
130 | .Vt modinfo_t | | 130 | .Vt modinfo_t |
131 | structure. | | 131 | structure. |
132 | The | | 132 | The |
133 | .Fa class | | 133 | .Fa class |
134 | argument identifies the class of module, and must be one of the following | | 134 | argument identifies the class of module, and must be one of the following |
135 | (note that | | 135 | (note that |
136 | .Dv MODULE_CLASS_ANY | | 136 | .Dv MODULE_CLASS_ANY |
137 | should not be used here): | | 137 | should not be used here): |
138 | .Bl -tag -width MODULE_CLASS_SECMODEL -offset indent | | 138 | .Bl -tag -width MODULE_CLASS_SECMODEL -offset indent |
139 | .It Dv MODULE_CLASS_VFS | | 139 | .It Dv MODULE_CLASS_VFS |
140 | The module provide a virtual file system - see | | 140 | The module provide a virtual file system - see |
141 | .Xr vfs 9 | | 141 | .Xr vfs 9 |
142 | .It Dv MODULE_CLASS_DRIVER | | 142 | .It Dv MODULE_CLASS_DRIVER |
143 | The module is a device driver - see | | 143 | The module is a device driver - see |
144 | .Xr driver 9 | | 144 | .Xr driver 9 |
145 | .It Dv MODULE_CLASS_EXEC | | 145 | .It Dv MODULE_CLASS_EXEC |
146 | The module provides an alternate execution environment - see the various | | 146 | The module provides an alternate execution environment - see the various |
147 | .Dv COMPAT_xxx | | 147 | .Dv COMPAT_xxx |
148 | options in | | 148 | options in |
149 | .Xr options 4 | | 149 | .Xr options 4 |
150 | .It Dv MODULE_CLASS_SECMODEL | | 150 | .It Dv MODULE_CLASS_SECMODEL |
151 | The module provides a security model - see | | 151 | The module provides a security model - see |
152 | .Xr secmodel 9 | | 152 | .Xr secmodel 9 |
153 | .It Dv MODULE_CLASS_BUFQ | | 153 | .It Dv MODULE_CLASS_BUFQ |
154 | The module provides a buffer queue strategy - see | | 154 | The module provides a buffer queue strategy - see |
155 | .Xr bufq 9 | | 155 | .Xr bufq 9 |
156 | .It Dv MODULE_CLASS_MISC | | 156 | .It Dv MODULE_CLASS_MISC |
157 | The module provides miscellaneous kernel services | | 157 | The module provides miscellaneous kernel services |
158 | .El | | 158 | .El |
159 | .Pp | | 159 | .Pp |
160 | The | | 160 | The |
161 | .Fa name | | 161 | .Fa name |
162 | argument provides the name of the module. | | 162 | argument provides the name of the module. |
163 | Loaded modules, including those that are built-in to the kernel, must all | | 163 | Loaded modules, including those that are built-in to the kernel, must all |
164 | have unique names. | | 164 | have unique names. |
165 | .Pp | | 165 | .Pp |
166 | The | | 166 | The |
167 | .Fa required | | 167 | .Fa required |
168 | argument is a quoted string containing a comma-separated list of module | | 168 | argument is a quoted string containing a comma-separated list of module |
169 | names that are required by this module. | | 169 | names that are required by this module. |
170 | The list must not contain any white-space. | | 170 | The list must not contain any white-space. |
171 | When a module is loaded, all of its required modules are auto-loaded and | | 171 | When a module is loaded, all of its required modules are auto-loaded and |
172 | initialized before the module itself is loaded. | | 172 | initialized before the module itself is loaded. |
173 | Loading of required modules is a recursive operation. | | 173 | Loading of required modules is a recursive operation. |
174 | .Pp | | 174 | .Pp |
175 | If there are no required modules, this argument should be specified as | | 175 | If there are no required modules, this argument should be specified as |
176 | .Dv NULL . | | 176 | .Dv NULL . |
177 | .Pp | | 177 | .Pp |
178 | In addition to the explicit arguments, the | | 178 | In addition to the explicit arguments, the |
179 | .Fn MODULE | | 179 | .Fn MODULE |
180 | macro creates a reference to the module's | | 180 | macro creates a reference to the module's |
181 | .Fn modcmd | | 181 | .Fn modcmd |
182 | function. | | 182 | function. |
183 | This function is defined as: | | 183 | This function is defined as: |
184 | .Bl -tag -width modcmd -offset indent | | 184 | .Bl -tag -width modcmd -offset indent |
185 | .It Ft modcmd_t | | 185 | .It Ft modcmd_t |
186 | .Fn xxx_modcmd "modcmd_t cmd" "void *data" | | 186 | .Fn xxx_modcmd "modcmd_t cmd" "void *data" |
187 | .El | | 187 | .El |
188 | .Pp | | 188 | .Pp |
189 | (where xxx is the name of the module, from the | | 189 | (where xxx is the name of the module, from the |
190 | .Dv MODULE | | 190 | .Dv MODULE |
191 | macro). | | 191 | macro). |
192 | .Pp | | 192 | .Pp |
193 | The | | 193 | The |
194 | .Fa cmd | | 194 | .Fa cmd |
195 | argument requests one of the following operations: | | 195 | argument requests one of the following operations: |
196 | .Bl -tag -width MODULE_CMD_AUTOUNLOAD -offset indent | | 196 | .Bl -tag -width MODULE_CMD_AUTOUNLOAD -offset indent |
197 | .It Dv MODULE_CMD_INIT | | 197 | .It Dv MODULE_CMD_INIT |
198 | Perform module-specific initialization when the module is loaded. | | 198 | Perform module-specific initialization when the module is loaded. |
199 | .It Dv MODULE_CMD_FINI | | 199 | .It Dv MODULE_CMD_FINI |
200 | Perform module-specific clean-up before the module is unloaded. | | 200 | Perform module-specific clean-up before the module is unloaded. |
201 | .It Dv MODULE_CMD_AUTOUNLOAD | | 201 | .It Dv MODULE_CMD_AUTOUNLOAD |
202 | Notify the module that it is about to be unloaded. | | 202 | Notify the module that it is about to be unloaded. |
203 | .It Dv MODULE_CMD_STAT | | 203 | .It Dv MODULE_CMD_STAT |
204 | Request the module to provide status information (not currently implemented). | | 204 | Request the module to provide status information (not currently implemented). |
205 | .El | | 205 | .El |
206 | .Pp | | 206 | .Pp |
207 | All modules' | | 207 | All modules' |
208 | .Fn modcmd | | 208 | .Fn modcmd |
209 | functions must implement the | | 209 | functions must implement the |
210 | .Dv MODULE_CMD_INIT | | 210 | .Dv MODULE_CMD_INIT |
211 | and | | 211 | and |
212 | .Dv MODULE_CMD_FINI | | 212 | .Dv MODULE_CMD_FINI |
213 | commands. | | 213 | commands. |
214 | The other commands are optional, | | 214 | The other commands are optional, |
215 | and should return | | 215 | and should return |
216 | .Er ENOTTY | | 216 | .Er ENOTTY |
217 | if not implemented. | | 217 | if not implemented. |
218 | .Pp | | 218 | .Pp |
219 | For the | | 219 | For the |
220 | .Dv MODULE_CMD_INIT | | 220 | .Dv MODULE_CMD_INIT |
221 | command, the | | 221 | command, the |
222 | .Fa data | | 222 | .Fa data |
223 | argument is used to pass a pointer to the module's | | 223 | argument is used to pass a pointer to the module's |
224 | .Xr prop_dictionary 3 . | | 224 | .Xr prop_dictionary 3 . |
225 | For the | | 225 | For the |
226 | .Dv MODULE_CMD_STAT | | 226 | .Dv MODULE_CMD_STAT |
227 | command, the | | 227 | command, the |
228 | .Fa data | | 228 | .Fa data |
229 | argument points to a buffer where the status information should be placed. | | 229 | argument points to a buffer where the status information should be placed. |
230 | .Pp | | 230 | .Pp |
231 | The __link_set mechanism is used to enable the | | 231 | The __link_set mechanism is used to enable the |
232 | .Nm | | 232 | .Nm |
233 | subsystem to locate the | | 233 | subsystem to locate the |
234 | .Vt modinfo_t | | 234 | .Vt modinfo_t |
235 | structure. | | 235 | structure. |
236 | .It Fn module_load "name" "flags" "props" "class" | | 236 | .It Fn module_load "name" "flags" "props" "class" |
237 | Load a module, link it into the running kernel, and call the module's | | 237 | Load a module, link it into the running kernel, and call the module's |
238 | .Fn modcmd | | 238 | .Fn modcmd |
239 | routine with a | | 239 | routine with a |
240 | .Fa cmd | | 240 | .Fa cmd |
241 | argument of | | 241 | argument of |
242 | .Dv MODULE_CMD_INIT . | | 242 | .Dv MODULE_CMD_INIT . |
243 | If the specified module requires other modules, they are loaded first; if | | 243 | If the specified module requires other modules, they are loaded first; if |
244 | any required module cannot be loaded or if any of their | | 244 | any required module cannot be loaded or if any of their |
245 | .Fn modcmd | | 245 | .Fn modcmd |
246 | control routines returns a non-zero status, loading of this module and | | 246 | control routines returns a non-zero status, loading of this module and |
247 | the specific required module will fail. | | 247 | the specific required module will fail. |
248 | The required modules are marked for automatic unloading. | | 248 | The required modules are marked for automatic unloading. |
249 | Thus, if the loading of the module failed, the required modules will | | 249 | Thus, if the loading of the module failed, the required modules will |
250 | be automatically unloaded after a short delay. | | 250 | be automatically unloaded after a short delay. |
251 | .Pp | | 251 | .Pp |
252 | The loader will look first for a built-in module with the specified | | 252 | The loader will look first for a built-in module with the specified |
253 | .Fa name | | 253 | .Fa name |
254 | that has not been disabled (see | | 254 | that has not been disabled (see |
255 | .Fn module_unload | | 255 | .Fn module_unload |
256 | below). | | 256 | below). |
257 | If a built-in module with that | | 257 | If a built-in module with that |
258 | .Fa name | | 258 | .Fa name |
259 | is not found, the list of modules prepared by the boot loader is searched. | | 259 | is not found, the list of modules prepared by the boot loader is searched. |
260 | If the named module is still not found, an attempt is made to locate the | | 260 | If the named module is still not found, an attempt is made to locate the |
261 | module within the file system, provided it has been mounted by the | | 261 | module within the file system, provided it has been mounted by the |
262 | initialization code. | | 262 | initialization code. |
263 | .Pp | | 263 | .Pp |
264 | The | | 264 | The |
265 | .Fa flags | | 265 | .Fa flags |
266 | argument can include: | | 266 | argument can include: |
267 | .Bl -tag -width MODCTL_LOAD_FORCE -offset indent | | 267 | .Bl -tag -width MODCTL_LOAD_FORCE -offset indent |
268 | .It Dv MODCTL_NO_PROP | | 268 | .It Dv MODCTL_NO_PROP |
269 | When loading a module from the file system, do not attempt to locate a | | 269 | When loading a module from the file system, do not attempt to locate a |
270 | corresponding prop_dictionary file. | | 270 | corresponding prop_dictionary file. |
271 | .It Dv MODCTL_LOAD_FORCE | | 271 | .It Dv MODCTL_LOAD_FORCE |
272 | Force loading of disabled built-in modules and modules built for a | | 272 | Force loading of disabled built-in modules and modules built for a |
273 | different version of the operating system. | | 273 | different version of the operating system. |
274 | .El | | 274 | .El |
275 | .Pp | | 275 | .Pp |
276 | The | | 276 | The |
277 | .Fa props | | 277 | .Fa props |
278 | argument points to an externalized property list which is passed to the | | 278 | argument points to an externalized property list which is passed to the |
279 | module's | | 279 | module's |
280 | .Fn modcmd | | 280 | .Fn modcmd |
281 | routine. | | 281 | routine. |
282 | If a module is being loaded from the file system, and the | | 282 | If a module is being loaded from the file system, and the |
283 | .Dv MODCTL_NO_PROP | | 283 | .Dv MODCTL_NO_PROP |
284 | flag is not set, the system searches for a file with the same name as the | | 284 | flag is not set, the system searches for a file with the same name as the |
285 | module file, but with the suffix | | 285 | module file, but with the suffix |
286 | .Dq Pa .plist . | | 286 | .Dq Pa .plist . |
287 | If this file is found, the prop_dictionary it contains is loaded and | | 287 | If this file is found, the prop_dictionary it contains is loaded and |
288 | merged with the prop_dictionary from the | | 288 | merged with the prop_dictionary from the |
289 | .Fa props | | 289 | .Fa props |
290 | argument. | | 290 | argument. |
291 | .Pp | | 291 | .Pp |
292 | The | | 292 | The |
293 | .Fa class | | 293 | .Fa class |
294 | argument can be any of: | | 294 | argument can be any of: |
295 | .Pp | | 295 | .Pp |
296 | .Bl -tag -width MODULE_CLASS_SECMODEL -offset indent -compact | | 296 | .Bl -tag -width MODULE_CLASS_SECMODEL -offset indent -compact |
297 | .It Dv MODULE_CLASS_ANY | | 297 | .It Dv MODULE_CLASS_ANY |
298 | .It Dv MODULE_CLASS_DRIVER | | 298 | .It Dv MODULE_CLASS_DRIVER |
299 | Device driver | | 299 | Device driver |
300 | .It Dv MODULE_CLASS_EXEC | | 300 | .It Dv MODULE_CLASS_EXEC |
301 | Executable image handler | | 301 | Executable image handler |
302 | .It Dv MODULE_CLASS_MISC | | 302 | .It Dv MODULE_CLASS_MISC |
303 | Miscellaneous module | | 303 | Miscellaneous module |
304 | .It Dv MODULE_CLASS_SECMODEL | | 304 | .It Dv MODULE_CLASS_SECMODEL |
305 | Security model (see | | 305 | Security model (see |
306 | .Xr secmodel 9 | | 306 | .Xr secmodel 9 |
307 | for more details) | | 307 | for more details) |
308 | .It Dv MODULE_CLASS_VFS | | 308 | .It Dv MODULE_CLASS_VFS |
309 | Virtual file system | | 309 | Virtual file system |
310 | .El | | 310 | .El |
311 | .Pp | | 311 | .Pp |
312 | If the class is not | | 312 | If the class is not |
313 | .Dv MODULE_CLASS_ANY , | | 313 | .Dv MODULE_CLASS_ANY , |
314 | the class of the module being loaded | | 314 | the class of the module being loaded |
315 | must match the requested | | 315 | must match the requested |
316 | .Fa class . | | 316 | .Fa class . |
317 | Except when verifying a module's class when it is being loaded, module | | 317 | Except when verifying a module's class when it is being loaded, module |
318 | classes other than | | 318 | classes other than |
319 | .Dv MODULE_CLASS_SECMODEL | | 319 | .Dv MODULE_CLASS_SECMODEL |
320 | are transparent to the module subsystem. | | 320 | are transparent to the module subsystem. |
321 | They are provided only for the benefit of the subsystem's clients. | | 321 | They are provided only for the benefit of the subsystem's clients. |
322 | Modules with class | | 322 | Modules with class |
323 | .Dv MODULE_CLASS_SECMODEL | | 323 | .Dv MODULE_CLASS_SECMODEL |
324 | are automatically registered with | | 324 | are automatically registered with |
325 | .Fn secmodel_register | | 325 | .Fn secmodel_register |
326 | after being successfully loaded, and automatically deregistered with | | 326 | after being successfully loaded, and automatically deregistered with |
327 | .Fn secmodel_deregister | | 327 | .Fn secmodel_deregister |
328 | when being unloaded. | | 328 | when being unloaded. |
329 | .Pp | | 329 | .Pp |
330 | The | | 330 | The |
331 | .Fn module_load | | 331 | .Fn module_load |
332 | routine is primarily intended as the implementation of the | | 332 | routine is primarily intended as the implementation of the |
333 | .Dv MODCTL_LOAD | | 333 | .Dv MODCTL_LOAD |
334 | option of the | | 334 | option of the |
335 | .Xr modctl 2 | | 335 | .Xr modctl 2 |
336 | system call. | | 336 | system call. |
337 | .It Fn module_autoload "name" "class" | | 337 | .It Fn module_autoload "name" "class" |
338 | Auto-load a module, making it available for automatic unloading. | | 338 | Auto-load a module, making it available for automatic unloading. |
339 | The | | 339 | The |
340 | .Fa name | | 340 | .Fa name |
341 | and | | 341 | and |
342 | .Fa class | | 342 | .Fa class |
343 | arguments are the same as for the | | 343 | arguments are the same as for the |
344 | .Fn module_load | | 344 | .Fn module_load |
345 | routine. | | 345 | routine. |
346 | .Pp | | 346 | .Pp |
347 | The module subsystem uses a kernel thread to attempt to automatically | | 347 | The module subsystem uses a kernel thread to attempt to automatically |
348 | unload modules a short time (currently, 10 seconds) after being loaded by | | 348 | unload modules a short time (currently, 10 seconds) after being loaded by |
349 | .Fn module_autoload . | | 349 | .Fn module_autoload . |
350 | Before the module is unloaded, its | | 350 | Before the module is unloaded, its |
351 | .Fn modcmd | | 351 | .Fn modcmd |
352 | is called with the | | 352 | is called with the |
353 | .Fa cmd | | 353 | .Fa cmd |
354 | argument specified as | | 354 | argument specified as |
355 | .Dv MODULE_CMD_AUTOUNLOAD . | | 355 | .Dv MODULE_CMD_AUTOUNLOAD . |
356 | A module can prevent itself from being unloaded by returning a non-zero | | 356 | A module can prevent itself from being unloaded by returning a non-zero |
357 | value. | | 357 | value. |
358 | .Pp | | 358 | .Pp |
359 | The | | 359 | The |
360 | .Fn module_autoload | | 360 | .Fn module_autoload |
361 | function is intended for use by kernel components to locate and load optional | | 361 | function is intended for use by kernel components to locate and load optional |
362 | system components. | | 362 | system components. |
363 | The function is also used to load modules that are required by other modules. | | 363 | The function is also used to load modules that are required by other modules. |
364 | .Pp | | 364 | .Pp |
365 | The directory from which the module is loaded will be searched for a file | | 365 | The directory from which the module is loaded will be searched for a file |
366 | with the same name as the module file, but with the suffix | | 366 | with the same name as the module file, but with the suffix |
367 | .Dq Pa .plist . | | 367 | .Dq Pa .plist . |
368 | If this file is found, the prop_dictionary it contains will be loaded and | | 368 | If this file is found, the prop_dictionary it contains will be loaded and |
369 | passed to the module's | | 369 | passed to the module's |
370 | .Fn modcmd | | 370 | .Fn modcmd |
371 | routine. | | 371 | routine. |
372 | If this prop_dictionary contains a | | 372 | If this prop_dictionary contains a |
373 | .Dq Pa noautoload | | 373 | .Dq Pa noautoload |
374 | property which is set to | | 374 | property which is set to |
375 | .Dq Pa true | | 375 | .Dq Pa true |
376 | then the system will refuse to load the module. | | 376 | then the system will refuse to load the module. |
377 | .It Fn module_unload "name" | | 377 | .It Fn module_unload "name" |
378 | Unload a module. | | 378 | Unload a module. |
379 | If the module's reference count is non-zero, the function returns | | 379 | If the module's reference count is non-zero, the function returns |
380 | .Er EBUSY . | | 380 | .Er EBUSY . |
381 | Otherwise, the module's | | 381 | Otherwise, the module's |
382 | .Fn modcmd | | 382 | .Fn modcmd |
383 | routine is called with a | | 383 | routine is called with a |
384 | .Fa cmd | | 384 | .Fa cmd |
385 | argument of | | 385 | argument of |
386 | .Dv MODULE_CMD_FINI . | | 386 | .Dv MODULE_CMD_FINI . |
387 | If the | | 387 | If the |
388 | .Fn modcmd | | 388 | .Fn modcmd |
389 | routine returns with an error, then the error is returned to the caller | | 389 | routine returns with an error, then the error is returned to the caller |
390 | otherwise the module is unloaded. | | 390 | otherwise the module is unloaded. |
391 | .Pp | | 391 | .Pp |
392 | The reference counts of all modules that were required by this module are | | 392 | The reference counts of all modules that were required by this module are |
393 | decremented, but the required modules are not unloaded by the call to | | 393 | decremented, but the required modules are not unloaded by the call to |
394 | .Fn module_unload . | | 394 | .Fn module_unload . |
395 | Instead, the required modules may be unloaded by subsequent calls to | | 395 | Instead, the required modules may be unloaded by subsequent calls to |
396 | .Fn module_unload . | | 396 | .Fn module_unload . |
397 | .Pp | | 397 | .Pp |
398 | Unloading a built-in module causes the module to be marked as disabled. | | 398 | Unloading a built-in module causes the module to be marked as disabled. |
399 | This prevents the module from being re-loaded, except by the | | 399 | This prevents the module from being re-loaded, except by the |
400 | .Fn module_load | | 400 | .Fn module_load |
401 | function with the | | 401 | function with the |
402 | .Fa flags | | 402 | .Fa flags |
403 | argument set to | | 403 | argument set to |
404 | .Dv MODULE_FORCE_LOAD . | | 404 | .Dv MODULE_FORCE_LOAD . |
405 | .Pp | | 405 | .Pp |
406 | The | | 406 | The |
407 | .Fn module_unload | | 407 | .Fn module_unload |
408 | function may be called by the | | 408 | function may be called by the |
409 | .Xr modctl 2 | | 409 | .Xr modctl 2 |
410 | system call, by the module subsystem's internal auto-unload thread, or by | | 410 | system call, by the module subsystem's internal auto-unload thread, or by |
411 | other kernel facilities. | | 411 | other kernel facilities. |
412 | Generally, other kernel facilities should not be calling this function. | | 412 | Generally, other kernel facilities should not be calling this function. |
413 | .It Fn module_init_class "class" | | 413 | .It Fn module_init_class "class" |
414 | Load and initialize all available modules of the specified | | 414 | Load and initialize all available modules of the specified |
415 | .Fa class . | | 415 | .Fa class . |
416 | Any built-in modules that have not been disabled, and any modules provided | | 416 | Any built-in modules that have not been disabled, and any modules provided |
417 | by the boot loader are loaded. | | 417 | by the boot loader are loaded. |
418 | .It Fn module_hold "module" | | 418 | .It Fn module_hold "module" |
419 | Increment the reference count of a module. | | 419 | Increment the reference count of a module. |
420 | A module cannot be unloaded if its reference count is non-zero. | | 420 | A module cannot be unloaded if its reference count is non-zero. |
421 | .It Fn module_rele "module" | | 421 | .It Fn module_rele "module" |
422 | Decrement the reference count of a module. | | 422 | Decrement the reference count of a module. |
423 | .It Fn module_find_section "name" "addr" "size" | | 423 | .It Fn module_find_section "name" "addr" "size" |
424 | Find the start address and size of linker section | | 424 | Find the start address and size of linker section |
425 | .Ar name | | 425 | .Ar name |
426 | within a module. | | 426 | within a module. |
427 | The miniroot module uses this routine to find the address and size of the | | 427 | The miniroot module uses this routine to find the address and size of the |
428 | embedded file system image. | | 428 | embedded file system image. |
429 | This routine can only examine the linker data for the module that is | | 429 | This routine can only examine the linker data for the module that is |
430 | currently being initialized; it cannot examine data for any other module. | | 430 | currently being initialized; it cannot examine data for any other module. |
431 | .It Fn module_kernel "void" | | 431 | .It Fn module_kernel "void" |
432 | Returns a pointer to a | | 432 | Returns a pointer to a |
433 | .Ft module_t | | 433 | .Ft module_t |
434 | structure describing the kernel module. | | 434 | structure describing the kernel module. |
435 | .It Fn module_name module | | 435 | .It Fn module_name module |
436 | Returns a pointer to the module's name. | | 436 | Returns a pointer to the module's name. |
437 | .It Fn module_source module | | 437 | .It Fn module_source module |
438 | Returns the source of the module, one of | | 438 | Returns the source of the module, one of |
439 | .Dv MODULE_SOURCE_KERNEL , | | 439 | .Dv MODULE_SOURCE_KERNEL , |
440 | .Dv MODULE_SOURCE_BOOT , | | 440 | .Dv MODULE_SOURCE_BOOT , |
441 | or | | 441 | or |
442 | .Dv MODULE_SOURCE_FILESYS . | | 442 | .Dv MODULE_SOURCE_FILESYS . |
443 | .It Fn module_init "void" | | 443 | .It Fn module_init "void" |
444 | Initialize the module subsystem. | | 444 | Initialize the module subsystem. |
445 | Creates and initializes various data structures, locates all built-in | | 445 | Creates and initializes various data structures, locates all built-in |
446 | modules, and establishes the sub-system's | | 446 | modules, and establishes the sub-system's |
447 | .Xr sysctl 8 | | 447 | .Xr sysctl 8 |
448 | tree. | | 448 | tree. |
449 | .Fn module_init | | 449 | .Fn module_init |
450 | is called early in system initialization to facilitate use of security model | | 450 | is called early in system initialization to facilitate use of security model |
451 | modules. | | 451 | modules. |
452 | .It Fn module_start_unload_thread "void" | | 452 | .It Fn module_start_unload_thread "void" |
453 | Create the thread that attempts to automatically unload modules that were | | 453 | Create the thread that attempts to automatically unload modules that were |
454 | loaded via the | | 454 | loaded via the |
455 | .Fn module_autoload | | 455 | .Fn module_autoload |
456 | routine. | | 456 | routine. |
457 | The function is called only once, | | 457 | The function is called only once, |
458 | after the scheduler and timer functions are initialized. | | 458 | after the scheduler and timer functions are initialized. |
459 | .It Fn module_builtin_require_force "void" | | 459 | .It Fn module_builtin_require_force "void" |
460 | Mark as "disabled" any built-in modules that have not been successfully | | 460 | Mark as "disabled" any built-in modules that have not been successfully |
461 | initialized. | | 461 | initialized. |
462 | Modules marked "disabled" can only be loaded if the | | 462 | Modules marked "disabled" can only be loaded if the |
463 | .Dv MODCTL_LOAD_FORCE | | 463 | .Dv MODCTL_LOAD_FORCE |
464 | is specified. | | 464 | is specified. |
465 | .Fn module_builtin_require_force | | 465 | .Fn module_builtin_require_force |
466 | is called near the end of system initialization, after the | | 466 | is called near the end of system initialization, after the |
467 | .Xr init 8 | | 467 | .Xr init 8 |
468 | process is created. | | 468 | process is created. |
469 | .It Fn module_load_vfs_init "void" | | 469 | .It Fn module_load_vfs_init "void" |
470 | The module subsystem is initialized early, long before any file systems | | 470 | The module subsystem is initialized early, long before any file systems |
471 | are available. | | 471 | are available. |
472 | After the root file system is mounted, | | 472 | After the root file system is mounted, |
473 | .Fn module_load_vfs_init "void" | | 473 | .Fn module_load_vfs_init "void" |
474 | is used to enable loading modules from the file system. | | 474 | is used to enable loading modules from the file system. |
475 | Until this routine is called, modules can only be loaded if they were | | 475 | Until this routine is called, modules can only be loaded if they were |
476 | built-in to the kernel image or provided by the boot loader. | | 476 | built-in to the kernel image or provided by the boot loader. |
477 | .It Fn module_register_callbacks "void (*load)(struct module *)" \ | | 477 | .It Fn module_register_callbacks "void (*load)(struct module *)" \ |
478 | "void (*unload)(struct module *)" | | 478 | "void (*unload)(struct module *)" |
479 | Register a new set of callbacks. | | 479 | Register a new set of callbacks. |
480 | The | | 480 | The |
481 | .Fa load | | 481 | .Fa load |
482 | callback is invoked after any module (including this module) is | | 482 | callback is invoked after any module (including this module) is |
483 | successfully loaded; the | | 483 | successfully loaded; the |
484 | .Fa unload | | 484 | .Fa unload |
485 | callback is invoked before any module is unloaded. | | 485 | callback is invoked before any module is unloaded. |
486 | Each load or unload event can result in multiple invocations of the | | 486 | Each load or unload event can result in multiple invocations of the |
487 | callback routines. | | 487 | callback routines. |
488 | An opaque cookie is returned which can be passed to | | 488 | An opaque cookie is returned which can be passed to |
489 | .Fn module_unregister_callbacks . | | 489 | .Fn module_unregister_callbacks . |
490 | .It Fn module_unregister_callbacks "void *opaque" | | 490 | .It Fn module_unregister_callbacks "void *opaque" |
491 | Unregister a set of callback routines previously registered with | | 491 | Unregister a set of callback routines previously registered with |
492 | .Fn module_register_callbacks . | | 492 | .Fn module_register_callbacks . |
493 | The | | 493 | The |
494 | .Fa opaque | | 494 | .Fa opaque |
495 | argument should be the return value from the previous | | 495 | argument should be the return value from the previous |
496 | .Fn module_register_callbacks | | 496 | .Fn module_register_callbacks |
497 | call. | | 497 | call. |
498 | .It Fn module_specific_key_create "specificdata_key_t *keyp" \ | | 498 | .It Fn module_specific_key_create "specificdata_key_t *keyp" \ |
499 | "specificdata_dtor_t dtor" | | 499 | "specificdata_dtor_t dtor" |
500 | Creates a new specificdata_key for use within the | | 500 | Creates a new specificdata_key for use within the |
501 | .Nm | | 501 | .Nm |
502 | domain. | | 502 | domain. |
503 | The key identifier is returned in | | 503 | The key identifier is returned in |
504 | .Fa keyp . | | 504 | .Fa keyp . |
505 | .It Fn module_specific_key_delete "specificdata_key_t key" | | 505 | .It Fn module_specific_key_delete "specificdata_key_t key" |
506 | Deletes the specified specificdata_key | | 506 | Deletes the specified specificdata_key |
507 | .Fa key | | 507 | .Fa key |
508 | from the | | 508 | from the |
509 | .Nm | | 509 | .Nm |
510 | domain. | | 510 | domain. |
511 | .It Fn module_getspecific "module_t *mod" "specificdata_key_t key" | | 511 | .It Fn module_getspecific "module_t *mod" "specificdata_key_t key" |
512 | Retrieves the value associated with | | 512 | Retrieves the value associated with |
513 | .Fa key | | 513 | .Fa key |
514 | from module | | 514 | from module |
515 | .Fa mod . | | 515 | .Fa mod . |
516 | .It Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data" | | 516 | .It Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data" |
517 | Stores | | 517 | Stores |
518 | .Fa data | | 518 | .Fa data |
519 | as the value associated with | | 519 | as the value associated with |
520 | .Fa key | | 520 | .Fa key |
521 | for module | | 521 | for module |
522 | .Fa mod . | | 522 | .Fa mod . |
523 | .El | | 523 | .El |
524 | .Sh PROGRAMMING CONSIDERATIONS | | 524 | .Sh PROGRAMMING CONSIDERATIONS |
525 | The module subsystem is designed to be called recursively, but only within | | 525 | The module subsystem is designed to be called recursively, but only within |
526 | a single LWP. | | 526 | a single LWP. |
527 | This permits one module's | | 527 | This permits one module's |
528 | .Fn modcmd | | 528 | .Fn modcmd |
529 | routine to load or unload other modules. | | 529 | routine to load or unload other modules. |
530 | .Pp | | 530 | .Pp |
531 | Additional considerations: | | 531 | Additional considerations: |
532 | .Bl -bullet -offset indent | | 532 | .Bl -bullet -offset indent |
533 | .It | | 533 | .It |
534 | A module is not permitted to load or unload itself. | | 534 | A module is not permitted to load or unload itself. |
535 | Attempts to load or unload a module from within its own | | 535 | Attempts to load or unload a module from within its own |
536 | .Fn modcmd | | 536 | .Fn modcmd |
537 | routine will fail with | | 537 | routine will fail with |
538 | .Er EEXIST | | 538 | .Er EEXIST |
539 | or | | 539 | or |
540 | .Er EBUSY , | | 540 | .Er EBUSY , |
541 | respectively. | | 541 | respectively. |
542 | .It | | 542 | .It |
543 | Although a module can be loaded by using either | | 543 | Although a module can be loaded by using either |
544 | .Fn module_load | | 544 | .Fn module_load |
545 | or | | 545 | or |
546 | .Fn module_autoload , | | 546 | .Fn module_autoload , |
547 | it is not possible for the module's | | 547 | it is not possible for the module's |
548 | .Fn modcmd | | 548 | .Fn modcmd |
549 | routine to distinguish between the two methods. | | 549 | routine to distinguish between the two methods. |
550 | Any module which needs to ensure that it does not get auto-unloaded must | | 550 | Any module which needs to ensure that it does not get auto-unloaded must |
551 | either handle the | | 551 | either handle the |
552 | .Dv MODULE_CMD_AUTOUNLOAD | | 552 | .Dv MODULE_CMD_AUTOUNLOAD |
553 | command in its | | 553 | command in its |
554 | .Fn modcmd | | 554 | .Fn modcmd |
555 | routine, or use | | 555 | routine, or use |
556 | .Fn module_hold | | 556 | .Fn module_hold |
557 | to increment its reference count. | | 557 | to increment its reference count. |
558 | Note however that modules loaded manually with | | 558 | Note however that modules loaded manually with |
559 | .Xr modload 8 | | 559 | .Xr modload 8 |
560 | are never auto-unloaded. | | 560 | are never auto-unloaded. |
561 | .El | | 561 | .El |
562 | .Sh EXAMPLES | | 562 | .Sh EXAMPLES |
563 | A set of example modules is available in the | | 563 | A set of example modules is available in the |
564 | .Pa src/sys/modules/examples | | 564 | .Pa src/sys/modules/examples |
565 | directory hierarchy. | | 565 | directory hierarchy. |
566 | .Sh CODE REFERENCES | | 566 | .Sh CODE REFERENCES |
567 | The core of the kernel module implementation is in | | 567 | The core of the kernel module implementation is in |
568 | .Pa sys/kern/kern_module.c | | 568 | .Pa sys/kern/kern_module.c |
569 | and | | 569 | and |
570 | .Pa sys/kern/kern_module_vfs.c . | | 570 | .Pa sys/kern/kern_module_vfs.c . |
571 | .Pp | | 571 | .Pp |
572 | The routines for linking the module are in | | 572 | The routines for linking the module are in |
573 | .Pa sys/kern/subr_kobj.c . | | 573 | .Pa sys/kern/subr_kobj.c . |
574 | .Pp | | 574 | .Pp |
575 | The routines for reading a module from the file system are in | | 575 | The routines for reading a module from the file system are in |
576 | .Pa sys/kern/subr_kobj_vfs.c . | | 576 | .Pa sys/kern/subr_kobj_vfs.c . |
577 | .Pp | | 577 | .Pp |
578 | The header file | | 578 | The header file |
579 | .In sys/sys/module.h | | 579 | .In sys/sys/module.h |
580 | describes the public interface. | | 580 | describes the public interface. |
581 | .Pp | | 581 | .Pp |
582 | In addition, each architecture is expected to provide | | 582 | In addition, each architecture is expected to provide |
583 | .Fn kobj_machdep , | | 583 | .Fn kobj_machdep , |
584 | .Fn kobj_reloc , | | 584 | .Fn kobj_reloc , |
585 | and | | 585 | and |
586 | .Fn module_init_md . | | 586 | .Fn module_init_md . |
587 | .Fn kobj_machdep | | 587 | .Fn kobj_machdep |
588 | is for any machine dependent actions, such as flushing caches, that are | | 588 | is for any machine dependent actions, such as flushing caches, that are |
589 | needed when a module is loaded or unloaded. | | 589 | needed when a module is loaded or unloaded. |
590 | .Fn kobj_reloc | | 590 | .Fn kobj_reloc |
591 | deals with resolution of relocatable symbols. | | 591 | deals with resolution of relocatable symbols. |
592 | .Fn module_init_md | | 592 | .Fn module_init_md |
593 | is for finding modules passed in by the boot loader. | | 593 | is for finding modules passed in by the boot loader. |
594 | .Sh SEE ALSO | | 594 | .Sh SEE ALSO |
595 | .Xr modctl 2 , | | 595 | .Xr modctl 2 , |
596 | .Xr module 7 , | | 596 | .Xr module 7 , |
597 | .Xr specificdata 9 , | | 597 | .Xr specificdata 9 , |
598 | .Xr intro 9lua | | 598 | .Xr intro 9lua |
599 | .Sh HISTORY | | 599 | .Sh HISTORY |
600 | The kernel module subsystem first appeared in | | 600 | The kernel module subsystem first appeared in |
601 | .Nx 5.0 . | | 601 | .Nx 5.0 . |
602 | It replaces the | | 602 | It replaces the |
603 | .Dq LKM | | 603 | .Dq LKM |
604 | subsystem from earlier releases. | | 604 | subsystem from earlier releases. |
605 | .Sh AUTHORS | | 605 | .Sh AUTHORS |
606 | .An -nosplit | | 606 | .An -nosplit |
607 | The | | 607 | The |
608 | .Nm | | 608 | .Nm |
609 | system was written by | | 609 | system was written by |
610 | .An Andrew Doran Aq Mt ad@NetBSD.org . | | 610 | .An Andrew Doran Aq Mt ad@NetBSD.org . |
611 | This manual page was written by | | 611 | This manual page was written by |
612 | .An Paul Goyette Aq Mt pgoyette@NetBSD.org . | | 612 | .An Paul Goyette Aq Mt pgoyette@NetBSD.org . |