Apa arti __init dalam kode kernel Linux?

91

Di kode sumber kernel Linux saya menemukan fungsi ini:

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

Di sini saya tidak mengerti apa __initartinya.

Jeegar Patel
sumber

Jawaban:

76

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)
Sangeeth Saravanaraj
sumber
55

Ini hanya makro untuk menemukan beberapa bagian dari kode linux ke dalam area khusus di biner pelaksana akhir. __init, misalnya (atau lebih baik __attribute__ ((__section__ (".init.text")))makro ini diperluas ke) memerintahkan kompilator untuk menandai fungsi ini dengan cara khusus. Pada akhirnya, penaut mengumpulkan semua fungsi dengan tanda ini di akhir (atau awal) file biner.

Ketika kernel dimulai, kode ini hanya berjalan sekali (inisialisasi). Setelah dijalankan, kernel dapat mengosongkan memori ini untuk digunakan kembali dan Anda akan melihat pesan kernel:

Membebaskan memori kernel yang tidak digunakan: 108k dibebaskan

Untuk menggunakan fitur ini, Anda memerlukan file skrip penaut khusus, yang memberi tahu penaut tempat untuk mencari semua fungsi yang ditandai.

sashoalm
sumber
11
Pintar! Jadi itulah yang dimaksud dengan "Membebaskan memori kernel yang tidak digunakan: 108k freed". :-) Saya telah bertanya-tanya selama ini. Saya berasumsi itu semacam buffer atau sesuatu, bukan kode.
Prof. Falken
6

Ini menunjukkan fitur kernel 2.2 dan yang lebih baru. Perhatikan perubahan definisi dari initdan cleanupfungsi. The __initmakro menyebabkan initfungsi yang akan dibuang dan memori dibebaskan setelah initselesai fungsi untuk built-in driver, tetapi tidak modul loadable. Jika Anda berpikir tentang kapan initfungsi tersebut dipanggil, ini masuk akal.

sumber

naveen kumar r
sumber
5

__init adalah makro yang ditentukan di ./include/linux/init.h yang diperluas menjadi __attribute__ ((__section__(".init.text"))).

Ini menginstruksikan kompiler untuk menandai fungsi ini dengan cara khusus. Pada akhirnya, penaut mengumpulkan semua fungsi dengan tanda ini di akhir (atau awal) file biner. Ketika kernel dimulai, kode ini hanya berjalan sekali (inisialisasi). Setelah dijalankan, kernel dapat mengosongkan memori ini untuk digunakan kembali dan Anda akan melihat kernel

Geoffroy
sumber
3

Baca komentar (dan docs pada saat yang sama) di linux / init.h .

Anda juga harus tahu bahwa gcc memiliki beberapa ekstensi yang dibuat khusus untuk kode kernel linux dan sepertinya makro ini menggunakan salah satunya.

elmo
sumber
1

Ketika Anda mengkompilasi dan memasukkan modul kernel Linux ke dalam kernel, fungsi pertama yang akan dijalankan adalah __init. Fungsi ini pada dasarnya digunakan untuk melakukan inisialisasi sebelum Anda melakukan operasi utama seperti mendaftarkan driver perangkat dll, Ada fungsi lain dengan efek sebaliknya __exit yang dipanggil saat Anda menghapus modul kernel yang sekali lagi digunakan untuk menghapus beberapa perangkat terdaftar atau fungsi serupa lainnya

Nnaik
sumber