161 lines
4.9 KiB
Text
161 lines
4.9 KiB
Text
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$FreeBSD$
|
|
-->
|
|
|
|
<chapter id="sysinit">
|
|
<title>The Sysinit Framework</title>
|
|
|
|
<para>Sysinit is the framework for a generic call sort and dispatch
|
|
mechanism. FreeBSD currently uses it for the dynamic
|
|
initialization of the kernel. Sysinit allows FreeBSD's kernel
|
|
subsystems to be reordered, and added, removed, and replaced at
|
|
kernel link time when the kernel or one of its modules is loaded
|
|
without having to edit a statically ordered initialization routing
|
|
and recompile the kernel. This system also allows kernel modules,
|
|
currently called <firstterm>KLD's</firstterm>, to be separately
|
|
compiled, linked, and initialized at boot time and loaded even
|
|
later while the system is already running. This is accomplished
|
|
using the <quote>kernel linker</quote> and <quote>linker
|
|
sets</quote>.</para>
|
|
|
|
<sect1 id="sysinit-term">
|
|
<title>Terminology</title>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>Linker Set</term>
|
|
<listitem>
|
|
<para>A linker technique in which the linker gathers
|
|
statically declared data throughout a program's source files
|
|
into a single contiguously addressable unit of
|
|
data.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect1>
|
|
|
|
<sect1 id="sysinit-operation">
|
|
<title>Sysinit Operation</title>
|
|
|
|
<para>Sysinit relies on the ability of the linker to take static
|
|
data declared at multiple locations throughout a program's
|
|
source and group it together as a single contiguous chunk of
|
|
data. This linker technique is called a <quote>linker
|
|
set</quote>. Sysinit uses two linker sets to maintain two data
|
|
sets containing each consumer's call order, function, and a
|
|
pointer to the data to pass to that function.</para>
|
|
|
|
<para>Sysinit uses two priorities when ordering the functions for
|
|
execution. The first priority is a subsystem ID giving an
|
|
overall order Sysinit's dispatch of functions. Current predeclared
|
|
ID's are in <filename><sys/kernel.h></filename> in the enum
|
|
list <literal>sysinit_sub_id</literal>. The second priority used
|
|
is an element order within the subsystem. Current predeclared
|
|
subsystem element orders are in
|
|
<filename><sys/kernel.h></filename> in the enum list
|
|
<literal>sysinit_elem_order</literal>.</para>
|
|
|
|
<para>There are currently two uses for Sysinit. Function dispatch
|
|
at system startup and kernel module loads, and function dispatch
|
|
at system shutdown and kernel module unload.</para>
|
|
</sect1>
|
|
|
|
|
|
<sect1 id="sysinit-using">
|
|
<title>Using Sysinit</title>
|
|
|
|
<sect2>
|
|
<title>Interface</title>
|
|
|
|
<sect3>
|
|
<title>Headers</title>
|
|
|
|
<programlisting><sys/kernel.h></programlisting>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Macros</title>
|
|
|
|
<programlisting>SYSINIT(uniquifier, subsystem, order, func, ident)
|
|
SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Startup</title>
|
|
|
|
<para>The <literal>SYSINIT()</literal> macro creates the
|
|
necessary sysinit data in Sysinit's startup data set for
|
|
Sysinit to sort and dispatch a function at system startup and
|
|
module load. <literal>SYSINIT()</literal> takes a uniquifier
|
|
that Sysinit uses identify the particular function dispatch
|
|
data, the subsystem order, the subsystem element order, the
|
|
function to call, and the data to pass the function. All
|
|
functions must take a constant pointer argument.
|
|
</para>
|
|
|
|
<para>For example:</para>
|
|
|
|
<programlisting>#include <sys/kernel.h>
|
|
|
|
void foo_null(void *unused)
|
|
{
|
|
foo_doo();
|
|
}
|
|
SYSINIT(foo_null, SI_SUB_FOO, SI_ORDER_FOO, NULL);
|
|
|
|
struct foo foo_voodoo = {
|
|
FOO_VOODOO;
|
|
}
|
|
|
|
void foo_arg(void *vdata)
|
|
{
|
|
struct foo *foo = (struct foo *)vdata;
|
|
foo_data(foo);
|
|
}
|
|
SYSINIT(foo_arg, SI_SUB_FOO, SI_ORDER_FOO, foo_voodoo);
|
|
</programlisting>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Shutdown</title>
|
|
|
|
<para>The <literal>SYSUNINIT()</literal> macro behaves similarly
|
|
to the <literal>SYSINIT()</literal> macro except that it adds
|
|
the Sysinit data to Sysinit's shutdown data set.</para>
|
|
|
|
<para>For example:</para>
|
|
|
|
<programlisting>#include <sys/kernel.h>
|
|
|
|
void foo_cleanup(void *unused)
|
|
{
|
|
foo_kill();
|
|
}
|
|
SYSUNINIT(foo_cleanup, SI_SUB_FOO, SI_ORDER_FOO, NULL);
|
|
|
|
struct foo_stack foo_stack = {
|
|
FOO_STACK_VOODOO;
|
|
}
|
|
|
|
void foo_flush(void *vdata)
|
|
{
|
|
}
|
|
SYSUNINIT(foo_flush, SI_SUB_FOO, SI_ORDER_FOO, foo_stack);
|
|
</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!--
|
|
Local Variables:
|
|
mode: sgml
|
|
sgml-declaration: "../chapter.decl"
|
|
sgml-indent-data: t
|
|
sgml-omittag: nil
|
|
sgml-always-quote-attributes: t
|
|
sgml-parent-document: ("../book.sgml" "part" "chapter")
|
|
End:
|
|
-->
|