แยกฮีป ION สำหรับ GKI

OEM ของ Android หลายรายแก้ไขไดรเวอร์เคอร์เนล ION ด้วยเหตุผลหลายประการ เช่น การใส่กองของผู้ให้บริการและการปรับแต่งการจัดการแคช (ดูรายละเอียดเกี่ยวกับการแก้ไขเหล่านี้ได้ที่การผสานรวมตัวจัดสรรหน่วยความจำ ION) เพื่อให้ OEM เก็บการแก้ไขดังกล่าวไว้ได้เมื่อใช้ Generic Kernel Image (GKI) นั้น Android Common Kernel v5.4 ได้เปิดตัวเฟรมเวิร์กสำหรับการจัดโมดูลกอง ION เฉพาะของผู้ให้บริการขณะที่ยังคงใช้ไดรเวอร์ ION หลักในตัว รูปภาพต่อไปนี้แสดงเลย์เอาต์ของภาพเคอร์เนล

กอง ION แบบแยกส่วน

รูปที่ 1 ไดรเวอร์เคอร์เนล ION แบบโมดูล

กอง ION แบบโมดูลมีข้อดีดังต่อไปนี้

  • โปรแกรมควบคุมหลัก ION สามารถเป็นส่วนหนึ่งของภาพ GKI ซึ่งช่วยให้การเพิ่มประสิทธิภาพและแก้ไขข้อบกพร่องที่ไม่ขึ้นอยู่กับอุปกรณ์ทั้งหมดเข้าถึงอุปกรณ์ทั้งหมดได้
  • โปรแกรมควบคุมหลัก ION ในเคอร์เนลทั่วไปสามารถจัดการการลงทะเบียนกองและจัดการอินเทอร์เฟซกับพื้นที่ผู้ใช้และไคลเอ็นต์เคอร์เนล จำเป็นต้องใช้ข้อบังคับของกองขยะผู้ให้บริการเพื่อใช้การดำเนินการกองขยะที่กำหนดเองเท่านั้น
  • โปรแกรมควบคุมหลัก ION (เป็นส่วนหนึ่งของ GKI) สามารถใส่ฮุกเพื่อให้ติดตามการใช้หน่วยความจำได้ง่ายขึ้น ซึ่งไม่สามารถทำได้เมื่อ OEM แต่ละรายมีโปรแกรมควบคุม ION เวอร์ชันของตนเอง
  • กอง ION ของเวนเดอร์แบบโมดูลจะช่วยให้การเปลี่ยนไปใช้กอง dmabuf ในอนาคตง่ายขึ้น

การใช้งาน

โมดูลกอง ION สามารถลงทะเบียนการดำเนินการ dmabuf ของตนเองเพื่อลบล้างการดำเนินการที่ลงทะเบียนโดยไดรเวอร์ ION หลัก การดำเนินการ dmabuf (เช่น get_flags()) ที่ไดรเวอร์ ION หลักไม่รองรับจะแสดงผลเป็น -EOPNOTSUPP หากการใช้งานกองไม่มีการลบล้างที่จำเป็น

เพื่อปรับปรุงประสิทธิภาพ ไดร์เวอร์ dmabuf สามารถทำการบำรุงรักษาแคชบางส่วนได้ (ดูรายการการเปลี่ยนแปลง) ไคลเอ็นต์เคอร์เนลสามารถใช้ฟังก์ชัน dma_buf_begin_cpu_access_partial และ dma_buf_end_cpu_access_partial เพื่อดำเนินการบำรุงรักษาแคชบางส่วน

Android Common Kernel มีการใช้ระบบแบบแยกส่วนและฮีปที่จัดสรรหน่วยความจำ (CMA) ต่อเนื่องเพื่อใช้เป็นข้อมูลอ้างอิงสำหรับการแยกฮีปเป็นโมดูล

การเปลี่ยนแปลงส่วนหัว ION UAPI

ส่วนหัว ION user space API (UAPI) มี ion_heap_id enum สำหรับใช้ในการกำหนดช่วงรหัสกองสำหรับใช้โดยกองของผู้ให้บริการ

 /**
 * ion_heap_id - list of heap IDs that Android can use
 *
 * @ION_HEAP_SYSTEM        ID for the ION_HEAP_TYPE_SYSTEM
 * @ION_HEAP_DMA_START     Start of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
 * @ION_HEAP_DMA_END       End of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
 * @ION_HEAP_CUSTOM_START  Start of reserved ID range for heaps of custom type
 * @ION_HEAP_CUSTOM_END    End of reserved ID range for heaps of custom type
 */

enum ion_heap_id {

   ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM),

   ION_HEAP_DMA_START = (ION_HEAP_SYSTEM << 1),

   ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7),
   ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1),

   ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 22),
};

นอกจากนี้ IOCTL ใหม่ (ION_IOC_ABI_VERSION) ยังช่วยให้ไคลเอ็นต์พื้นที่ผู้ใช้ทราบได้ว่ามีการใช้กองแบบโมดูลหรือไม่

การลบล้างฮีประบบทั่วไป

กองขยะระบบ ION จะฝังอยู่ในและเป็นส่วนหนึ่งของอิมเมจ GKI เพื่อให้แน่ใจว่าฟีเจอร์ใดก็ตามที่ต้องการเข้าถึงกองขยะทั่วไป/ที่ไม่ขึ้นอยู่กับอุปกรณ์จะใช้งานได้ คุณจึงลบล้างรหัสกองขยะของ ION_HEAP_SYSTEM ไม่ได้ หากต้องการสร้างกองขยะของระบบที่กําหนดเอง ให้ใช้รหัสกองขยะในช่วงที่กําหนดเอง (ION_HEAP_CUSTOM_START ถึง ION_HEAP_CUSTOM_END) เพื่อจัดสรร