ตามข้อกำหนดเคอร์เนลของโมดูลที่นำมาใช้ใน Android 8.0 เคอร์เนลระบบบนชิป (SoC) ต้องรองรับโมดูลเคอร์เนลที่โหลดได้
ตัวเลือกการกำหนดค่าเคอร์เนล
เพื่อรองรับโมดูลเคอร์เนลที่โหลดได้ android-base.config ในเคอร์เนลทั่วไปทั้งหมดรวมถึง ตัวเลือกการกำหนดค่าเคอร์เนลต่อไปนี้ (หรือเวอร์ชันเคอร์เนลเทียบเท่า)
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
เคอร์เนลของอุปกรณ์ทั้งหมดต้องเปิดใช้ตัวเลือกเหล่านี้ โมดูลเคอร์เนลควร สนับสนุนการยกเลิกการโหลดและโหลดซ้ำเมื่อเป็นไปได้
การรับรองข้อบังคับ
โมดูลผู้ให้บริการ GKI ไม่รองรับการรับรองโมดูล ในอุปกรณ์ที่ต้องใช้เพื่อ
รองรับการเปิดเครื่องที่ได้รับการยืนยัน Android กำหนดให้โมดูลเคอร์เนลอยู่ในพาร์ติชัน
ที่เปิดใช้ DM-verity ไว้ ทำให้ไม่จำเป็นต้องลงนามในนามบุคคลธรรมดา
เพื่อความน่าเชื่อถือ
Android 13 เปิดตัวแนวคิดของโมดูล GKI โมดูล GKI ใช้เวลาบิลด์ของเคอร์เนล
ลงนามในโครงสร้างพื้นฐานเพื่อแยกความแตกต่างระหว่าง GKI และโมดูลอื่นๆ ขณะรันไทม์
โมดูลที่ไม่ได้ลงนามจะสามารถโหลดได้ตราบใดที่โมดูลเหล่านั้นใช้เฉพาะสัญลักษณ์ที่ปรากฏในรายการที่อนุญาต
หรือจัดหาโดยโมดูลที่ไม่ได้ลงชื่อ
เพื่อช่วยให้ลงนามโมดูล GKI ระหว่างการสร้าง GKI โดยใช้คู่คีย์เวลาบิลด์ของเคอร์เนล
การกำหนดค่าเคอร์เนล GKI เปิดใช้ CONFIG_MODULE_SIG_ALL=y
แล้ว
หากต้องการหลีกเลี่ยงการลงชื่อในโมดูลที่ไม่ใช่ GKI ระหว่างการสร้างเคอร์เนลของอุปกรณ์ คุณต้องเพิ่ม
# CONFIG_MODULE_SIG_ALL is not set
เป็นส่วนหนึ่งของการกำหนดค่าเคอร์เนล
ส่วนย่อย
ตำแหน่งที่ตั้งไฟล์
แม้ว่า Android 7.x และเวอร์ชันที่ต่ำกว่าจะไม่บังคับใช้โมดูลเคอร์เนล (และรวมถึง
รองรับ insmod
และ rmmod
), Android 8.x และ
ขอแนะนำให้ใช้โมดูลเคอร์เนลในระบบนิเวศที่สูงกว่า ดังต่อไปนี้
ตารางแสดงการรองรับอุปกรณ์ต่อพ่วงสำหรับกระดานโดยเฉพาะซึ่งจำเป็นต้องมีใน 3 แพลตฟอร์ม
โหมดเปิดเครื่องของ Android
โหมดเปิดเครื่อง | พื้นที่เก็บข้อมูล | จอแสดงผล | ปุ่มกด | แบตเตอรี่ | PMIC | หน้าจอสัมผัส | NFC, Wi-Fi, บลูทูธ |
เซ็นเซอร์ | กล้อง |
---|---|---|---|---|---|---|---|---|---|
แย่งลูกคืนมา | |||||||||
ที่ชาร์จ | |||||||||
Android |
นอกจากความพร้อมใช้งานในโหมดเปิดเครื่องของ Android แล้ว โมดูลเคอร์เนลยังอาจ จัดหมวดหมู่ตามผู้ที่เป็นเจ้าของ (ผู้ให้บริการ SoC หรือ ODM) หากโมดูลเคอร์เนล ข้อกำหนดสำหรับตำแหน่งในระบบไฟล์มีดังนี้ ดังต่อไปนี้:
- เคอร์เนลทั้งหมดควรมีการรองรับในตัวสำหรับการเปิดเครื่องและการต่อเชื่อม พาร์ติชัน
- โมดูลเคอร์เนลต้องโหลดจากพาร์ติชันแบบอ่านอย่างเดียว
- สำหรับอุปกรณ์ที่จำเป็นต้องมีการเปิดเครื่องที่ได้รับการยืนยัน โมดูลเคอร์เนลควร โหลดจากพาร์ติชันที่ยืนยันแล้ว
- โมดูลเคอร์เนลไม่ควรอยู่ใน
/system
- ควรโหลดโมดูล GKI ที่จำเป็นสำหรับอุปกรณ์
/system/lib/modules
ซึ่งเป็นลิงก์สัญลักษณ์ไปยัง/system_dlkm/lib/modules
- โมดูลเคอร์เนลจากผู้ให้บริการ SoC ที่จำเป็นสำหรับ Android เวอร์ชันเต็มหรือ
โหมดที่ชาร์จควรอยู่ใน
/vendor/lib/modules
- หากมีพาร์ติชัน ODM อยู่ โมดูลเคอร์เนลจาก ODM ที่จำเป็น
สำหรับโหมด Android หรือโหมดที่ชาร์จทั้งหมดควรอยู่ใน
/odm/lib/modules
ไม่เช่นนั้น โมดูลเหล่านี้ควรอยู่ใน/vendor/lib/modules
- โมดูลเคอร์เนลจากผู้ให้บริการ SoC และ ODM ที่จำเป็นสำหรับการกู้คืน
โหมดควรอยู่ในการกู้คืน
ramfs
ที่/lib/modules
- จำเป็นต้องมีโมดูลเคอร์เนลสำหรับทั้งโหมดการกู้คืนและ Android เต็มรูปแบบหรือ
ควรมีโหมดที่ชาร์จอยู่ทั้งใน
rootfs
และ พาร์ติชัน/vendor
หรือ/odm
(ตามที่อธิบายไว้ ที่ด้านบน) - โมดูลเคอร์เนลที่ใช้ในโหมดการกู้คืนไม่ควรขึ้นอยู่กับโมดูลที่อยู่
เฉพาะใน
/vendor
หรือ/odm
เท่านั้น เนื่องจากพาร์ติชันเหล่านั้นไม่ใช่ ซึ่งต่อเชื่อมไว้ในโหมดการกู้คืน - โมดูลเคอร์เนลของผู้ให้บริการ SoC ไม่ควรขึ้นอยู่กับโมดูลเคอร์เนล ODM
ใน Android 7.x และเก่ากว่านั้น /vendor
และ /odm
ไม่มีการต่อเชื่อมพาร์ติชันก่อนกำหนด ใน Android 8.x ขึ้นไป
เพื่อให้สามารถโหลดโมดูลจากพาร์ติชันเหล่านี้ได้ การจัดสรร
สร้างขึ้นเพื่อต่อเชื่อมพาร์ติชันตั้งแต่เนิ่นๆ สำหรับทั้ง 2 แบบ
อุปกรณ์ที่ไม่ใช่ A/B และ A/B ยัง
ตรวจดูว่าพาร์ติชันติดตั้งอยู่ทั้งในโหมด Android และโหมดที่ชาร์จ
การสนับสนุนระบบบิลด์ของ Android
ใน BoardConfig.mk
บิลด์ของ Android ได้กำหนด
ตัวแปร BOARD_VENDOR_KERNEL_MODULES
ที่แสดงรายการทั้งหมด
ของโมดูลเคอร์เนลที่มีไว้สำหรับอิมเมจของผู้ให้บริการ โมดูลที่แสดงใน
ระบบจะคัดลอกตัวแปรนี้ไปยังอิมเมจผู้ให้บริการที่ /lib/modules/
และหลังจากต่อเชื่อมใน Android แล้ว จะปรากฏใน
/vendor/lib/modules
(ตามข้อกำหนดข้างต้น)
ตัวอย่างการกำหนดค่าของโมดูลเคอร์เนลของผู้ให้บริการ
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
ในตัวอย่างนี้ ที่เก็บโมดูลเคอร์เนลของผู้ให้บริการที่สร้างไว้ล่วงหน้าจะแมปลงใน บิลด์ของ Android ในตำแหน่งที่ระบุไว้ด้านบน
อิมเมจการกู้คืนอาจมีกลุ่มย่อยของโมดูลผู้ให้บริการ Android
กำหนดตัวแปร BOARD_RECOVERY_KERNEL_MODULES
สำหรับ
โมดูลเหล่านี้ ตัวอย่าง
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
บิลด์ของ Android จะดูแลเรื่องการเรียกใช้ depmod
เพื่อสร้าง
ต้องใช้ modules.dep
ไฟล์ใน /vendor/lib/modules
และ /lib/modules
(recovery ramfs
)
การโหลดโมดูลและการกำหนดเวอร์ชัน
โหลดโมดูลเคอร์เนลทั้งหมดในบัตรผ่านเดียวจาก init.rc*
ด้วยการเรียกใช้
modprobe -a
การดำเนินการนี้จะช่วยหลีกเลี่ยงค่าใช้จ่ายในการเริ่มต้นทำงานซ้ำๆ
สภาพแวดล้อมรันไทม์ C สำหรับไบนารี modprobe
แก้ไขเหตุการณ์ early-init
รายการให้เรียกใช้ modprobe
ได้
on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ...
โดยปกติแล้ว โมดูลเคอร์เนลจะต้องได้รับการคอมไพล์ด้วยเคอร์เนลที่โมดูลดังกล่าว
ที่จะใช้กับ (มิฉะนั้นเคอร์เนลจะไม่โหลดโมดูล)
CONFIG_MODVERSIONS
ให้วิธีแก้ปัญหาด้วยการตรวจหาการหยุดทำงาน
ในอินเทอร์เฟซแบบไบนารีของแอปพลิเคชัน (ABI) ฟีเจอร์นี้จะคำนวณเป็นวงกลม
ค่าการตรวจสอบความซ้ำซ้อน (CRC) สำหรับต้นแบบของสัญลักษณ์ที่ส่งออกแต่ละรายการในแอตทริบิวต์
เคอร์เนลและจัดเก็บค่าไว้เป็นส่วนหนึ่งของเคอร์เนล สำหรับสัญลักษณ์ที่ใช้โดย
โมดูลเคอร์เนล ค่าจะได้รับการจัดเก็บไว้ในโมดูลเคอร์เนลด้วย เมื่อ
ระบบจะโหลดโมดูล ระบบจะเปรียบเทียบค่าสำหรับสัญลักษณ์ที่โมดูลใช้
กับผู้ใช้ในเคอร์เนล หากค่าตรงกัน ระบบจะโหลดโมดูล
ไม่เช่นนั้นการโหลดจะไม่สำเร็จ
หากต้องการเปิดใช้การอัปเดตอิมเมจเคอร์เนลแยกต่างหากจากอิมเมจของผู้ให้บริการ
เปิดใช้ CONFIG_MODVERSIONS
เนื่องจากจะทำให้สามารถอัปเดต
เคอร์เนล (เช่น การแก้ไขข้อบกพร่องจาก LTS) ที่จะดำเนินการในขณะที่ยังคงรักษาความเข้ากันได้
พร้อมโมดูลเคอร์เนลที่มีอยู่ในอิมเมจของผู้ให้บริการ อย่างไรก็ตาม
CONFIG_MODVERSIONS
จะไม่แก้ไขการหยุดทำงานของ ABI ด้วยตัวเอง หาก
ต้นแบบของสัญลักษณ์ที่ส่งออกในการเปลี่ยนแปลงเคอร์เนล เนื่องจาก
ของแหล่งที่มา หรือเนื่องจากการกำหนดค่าเคอร์เนลมีการเปลี่ยนแปลง
เข้ากันไม่ได้กับโมดูลเคอร์เนลที่ใช้สัญลักษณ์นั้น ในกรณีดังกล่าว
โมดูลเคอร์เนลจะต้องได้รับการคอมไพล์ใหม่
ตัวอย่างเช่น โครงสร้าง task_struct
ในเคอร์เนล (ตามที่กำหนดไว้ใน
include/linux/sched.h
) มีหลายฟิลด์อย่างมีเงื่อนไข
ที่รวมอยู่โดยขึ้นอยู่กับการกำหนดค่าเคอร์เนล sched_info
จะปรากฏขึ้นเมื่อเปิดใช้ CONFIG_SCHED_INFO
เท่านั้น (ซึ่ง
เกิดขึ้นเมื่อ CONFIG_SCHEDSTATS
หรือ
CONFIG_TASK_DELAY_ACCT
เปิดใช้อยู่) หากการกำหนดค่าเหล่านี้
ตัวเลือกเปลี่ยนสถานะ เลย์เอาต์ของโครงสร้าง task_struct
และอินเทอร์เฟซที่ส่งออกจากเคอร์เนลที่ใช้
task_struct
มีการเปลี่ยนแปลง (เช่น
set_cpus_allowed_ptr
ใน kernel/sched/core.c
)
ความเข้ากันได้กับโมดูลเคอร์เนลที่คอมไพล์ก่อนหน้านี้ซึ่งใช้โมดูลเหล่านี้
อินเทอร์เฟซไม่ทำงาน ทำให้ต้องสร้างโมดูลใหม่ด้วยเคอร์เนลใหม่
การกำหนดค่า
ดูรายละเอียดเพิ่มเติมเกี่ยวกับ CONFIG_MODVERSIONS
ได้ที่
ในแผนผังเคอร์เนลที่
Documentation/kbuild/modules.rst