2012-01-12 39 views

Trả lời

52

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) 
40

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

Giải phóng bộ nhớ hạt 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 có một tệp trình liên kết tệp đặc biệt, cho biết trình liên kết nơi xác định tất cả các hàm được đánh dấu.

+8

Thông minh! Vì vậy, đó là những gì "Giải phóng bộ nhớ hạt nhân không sử dụng: 108k giải phóng" 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 một cái gì đó, không phải mã. –

2

Đọc nhận xét (và tài liệu cùng một lúc) trong linux/ini.h.

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

3

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

Hướng dẫn trình biên dịch đánh dấu chức năng này theo cách đặc biệt. Cuối cùng, 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 bắt đầ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 để tái sử dụng nó và bạn sẽ thấy hạt nhân

3

Điều này thể hiện tính năng của hạt nhân 2.2 trở lên. Lưu ý sự thay đổi trong định nghĩa của các hàm initcleanup. Macro __init khiến chức năng init bị hủy và bộ nhớ của nó được giải phóng sau khi chức năng init kết thúc với trình điều khiển tích hợp, nhưng không thể tải mô-đun. Nếu bạn nghĩ về khi hàm init được gọi, điều này có ý nghĩa hoàn hảo.

source

Các vấn đề liên quan