versiones kernels estructura descargar compilar como linux-kernel embedded ubifs

linux kernel - kernels - ¿Cómo determina Linux el orden de las llamadas de inicio de módulo?



linux y sus versiones (3)

@Tim Bird ya lo ha respondido. Me gustaría mostrar cómo cambiar el orden de un módulo:

pure_initcall(fn) --> Loaded first core_initcall(fn) core_initcall_sync(fn) postcore_initcall(fn) postcore_initcall_sync(fn) arch_initcall(fn) arch_initcall_sync(fn) subsys_initcall(fn) subsys_initcall_sync(fn) fs_initcall(fn) fs_initcall_sync(fn) rootfs_initcall(fn) device_initcall(fn) device_initcall_sync(fn) late_initcall(fn) late_initcall_sync(fn) --> Loaded last Usage - Replace fn by the module init function pointer, example for i2c core driver: ....... postcore_initcall(i2c_init); // To delay i2c core loading use subsys_initcall(i2c_init) module_exit(i2c_exit); .......

Tengo un dispositivo con almacenamiento flash SPI. Me gustaría usar un sistema de archivos UBIFS en ese dispositivo flash como mis rootfs. El problema al que me estoy enfrentando es que el módulo UBI se inicializa antes de que el módulo SPI se inicialice. Debido a esto, cuando se carga UBI, no se puede adjuntar al dispositivo UBI que le dije (a través de la línea de comandos del kernel), por lo que no hay rootfs. La salida de la consola a continuación ilustra esto.

He estado buceando en la fuente lo suficiente para ver que init/main.c tiene una función do_initcalls() que simplemente llama a una lista de punteros de función. Esos punteros de función apuntan a todas las funciones module_init() de los módulos que están incorporados en el kernel. Esos punteros de función se colocan en una sección especial en el binario del núcleo, por lo que este orden se elige en tiempo de compilación. Sin embargo, todavía no he descubierto cómo se determina esa orden.

[ 0.482500] UBI error: ubi_init: UBI error: cannot initialize UBI, error -19 [ 0.492500] atmel_spi atmel_spi.0: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers [ 0.500000] atmel_spi atmel_spi.0: Atmel SPI Controller at 0xf0000000 (irq 13) [ 0.507500] m25p80 spi0.1: mx25l25635e (32768 Kbytes) [ 0.512500] Creating 7 MTD partitions on "jedec_flash": [ 0.520000] 0x000000000000-0x000000020000 : "loader" [ 0.527500] 0x000000020000-0x000000060000 : "u-boot" [ 0.537500] 0x000000060000-0x000000080000 : "u-boot-env" [ 0.547500] 0x000000080000-0x000000280000 : "kernel0" [ 0.557500] 0x000000280000-0x000000480000 : "kernel1" [ 0.567500] 0x000000480000-0x000001240000 : "fs" [ 0.575000] 0x000001240000-0x000002000000 : "play" [ 0.590000] AT91SAM9 Watchdog enabled (heartbeat=15 sec, nowayout=0) [ 0.607500] TCP cubic registered [ 0.615000] VFS: Cannot open root device "ubi0:root0" or unknown-block(0,0) [ 0.622500] Please append a correct "root=" boot option; here are the available partitions: [ 0.630000] 1f00 128 mtdblock0 (driver?) [ 0.635000] 1f01 256 mtdblock1 (driver?) [ 0.640000] 1f02 128 mtdblock2 (driver?) [ 0.645000] 1f03 2048 mtdblock3 (driver?) [ 0.650000] 1f04 2048 mtdblock4 (driver?) [ 0.655000] 1f05 14080 mtdblock5 (driver?) [ 0.660000] 1f06 14080 mtdblock6 (driver?) [ 0.665000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)


Las rutinas de inicio para un módulo que es inicializado por el núcleo (cuando están vinculadas estáticamente al núcleo) están envueltas en una macro initcall () que indica cuándo deben ejecutarse en la secuencia de inicio.

Consulte el archivo de inclusión: include / linux / init.h para obtener una lista de las macros y su orden.

El orden especificado allí es:

  • early_initcall
  • pure_initcall
  • core_initcall
  • postcore_initcall
  • arch_initcall
  • subsys_initcall
  • fs_initcall
  • rootfs_initcall
  • device_initcall
  • late_initcall

La mayoría de estos tienen una "fase initcall_sync (), que se usa para esperar a que se completen todas las rutinas de inicialización del módulo dentro de esa fase. Las macros se usan para construir una tabla de punteros de función para cada fase, que se llaman en secuencia por do_initcalls() .

Si se usa "module_init ()" para ajustar la función de inicialización, entonces, por defecto, initcall () coloca la llamada en la fase de inicialización del "dispositivo". Dentro de esa fase, los artículos se ordenan por orden de enlace. Esto significa que la tabla se crea por el orden de las funciones según las encuentra el vinculador.

Es posible que pueda mover una inicialización a una fase anterior, cambiando la macro initcall que encierra la función de inicialización de los módulos, pero tenga cuidado porque existen dependencias de orden entre los distintos módulos. Otro método para cambiar el orden de inicialización (dentro de una fase) sería ajustar el orden de enlace para el módulo en el kernel.


Podría estar equivocado, así que por favor verifique si esto es correcto.
Intente compilar todos los controladores que necesita como módulos (M) y coloque los módulos que se van a cargar en / etc / modules, en el orden correcto, esto podría resolver su problema. Solo para ser precisos, ya que está haciendo esto antes de montar sus rootfs, el paso anterior se debe realizar en el disco de inicio. (Tengo un escenario similar y necesito cargar algunos módulos en el orden correcto, para poder descifrar un fs)

Espero que esto ayude
Ciao Ciao
Sergio