¿Qué significa __init en el código del kernel de Linux?

4 minutos de lectura

avatar de usuario
Jeegar Patel

En el código fuente del kernel de Linux encontré esta función:

static int __init clk_disable_unused(void) 
{
   // some code
}

Aquí no puedo entender lo que hace __init medio.

include/linux/init.h

/* These macros are used to mark some functions or 
 * initialized data (doesn't apply to uninitialized data)
 * as `initialization' functions. The kernel can take this
 * as hint that the function is used only during the initialization
 * phase and free up used memory resources after
 *
 * Usage:
 * For functions:
 * 
 * You should add __init immediately before the function name, like:
 *
 * static void __init initme(int x, int y)
 * {
 *    extern int z; z = x * y;
 * }
 *
 * If the function has a prototype somewhere, you can also add
 * __init between closing brace of the prototype and semicolon:
 *
 * extern int initialize_foobar_device(int, int, int) __init;
 *
 * For initialized data:
 * You should insert __initdata between the variable name and equal
 * sign followed by value, e.g.:
 *
 * static int init_variable __initdata = 0;
 * static const char linux_logo[] __initconst = { 0x32, 0x36, ... };
 *
 * Don't forget to initialize data not at file scope, i.e. within a function,
 * as gcc otherwise puts the data into the bss section and not into the init
 * section.
 * 
 * Also note, that this data cannot be "const".
 */

/* These are for everybody (although not all archs will actually
   discard it in modules) */
#define __init      __section(.init.text) __cold notrace
#define __initdata  __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata  __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)

avatar de usuario
sashoalm

Estas son solo macros para ubicar algunas partes del código de Linux en áreas especiales en el binario de ejecución final.
__initpor ejemplo (o mejor el __attribute__ ((__section__
(".init.text")))
esta macro se expande a) indica al compilador que marque esta función de una manera especial. Al final, el enlazador recopila todas las funciones con esta marca al final (o al principio) del archivo binario.

Cuando se inicia el kernel, este código se ejecuta solo una vez (inicialización). Después de ejecutarse, el kernel puede liberar esta memoria para reutilizarla y verá el mensaje del kernel:

Liberando la memoria del kernel no utilizada: 108k liberados

Para usar esta función, necesita un archivo de secuencia de comandos de enlazador especial, que le dice al enlazador dónde ubicar todas las funciones marcadas.

  • ¡Inteligente! Así que eso es lo que significa “Liberar memoria del kernel no utilizada: 108k liberados”. 🙂 Me he preguntado todos estos años. Supuse que era algún tipo de búfer o algo así, no código.

    – Profesor Falken

    12 de enero de 2012 a las 9:09

avatar de usuario
naveen kumar r

Esto demuestra una característica del kernel 2.2 y posteriores. Observe el cambio en las definiciones de los init y cleanup funciones los __init la macro provoca la init función para ser descartada y su memoria liberada una vez que la init la función finaliza para los controladores integrados, pero no para los módulos cargables. Si piensas en cuando el init se invoca la función, esto tiene mucho sentido.

fuente

__init es una macro definida en ./include/linux/init.h que se expande a __attribute__ ((__section__(".init.text"))).

Le indica al compilador que marque esta función de una manera especial. Al final, el enlazador recopila todas las funciones con esta marca al final (o al principio) del archivo binario. Cuando se inicia el kernel, este código se ejecuta solo una vez (inicialización). Después de ejecutarse, el kernel puede liberar esta memoria para reutilizarla y verá el kernel

avatar de usuario
elmo

Leer comentario (y documentos al mismo tiempo) en linux/init.h.

También debe saber que gcc tiene algunas extensiones hechas especialmente para el código del kernel de Linux y parece que esta macro usa una de ellas.

avatar de usuario
Nnaik

Cuando compila e inserta un módulo del kernel de Linux en el kernel, la primera función que se ejecuta es __init. Esta función se usa básicamente para realizar la inicialización antes de realizar las operaciones principales, como registrar un controlador de dispositivo, etc. Hay otra función con el efecto opuesto. __exit que se llama cuando elimina el módulo del kernel que se usa nuevamente para eliminar algún dispositivo registrado o cualquier función similar

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad