__Init có nghĩa là gì trong mã nhân Linux?


91

Trong mã nguồn nhân Linux, tôi tìm thấy chức năng này:

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

Ở đây tôi không thể hiểu __initnghĩa là gì.

Câu trả lời:


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)

55

Đây chỉ là các macro để định vị một số phần của mã linux vào các khu vực đặc biệt trong tệp nhị phân thực thi cuối cùng. __init, ví dụ (hoặc tốt hơn là __attribute__ ((__section__ (".init.text")))macro này mở rộng thành) hướng dẫn trình biên dịch đánh dấu chức năng này theo một cách đặc biệt. Ở phần cuối, trình liên kết thu thập tất cả các hàm có dấu này ở cuối (hoặc đầu) của tệp nhị phân.

Khi hạt nhân khởi động, mã này chỉ chạy một lần (khởi tạo). Sau khi nó chạy, hạt nhân có thể giải phóng bộ nhớ này để sử dụng lại nó và bạn sẽ thấy thông báo hạt nhân:

Giải phóng bộ nhớ nhân không sử dụng: 108k giải phóng

Để sử dụng tính năng này, bạn cần một tệp tập lệnh trình liên kết đặc biệt, tệp này cho trình liên kết biết vị trí của tất cả các chức năng được đánh dấu.


11
Tài giỏi! Vì vậy, đó là những gì "Giải phóng bộ nhớ hạt nhân không sử dụng: giải phóng 108k" có nghĩa là. :-) Tôi đã tự hỏi tất cả những năm này. Tôi cho rằng đó là một số loại bộ đệm hoặc thứ gì đó, không phải mã.
Giáo sư Falken

6

Điều này thể hiện một tính năng của nhân 2.2 trở lên. Lưu ý sự thay đổi trong các định nghĩa của hàm initcleanup. Các __initvĩ mô gây ra các initchức năng để được loại bỏ và bộ nhớ của nó được giải phóng khi initkết thúc chức năng được xây dựng trong trình điều khiển, nhưng không phải module khả nạp. Nếu bạn nghĩ về thời điểm inithàm được gọi, điều này hoàn toàn hợp lý.

nguồn


5

__init là một macro được định nghĩa trong ./include/linux/init.h mở rộng thành __attribute__ ((__section__(".init.text"))).

Nó hướng dẫn trình biên dịch đánh dấu chức năng này theo một cách đặc biệt. Ở phần cuối, trình liên kết thu thập tất cả các hàm có dấu này ở cuối (hoặc đầu) của tệp nhị phân. Khi hạt nhân khởi động, mã này chỉ chạy một lần (khởi tạo). Sau khi nó chạy, kernel có thể giải phóng bộ nhớ này để sử dụng lại và bạn sẽ thấy kernel


3

Đọc bình luận (và tài liệu cùng một lúc) trong linux / init.h .

Bạn cũng nên biết rằng gcc có một số phần mở rộng được tạo đặc biệt cho mã nhân linux và có vẻ như macro này sử dụng một trong số chúng.


1

Khi bạn biên dịch và chèn một mô-đun nhân Linux vào nhân, chức năng đầu tiên được thực thi là __init, về cơ bản, chức năng này được sử dụng để thực hiện khởi tạo trước khi bạn thực hiện các thao tác chính như đăng ký trình điều khiển thiết bị, v.v., Có một chức năng khác có tác dụng ngược lại __exit được gọi khi bạn loại bỏ mô-đun hạt nhân được sử dụng lại để xóa một số thiết bị đã đăng ký hoặc bất kỳ chức năng tương tự nào

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.