2011-12-19 28 views
28

Khi biên dịch mô-đun hạt nhân, tôi nhận được một CẢNH BÁO với một ghi chú để thêm tùy chọn biên dịch, CONFIG_DEBUG_SECTION_MISMATCH = y. Nó cung cấp cho tôi các thông tin chi tiết hơn về vấn đề:Phần hạt nhân không khớp là gì?

WARNING: \**\*path to module\***(.text+0x8d2): Section mismatch in reference from the function Pch_Spi_Enable_Bios_Wr() to the variable .devinit.data:ich9_pci_tbl.22939 
The function Pch_Spi_Enable_Bios_Wr() references 
the variable __devinitdata ich9_pci_tbl.22939. 
This is often because Pch_Spi_Enable_Bios_Wr lacks a __devinitdata 
annotation or the annotation of ich9_pci_tbl.22939 is wrong. 

tôi không thể tìm thấy chính xác những gì kernel phần không phù hợp là, chưa kể đến làm thế nào để đi về sửa chữa nó.

Trả lời

35

Điều này có nghĩa là một hàm nằm trong phần có thời lượng đã cho tham chiếu đến nội dung có trong phần có thời lượng khác.

Khi liên kết nhị phân hạt nhân, các phần khác nhau của mã và dữ liệu được chia thành các phần khác nhau. Một số phần này được lưu giữ mọi lúc, nhưng một số phần khác được loại bỏ khi chúng không còn cần thiết nữa (những thứ chỉ cần trong khi khởi động ví dụ có thể được giải phóng khi khởi động xong - điều này tiết kiệm bộ nhớ).

Nếu chức năng trong phần dài hạn đề cập đến dữ liệu ở một trong các phần có thể hủy, có sự cố - có thể cố truy cập dữ liệu đó khi dữ liệu đã được phát hành, dẫn đến tất cả các loại thời gian chạy vấn đề.

Đây không phải là cảnh báo bạn sẽ tự khắc phục, trừ khi bạn viết mã đó hoặc rất quen thuộc với nó. Nó được sửa bằng cách chú thích một cách chính xác hàm (hoặc dữ liệu nó đề cập đến) để nó đi vào phần bên phải. Việc sửa chữa đúng chỉ có thể được xác định với kiến ​​thức chi tiết về phần đó của hạt nhân.


Đối với một danh sách các phần và các chú thích, tham khảo các include/linux/init.h tiêu đề trong mã nguồn kernel:

/* 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) 

khác làm theo, với nhiều ý kiến ​​và giải thích.

cũng Xem văn bản trợ giúp cho biểu tượng CONFIG_DEBUG_SECTION_MISMATCH Kconfig:

Phần kiểm tra phân tích không phù hợp nếu có bất hợp pháp
tài liệu tham khảo từ một phần tới phần khác.
Linux sẽ trong khi liên kết hoặc trong thời gian chạy thả một số phần
và bất kỳ việc sử dụng mã/dữ liệu nào trước đây trong các phần này sẽ
nhiều khả năng dẫn đến kết quả.
Trong các chức năng mã và các biến được chú thích với
__init, __devinit v.v. (xem danh sách đầy đủ bao gồm/linux/init.h)
dẫn đến mã/dữ liệu được đặt trong các phần cụ thể.
Phân tích phần không phù hợp luôn được thực hiện sau một đầy đủ
hạt nhân xây dựng nhưng cho phép tùy chọn này sẽ bổ sung
làm như sau:

  • Thêm tùy chọn -fno-inline-chức năng gọi là-một lần để gcc
    Khi nội tuyến một hàm được chú thích __init trong hàm phi init
    , chúng tôi sẽ mất thông tin phần và do đó,
    phân tích sẽ không bắt được tham chiếu bất hợp pháp.
    Tùy chọn này cho gcc biết nội tuyến ít hơn nhưng cũng sẽ
    dẫn đến hạt nhân lớn hơn.
  • Chạy phân tích phần không phù hợp cho mỗi mô-đun/xây dựng in.o
    Khi chúng tôi chạy phân tích phần không phù hợp trên vmlinux.o chúng tôi
    mất thông tin valueble về nơi không phù hợp là
    giới thiệu.
    Chạy phân tích cho từng mô-đun/tệp built-in.o
    sẽ cho biết vị trí không phù hợp xảy ra gần hơn với nguồn
    . Nhược điểm là chúng tôi sẽ báo cáo cùng một số
    không khớp ít nhất hai lần.
  • Bật báo cáo chi tiết từ modpost để giúp giải quyết
    các phần không phù hợp được báo cáo.
Các vấn đề liên quan