Hỗ trợ mô-đun nhân

Hình ảnh kernel chung (GKI) có thể không chứa trình điều khiển cần thiết để cho phép thiết bị gắn các phân vùng. Để cho phép thiết bị gắn các phân vùng và tiếp tục khởi động, init giai đoạn đầu tiên sẽ được nâng cao để tải các mô-đun hạt nhân có trên ramdisk. Ramdisk được chia thành ramdisk chung và ramdisk của nhà cung cấp. Các mô-đun hạt nhân của nhà cung cấp được lưu trữ trong ramdisk của nhà cung cấp. Bạn có thể định cấu hình thứ tự tải các mô-đun của nhân.

Vị trí mô-đun

Ramdisk là hệ thống tệp cho init, giai đoạn đầu và cho hình ảnh recovery/fastbootd trên các thiết bị A/B và A/B ảo. Đây là một initramfs bao gồm 2 kho lưu trữ cpio được trình tải khởi động nối lại với nhau. Kho lưu trữ cpio đầu tiên (được lưu trữ dưới dạng ramdisk của nhà cung cấp trong phân vùng khởi động của nhà cung cấp) chứa các thành phần sau:

  • Các mô-đun hạt nhân của nhà cung cấp init giai đoạn đầu, nằm trong /lib/modules/.
  • Tệp cấu hình modprobe, nằm trong /lib/modules/: modules.dep, modules.softdep, modules.alias, modules.options.
  • Tệp modules.load cho biết những mô-đun cần tải trong quá trình khởi động giai đoạn đầu và theo thứ tự nào trong /lib/modules/.
  • Các mô-đun kernel khôi phục của nhà cung cấp, cho các thiết bị A/B và A/B ảo, trong /lib/modules/
  • modules.load.recovery cho biết các mô-đun cần tải và thứ tự tải cho các thiết bị A/B và A/B ảo trong /lib/modules.

Kho lưu trữ cpio thứ hai (được cung cấp cùng với GKI dưới dạng ramdisk của boot.img và được áp dụng trên kho lưu trữ đầu tiên) chứa first_stage_init và các thư viện mà kho lưu trữ này phụ thuộc vào.

Tải mô-đun trong giai đoạn khởi động đầu tiên

init ở giai đoạn đầu tiên bắt đầu bằng cách đọc các tệp cấu hình modprobe từ /lib/modules/ trên ramdisk. Tiếp theo, nó sẽ đọc danh sách các mô-đun được chỉ định trong /lib/modules/modules.load (hoặc trong trường hợp khôi phục, /lib/modules/modules.load.recovery) và cố gắng tải từng mô-đun đó theo thứ tự, tuân theo cấu hình được chỉ định trong các tệp đã tải trước đó. Thứ tự được yêu cầu có thể bị lệch để đáp ứng các phần phụ thuộc bắt buộc hoặc không bắt buộc.

Hỗ trợ bản dựng, giai đoạn khởi động đầu tiên

Để chỉ định các mô-đun hạt nhân cần sao chép vào cpio ramdisk của nhà cung cấp, hãy liệt kê các mô-đun đó trong BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Bản dựng chạy depmod trên các mô-đun này và đặt các tệp cấu hình modprobe kết quả vào cpio ramdisk của nhà cung cấp.

Bản dựng này cũng tạo một tệp modules.load và lưu trữ tệp đó trong cpio ramdisk của nhà cung cấp. Theo mặc định, tệp này chứa tất cả các mô-đun được liệt kê trong BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Để ghi đè nội dung của tệp đó, hãy sử dụng BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD, như minh hoạ trong ví dụ này:

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

Hỗ trợ bản dựng, Android đầy đủ

Như trong các bản phát hành Android 10 trở xuống, các mô-đun nhân có trong BOARD_VENDOR_KERNEL_MODULES sẽ được bản dựng nền tảng Android sao chép vào phân vùng nhà cung cấp tại /vendor/lib/modules. Bản dựng nền tảng chạy depmod trên các mô-đun này và sao chép các tệp đầu ra depmod vào phân vùng nhà cung cấp ở cùng một vị trí. Cơ chế tải các mô-đun hạt nhân từ /vendor vẫn giữ nguyên như đối với các bản phát hành trước của Android. Bạn có thể quyết định cách thức và thời điểm tải các mô-đun này, mặc dù thường thì việc này được thực hiện bằng cách sử dụng tập lệnh init.rc.

Ký tự đại diện và bản dựng kernel tích hợp

Những nhà cung cấp kết hợp bản dựng nhân thiết bị với bản dựng nền tảng Android có thể gặp phải vấn đề khi sử dụng các macro BOARD nêu trên để chỉ định các mô-đun nhân cần sao chép vào thiết bị. Nếu nhà cung cấp muốn tránh liệt kê các mô-đun kernel trong tệp bản dựng nền tảng của thiết bị, họ có thể sử dụng ký tự đại diện ($(wildcard device/vendor/mydevice/*.ko). Xin lưu ý rằng ký tự đại diện không hoạt động trong trường hợp bản dựng kernel tích hợp, vì khi lệnh make được gọi và các macro được mở rộng trong tệp makefile, các mô-đun kernel chưa được tạo, nên các macro sẽ trống.

Để giải quyết vấn đề này, nhà cung cấp có thể tạo bản dựng kernel để tạo một tệp lưu trữ zip chứa các mô-đun kernel cần sao chép vào từng phân vùng. Đặt đường dẫn của tệp lưu trữ zip đó trong BOARD_*_KERNEL_MODULES_ARCHIVE, trong đó * là tên của phân vùng (chẳng hạn như BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). Bản dựng nền tảng Android sẽ trích xuất tệp lưu trữ zip này vào vị trí thích hợp và chạy depmod trên các mô-đun.

Tệp lưu trữ zip của mô-đun kernel phải có một quy tắc tạo để đảm bảo bản dựng nền tảng có thể tạo tệp lưu trữ khi cần.

Khôi phục

Trong các bản phát hành Android trước đây, các mô-đun hạt nhân cần thiết cho quá trình khôi phục được chỉ định trong BOARD_RECOVERY_KERNEL_MODULES. Trong Android 12, các mô-đun hạt nhân cần thiết cho quá trình khôi phục vẫn được chỉ định bằng macro này. Tuy nhiên, các mô-đun kernel khôi phục sẽ được sao chép vào cpio ramdisk của nhà cung cấp, thay vì cpio ramdisk chung. Theo mặc định, tất cả các mô-đun kernel có trong BOARD_RECOVERY_KERNEL_MODULES sẽ được tải trong giai đoạn đầu tiên init. Nếu bạn chỉ muốn tải một số ít trong số các mô-đun này, hãy chỉ định nội dung của nhóm nhỏ đó trong BOARD_RECOVERY_KERNEL_MODULES_LOAD.

Để tìm hiểu về cách tạo một phân vùng khởi động của nhà cung cấp (chứa ramdisk của nhà cung cấp được đề cập trên trang này), hãy xem Phân vùng khởi động.