No código-fonte do kernel do Linux, encontrei esta função:
static int __init clk_disable_unused(void)
{
// some code
}
Aqui eu não consigo entender o que __init
significa.
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)
Essas são apenas macros para localizar algumas partes do código Linux em áreas especiais no binário de execução final.
__init
, por exemplo (ou melhor, para que __attribute__ ((__section__
(".init.text")))
esta macro se expanda) instrui o compilador a marcar esta função de uma maneira especial. No final, o vinculador coleta todas as funções com esta marca no final (ou início) do arquivo binário.
Quando o kernel é iniciado, este código é executado apenas uma vez (inicialização). Depois de executado, o kernel pode liberar essa memória para reutilizá-la e você verá a mensagem do kernel:
Liberando memória do kernel não utilizada: 108k liberados
Para usar esse recurso, você precisa de um arquivo de script de vinculador especial, que informa ao vinculador onde localizar todas as funções marcadas.
Isso demonstra um recurso do kernel 2.2 e posterior. Observe a mudança nas definições das funções
init
ecleanup
. A__init
macro faz com que ainit
função seja descartada e sua memória seja liberada quando ainit
função for concluída para drivers embutidos, mas não para módulos carregáveis. Se você pensar em quando ainit
função é invocada, isso faz todo o sentido.fonte
fonte
__init é uma macro definida em ./include/linux/init.h que se expande para
__attribute__ ((__section__(".init.text")))
.Ele instrui o compilador a marcar essa função de uma maneira especial. No final, o vinculador coleta todas as funções com esta marca no final (ou início) do arquivo binário. Quando o kernel é iniciado, este código é executado apenas uma vez (inicialização). Depois de executado, o kernel pode liberar essa memória para reutilizá-la e você verá o kernel
fonte
Leia comentários (e documentos ao mesmo tempo) em linux / init.h .
Você também deve saber que o gcc tem algumas extensões feitas especialmente para o código do kernel do Linux e parece que esta macro usa uma delas.
fonte
Quando você compila e insere um módulo do kernel do Linux no kernel, a primeira função a ser executada é __init. Esta função é basicamente usada para executar a inicialização antes de você realizar as operações principais, como registrar um driver de dispositivo, etc. Há outra função com o efeito oposto __exit que é chamado quando você remove o módulo do kernel que é novamente usado para remover algum dispositivo registrado ou qualquer função semelhante
fonte