| Entendiendo el Mecanismo de Inicio (Initcall) del Kernel de Linux: Creando funciones Dinámicas de apuntadores de Llamadas a Tablas | ||
|---|---|---|
| <<< Anterior | Siguiente >>> | |
Qué me motivo a explorar este tema?
Estaba mirando a través del codigo fuente del kernel de Linux, tratando de entender los pasos exactos y trabajos de como arranca el kernel. Navegué a través del código que y encontré que parte del código simplemente no se podría deducir, o no me hizo caer en cuenta como trabajaba este código.
En init/main.c:do_basic_setup() hay una llamada a do_initcalls() la cual se define como:
static void __init do_initcalls(void)
{
initcall_t *call;
call = &__initcall_start;
do {
(*call)();
call++;
} while (call < &__initcall_end);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_tasks();
}
|
Buscando arriba y abajo __initcall_start revela que no aparece en ninguno de los archivos fuente *.c , esta solo aparece en los sripts del enlazador (*.lds) para varias arquitecturas.
[trevor]$ grep -ri __initcall_start *
System.map:c013ea68 A __initcall_start
arch/sh64/vmlinux.lds.S: __initcall_start = .;
arch/x86_64/vmlinux.lds: __initcall_start = .;
arch/ppc64/vmlinux.lds: __initcall_start = .;
arch/i386/vmlinux.lds: __initcall_start = .;
arch/alpha/vmlinux.lds.in: __initcall_start = .;
arch/sparc/vmlinux.lds: __initcall_start = .;
arch/mips/ld.script.in: __initcall_start = .;
arch/ppc/vmlinux.lds: __initcall_start = .;
arch/m68k/vmlinux.lds: __initcall_start = .;
arch/m68k/vmlinux-sun3.lds: __initcall_start = .;
arch/sparc64/vmlinux.lds: __initcall_start = .;
arch/arm/vmlinux-armo.lds.in: __initcall_start = .;
arch/arm/vmlinux-armv.lds.in: __initcall_start = .;
arch/sh/vmlinux.lds.S: __initcall_start = .;
arch/ia64/vmlinux.lds.S: __initcall_start = .;
arch/mips64/ld.script.elf64: __initcall_start = .;
arch/mips64/ld.script.elf32.S: __initcall_start = .;
arch/s390/vmlinux.lds: __initcall_start = .;
arch/s390/vmlinux-shared.lds: __initcall_start = .;
arch/parisc/vmlinux64.lds: __initcall_start = .;
arch/parisc/vmlinux.lds: __initcall_start = .;
arch/parisc/kernel/head.S: .export __initcall_start
arch/parisc/kernel/head.S:__initcall_start:
arch/parisc/kernel/head64.S: .export __initcall_start
arch/parisc/kernel/head64.S:__initcall_start:
arch/cris/cris.ld: __initcall_start = .;
arch/s390x/vmlinux.lds: __initcall_start = .;
arch/s390x/vmlinux-shared.lds: __initcall_start = .;
drivers/message/fusion/linux_compat.h:extern initcall_t __initcall_start, __initcall_end;
include/linux/init.h:extern initcall_t __initcall_start, __initcall_end;
init/main.c: call = &__initcall_start;
Binary file init/main.o matches
Binary file vmlinux matches
|
Aquí esta como se ve el script del enlazador espefico de la arquitecura PowerPC :
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* .init : { *(.init) } =0*/
.plt : { *(.plt) }
.text :
{
*(.text)
*(.fixup)
*(.got1)
__got2_start = .;
*(.got2)
__got2_end = .;
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata.*)
*(.rodata1)
}
.kstrtab : { *(.kstrtab) }
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.got.plt) *(.got)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
. = ALIGN(8);
.fixup : { *(.fixup) }
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
. = ALIGN(8);
__start___ftr_fixup = .;
__ftr_fixup : { *(__ftr_fixup) }
__stop___ftr_fixup = .;
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : {
*(.data.init);
__vtop_table_begin = .;
*(.vtop_fixup);
__vtop_table_end = .;
__ptov_table_begin = .;
*(.ptov_fixup);
__ptov_table_end = .;
}
. = ALIGN(16);
__setup_start = .;
.setup.init : { *(.setup.init) }
__setup_end = .;
__initcall_start = .;
.initcall.init : { *(.initcall.init) }
__initcall_end = .;
. = ALIGN(4096);
__init_end = .;
. = ALIGN(4096);
__pmac_begin = .;
.text.pmac : { *(.text.pmac) }
.data.pmac : { *(.data.pmac) }
. = ALIGN(4096);
__pmac_end = .;
. = ALIGN(4096);
__prep_begin = .;
.text.prep : { *(.text.prep) }
.data.prep : { *(.data.prep) }
. = ALIGN(4096);
__prep_end = .;
. = ALIGN(4096);
__chrp_begin = .;
.text.chrp : { *(.text.chrp) }
.data.chrp : { *(.data.chrp) }
. = ALIGN(4096);
__chrp_end = .;
. = ALIGN(4096);
__openfirmware_begin = .;
.text.openfirmware : { *(.text.openfirmware) }
.data.openfirmware : { *(.data.openfirmware) }
. = ALIGN(4096);
__openfirmware_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
. = ALIGN(4);
_end = . ;
PROVIDE (end = .);
}
|
| <<< Anterior | Inicio | Siguiente >>> |
| Herramientas | Información Relacionada |