Source string Read only

(itstool) path: sect1/programlisting
222/2220
Context English State
<literal>boot2</literal> defines an important structure, <literal>struct bootinfo</literal>. This structure is initialized by <literal>boot2</literal> and passed to the 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:
<filename>/usr/include/machine/bootinfo.h:</filename>
struct bootinfo {
u_int32_t bi_version;
u_int32_t bi_kernelname; /* represents a char * */
u_int32_t bi_nfs_diskless; /* struct nfs_diskless * */
/* End of fields that are always present. */
#define bi_endcommon bi_n_bios_used
u_int32_t bi_n_bios_used;
u_int32_t bi_bios_geom[N_BIOS_GEOM];
u_int32_t bi_size;
u_int8_t bi_memsizes_valid;
u_int8_t bi_bios_dev; /* bootdev BIOS unit number */
u_int8_t bi_pad[2];
u_int32_t bi_basemem;
u_int32_t bi_extmem;
u_int32_t bi_symtab; /* struct symtab * */
u_int32_t bi_esymtab; /* struct symtab * */
/* Items below only from advanced bootloader */
u_int32_t bi_kernend; /* end of kernel space */
u_int32_t bi_envp; /* environment */
u_int32_t bi_modulep; /* preloaded modules */
};
<literal>boot2</literal> enters into an infinite loop waiting for user input, then calls <function>load()</function>. If the user does not press anything, the loop breaks by a timeout, so <function>load()</function> will load the default file (<filename>/boot/loader</filename>). Functions <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 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 execution to the loader's entry:
<filename>sys/boot/i386/boot2/boot2.c:</filename>
__exec((caddr_t)addr, RB_BOOTINFO | (opts &amp; RBX_MASK),
MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&amp;bootinfo));
<application>loader</application> Stage
<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, <citerefentry><refentrytitle>loader</refentrytitle><manvolnum>8</manvolnum></citerefentry>. The underlying mechanisms and <acronym>BTX</acronym> were discussed above.
The main task for the loader is to boot the kernel. When the kernel is loaded into memory, it is being called by the loader:
<filename>sys/boot/common/boot.c:</filename>
/* Call the exec handler from the loader matching the kernel */
module_formats[km-&gt;m_loader]-&gt;l_exec(km);
Kernel Initialization
Let us take a look at the command that links the kernel. This will help identify the exact location where the loader passes execution to the kernel. This location is the kernel's actual entry point.
<filename>sys/conf/Makefile.i386:</filename>
ld -elf -Bdynamic -T /usr/src/sys/conf/ldscript.i386 -export-dynamic \
-dynamic-linker /red/herring -o kernel -X locore.o \
&lt;lots of kernel .o files&gt;
<primary>ELF</primary>
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 <filename>sys/conf/ldscript.i386</filename> gives an idea about what <application>ld</application> options are used when compiling a kernel. Reading through the first few lines, the string
<filename>sys/conf/ldscript.i386:</filename>
ENTRY(btext)
says that a kernel's entry point is the symbol `btext'. This symbol is defined in <filename>locore.s</filename>:
<filename>sys/i386/i386/locore.s:</filename>
.text
/**********************************************************************
*
* This is where the bootblocks start us, set the ball rolling...
*
*/
NON_GPROF_ENTRY(btext)
First, the register EFLAGS is set to a predefined value of 0x00000002. Then all the segment registers are initialized:
<filename>sys/i386/i386/locore.s:</filename>
/* Don't trust what the BIOS gives for eflags. */
pushl $PSL_KERNEL
popfl

/*
* Don't trust what the BIOS gives for %fs and %gs. Trust the bootstrap
* to set %cs, %ds, %es and %ss.
*/
mov %ds, %ax
mov %ax, %fs
mov %ax, %gs
btext calls the routines <function>recover_bootinfo()</function>, <function>identify_cpu()</function>, <function>create_pagetables()</function>, which are also defined in <filename>locore.s</filename>. Here is a description of what they do:
<function>recover_bootinfo</function>
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, 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.
<function>identify_cpu</function>
This functions tries to find out what CPU it is running on, storing the value found in a variable <varname>_cpu</varname>.
<function>create_pagetables</function>
This function allocates and fills out a Page Table Directory at the top of the kernel memory area.
The next steps are enabling VME, if the CPU supports it:
testl $CPUID_VME, R(_cpu_feature)
jz 1f
movl %cr4, %eax
orl $CR4_VME, %eax
movl %eax, %cr4
Then, enabling paging:
/* Now enable paging */
movl R(_IdlePTD), %eax
movl %eax,%cr3 /* load ptd addr into mmu */
movl %cr0,%eax /* get control word */
orl $CR0_PE|CR0_PG,%eax /* enable paging */
movl %eax,%cr0 /* and let's page NOW! */
The next three lines of code are because the paging was set, so the jump is needed to continue the execution in virtualized address space:
pushl $begin /* jump to high virtualized address */
ret

/* now running relocated at KERNBASE where the system is linked to run */
begin:

Loading…

No matching activity found.

Browse all component changes

Things to check

Multiple failing checks

The translations in several languages have failing checks

Reset

Ellipsis

The string uses three dots (...) instead of an ellipsis character (…)

Reset

Glossary

English English
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect1/programlisting
Flags
no-wrap, read-only
Source string location
book.translate.xml:2108
String age
a year ago
Source string age
a year ago
Translation file
books/arch-handbook.pot, string 214