รูปภาพเคอร์เนลทั่วไป

Android สามัญเมล็ด (ACKs) เป็นพื้นฐานสำหรับการทั้งหมดของ Android เมล็ดสินค้า เคอร์เนลของผู้จำหน่ายและอุปกรณ์อยู่ปลายน้ำของ ACK ผู้จำหน่ายเพิ่มการรองรับสำหรับ SoC และอุปกรณ์ต่อพ่วงโดยการแก้ไขซอร์สโค้ดเคอร์เนลและเพิ่มไดรเวอร์อุปกรณ์ การปรับเปลี่ยนเหล่านี้สามารถที่กว้างขวางไปยังจุดที่ได้มากถึง 50% ของรหัสที่ทำงานบนอุปกรณ์ที่เป็นรหัสที่ออกจากต้นไม้ (ไม่ได้มาจากต้นน้ำลินุกซ์หรือจาก AOSP เมล็ดธรรมดา)

ดังนั้น เคอร์เนลของอุปกรณ์จึงประกอบด้วย:

  • ต้นน้ำ: เคอร์เนล Linux จาก kernel.org
  • AOSP: แพตช์เฉพาะ Android เพิ่มเติมจากเคอร์เนลทั่วไปของ AOSP
  • ผู้จำหน่าย: SoC และการเปิดใช้งานอุปกรณ์ต่อพ่วงและแพตช์การปรับให้เหมาะสมจากผู้ขาย
  • OEM/อุปกรณ์: ไดรเวอร์อุปกรณ์เพิ่มเติมและการปรับแต่ง

เกือบทุกอุปกรณ์มีเคอร์เนลที่กำหนดเอง นี่คือการกระจายตัวของเคอร์เนล

ลำดับชั้นของเคอร์เนล Android นำไปสู่การแตกแฟรกเมนต์

รูปที่ 1 Android ลำดับชั้นเคอร์เนลนำไปสู่การกระจายตัว

ค่าใช้จ่ายในการกระจายตัว

การกระจายตัวของเคอร์เนลมีผลเสียหลายประการต่อชุมชน Android

การอัปเดตความปลอดภัยต้องใช้แรงงานมาก

แพทช์การรักษาความปลอดภัยอ้างถึงใน Android Security Bulletin (ASB) จะต้อง backported ในแต่ละเมล็ดอุปกรณ์ อย่างไรก็ตาม เนื่องจากการแตกแฟรกเมนต์ของเคอร์เนล การเผยแพร่การแก้ไขความปลอดภัยไปยังอุปกรณ์ Android ในภาคสนามจึงมีราคาแพงมาก

ยากที่จะรวมการอัปเดตที่รองรับระยะยาว

ระยะยาวที่สนับสนุน (LTS) รุ่นรวมถึงการแก้ไขการรักษาความปลอดภัยและแก้ไขข้อบกพร่องที่สำคัญอื่น ๆ การอัปเดต LTS ให้ทันสมัยอยู่เสมอได้พิสูจน์แล้วว่าเป็นวิธีที่มีประสิทธิภาพมากที่สุดในการแก้ไขปัญหาด้านความปลอดภัย บนอุปกรณ์ Pixel พบว่า 90% ของปัญหาด้านความปลอดภัยเคอร์เนลที่รายงานใน ASB ได้รับการแก้ไขแล้วสำหรับอุปกรณ์ที่อัปเดตอยู่เสมอ

อย่างไรก็ตาม ด้วยการปรับเปลี่ยนแบบกำหนดเองทั้งหมดในเคอร์เนลของอุปกรณ์ เป็นการยากที่จะผสานการแก้ไข LTS เข้ากับเคอร์เนลของอุปกรณ์

ยับยั้งการอัปเกรดการเปิดตัวแพลตฟอร์ม Android

การแยกส่วนทำให้คุณลักษณะใหม่ของ Android ที่ต้องการการเปลี่ยนแปลงเคอร์เนลในการเพิ่มอุปกรณ์ในภาคสนามทำได้ยาก รหัส Android Framework ต้องถือว่ารองรับเวอร์ชันเคอร์เนลมากถึงห้าเวอร์ชันและไม่มีการเปลี่ยนแปลงเคอร์เนลสำหรับการเปิดตัวแพลตฟอร์มใหม่ (Android 10 รองรับ 3.18, 4.4, 4.9, 4.14 และ 4.19 เคอร์เนลซึ่งในบางกรณียังไม่ได้รับ ปรับปรุงด้วยคุณสมบัติใหม่ตั้งแต่ Android 8 ในปี 2560)

ยากที่จะสนับสนุนการเปลี่ยนแปลงเคอร์เนลกลับไปเป็นอัปสตรีม Linux

ด้วยการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นกับเคอร์เนล อุปกรณ์เรือธงส่วนใหญ่จะมาพร้อมกับเวอร์ชันเคอร์เนลที่มีอายุอย่างน้อย 18 เดือนแล้ว ยกตัวอย่างเช่น 4.14 เคอร์เนลถูกปล่อยออกจาก kernel.org ในเดือนพฤศจิกายน 2017 และโทรศัพท์ Android ครั้งแรกที่ใช้ 4.14 เมล็ดส่งในฤดูใบไม้ผลิของ 2019

ความล่าช้าที่ยาวนานระหว่างการเปิดตัวเคอร์เนลอัปสตรีมและผลิตภัณฑ์ทำให้ชุมชน Android ป้อนคุณสมบัติและไดรเวอร์ที่จำเป็นลงในเคอร์เนลอัปสตรีมได้ยาก ดังนั้นจึงเป็นเรื่องยากที่จะแก้ไขปัญหาการแตกแฟรกเมนต์

การแก้ไขการแตกแฟรกเมนต์: Generic Kernel Image

การกระจายตัวทั่วไป Kernel ภาพ (GKI) โครงการที่อยู่เคอร์เนลโดยรวมเคอร์เนลหลักและย้าย SoC และคณะกรรมการสนับสนุนจากเคอร์เนลหลักเป็นโมดูลที่ใส่ได้ GKI เคอร์เนลของขวัญที่มีเสถียรภาพเคอร์เนลโมดูล Interface (KMI) สำหรับโมดูลเคอร์เนลดังนั้นโมดูลและเคอร์เนลสามารถปรับปรุงได้อย่างอิสระ

GKI:

  • ถูกสร้างขึ้นมาจากแหล่ง ACK
  • เป็นคนเดียวเคอร์เนลไบนารีบวกที่เกี่ยวข้องโมดูลที่ใส่ต่อสถาปัตยกรรมต่อ LTS รีลีส (ปัจจุบันเท่านั้น arm64 สำหรับ android11-5.4 และ android12-5.4 )
  • มีการทดสอบกับทุกรุ่น Android แพลตฟอร์มที่ได้รับการสนับสนุนสำหรับ ACK ที่เกี่ยวข้อง ไม่มีการเลิกใช้งานฟีเจอร์ตลอดอายุของเวอร์ชันเคอร์เนล GKI
  • ตีแผ่มั่นคง KMI กับคนขับรถภายใน LTS รับ
  • ไม่ได้มี SoC- หรือคณะกรรมการเฉพาะรหัส

นี่คือลักษณะที่อุปกรณ์ Android ใช้งาน GKI

สถาปัตยกรรม GKI

สถาปัตยกรรมรูปที่ 2 GKI

GKI เป็นการเปลี่ยนแปลงที่ซับซ้อนซึ่งจะเปิดตัวในหลายขั้นตอนโดยเริ่มจากเคอร์เนล v5.4 ในการเปิดตัวแพลตฟอร์ม Android 11

GKI 1.0 — ข้อกำหนดความเข้ากันได้ของ GKI

สำหรับอุปกรณ์บางรุ่นที่เปิดตัวพร้อมกับแพลตฟอร์ม Android 11 ความเข้ากันได้ของ Treble ต้องใช้การทดสอบ GKI สำหรับอุปกรณ์ที่ใช้เคอร์เนล v5.4

พาร์ติชันสำหรับการทดสอบความเข้ากันได้ของ GKI

รูปที่ 3 พาร์ทิชันสำหรับการทดสอบความเข้ากันได้ GKI

GKI เข้ากันได้หมายความว่าอุปกรณ์ที่ผ่านการทดสอบและ VTS CTS-on-GSI + GKI กับทั่วไประบบภาพ (GSI) และเคอร์เนล GKI ติดตั้งโดยการกระพริบของภาพบูต GKI เข้าไปใน boot พาร์ทิชันและระบบภาพ GSI ใน system พาร์ทิชัน อุปกรณ์ที่สามารถจัดส่งกับเคอร์เนลผลิตภัณฑ์ที่แตกต่างและสามารถใช้โมดูลที่ใส่ที่ GKI ไม่ได้ให้ อย่างไรก็ตามทั้งผลิตภัณฑ์และเมล็ด GKI ต้องโหลดโมดูลจากที่เดียวกัน vendor_boot และ vendor พาร์ทิชัน ดังนั้น เคอร์เนลผลิตภัณฑ์ทั้งหมดจะต้องมีอินเทอร์เฟซโมดูลเคอร์เนลไบนารี (KMI) เดียวกัน ผู้ขายสามารถขยาย KMI สำหรับเมล็ดผลิตภัณฑ์ได้ตราบเท่าที่ยังคงเข้ากันได้กับ GKI KMI ไม่มีข้อกำหนดว่าโมดูลผู้ขายจะยกเลิกการโหลดใน GKI 1.0 ได้

GKI 1.0 ประตู

  • อย่าแนะนำการถดถอยใน VTS หรือ CTS เมื่อเคอร์เนลผลิตภัณฑ์ถูกแทนที่ด้วยเคอร์เนล GKI
  • ลดภาระการบำรุงรักษาเคอร์เนลสำหรับ OEM และผู้จำหน่ายเพื่อให้ทันกับเคอร์เนลทั่วไปของ AOSP
  • รวมการเปลี่ยนแปลงหลักของ Android ในเมล็ดไม่ว่าอุปกรณ์จะได้รับการอัปเกรดเป็นแพลตฟอร์ม Android รุ่นใหม่หรือที่เพิ่งเปิดตัวใหม่
  • ไม่เคยทำลายพื้นที่ผู้ใช้ Android
  • แยกส่วนประกอบเฉพาะฮาร์ดแวร์ออกจากเคอร์เนลหลักเป็นโมดูลที่โหลดได้

GKI 2.0 - ผลิตภัณฑ์ GKI

อุปกรณ์บางอย่างที่เปิดตัวกับ Android 12 (2021) เปิดตัวแพลตฟอร์มใช้รุ่นเคอร์เนล V5.10 หรือสูงกว่าจะต้องมาพร้อมกับเคอร์เนล GKI รูปภาพสำหรับบูตที่ผ่านการรับรองจะพร้อมใช้งานและอัปเดตเป็นประจำด้วย LTS และการแก้ไขจุดบกพร่องที่สำคัญ เนื่องจากจะคงความเสถียรของไบนารีไว้สำหรับ KMI อิมเมจสำหรับบูตเหล่านี้จึงสามารถติดตั้งได้โดยไม่เปลี่ยนแปลงอิมเมจของผู้ขาย

GKI 2.0 เป้าหมาย

  • อย่าแนะนำประสิทธิภาพที่สำคัญหรือการถดถอยของพลังงานกับ GKI
  • เปิดใช้งาน OEM เพื่อส่งมอบการแก้ไขความปลอดภัยของเคอร์เนลและการแก้ไขจุดบกพร่อง (LTS) โดยไม่ต้องให้ผู้ขายเข้ามาเกี่ยวข้อง
  • ลดค่าใช้จ่ายในการอัปเดตเวอร์ชันเคอร์เนลหลักสำหรับอุปกรณ์ (เช่น จาก v5.10 เป็นเคอร์เนล 2021 LTS)
  • รักษาไบนารีเคอร์เนล GKI เพียง 1 รายการต่อสถาปัตยกรรมโดยอัปเดตเวอร์ชันเคอร์เนลด้วยกระบวนการที่ชัดเจนสำหรับการอัปเกรด

GKI 2.0 boot.img บูรณาการ

ตั้งค่าตัวแปรคณะกรรมการดังต่อไปนี้จะรวม GKI ได้รับการรับรอง boot.img เข้า codebase ของคุณ การตั้งค่าที่แสดงด้านล่างเป็นเพียงตัวอย่างที่จะปรับตามอุปกรณ์แต่ละเครื่อง

# Uses a prebuilt boot.img
TARGET_NO_KERNEL := true
BOARD_PREBUILT_BOOTIMAGE := device/${company}/${board}/boot.img

# Enables chained vbmeta for the boot.img so it can be updated independently,
# without updating the vbmeta.img. The following configs are optional.
# When they're absent, the hash of the boot.img will be stored then signed in
# the vbmeta.img.
BOARD_AVB_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
BOARD_AVB_BOOT_ALGORITHM := SHA256_RSA4096
BOARD_AVB_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION := 2

การออกแบบ GKI

สาขาเคอร์เนล KMI

เมล็ด GKI ถูกสร้างขึ้นจากสาขาเคอร์เนล ACK KMI ซึ่งจะมีการอธิบายในรายละเอียดใน Android เมล็ดทั่วไป KMI มีการระบุที่ไม่ซ้ำกันโดยรุ่นเคอร์เนลและการเปิดตัวแพลตฟอร์ม Android ดังนั้นสาขาจะถูกตั้งชื่อ <androidRelease>-<kernel version> ยกตัวอย่างเช่น 5.4 KMI สาขาเคอร์เนลสำหรับ Android 11 เป็นชื่อ android11-5.4. มันเป็นที่คาดว่าสำหรับ Android 12 (ไม่ได้มุ่งมั่นและแสดงให้เห็นเพียงเพื่อที่จะแสดงให้เห็นว่ารูปแบบการแตกกิ่งใหม่จะมีความคืบหน้าในอนาคต) จะมีสอง KMI เพิ่มเติมเมล็ด android12-5.4 และเคอร์เนลที่สองขึ้นอยู่กับ 5.10 LTS เมล็ดออกในเดือนธันวาคม 2020.

ลำดับชั้นเคอร์เนล KMI

รูปที่ 4 แสดงลำดับชั้นสาขาสำหรับเมล็ด 5.10 KMI android12-5.10 เป็นเคอร์เนล KMI สอดคล้องกับ Android ที่ 12 และ android13-5.10 สอดคล้องกับ Android T (AOSP ทดลอง) (ไม่ได้มุ่งมั่นและแสดงให้เห็นเพียงเพื่อที่จะแสดงให้เห็นว่ารูปแบบการแตกกิ่งใหม่จะมีความคืบหน้าในอนาคต)

ลำดับชั้นเคอร์เนล KMI สำหรับ 5.10

ลำดับชั้นรูปที่ 4 KMI เคอร์เนลสำหรับ 5.10

ดังแสดงในรูปที่ 4 KMI สาขาวงจรผ่านขั้นตอนที่สาม: การพัฒนา (dev) เสถียรภาพ (แทง) และแช่แข็ง ขั้นตอนเหล่านี้จะอธิบายในรายละเอียดใน Android เมล็ดทั่วไป

หลังจากที่เคอร์เนล KMI ถูกตรึง จะไม่ยอมรับการเปลี่ยนแปลงที่ทำลาย KMI เว้นแต่จะระบุปัญหาด้านความปลอดภัยที่ร้ายแรงซึ่งไม่สามารถบรรเทาได้โดยไม่ส่งผลต่อ KMI ที่เสถียร กิ่งก้านยังคงแข็งตลอดอายุขัย

การแก้ไขข้อบกพร่องและคุณสมบัติของพันธมิตรสามารถยอมรับได้ในสาขาที่ถูกระงับ ตราบใดที่ KMI ที่มีอยู่ไม่เสียหาย KMI สามารถขยายได้ด้วยสัญลักษณ์ที่ส่งออกใหม่ ตราบใดที่อินเทอร์เฟซที่ประกอบด้วย KMI ปัจจุบันไม่ได้รับผลกระทบ เมื่อมีการเพิ่มอินเทอร์เฟซใหม่ลงใน KMI อินเทอร์เฟซจะเสถียรในทันทีและจะไม่ถูกทำลายโดยการเปลี่ยนแปลงในอนาคต

ตัวอย่างเช่น ไม่อนุญาตให้ทำการเปลี่ยนแปลงที่เพิ่มฟิลด์ให้กับโครงสร้างที่ใช้โดยอินเทอร์เฟซ KMI เนื่องจากจะเปลี่ยนการกำหนดอินเทอร์เฟซ:

struct foo {
  int original_field1;
  int original_field2;
  int new_field; // Not allowed
};

int do_foo(struct foo &myarg)
{
  do_something(myarg);
}
EXPORT_SYMBOL_GPL(do_foo);

อย่างไรก็ตาม การเพิ่มฟังก์ชันใหม่นั้นใช้ได้:

struct foo_ext {
  struct foo orig_foo;
  int new_field;
};

int do_foo2(struct foo_ext &myarg)
{
  do_something_else(myarg);
}
EXPORT_SYMBOL_GPL(do_foo2);

เสถียรภาพ KMI

เพื่อให้บรรลุเป้าหมาย GKI การรักษา KMI ให้คงที่สำหรับผู้ขับขี่ถือเป็นสิ่งสำคัญ เคอร์เนล GKI ถูกสร้างและจัดส่งในรูปแบบไบนารี แต่โมดูลที่ผู้ขายโหลดได้นั้นสร้างขึ้นในโครงสร้างที่แยกจากกัน เคอร์เนลและโมดูล GKI ที่เป็นผลลัพธ์ต้องทำงานเสมือนว่าสร้างขึ้นร่วมกัน สำหรับการทดสอบความเข้ากันได้ของ GKI อิมเมจสำหรับเริ่มระบบที่มีเคอร์เนลจะถูกแทนที่ด้วยอิมเมจสำหรับเริ่มระบบที่มีเคอร์เนล GKI และโมดูลที่โหลดได้ในอิมเมจผู้ขายจะต้องทำงานอย่างถูกต้องกับเคอร์เนลอย่างใดอย่างหนึ่ง

KMI ไม่ได้รวมสัญลักษณ์ทั้งหมดในเคอร์เนลหรือแม้แต่สัญลักษณ์ที่ส่งออกทั้งหมด 30,000+ รายการ สัญลักษณ์ที่สามารถใช้ได้โดยโมดูลจะถูกระบุไว้อย่างชัดเจนในชุดของไฟล์รายการสัญลักษณ์ที่ดูแลต่อสาธารณะในรูทของเคอร์เนลทรี การรวมกันของสัญลักษณ์ทั้งหมดในไฟล์รายการสัญลักษณ์ทั้งหมดกำหนดชุดของสัญลักษณ์ KMI ที่คงไว้ซึ่งความเสถียร ไฟล์ตัวอย่างรายการสัญลักษณ์ abi_gki_aarch64_db845c ซึ่งประกาศสัญลักษณ์ที่จำเป็นสำหรับ 845C DragonBoard

เฉพาะสัญลักษณ์ที่อยู่ในรายการสัญลักษณ์และโครงสร้างและคำจำกัดความที่เกี่ยวข้องเท่านั้นที่ถือว่าเป็นส่วนหนึ่งของ KMI คุณสามารถโพสต์การเปลี่ยนแปลงไปยังรายการสัญลักษณ์ของคุณได้หากไม่มีสัญลักษณ์ที่คุณต้องการ หลังจากที่อินเทอร์เฟซใหม่อยู่ในรายการสัญลักษณ์ และเป็นส่วนหนึ่งของคำอธิบาย KMI อินเทอร์เฟซเหล่านั้นจะคงความเสถียรและต้องไม่ถูกลบออกจากรายการสัญลักษณ์หรือแก้ไขหลังจากที่สาขาถูกตรึง

ต้นไม้เคอร์เนล KMI แต่ละอันมีชุดรายการสัญลักษณ์ของตัวเอง ไม่มีการพยายามให้ความเสถียรของ ABI ระหว่างสาขาเคอร์เนล KMI ที่ต่างกัน ยกตัวอย่างเช่น KMI สำหรับ android11-5.4 เป็นอิสระอย่างสมบูรณ์ของ KMI สำหรับ android12-5.4

โดยทั่วไปชุมชน Linux ได้ ขมวดคิ้วคิดของในเคอร์เนล ABI ความมั่นคง สำหรับเคอร์เนลฉีด เมื่อเผชิญกับ toolchains การกำหนดค่าต่างๆ และเคอร์เนล mainline ของ Linux ที่เปลี่ยนแปลงตลอดเวลา การรักษา KMI ที่เสถียรใน mainline นั้นไม่สามารถทำได้ อย่างไรก็ตาม เป็นไปได้ในสภาพแวดล้อม GKI ที่มีข้อจำกัดสูง ข้อจำกัดคือ:

  • KMI เป็นเพียงมั่นคงภายใน LTS เคอร์เนลเดียวกัน (เช่น android11-5.4 )
    • ความมั่นคงไม่มี KMI เพื่อรักษา android-mainline
  • เฉพาะที่เฉพาะเจาะจง toolchain เสียงดังกราวจำหน่ายใน AOSP และกำหนดไว้สำหรับสาขาที่สอดคล้องกันถูกนำมาใช้สำหรับการสร้างเคอร์เนลและโมดูล
  • เฉพาะสัญลักษณ์ที่ทราบว่าใช้โดยโมดูลตามที่ระบุไว้ในรายการสัญลักษณ์เท่านั้นที่จะถูกตรวจสอบเพื่อความเสถียรและถือเป็นสัญลักษณ์ KMI
    • ผลที่ตามมาคือโมดูลต้องใช้สัญลักษณ์ KMI เท่านั้น สิ่งนี้ถูกบังคับใช้โดยการโหลดโมดูลที่ล้มเหลวหากจำเป็นต้องใช้สัญลักษณ์ที่ไม่ใช่ KMI
  • หลังจากที่สาขา KMI ถูกแช่แข็ง การเปลี่ยนแปลงใดๆ ก็ตามไม่สามารถทำลาย KMI ได้ ซึ่งรวมถึง:
    • การเปลี่ยนแปลงการกำหนดค่า
    • การเปลี่ยนแปลงรหัสเคอร์เนล
    • การเปลี่ยนแปลง Toolchain (รวมถึงการอัปเดต)

การตรวจสอบ KMI

ABI เครื่องมือการตรวจสอบการ ตรวจสอบความมั่นคง KMI ในระหว่างการทดสอบ presubmit การเปลี่ยนแปลงที่ทำลาย KMI ล้มเหลวในการทดสอบล่วงหน้าและต้องทำงานใหม่เพื่อให้เข้ากันได้ เครื่องมือเหล่านี้มีให้สำหรับพันธมิตรและสาธารณชนทั่วไปสำหรับการรวมเข้ากับกระบวนการสร้างของพวกเขา ทีมเคอร์เนลของ Android ใช้เครื่องมือเหล่านี้เพื่อค้นหาการขัดข้องของ KMI ระหว่างการพัฒนาและเมื่อรวมรุ่น LTS เข้าด้วยกัน หากตรวจพบการแตกของ KMI ระหว่างการผสาน LTS KMI จะได้รับการเก็บรักษาไว้โดยการเอาแพตช์ที่ละเมิดออก หรือโดยการปรับโครงสร้างแพตช์ใหม่เพื่อให้เข้ากันได้

KMI จะถือว่าใช้งานไม่ได้หากสัญลักษณ์ KMI ที่มีอยู่ได้รับการแก้ไขในลักษณะที่เข้ากันไม่ได้ ตัวอย่าง:

  • เพิ่มอาร์กิวเมนต์ใหม่ในฟังก์ชัน KMI
  • เพิ่มฟิลด์ใหม่ให้กับโครงสร้างที่ใช้โดยฟังก์ชัน KMI
  • เพิ่มค่า enum ใหม่ที่เปลี่ยนค่าของ enums ที่ใช้โดยฟังก์ชัน KMI
  • การเปลี่ยนแปลงการกำหนดค่าที่เปลี่ยนการมีอยู่ของสมาชิกข้อมูลที่ส่งผลต่อ KMI

การเพิ่มสัญลักษณ์ใหม่ไม่จำเป็นต้องทำให้ KMI เสียหาย แต่จะต้องเพิ่มสัญลักษณ์ใหม่ที่ใช้ในรายการสัญลักษณ์และในการแทนค่า ABI มิฉะนั้น การเปลี่ยนแปลงในอนาคตในส่วนนี้ของ KMI จะไม่เป็นที่รู้จัก

พาร์ทเนอร์ควรใช้เครื่องมือตรวจสอบ ABI เพื่อเปรียบเทียบ KMI ระหว่างเคอร์เนลผลิตภัณฑ์กับเคอร์เนล GKI และตรวจสอบว่าเข้ากันได้

ล่าสุด android11-5.4 ไบนารี GKI เคอร์เนลสามารถดาวน์โหลดได้จาก ci.android.com ( kernel_aarch64 สร้าง)

คอมไพเลอร์เดี่ยว

การเปลี่ยนแปลงคอมไพเลอร์สามารถเปลี่ยนเค้าโครงโครงสร้างข้อมูลเคอร์เนลภายในที่ส่งผลต่อ ABI เนื่องจากการรักษา KMI ให้มีเสถียรภาพเป็นสิ่งสำคัญ ดังนั้น toolchain ที่ใช้สร้างเคอร์เนล GKI จึงต้องเข้ากันได้กับ toolchain ที่ใช้สร้างโมดูลผู้ขายอย่างสมบูรณ์ เคอร์เนล GKI สร้างขึ้นด้วยชุดเครื่องมือ LLVM ที่รวมอยู่ใน AOSP

ตั้งแต่ Android 10 เป็นต้นไป เคอร์เนล Android ทั้งหมดจะต้องสร้างด้วย LLVM toolchain ด้วย GKI ชุดเครื่องมือ LLVM ที่ใช้สร้างเคอร์เนลผลิตภัณฑ์และโมดูลผู้ขายต้องสร้าง ABI เดียวกันกับชุดเครื่องมือ LLVM จาก AOSP และพาร์ทเนอร์ต้องมั่นใจว่า KMI เข้ากันได้กับเคอร์เนล GKI

Android เคอร์เนลสร้างเอกสาร อธิบายวิธีเคอร์เนลอ้างอิง GKI ถูกสร้างขึ้น โดยเฉพาะอย่างยิ่ง โพรซีเดอร์ที่จัดทำเป็นเอกสารช่วยให้แน่ใจว่า toolchain และคอนฟิกูเรชันที่ถูกต้องถูกใช้เพื่อสร้างเคอร์เนล พาร์ทเนอร์ดาวน์สตรีมควรใช้เครื่องมือเดียวกันเพื่อสร้างเคอร์เนลสุดท้ายเพื่อหลีกเลี่ยงความไม่เข้ากันที่เกิดจาก toolchain หรือการพึ่งพาเวลาสร้างอื่นๆ

การกำหนดค่าเคอร์เนล

เคอร์เนล GKI สร้างขึ้นโดยใช้ arch/arm64/configs/gki_defconfig เนื่องจากการกำหนดค่าเหล่านี้ส่งผลต่อ KMI การกำหนดค่า GKI จึงได้รับการจัดการอย่างระมัดระวัง สำหรับเคอร์เนล KMI ที่ตรึงไว้ การกำหนดค่าสามารถเพิ่มหรือลบได้ก็ต่อเมื่อไม่มีผลกระทบกับ KMI เท่านั้น

ต้องกำหนดค่าเคอร์เนล GKI เพื่อให้ทำงานบนอุปกรณ์ที่หลากหลาย ดังนั้นจึงต้องมีการรองรับในตัวสำหรับระบบย่อยและตัวเลือกทั้งหมดที่จำเป็นสำหรับอุปกรณ์เหล่านี้ทั้งหมด ไม่รวมโมดูลที่โหลดได้ที่ใช้เพื่อเปิดใช้งานฮาร์ดแวร์ พาร์ทเนอร์ควร ขอเปลี่ยนแปลงการตั้งค่าที่จำเป็น เพื่อ dev เมล็ด

การเปลี่ยนแปลงการบูต

เพื่ออำนวยความสะดวกการแยกทำความสะอาดระหว่าง GKI และผู้ขายชิ้นส่วนที่ boot พาร์ทิชันที่มีเพียงส่วนประกอบทั่วไปรวมทั้งเมล็ดและ ramdisk กับโมดูล GKI เวอร์ชันใหม่ของส่วนหัวสำหรับบูต (v3) ถูกกำหนดเพื่อระบุการปฏิบัติตามสถาปัตยกรรม GKI Google เป็นผู้จัดส่งรูปภาพสำหรับบูตเวอร์ชัน GKI และแทนที่เวอร์ชันสำหรับบูตอิมเมจของผู้ขายเมื่อทดสอบความเข้ากันได้ของ GKI

ramdisk สำหรับขั้นตอนแรก init , recovery และ fastbootd เป็น initramfs ภาพประกอบด้วยสองจดหมายเหตุ CPIO ที่มีการตัดแบ่งโดยบูต ครั้งแรกที่เก็บมาจาก CPIO ใหม่ vendor_boot พาร์ทิชัน อย่างที่สองมาจาก boot พาร์ทิชัน

ข้อมูลสรุปการเปลี่ยนแปลงมีให้ที่นี่ ดู พาร์ทิชันบูตผู้ขาย สำหรับรายละเอียด

พาร์ติชั่นบูต

boot พาร์ทิชันรวมถึงส่วนหัวเคอร์เนลและ CPIO เก็บของส่วนทั่วไปของ ramdisk บูต

ด้วย v3 หัวบูต boot พาร์ทิชันส่วนเหล่านี้ก่อน boot พาร์ทิชันปัจจุบันนี้ไม่มีอีกต่อไป:

  • bootloader ขั้นที่สอง: หากอุปกรณ์มี bootloader ระยะที่สอง จะต้องเก็บไว้ในพาร์ติชั่นของตัวเอง
  • DTB: ผู้ DTB ถูกเก็บไว้ใน พาร์ทิชันบูตผู้ขาย

boot พาร์ทิชันที่มีเก็บ CPIO มีส่วนประกอบ GKI นี้:

  • โมดูลเคอร์เนล GKI อยู่ใน /lib/modules/
  • first_stage_init และห้องสมุดมันขึ้นอยู่กับ
  • fastbootd และ recovery (ใช้ไปใน A / B และ Virtual A / อุปกรณ์ B)

ภาพบูต GKI ให้บริการโดย Google และจะต้องใช้สำหรับการ ทดสอบความเข้ากัน GKI

ล่าสุด arm64 android11-5.4 boot.img สามารถดาวน์โหลดได้จาก ci.android.com ใน aosp_arm64 สร้างสิ่งประดิษฐ์ของ aosp-master สาขา

ล่าสุด arm64 android11-5.4 เคอร์เนลภาพ ( Image.gz ) สามารถดาวน์โหลดได้จาก ci.android.com ใน kernel_aarch64 สร้างสิ่งประดิษฐ์ของ aosp_kernel-common-android11-5.4 สาขา

พาร์ติชันสำหรับเริ่มระบบของผู้จำหน่าย

vendor_boot พาร์ทิชันที่ถูกนำมาใช้กับ GKI เป็น A/B กับ Virtual A/B และประกอบด้วยส่วนหัว ramdisk ของผู้ขาย และ tree blob ของอุปกรณ์ ramdisk ของผู้ขายเป็นไฟล์เก็บถาวร CPIO ที่มีโมดูลผู้ขายที่จำเป็นสำหรับการบู๊ตอุปกรณ์ ซึ่งรวมถึงโมดูลเพื่อเปิดใช้งานฟังก์ชันการทำงานที่สำคัญของ SoC ตลอดจนไดรฟ์จัดเก็บข้อมูลและการแสดงผลที่จำเป็นสำหรับการบูตอุปกรณ์และแสดงหน้าจอเริ่มต้น

ไฟล์เก็บถาวร CPIO ประกอบด้วย:

  • ขั้นตอนแรก init ผู้ขายเคอร์เนลโมดูลอยู่ใน /lib/modules/
  • modprobe ไฟล์ config อยู่ใน /lib/modules
  • modules.load ไฟล์ที่ระบุโมดูลที่จะโหลดในช่วงระยะแรก init

ข้อกำหนดสำหรับบูตโหลดเดอร์

bootloader ต้องโหลด ramdisk ทั่วไป CPIO ภาพ (จาก boot พาร์ทิชัน ) ในหน่วยความจำได้ทันทีดังต่อไปนี้ภาพของผู้ขาย ramdisk CPIO (จาก vendor_boot พาร์ทิชัน ) หลังจากคลายการบีบอัด ผลลัพธ์จะเป็น ramdisk ทั่วไปที่ซ้อนทับบนโครงสร้างไฟล์ของ ramdisk ของผู้ขาย

การทดสอบความเข้ากันได้ของ GKI

สำหรับการเปิดตัวแพลตฟอร์ม Android 11 อุปกรณ์ที่เปิดตัวด้วยเคอร์เนล v5.4 จะต้องเรียกใช้การทดสอบ VTS และ CTS-on-GSI โดยใช้อิมเมจสำหรับบูต GKI ที่ Google จัดหาให้

มีส่วนร่วมในเคอร์เนล GKI

เคอร์เนล GKI ถูกสร้างขึ้นจาก AOSP สามัญเมล็ดที่เริ่มต้นด้วย android11-5.4 แพทช์ส่งทั้งหมดต้องเป็นไปตาม แนวทางการมีส่วนร่วมเหล่านี้ ซึ่งเอกสารสองกลยุทธ์:

  1. ที่ดีที่สุด: ทำให้การเปลี่ยนแปลงทั้งหมดของคุณต้นน้ำลินุกซ์ หากเหมาะสม ให้แบ็คพอร์ตไปยังรุ่นเสถียร แพตช์เหล่านี้จะถูกรวมโดยอัตโนมัติในเคอร์เนลทั่วไปของ AOSP ที่สอดคล้องกัน หากแพตช์อยู่ในอัปสตรีม Linux อยู่แล้ว ให้โพสต์แบ็คพอร์ตของแพตช์ที่สอดคล้องกับข้อกำหนดของแพตช์ด้านล่าง
  2. น้อยดี: การพัฒนาแพทช์ของคุณออกจากต้นไม้ (จากจุดต้นน้ำลินุกซ์ของมุมมอง) เว้นแต่แพทช์ที่มีการแก้ไขข้อผิดพลาดของ Android เฉพาะที่พวกเขากำลังมากไม่น่าจะได้รับการยอมรับจนกว่าพวกเขาจะได้รับการประสานงานกับ kernel-team@android.com

สำหรับพันธมิตรที่ใช้ GKI อาจมีเหตุผลที่ถูกต้องว่าทำไมต้องมีโปรแกรมแก้ไขที่ไม่อยู่ในโครงสร้าง (โดยเฉพาะอย่างยิ่งหากมีกำหนดการซิลิคอนที่ต้องปฏิบัติตาม) สำหรับกรณีนี้ยื่น Buganizer ปัญหา

ส่งการเปลี่ยนแปลง GKI ผ่าน Gerrit กับ android-mainline สาขาแรกแล้ว backported สาขาเปิดตัวอื่น ๆ ที่จำเป็น

ซอร์สโค้ดที่เชื่อมโยงกับโมดูลที่โหลดได้ไม่จำเป็นต้องสนับสนุนโครงสร้างต้นทางเคอร์เนล GKI อย่างไรก็ตาม ขอแนะนำอย่างยิ่งให้ส่งไดรเวอร์ทั้งหมดไปยังอัปสตรีม Linux

ขอ backport จาก mainline

โดยทั่วไป แพตช์หลักที่จำเป็นสำหรับพาร์ทเนอร์ GKI สามารถแบ็คพอร์ตไปยังเคอร์เนล GKI ได้ อัปโหลดแพทช์เพื่อ Gerrit ดังต่อไปนี้ แนวทางการมีส่วนร่วม

หากแพตช์ถูกโพสต์อัปสตรีมแล้ว แต่ยังไม่ได้รับการยอมรับ ขอแนะนำให้รอจนกว่าจะได้รับการยอมรับ หากกำหนดการไม่อนุญาตให้รอการรองรับแพตช์อัปสตรีม ให้ยื่นเรื่อง Buganizer

การเพิ่มและลบการกำหนดค่า GKI

หากต้องการขอเพิ่มหรือการกำจัดของ configs ใน arch/arm64/configs/gki_defconfig ยื่นปัญหา Buganizer อย่างชัดเจนระบุคำขอและเหตุผล หากไม่มีโครงการ Buganizer ที่เข้าถึงได้ ให้โพสต์โปรแกรมแก้ไขโดยเปลี่ยนการกำหนดค่าเป็น Gerrit และตรวจสอบให้แน่ใจว่าข้อความยืนยันระบุเหตุผลที่ต้องมีการกำหนดค่าอย่างชัดเจน

การเปลี่ยนแปลงการกำหนดค่าในเคอร์เนล KMI ที่ตรึงไว้ต้องไม่มีผลกับ KMI

การแก้ไขรหัสเคอร์เนลหลัก

ไม่แนะนำให้แก้ไขรหัสเคอร์เนลหลักในเคอร์เนลทั่วไปของ AOSP ขั้นแรกให้ส่งแพตช์ไปยังอัปสตรีม Linux แล้วจึงแบ็คพอร์ต หากมีเหตุผลที่ดีสำหรับการเปลี่ยนแปลงเคอร์เนลหลัก ให้ยื่นปัญหา Buganizer โดยระบุคำขอและเหตุผลให้ชัดเจน ไม่ยอมรับคุณสมบัติเฉพาะของ Android โดยไม่มีปัญหา Buganizer ส่งอีเมลไปที่ kernel-team@android.com ถ้าคุณไม่สามารถสร้างปัญหา Buganizer

การส่งออกสัญลักษณ์โดยใช้ผ่าน EXPORT_SYMBOL_GPL()

อย่าส่งแพตช์อัปสตรีมที่มีเฉพาะการส่งออกสัญลักษณ์ ที่จะได้รับการพิจารณาสำหรับลินุกซ์ต้นน้ำเพิ่มเติมของ EXPORT_SYMBOL_GPL() ต้องมีไดรเวอร์ modular ในต้นไม้ที่ใช้สัญลักษณ์เพื่อให้รวมถึงคนขับรถใหม่หรือการเปลี่ยนแปลงไปสู่การขับรถที่มีอยู่ใน patchset เช่นเดียวกับการส่งออก

เมื่อส่งแพตช์อัพสตรีม ข้อความคอมมิตต้องมีเหตุผลที่ชัดเจนว่าเหตุใดแพตช์จึงมีความจำเป็นและเป็นประโยชน์ต่อชุมชน การเปิดใช้งานการส่งออกเพื่อประโยชน์ของไดรเวอร์หรือฟังก์ชันที่ไม่อยู่ในโครงสร้าง ไม่ใช่ข้อโต้แย้งที่โน้มน้าวใจผู้ดูแลต้นน้ำ

หากไม่สามารถส่งแพตช์อัพสตรีมได้ด้วยเหตุผลบางประการ แจ้งปัญหา Buganizer และอธิบายว่าทำไมแพตช์จึงไม่สามารถส่งอัปสตรีมได้ โดยทั่วไป สัญลักษณ์ที่เป็นอินเทอร์เฟซที่รองรับกับระบบย่อยเคอร์เนลมักจะได้รับการยอมรับว่าเป็นการส่งออก อย่างไรก็ตาม ระบบอาจไม่ยอมรับฟังก์ชันตัวช่วยภายในแบบสุ่ม และระบบจะขอให้คุณจัดโครงสร้างโค้ดใหม่เพื่อหลีกเลี่ยงการใช้งาน

การเพิ่มสัญลักษณ์ในรายการสัญลักษณ์ KMI

รายการสัญลักษณ์ KMI ต้องอัปเดตด้วยสัญลักษณ์เคอร์เนล GKI ที่ใช้โดยโมดูลผู้ขาย เนื่องจากมีเพียงสัญลักษณ์ KMI เท่านั้นที่รักษาความเสถียร GKI ไม่อนุญาตให้โหลดโมดูลหากใช้สัญลักษณ์ที่ไม่ใช่ KMI

extract_symbols สคริปต์สารสกัดจากสัญลักษณ์ที่เกี่ยวข้องจากเคอร์เนลสร้างต้นไม้และสามารถนำมาใช้ในการปรับปรุงรายการสัญลักษณ์ KMI อ้างถึง เอกสารรายชื่อสัญลักษณ์ สำหรับรายละเอียดเพิ่มเติม