Nằm trong yêu cầu về hạt nhân của mô-đun được giới thiệu trong Android 8.0, tất cả nhân hệ thống trên chip (SoC) phải hỗ trợ các mô-đun nhân hệ điều hành có thể tải.
Tuỳ chọn cấu hình kernel
Để hỗ trợ các mô-đun nhân hệ điều hành có thể tải, android-base.config trong tất cả các nhân phổ biến bao gồm sau đây là các tuỳ chọn kernel-config (hoặc phiên bản kernel tương đương):
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
Tất cả nhân hệ điều hành của thiết bị phải bật các tuỳ chọn này. Mô-đun hạt nhân cũng nên hỗ trợ huỷ tải và tải lại bất cứ khi nào có thể.
Ký mô-đun
Tính năng ký mô-đun không được hỗ trợ cho các mô-đun của nhà cung cấp GKI. Trên những thiết bị được yêu cầu để
hỗ trợ xác minh quy trình khởi động, Android yêu cầu các mô-đun nhân phải nằm trong phân vùng
đã bật dm-verity. Thao tác này giúp bạn không cần phải ký tài khoản cá nhân
các mô-đun để đảm bảo tính xác thực.
Android 13 ra mắt khái niệm về mô-đun GKI. Các mô-đun GKI sử dụng thời gian xây dựng của nhân hệ điều hành
cơ sở hạ tầng ký để phân biệt giữa GKI và các mô-đun khác trong thời gian chạy.
Các mô-đun chưa có chữ ký được phép tải, miễn là các mô-đun đó chỉ sử dụng những biểu tượng có trên danh sách cho phép
hoặc được cung cấp bởi các mô-đun chưa được ký khác.
Để tạo điều kiện cho các mô-đun GKI ký trong quá trình tạo bản dựng GKI bằng cặp khoá thời gian xây dựng của nhân,
Cấu hình hạt nhân GKI đã bật CONFIG_MODULE_SIG_ALL=y
.
Để tránh ký các mô-đun không phải GKI trong quá trình tạo bản dựng nhân hệ điều hành của thiết bị, bạn phải thêm
# CONFIG_MODULE_SIG_ALL is not set
trong cấu hình nhân hệ điều hành của bạn
mảnh.
Vị trí tệp
Mặc dù Android 7.x trở xuống không bắt buộc các mô-đun nhân (và bao gồm
hỗ trợ cho insmod
và rmmod
), Android 8.x và
thì bạn nên sử dụng các mô-đun nhân trong hệ sinh thái. Nội dung sau đây
bảng cho thấy khả năng hỗ trợ thiết bị ngoại vi tiềm năng dành riêng cho bo mạch trên ba thiết bị
Chế độ khởi động Android.
Chế độ khởi động | Bộ nhớ | Màn hình | Bàn phím | Pin | PMIC | Màn hình cảm ứng | NFC, Wi-Fi, Bluetooth |
Cảm biến | Camera |
---|---|---|---|---|---|---|---|---|---|
Khôi phục | |||||||||
Bộ sạc | |||||||||
Android |
Ngoài khả năng sử dụng trong các chế độ khởi động của Android, các mô-đun nhân cũng có thể được phân loại theo người sở hữu chúng (nhà cung cấp SoC hoặc ODM). Nếu mô-đun nhân đang được sử dụng, yêu cầu về vị trí của chúng trong hệ thống tệp là như sau:
- Tất cả nhân hệ điều hành đều phải tích hợp sẵn tính năng hỗ trợ khởi động và gắn kết phân vùng.
- Các mô-đun hạt nhân phải được tải từ phân vùng chỉ đọc.
- Đối với các thiết bị bắt buộc phải xác minh quy trình khởi động, các mô-đun nhân phải được được tải từ các phân vùng đã xác minh.
- Không được đặt các mô-đun hạt nhân trong
/system
. - Các mô-đun GKI bắt buộc đối với thiết bị phải được tải từ
/system/lib/modules
là mối liên kết tượng trưng đến/system_dlkm/lib/modules
- Các mô-đun hạt nhân từ nhà cung cấp SoC bắt buộc phải có cho phiên bản Android hoặc
Bạn nên đặt chế độ bộ sạc ở
/vendor/lib/modules
. - Nếu có phân vùng ODM, các mô-đun nhân từ ODM là bắt buộc
cho chế độ Android hoặc chế độ Bộ sạc đầy đủ sẽ được đặt trong
/odm/lib/modules
. Nếu không, các mô-đun này phải được đặt trong/vendor/lib/modules
. - Các mô-đun hạt nhân của nhà cung cấp SoC và ODM cần có cho tính năng Khôi phục
nên được đặt trong
ramfs
khôi phục tại/lib/modules
- Cần có mô-đun hạt nhân cho cả chế độ Khôi phục và phiên bản Android đầy đủ hoặc
Chế độ bộ sạc phải tồn tại cả trong
rootfs
khôi phục và phân vùng/vendor
hoặc/odm
(như mô tả ở trên). - Các mô-đun hạt nhân dùng ở chế độ Khôi phục không được phụ thuộc vào các mô-đun nằm trong
chỉ trong
/vendor
hoặc/odm
, vì những phân vùng đó không gắn kết ở chế độ Khôi phục. - Mô-đun nhân của nhà cung cấp SoC không được phụ thuộc vào mô-đun nhân ODM.
Trong Android 7.x trở xuống, /vendor
và /odm
phân vùng không được gắn kết sớm. Trong Android 8.x trở lên,
để có thể tải mô-đun từ các phân vùng này, các điều khoản đã được
phải gắn các phân vùng sớm cho cả hai
các thiết bị không phải A/B và A/B. Việc này cũng
đảm bảo các phân vùng được gắn ở cả chế độ Android và chế độ Bộ sạc.
Hỗ trợ hệ thống xây dựng Android
Trong BoardConfig.mk
, bản dựng Android sẽ xác định một
Biến BOARD_VENDOR_KERNEL_MODULES
cung cấp danh sách đầy đủ
của mô-đun nhân dành cho hình ảnh nhà cung cấp. Các mô-đun được liệt kê trong
biến này được sao chép vào hình ảnh nhà cung cấp tại /lib/modules/
,
và sau khi được gắn kết trong Android, sẽ xuất hiện trong
/vendor/lib/modules
(theo các yêu cầu ở trên).
Cấu hình mẫu của các mô-đun nhân hệ điều hành của nhà cung cấp:
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_VENDOR_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko \ $(vendor_lkm_dir)/vendor_module_c.ko
Trong ví dụ này, kho lưu trữ tạo sẵn mô-đun nhân của nhà cung cấp được ánh xạ vào bản dựng Android tại vị trí nêu trên.
Hình ảnh khôi phục có thể chứa một số mô-đun của nhà cung cấp. Hệ điều hành Android
Bản dựng xác định biến BOARD_RECOVERY_KERNEL_MODULES
cho
các mô-đun này. Ví dụ:
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_RECOVERY_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko
Bản dựng Android sẽ đảm nhận việc chạy depmod
để tạo
tệp modules.dep
bắt buộc trong /vendor/lib/modules
và /lib/modules
(recovery ramfs
).
Tải mô-đun và tạo phiên bản
Tải tất cả các mô-đun nhân trong một lượt truyền từ init.rc*
bằng cách gọi
modprobe -a
Điều này giúp tránh hao tổn tài nguyên khi khởi chạy nhiều lần
môi trường thời gian chạy C cho tệp nhị phân modprobe
. Chiến lược phát hành đĩa đơn
Có thể sửa đổi sự kiện early-init
để gọi modprobe
:
on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ...
Thông thường, một mô-đun nhân phải được biên dịch với nhân mà mô-đun đó là
được sử dụng cùng (nếu không, nhân sẽ từ chối tải mô-đun).
CONFIG_MODVERSIONS
cung cấp một giải pháp bằng cách phát hiện sự cố
trong giao diện nhị phân của ứng dụng (ABI). Tính năng này tính chu kỳ
giá trị kiểm tra dự phòng (CRC) cho nguyên mẫu của từng biểu tượng được xuất trong
kernel và lưu trữ các giá trị như một phần của kernel; cho các ký hiệu được sử dụng bởi
nhân, các giá trị cũng được lưu trữ trong mô-đun nhân. Khi
mô-đun sẽ được tải, giá trị của các ký hiệu mà mô-đun sử dụng sẽ được so sánh
với các mã trong nhân. Nếu các giá trị này khớp nhau thì mô-đun sẽ được tải;
nếu không thì không tải được.
Để cho phép cập nhật hình ảnh hạt nhân tách biệt với hình ảnh nhà cung cấp,
bật CONFIG_MODVERSIONS
. Làm như vậy cho phép các cập nhật nhỏ đối với
nhân hệ điều hành (chẳng hạn như các bản sửa lỗi từ LTS) cần thực hiện trong khi vẫn duy trì khả năng tương thích
bằng các mô-đun nhân hiện có trong hình ảnh nhà cung cấp. Tuy nhiên,
CONFIG_MODVERSIONS
không tự khắc phục sự cố về ABI. Nếu
nguyên mẫu của một biểu tượng được xuất trong những thay đổi về hạt nhân, do
việc sửa đổi nguồn hoặc do cấu hình hạt nhân thay đổi, điều này
phá vỡ khả năng tương thích với các mô-đun nhân sử dụng biểu tượng đó. Trong những trường hợp như vậy,
mô-đun nhân phải được biên dịch lại.
Ví dụ: cấu trúc task_struct
trong hạt nhân (được định nghĩa trong
include/linux/sched.h
) chứa nhiều trường theo điều kiện
tuỳ thuộc vào cấu hình nhân. sched_info
chỉ xuất hiện nếu CONFIG_SCHED_INFO
được bật (điều này
xảy ra khi CONFIG_SCHEDSTATS
hoặc
CONFIG_TASK_DELAY_ACCT
đã được bật). Nếu các cấu hình này
các tuỳ chọn thay đổi trạng thái, bố cục của cấu trúc task_struct
các thay đổi và mọi giao diện đã xuất từ nhân hệ điều hành sử dụng
task_struct
đã được thay đổi (ví dụ:
set_cpus_allowed_ptr
trong kernel/sched/core.c
).
Khả năng tương thích với các mô-đun nhân được biên dịch trước đây sử dụng
làm hỏng giao diện, buộc các mô-đun đó phải được xây dựng lại bằng nhân hệ điều hành mới
.
Để biết thêm thông tin về CONFIG_MODVERSIONS
, hãy tham khảo
tài liệu trong cây nhân tại
Documentation/kbuild/modules.rst