Linux Kernel Architecture

(Jacob Rumans) #1
Mauerer app04.tex V1 - 09/04/2008 6:12pm Page 1236

Appendix D: System Startup


The linker places initcall sections one after the other in the correct sequence in the binary file. The order
is defined in the architecture-independentfile<include/asm-generic/vmlinux.lds.h>, as shown here:

<asm-generic/vmlinux.lds.h>
#define INITCALLS \
*(.initcall0.init) \
*(.initcall1.init) \
*(.initcall2.init) \
*(.initcall3.init) \
*(.initcall4.init) \
*(.initcall5.init) \
*(.initcallrootfs.init) \
*(.initcall6.init) \
*(.initcall7.init) \

This is how a linker file employs the specification (the linker script for Alpha processors is shown here,
but the procedure is practically the same on all other systems):

arch/alpha/kernel/vmlinux.lds.S...
.initcall.init : {
__initcall_start = .;
INITCALLS
__initcall_end = .;
}
...

The linker holds the start and end of the initcall range in the__initcall_startand__initcall_end
variables, which are visible in the kernel and whose benefits are described shortly.

The mechanism described defines only the call sequence of the different initcall
categories. The call sequence of the functions inthe individual categories is defined
implicitly by the position of the specified binary file in the link process and cannot
be modified manually from within the C code.

Because the compiler and linker do the preliminary work, the task ofdo_initcallsis not all that com-
plicated as the following glance at the kernel sources shows:

init/main.c
static void __init do_initcalls(void)
{
initcall_t *call;
int count = preempt_count();

for (call = __initcall_start; call < __initcall_end; call++) {
...
char *msg;
int result;

if (initcall_debug) {
printk("calling initcall 0x%p\n", *call);
...
Free download pdf