Narrow an overwide table, clarify some wording, fix header filenames in

programlistings so they consistently end with a colon, split some long
sentences in two, remove some extraneous commas and words, make a
reference to the Developers Handbook a link, and fix title capitalization.

Approved by:	gjb (mentor)
This commit is contained in:
Warren Block 2012-01-09 18:26:08 +00:00
parent 86a7a72c9d
commit ec5792c0b8
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=38165

View file

@ -16,7 +16,7 @@ $FreeBSD$
</author> <!-- devnull@uptsoft.com 12 Jun 2002 -->
</authorgroup>
</chapterinfo>
<title>Bootstrapping and kernel initialization</title>
<title>Bootstrapping and Kernel Initialization</title>
<sect1 id="boot-synopsis">
<title>Synopsis</title>
@ -62,11 +62,11 @@ $FreeBSD$
using the table that follows. Please note that the actual data
may differ from machine to machine:</para>
<informaltable frame="none" pgwide="1">
<informaltable frame="none" pgwide="0">
<tgroup cols="2">
<tbody>
<row>
<entry><para>may vary</para></entry>
<entry><para>Output (may vary)</para></entry>
<entry><para>BIOS (firmware) messages</para></entry>
</row>
@ -184,7 +184,7 @@ Timecounter "i8254" frequency 1193182 Hz</screen></para></entry>
</sect1>
<sect1 id="boot-boot0">
<title><literal>boot0</literal> stage</title>
<title><literal>boot0</literal> Stage</title>
<indexterm><primary>MBR</primary></indexterm>
<para>Take a look at the file <filename>/boot/boot0</filename>.
@ -269,7 +269,7 @@ Timecounter "i8254" frequency 1193182 Hz</screen></para></entry>
</sect1>
<sect1 id="boot-boot2">
<title><literal>boot2</literal> stage</title>
<title><literal>boot2</literal> Stage</title>
<para>You might wonder, why <literal>boot2</literal> comes after
<literal>boot0</literal>, and not boot1. Actually, there is a
@ -316,7 +316,7 @@ Timecounter "i8254" frequency 1193182 Hz</screen></para></entry>
<para>The <literal>boot2</literal> binary is created in special
way:</para>
<programlisting><filename>sys/boot/i386/boot2/Makefile</filename>
<programlisting><filename>sys/boot/i386/boot2/Makefile:</filename>
boot2: boot2.ldr boot2.bin ${BTX}/btx/btx
btxld -v -E ${ORG2} -f bin -b ${BTX}/btx/btx -l boot2.ldr \
-o boot2.ld -P 1 boot2.bin</programlisting>
@ -415,7 +415,7 @@ init.2: shr %bx # Handle this int?
boot device, physical memory available, <literal>envp</literal>
pointer etc. The definition for it is:</para>
<programlisting><filename>/usr/include/machine/bootinfo.h</filename>
<programlisting><filename>/usr/include/machine/bootinfo.h:</filename>
struct bootinfo {
u_int32_t bi_version;
u_int32_t bi_kernelname; /* represents a char * */
@ -459,7 +459,7 @@ struct bootinfo {
</sect1>
<sect1 id="boot-loader">
<title><application>loader</application> stage</title>
<title><application>loader</application> Stage</title>
<para><application>loader</application> is a BTX client as well.
I will not describe it here in detail, there is a comprehensive
@ -476,10 +476,10 @@ struct bootinfo {
</sect1>
<sect1 id="boot-kernel">
<title>Kernel initialization</title>
<title>Kernel Initialization</title>
<para>Let us take a look at the command that links the kernel. This
will help us identify the exact location where the loader passes
will help identify the exact location where the loader passes
execution to the kernel. This location is the kernel's actual entry
point.</para>
@ -489,7 +489,7 @@ ld -elf -Bdynamic -T /usr/src/sys/conf/ldscript.i386 -export-dynamic \
&lt;lots of kernel .o files&gt;</programlisting>
<indexterm><primary>ELF</primary></indexterm>
<para>A few interesting things can be seen in this line. First,
<para>A few interesting things can be seen here. First,
the kernel is an ELF dynamically linked binary, but the dynamic
linker for kernel is <filename>/red/herring</filename>, which is
definitely a bogus file. Second, taking a look at the file
@ -513,11 +513,11 @@ ENTRY(btext)</programlisting>
*/
NON_GPROF_ENTRY(btext)</programlisting>
<para>First what is done is the register EFLAGS is set to a
predefined value of 0x00000002, and then all the segment
<para>First, the register EFLAGS is set to a
predefined value of 0x00000002. Then all the segment
registers are initialized:</para>
<programlisting><filename>sys/i386/i386/locore.s</filename>
<programlisting><filename>sys/i386/i386/locore.s:</filename>
/* Don't trust what the BIOS gives for eflags. */
pushl $PSL_KERNEL
popfl
@ -546,7 +546,7 @@ NON_GPROF_ENTRY(btext)</programlisting>
<entry>This routine parses the parameters to the kernel
passed from the bootstrap. The kernel may have been
booted in 3 ways: by the loader, described above, by the
old disk boot blocks, and by the old diskless boot
old disk boot blocks, or by the old diskless boot
procedure. This function determines the booting method,
and stores the <literal>struct bootinfo</literal>
structure into the kernel memory.</entry>
@ -597,7 +597,7 @@ NON_GPROF_ENTRY(btext)</programlisting>
/* now running relocated at KERNBASE where the system is linked to run */
begin:</programlisting>
<para>The function <function>init386()</function> is called, with
<para>The function <function>init386()</function> is called with
a pointer to the first free physical page, after that
<function>mi_startup()</function>. <function>init386</function>
is an architecture dependent initialization function, and
@ -618,11 +618,11 @@ begin:</programlisting>
<para><function>init386()</function> is defined in
<filename>sys/i386/i386/machdep.c</filename> and performs
low-level initialization, specific to the i386 chip. The
low-level initialization specific to the i386 chip. The
switch to protected mode was performed by the loader. The
loader has created the very first task, in which the kernel
continues to operate. Before running straight away to the
code, I will enumerate the tasks the processor must complete
continues to operate. Before looking at the
code, consider the tasks the processor must complete
to initialize protected mode execution:</para>
<itemizedlist>
@ -662,9 +662,9 @@ begin:</programlisting>
</itemizedlist>
<indexterm><primary>parameters</primary></indexterm>
<para>What <function>init386()</function> first does is
initialize the tunable parameters passed from bootstrap. This
is done by setting the environment pointer (envp) and calling
<para><function>init386()</function>
initializes the tunable parameters passed from bootstrap
by setting the environment pointer (envp) and calling
<function>init_param1()</function>. The envp pointer has been
passed from loader in the <literal>bootinfo</literal>
structure:</para>
@ -682,19 +682,19 @@ begin:</programlisting>
<function>init_param2()</function>, that are called from
<function>init386()</function>:</para>
<programlisting><filename>sys/kern/subr_param.c</filename>
<programlisting><filename>sys/kern/subr_param.c:</filename>
hz = HZ;
TUNABLE_INT_FETCH("kern.hz", &amp;hz);</programlisting>
<para>TUNABLE_&lt;typename&gt;_FETCH is used to fetch the value
from the environment:</para>
<programlisting><filename>/usr/src/sys/sys/kernel.h</filename>
<programlisting><filename>/usr/src/sys/sys/kernel.h:</filename>
#define TUNABLE_INT_FETCH(path, var) getenv_int((path), (var))
</programlisting>
<para>Sysctl <literal>kern.hz</literal> is the system clock tick. Along with
this, the following sysctls are set by
<para>Sysctl <literal>kern.hz</literal> is the system clock tick.
Additionally, these sysctls are set by
<function>init_param1()</function>: <literal>kern.maxswzone,
kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.maxdsiz, kern.dflssiz,
kern.maxssiz, kern.sgrowsiz</literal>.</para>
@ -746,7 +746,7 @@ union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */
<indexterm><primary>Interrupt Descriptor Table (IDT)</primary></indexterm>
<para>The next step is to initialize the Interrupt Descriptor
Table (IDT). This table is to be referenced by the processor
Table (IDT). This table is referenced by the processor
when a software or hardware interrupt occurs. For example, to
make a system call, user application issues the <literal>INT
0x80</literal> instruction. This is a software interrupt, so
@ -797,7 +797,7 @@ struct gate_descriptor *idt = &amp;idt0[0]; /* interrupt descriptor table */
LDT, they are the system call gates and the user code and data
selectors:</para>
<programlisting><filename>/usr/include/machine/segments.h</filename>
<programlisting><filename>/usr/include/machine/segments.h:</filename>
#define LSYS5CALLS_SEL 0 /* forced by intel BCS */
#define LSYS5SIGR_SEL 1
#define L43BSDCALLS_SEL 2 /* notyet */
@ -844,7 +844,9 @@ struct gate_descriptor *idt = &amp;idt0[0]; /* interrupt descriptor table */
}</programlisting>
<para>Although the sysinit framework is described in the
Developers' Handbook, I will discuss the internals of it.</para>
<ulink
url="&url.doc.langbase;/books/developers-handbook">Developers'
Handbook</ulink>, I will discuss the internals of it.</para>
<indexterm><primary>sysinit objects</primary></indexterm>
<para>Every system initialization object (sysinit object) is
@ -885,7 +887,7 @@ SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)</p
<literal>MAKE_SET()</literal>, and that macro is the point where
the all sysinit magic is hidden:</para>
<programlisting><filename>/usr/include/linker_set.h</filename>
<programlisting><filename>/usr/include/linker_set.h:</filename>
#define MAKE_SET(set, sym) \
static void const * const __set_##set##_sym_##sym = &amp;sym; \
__asm(".section .set." #set ",\"aw\""); \