Cách bao gồm các tệp tiêu đề cục bộ trong mô-đun hạt nhân linux


17

Nói rằng tôi có một mô-đun mymodvới các tệp nguồn như sau:

src / mod / mymod.c
src / inc / mymod.h

Tôi cố gắng bao gồm mymod.h như sau

#include <mymod.h>

Makefile của tôi chứa EXTRA_CFLAGS= -I$(shell pwd)/../inc/nhưng khi kernel được tạo, tôi gặp lỗi:

mymod.h không tìm thấy

Lý do có vẻ là khi các mô-đun hạt nhân được thực hiện, lệnh này được chạy từ makefile: (sử dụng makeV1):

make -C <path/to/linux/src> M=<path/to/mymod> modules

Trong các công việc khác, tôi $(shell pwd)đã mở rộng đến <path/to/linux>. Đây không phải là điều tôi muốn. Làm cách nào tôi có thể chỉ định -Itham số để trỏ đến cây nguồn src/inccủa mình mymod?

Câu trả lời:


19

Các makefile kernel Linux sử dụng khung Kbuild. Mặc dù những điều này được giải thích bởi GNU make, Kbuild bao gồm một tập hợp các macro lớn với các quy ước sử dụng đặc biệt, vì vậy các hướng dẫn makefile điển hình không được áp dụng. Điều hay ho ở Kbuild là bạn cần rất ít nồi hơi xem xét sự phức tạp của nhiệm vụ.

Kbuild được ghi lại trong nguồn kernel, in Documentation/kbuild. Là một người viết mô-đun, bạn đặc biệt nên đọc modules.txt(và ít nhất là đọc lướt qua những người khác).

Những gì bạn đang làm bây giờ không hoạt động vì $(shell pwd)được mở rộng khi EXTRA_CFLAGSbiến được sử dụng. Vì tệp Makefile chạy từ cây nguồn kernel chứ không phải từ thư mục của mô-đun của bạn (đây là một trong nhiều khía cạnh không gây khó chịu của Kbuild), nên nó chọn thư mục sai.

Thành ngữ chính thức để chỉ định bao gồm các thư mục trong mô-đun ngoài cây nằm trong §5.3 của modules.txt. Các srcbiến được đặt vào thư mục mục cấp đầu của mô-đun của bạn. Vì thế:

EXTRA_CFLAGS := -I$(src)/src/inc

Lưu ý rằng khai báo này phải ở trong một tệp được gọi Kbuildở gốc của cây mô-đun của bạn. (Bạn có thể muốn coi srcthư mục là gốc của cây mô-đun của mình; nếu vậy, hãy đặt Kbuildở đó và thay thế giá trị ở trên bằng -I$(src)/inc). Cũng có thể đặt chúng vào một Makefile, nhưng lưu ý rằng định nghĩa này (miễn là mọi thứ khác chỉ áp dụng khi xây dựng mô-đun hạt nhân) phải nằm trong một lệnh có điều kiện ifeq ($(KERNELRELEASE),). Xem §4.1 của modules.txt.

Nếu bạn chưa có Kbuildtệp và muốn chuyển sang có tệp, hãy đọc §4.1 modules.txt. Có một Kbuildtập tin riêng thì rõ ràng hơn một chút. Đừng đặt bất cứ thứ gì áp dụng cho kernel vào tệp chính của bạn, ngoài quy tắc cần gọi make -C $(KERNELDIR) M=$(pwd). Trong đó Kbuild, tối thiểu bạn cần là danh sách các mô-đun bạn đang xây dựng (thường chỉ là một) và danh sách các tệp cần có trong mô-đun của bạn, cộng với khai báo phụ thuộc:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h

Tôi không thể cập nhật bài viết vì tôi không có đủ danh tiếng.
Om Narasimhan

1
@Om Narasimhan: Nếu điều này giúp bạn tìm ra giải pháp, bạn nên đánh dấu câu trả lời là được chấp nhận.
một CVn

1

Theo truyền thống, cách để #includecác tệp có đường dẫn liên quan đến thư mục của mã nguồn hiện tại là sử dụng dấu ngoặc kép thay vì dấu ngoặc nhọn:

#include <stdio.h>
#include "mygreatfunctions.h"

Trong trường hợp này, cái đầu tiên #includesẽ tham chiếu trình biên dịch bao gồm đường dẫn tìm kiếm (trong trường hợp của gcc, được điều khiển bởi công -Itắc dòng lệnh), trong khi cái thứ hai sẽ tìm trong thư mục chứa tệp nguồn với #include.

Những con đường như vậy có thể là tương đối, quá. Vì vậy, trong src / mod / mymod.c, bạn có thể nói:

#include "../inc/mymod.h"

và nó sẽ "chỉ hoạt động".

Tôi không biết liệu đây có phải là thông lệ phổ biến trong cây nhân Linux hay không, nhưng chắc chắn là tốt hơn so với việc tìm kiếm xung quanh với đường dẫn bao gồm, có thể có bất kỳ số lượng tác dụng phụ ngoài ý muốn.


1
Lời khuyên tốt nói chung, tuy nhiên makefiles kernel Linux rất đặc biệt. Họ gọi một bộ macro khá phức tạp gọi là Kbuild; tốt nhất là coi Kbuild như một ngôn ngữ gần như, nhưng không hoàn toàn, không giống như hoàn toàn.
Gilles 'SO- ngừng trở nên xấu xa'

1
Chắc chắn rồi, nhưng hành vi của trình biên dịch C tìm kiếm <foo> trong một số bộ thư mục được định cấu hình và cho "thanh" tìm kiếm đầu tiên vào thư mục hiện tại và sau đó quay lại đường dẫn được đề cập trước khi không thay đổi bởi ý nghĩa kỳ quái được gọi là gì trình biên dịch ở nơi đầu tiên.
vonbrand
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.