Cleanup some textproc/igor warnings where possible:
- wrap long lines - spelling Event: vBSDcon FreeBSD Hackathon
This commit is contained in:
parent
9e65c2492f
commit
e6a8ba37d0
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=53376
1 changed files with 88 additions and 79 deletions
|
@ -51,17 +51,18 @@ $FreeBSD$
|
|||
<indexterm><primary>booting</primary></indexterm>
|
||||
<indexterm><primary>system initialization</primary></indexterm>
|
||||
<para>This chapter is an overview of the boot and system
|
||||
initialization processes, starting from the <acronym>BIOS</acronym> (firmware)
|
||||
<acronym>POST</acronym>, to the first user process creation. Since the initial
|
||||
initialization processes, starting from the
|
||||
<acronym>BIOS</acronym> (firmware) <acronym>POST</acronym>, to
|
||||
the first user process creation. Since the initial
|
||||
steps of system startup are very architecture dependent, the
|
||||
IA-32 architecture is used as an example.</para>
|
||||
|
||||
<para>The &os; boot process can be surprisingly complex. After
|
||||
control is passed from the <acronym>BIOS</acronym>, a considerable amount of
|
||||
low-level configuration must be done before the kernel can be
|
||||
loaded and executed. This setup must be done in a simple and
|
||||
flexible manner, allowing the user a great deal of customization
|
||||
possibilities.</para>
|
||||
control is passed from the <acronym>BIOS</acronym>, a
|
||||
considerable amount of low-level configuration must be done
|
||||
before the kernel can be loaded and executed. This setup must
|
||||
be done in a simple and flexible manner, allowing the user a
|
||||
great deal of customization possibilities.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="boot-overview">
|
||||
|
@ -116,10 +117,10 @@ F5 Disk 2</screen></entry>
|
|||
|
||||
<row>
|
||||
<entry><literal>boot2</literal>
|
||||
<footnote><para>This prompt will appear if the user
|
||||
presses a key just after selecting an OS to boot
|
||||
at the <literal>boot0</literal>
|
||||
stage.</para></footnote></entry>
|
||||
<footnote><para>This prompt will appear if the user
|
||||
presses a key just after selecting an OS to boot at
|
||||
the <literal>boot0</literal>
|
||||
stage.</para></footnote></entry>
|
||||
<entry><screen>>>FreeBSD/i386 BOOT
|
||||
Default: 1:ad(1,a)/boot/loader
|
||||
boot:</screen></entry>
|
||||
|
@ -241,12 +242,12 @@ FreeBSD clang version 3.3 (tags/RELEASE_33/final 183502) 20130610</screen></entr
|
|||
<quote>partitions</quote>
|
||||
<footnote>
|
||||
<para><link
|
||||
xlink:href="http://en.wikipedia.org/wiki/Master_boot_record"></link></para></footnote>.
|
||||
xlink:href="http://en.wikipedia.org/wiki/Master_boot_record"></link></para></footnote>.
|
||||
<filename>boot0</filename> resides in the filesystem as
|
||||
<filename>/boot/boot0</filename>. It is a small 512-byte file,
|
||||
and it is exactly what &os;'s installation procedure wrote to
|
||||
the hard disk's <acronym>MBR</acronym> if you chose the <quote>bootmanager</quote>
|
||||
option at installation time. Indeed,
|
||||
the hard disk's <acronym>MBR</acronym> if you chose the
|
||||
<quote>bootmanager</quote> option at installation time. Indeed,
|
||||
<filename>boot0</filename> <emphasis>is</emphasis> the
|
||||
<acronym>MBR</acronym>.</para>
|
||||
|
||||
|
@ -895,9 +896,9 @@ read_key:
|
|||
Register <literal>%bx</literal> holds the memory address where
|
||||
the <acronym>MBR</acronym> will be loaded. The instruction
|
||||
pushing <literal>%cs</literal> onto the stack is very
|
||||
interesting. In this context, it accomplishes nothing. However, as
|
||||
we will see shortly, <filename>boot2</filename>, in conjunction
|
||||
with the <acronym>BTX</acronym> server, also uses
|
||||
interesting. In this context, it accomplishes nothing.
|
||||
However, as we will see shortly, <filename>boot2</filename>, in
|
||||
conjunction with the <acronym>BTX</acronym> server, also uses
|
||||
<literal>xread.1</literal>. This mechanism will be discussed in
|
||||
the next section.</para>
|
||||
|
||||
|
@ -1000,9 +1001,10 @@ main.3:
|
|||
<filename>boot1</filename> are 512 bytes each, so they fit
|
||||
<emphasis>exactly</emphasis> in one disk sector.
|
||||
<filename>boot2</filename> is much bigger, holding both
|
||||
the <acronym>BTX</acronym> server and the <filename>boot2</filename> client.
|
||||
Finally, a file called simply <filename>boot</filename> is 512
|
||||
bytes larger than <filename>boot2</filename>. This file is a
|
||||
the <acronym>BTX</acronym> server and the
|
||||
<filename>boot2</filename> client. Finally, a file called
|
||||
simply <filename>boot</filename> is 512 bytes larger than
|
||||
<filename>boot2</filename>. This file is a
|
||||
concatenation of <filename>boot1</filename> and
|
||||
<filename>boot2</filename>. As already noted,
|
||||
<filename>boot0</filename> is the file written to the absolute
|
||||
|
@ -1065,7 +1067,7 @@ main.3:
|
|||
<para>This is necessary for legacy reasons. Interested
|
||||
readers should see <link
|
||||
xlink:href="http://en.wikipedia.org/wiki/A20_line"/>.</para></footnote>
|
||||
and concludes with a jump to the starting point of the
|
||||
and concludes with a jump to the starting point of the
|
||||
<acronym>BTX</acronym> server:</para>
|
||||
|
||||
<figure xml:id="boot-boot1-seta20">
|
||||
|
@ -1252,8 +1254,7 @@ seta20.3:
|
|||
<figure xml:id="boot-boot1-make-boot2h">
|
||||
<title><filename>sys/boot/i386/boot2/boot2.h</filename></title>
|
||||
|
||||
<programlisting>
|
||||
#define XREADORG 0x725</programlisting>
|
||||
<programlisting>#define XREADORG 0x725</programlisting>
|
||||
</figure>
|
||||
|
||||
<para>Recall that <filename>boot1</filename> was relocated (i.e.,
|
||||
|
@ -1332,7 +1333,7 @@ seta20.3:
|
|||
<acronym>BTX</acronym> server. This file, which takes
|
||||
exactly 16 sectors, or 8192 bytes, is what is
|
||||
actually written to the beginning of the &os; slice
|
||||
during instalation. Let us now proceed to study the
|
||||
during installation. Let us now proceed to study the
|
||||
<acronym>BTX</acronym> server program.</para>
|
||||
|
||||
<para>The <acronym>BTX</acronym> server prepares a simple
|
||||
|
@ -1461,14 +1462,14 @@ init: cli # Disable interrupts
|
|||
|
||||
<para>Recall that <filename>boot1</filename> was originally loaded
|
||||
to address <literal>0x7c00</literal>, so, with this memory
|
||||
initialization, that copy effectively dissapeared. However,
|
||||
initialization, that copy effectively disappeared. However,
|
||||
also recall that <filename>boot1</filename> was relocated to
|
||||
<literal>0x700</literal>, so <emphasis>that</emphasis> copy is
|
||||
still in memory, and the <acronym>BTX</acronym> server will make
|
||||
use of it.</para>
|
||||
|
||||
<para>Next, the real-mode <acronym>IVT</acronym> (Interrupt Vector
|
||||
Table is updated. The <acronym>IVT</acronym> is an array of
|
||||
Table is updated. The <acronym>IVT</acronym> is an array of
|
||||
segment/offset pairs for exception and interrupt handlers. The
|
||||
<acronym>BIOS</acronym> normally maps hardware interrupts to
|
||||
interrupt vectors <literal>0x8</literal> to
|
||||
|
@ -1599,18 +1600,19 @@ init.4: movb $_ESP0H,TSS_ESP0+1(%di) # Set ESP0
|
|||
</figure>
|
||||
|
||||
<para>Note that a value is given for the Privilege Level 0 stack
|
||||
pointer and stack segment in the <acronym>TSS</acronym>. This is needed because,
|
||||
if an interrupt or exception is received while executing
|
||||
<filename>boot2</filename> in Privilege Level 3, a change to
|
||||
Privilege Level 0 is automatically performed by the processor,
|
||||
so a new working stack is needed. Finally, the I/O Map Base
|
||||
Address field of the <acronym>TSS</acronym> is given a value, which is a 16-bit
|
||||
offset from the beginning of the <acronym>TSS</acronym> to the I/O Permission
|
||||
Bitmap and the Interrupt Redirection Bitmap.</para>
|
||||
pointer and stack segment in the <acronym>TSS</acronym>. This
|
||||
is needed because, if an interrupt or exception is received
|
||||
while executing <filename>boot2</filename> in Privilege Level 3,
|
||||
a change to Privilege Level 0 is automatically performed by the
|
||||
processor, so a new working stack is needed. Finally, the I/O
|
||||
Map Base Address field of the <acronym>TSS</acronym> is given a
|
||||
value, which is a 16-bit offset from the beginning of the
|
||||
<acronym>TSS</acronym> to the I/O Permission Bitmap and the
|
||||
Interrupt Redirection Bitmap.</para>
|
||||
|
||||
<para>After the <acronym>IDT</acronym> and <acronym>TSS</acronym> are created, the processor is ready to
|
||||
switch to protected mode. This is done in the next
|
||||
block:</para>
|
||||
<para>After the <acronym>IDT</acronym> and <acronym>TSS</acronym>
|
||||
are created, the processor is ready to switch to protected mode.
|
||||
This is done in the next block:</para>
|
||||
|
||||
<figure xml:id="btx-prot">
|
||||
<title><filename>sys/boot/i386/btx/btx/btx.S</filename></title>
|
||||
|
@ -1633,20 +1635,22 @@ init.8: xorl %ecx,%ecx # Zero
|
|||
</figure>
|
||||
|
||||
<para>First, a call is made to <literal>setpic</literal> to
|
||||
program the 8259A <acronym>PIC</acronym> (Programmable Interrupt Controller).
|
||||
This chip is connected to multiple hardware interrupt sources.
|
||||
Upon receiving an interrupt from a device, it
|
||||
signals the processor with the appropriate interrupt vector.
|
||||
program the 8259A <acronym>PIC</acronym> (Programmable Interrupt
|
||||
Controller). This chip is connected to multiple hardware
|
||||
interrupt sources. Upon receiving an interrupt from a device,
|
||||
it signals the processor with the appropriate interrupt vector.
|
||||
This can be customized so that specific interrupts are
|
||||
associated with specific interrupt vectors, as explained before.
|
||||
Next, the <acronym>IDTR</acronym> (Interrupt Descriptor Table Register) and
|
||||
<acronym>GDTR</acronym> (Global Descriptor Table Register) are loaded with the
|
||||
instructions <literal>lidt</literal> and <literal>lgdt</literal>, respectively. These registers are
|
||||
loaded with the base address and limit address for the <acronym>IDT</acronym> and
|
||||
<acronym>GDT</acronym>. The following three instructions set the Protection Enable
|
||||
(PE) bit of the <literal>%cr0</literal> register. This
|
||||
effectively switches the processor to
|
||||
32-bit protected mode. Next, a long jump is made to
|
||||
Next, the <acronym>IDTR</acronym> (Interrupt Descriptor Table
|
||||
Register) and <acronym>GDTR</acronym> (Global Descriptor Table
|
||||
Register) are loaded with the instructions
|
||||
<literal>lidt</literal> and <literal>lgdt</literal>,
|
||||
respectively. These registers are loaded with the base address
|
||||
and limit address for the <acronym>IDT</acronym> and
|
||||
<acronym>GDT</acronym>. The following three instructions set
|
||||
the Protection Enable (PE) bit of the <literal>%cr0</literal>
|
||||
register. This effectively switches the processor to 32-bit
|
||||
protected mode. Next, a long jump is made to
|
||||
<literal>init.8</literal> using segment selector SEL_SCODE,
|
||||
which selects the Supervisor Code Segment. The processor is
|
||||
effectively executing in CPL 0, the most privileged level, after
|
||||
|
@ -1656,10 +1660,10 @@ init.8: xorl %ecx,%ecx # Zero
|
|||
privilege level of <literal>0</literal>.</para>
|
||||
|
||||
<para>Our last code block is responsible for loading the
|
||||
<acronym>TR</acronym> (Task Register) with the segment selector for the <acronym>TSS</acronym> we created
|
||||
earlier, and setting the User Mode environment before passing
|
||||
execution control to the <filename>boot2</filename>
|
||||
client.</para>
|
||||
<acronym>TR</acronym> (Task Register) with the segment selector
|
||||
for the <acronym>TSS</acronym> we created earlier, and setting
|
||||
the User Mode environment before passing execution control to
|
||||
the <filename>boot2</filename> client.</para>
|
||||
|
||||
<figure xml:id="btx-end">
|
||||
<title><filename>sys/boot/i386/btx/btx/btx.S</filename></title>
|
||||
|
@ -1698,17 +1702,18 @@ init.9: push $0x0 # general
|
|||
|
||||
<para>Note that the client's environment include a stack segment
|
||||
selector and stack pointer (registers <literal>%ss</literal> and
|
||||
<literal>%esp</literal>). Indeed, once the <acronym>TR</acronym> is loaded with
|
||||
the appropriate stack segment selector (instruction
|
||||
<literal>ltr</literal>), the stack pointer is calculated and
|
||||
pushed onto the stack along with the stack's segment selector.
|
||||
Next, the value <literal>0x202</literal> is pushed onto the
|
||||
stack; it is the value that the EFLAGS will get when control is
|
||||
passed to the client. Also, the User Mode code segment selector
|
||||
and the client's entry point are pushed. Recall that this entry
|
||||
point is patched in the <acronym>BTX</acronym> header at link time. Finally,
|
||||
segment selectors (stored in register <literal>%ecx</literal>)
|
||||
for the segment registers
|
||||
<literal>%esp</literal>). Indeed, once the
|
||||
<acronym>TR</acronym> is loaded with the appropriate stack
|
||||
segment selector (instruction <literal>ltr</literal>), the stack
|
||||
pointer is calculated and pushed onto the stack along with the
|
||||
stack's segment selector. Next, the value
|
||||
<literal>0x202</literal> is pushed onto the stack; it is the
|
||||
value that the EFLAGS will get when control is passed to the
|
||||
client. Also, the User Mode code segment selector and the
|
||||
client's entry point are pushed. Recall that this entry
|
||||
point is patched in the <acronym>BTX</acronym> header at link
|
||||
time. Finally, segment selectors (stored in register
|
||||
<literal>%ecx</literal>) for the segment registers
|
||||
<literal>%gs, %fs, %ds and %es</literal> are pushed onto the
|
||||
stack, along with the value at <literal>%edx</literal>
|
||||
(<literal>0xa000</literal>). Keep in mind the various values
|
||||
|
@ -1726,12 +1731,12 @@ init.9: push $0x0 # general
|
|||
various segment registers. Five values still remain on the
|
||||
stack. They are popped when the <literal>iret</literal>
|
||||
instruction is executed. This instruction first pops
|
||||
the value that was pushed from the <acronym>BTX</acronym> header. This value is a
|
||||
pointer to <filename>boot2</filename>'s entry point. It is
|
||||
placed in the register <literal>%eip</literal>, the instruction
|
||||
pointer register. Next, the segment selector for the User
|
||||
Code Segment is popped and copied to register
|
||||
<literal>%cs</literal>. Remember that
|
||||
the value that was pushed from the <acronym>BTX</acronym>
|
||||
header. This value is a pointer to <filename>boot2</filename>'s
|
||||
entry point. It is placed in the register
|
||||
<literal>%eip</literal>, the instruction pointer register.
|
||||
Next, the segment selector for the User Code Segment is popped
|
||||
and copied to register <literal>%cs</literal>. Remember that
|
||||
this segment's privilege level is 3, the least privileged
|
||||
level. This means that we must provide values for the stack of
|
||||
this privilege level. This is why the processor, besides
|
||||
|
@ -1760,9 +1765,10 @@ init.9: push $0x0 # general
|
|||
loader, and then further to the kernel. Some nodes of this
|
||||
structures are set by <literal>boot2</literal>, the rest by the
|
||||
loader. This structure, among other information, contains the
|
||||
kernel filename, <acronym>BIOS</acronym> harddisk geometry, <acronym>BIOS</acronym> drive number for
|
||||
boot device, physical memory available, <literal>envp</literal>
|
||||
pointer etc. The definition for it is:</para>
|
||||
kernel filename, <acronym>BIOS</acronym> harddisk geometry,
|
||||
<acronym>BIOS</acronym> drive number for boot device, physical
|
||||
memory available, <literal>envp</literal> pointer etc. The
|
||||
definition for it is:</para>
|
||||
|
||||
<programlisting><filename>/usr/include/machine/bootinfo.h:</filename>
|
||||
struct bootinfo {
|
||||
|
@ -1795,8 +1801,10 @@ struct bootinfo {
|
|||
<function>ino_t lookup(char *filename)</function> and
|
||||
<function>int xfsread(ino_t inode, void *buf, size_t
|
||||
nbyte)</function> are used to read the content of a file into
|
||||
memory. <filename>/boot/loader</filename> is an <acronym>ELF</acronym> binary, but
|
||||
where the <acronym>ELF</acronym> header is prepended with <filename>a.out</filename>'s <literal>struct
|
||||
memory. <filename>/boot/loader</filename> is an
|
||||
<acronym>ELF</acronym> binary, but where the
|
||||
<acronym>ELF</acronym> header is prepended with
|
||||
<filename>a.out</filename>'s <literal>struct
|
||||
exec</literal> structure. <function>load()</function> scans the
|
||||
loader's ELF header, loading the content of
|
||||
<filename>/boot/loader</filename> into memory, and passing the
|
||||
|
@ -1811,10 +1819,11 @@ struct bootinfo {
|
|||
<sect1 xml:id="boot-loader">
|
||||
<title><application>loader</application> Stage</title>
|
||||
|
||||
<para><application>loader</application> is a <acronym>BTX</acronym> client as well.
|
||||
I will not describe it here in detail, there is a comprehensive
|
||||
manpage written by Mike Smith, &man.loader.8;. The underlying
|
||||
mechanisms and <acronym>BTX</acronym> were discussed above.</para>
|
||||
<para><application>loader</application> is a
|
||||
<acronym>BTX</acronym> client as well. I will not describe it
|
||||
here in detail, there is a comprehensive man page written by
|
||||
Mike Smith, &man.loader.8;. The underlying mechanisms and
|
||||
<acronym>BTX</acronym> were discussed above.</para>
|
||||
|
||||
<para>The main task for the loader is to boot the kernel. When
|
||||
the kernel is loaded into memory, it is being called by the
|
||||
|
|
Loading…
Reference in a new issue