Source string Read only

(itstool) path: sect2/programlisting
445/4450
Context English State
In our case, the following declaration will occur:
static struct sysinit announce_sys_init = {
SI_SUB_COPYRIGHT,
SI_ORDER_FIRST,
(sysinit_cfunc_t)(sysinit_nfunc_t) print_caddr_t,
(void *) copyright
};

static void const *const __set_sysinit_set_sym_announce_sys_init =
&announce_sys_init;
__asm(".section .set.sysinit_set" ",\"aw\"");
__asm(".long " "announce_sys_init");
__asm(".previous");
The first <literal>__asm</literal> instruction will create an ELF section within the kernel's executable. This will happen at kernel link time. The section will have the name <literal>.set.sysinit_set</literal>. The content of this section is one 32-bit value, the address of announce_sys_init structure, and that is what the second <literal>__asm</literal> is. The third <literal>__asm</literal> instruction marks the end of a section. If a directive with the same section name occurred before, the content, i.e., the 32-bit value, will be appended to the existing section, so forming an array of 32-bit pointers.
Running <application>objdump</application> on a kernel binary, you may notice the presence of such small sections:
<prompt>%</prompt> <userinput>objdump -h /kernel</userinput>
7 .set.cons_set 00000014 c03164c0 c03164c0 002154c0 2**2
CONTENTS, ALLOC, LOAD, DATA
8 .set.kbddriver_set 00000010 c03164d4 c03164d4 002154d4 2**2
CONTENTS, ALLOC, LOAD, DATA
9 .set.scrndr_set 00000024 c03164e4 c03164e4 002154e4 2**2
CONTENTS, ALLOC, LOAD, DATA
10 .set.scterm_set 0000000c c0316508 c0316508 00215508 2**2
CONTENTS, ALLOC, LOAD, DATA
11 .set.sysctl_set 0000097c c0316514 c0316514 00215514 2**2
CONTENTS, ALLOC, LOAD, DATA
12 .set.sysinit_set 00000664 c0316e90 c0316e90 00215e90 2**2
CONTENTS, ALLOC, LOAD, DATA
This screen dump shows that the size of .set.sysinit_set section is 0x664 bytes, so <literal>0x664/sizeof(void *)</literal> sysinit objects are compiled into the kernel. The other sections such as <literal>.set.sysctl_set</literal> represent other linker sets.
By defining a variable of type <literal>struct linker_set</literal> the content of <literal>.set.sysinit_set</literal> section will be <quote>collected</quote> into that variable:
<filename>sys/kern/init_main.c:</filename>
extern struct linker_set sysinit_set; /* XXX */
The <literal>struct linker_set</literal> is defined as follows:
<filename>/usr/include/linker_set.h:</filename>
struct linker_set {
int ls_length;
void *ls_items[1]; /* really ls_length of them, trailing NULL */
};
The first node will be equal to the number of a sysinit objects, and the second node will be a NULL-terminated array of pointers to them.
Returning to the <function>mi_startup()</function> discussion, it is must be clear now, how the sysinit objects are being organized. The <function>mi_startup()</function> function sorts them and calls each. The very last object is the system scheduler:
<filename>/usr/include/sys/kernel.h:</filename>
enum sysinit_sub_id {
SI_SUB_DUMMY = 0x0000000, /* not executed; for linker*/
SI_SUB_DONE = 0x0000001, /* processed*/
SI_SUB_CONSOLE = 0x0800000, /* console*/
SI_SUB_COPYRIGHT = 0x0800001, /* first use of console*/
...
SI_SUB_RUN_SCHEDULER = 0xfffffff /* scheduler: no return*/
};
The system scheduler sysinit object is defined in the file <filename>sys/vm/vm_glue.c</filename>, and the entry point for that object is <function>scheduler()</function>. That function is actually an infinite loop, and it represents a process with PID 0, the swapper process. The proc0 structure, mentioned before, is used to describe it.
The first user process, called <emphasis>init</emphasis>, is created by the sysinit object <literal>init</literal>:
<filename>sys/kern/init_main.c:</filename>
static void
create_init(const void *udata __unused)
{
int error;
int s;

s = splhigh();
error = fork1(&amp;proc0, RFFDG | RFPROC, &amp;initproc);
if (error)
panic("cannot fork init: %d\n", error);
initproc-&gt;p_flag |= P_INMEM | P_SYSTEM;
cpu_set_fork_handler(initproc, start_init, NULL);
remrunqueue(initproc);
splx(s);
}
SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
The <function>create_init()</function> allocates a new process by calling <function>fork1()</function>, but does not mark it runnable. When this new process is scheduled for execution by the scheduler, the <function>start_init()</function> will be called. That function is defined in <filename>init_main.c</filename>. It tries to load and exec the <filename>init</filename> binary, probing <filename>/sbin/init</filename> first, then <filename>/sbin/oinit</filename>, <filename>/sbin/init.bak</filename>, and finally <filename>/stand/sysinstall</filename>:
<filename>sys/kern/init_main.c:</filename>
static char init_path[MAXPATHLEN] =
#ifdef INIT_PATH
__XSTRING(INIT_PATH);
#else
"/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall";
#endif
Locking Notes
<primary>SMP Next Generation Project</primary>
<emphasis>This chapter is maintained by the FreeBSD SMP Next Generation Project.</emphasis>
<primary>locking</primary>
<primary>multi-processing</primary>
<primary>mutexes</primary>
<primary>lockmgr</primary>
<primary>atomic operations</primary>
This document outlines the locking used in the FreeBSD kernel to permit effective multi-processing within the kernel. Locking can be achieved via several means. Data structures can be protected by mutexes or <citerefentry><refentrytitle>lockmgr</refentrytitle><manvolnum>9</manvolnum></citerefentry> locks. A few variables are protected simply by always using atomic operations to access them.
Mutexes
A mutex is simply a lock used to guarantee mutual exclusion. Specifically, a mutex may only be owned by one entity at a time. If another entity wishes to obtain a mutex that is already owned, it must wait until the mutex is released. In the FreeBSD kernel, mutexes are owned by processes.
Mutexes may be recursively acquired, but they are intended to be held for a short period of time. Specifically, one may not sleep while holding a mutex. If you need to hold a lock across a sleep, use a <citerefentry><refentrytitle>lockmgr</refentrytitle><manvolnum>9</manvolnum></citerefentry> lock.
Each mutex has several properties of interest:

Loading…

No matching activity found.

Browse all component changes

Things to check

Multiple failing checks

The translations in several languages have failing checks

Reset

Unpluralised

The string is used as plural, but not using plural forms

Reset

Glossary

English English
No related strings found in the glossary.

Source information

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