OEM ของ Android จำนวนมากแก้ไขไดรเวอร์เคอร์เนล ION ด้วยเหตุผลหลายประการ เช่น การเพิ่มฮีปของผู้จำหน่ายและการปรับแต่งการจัดการแคช (สำหรับรายละเอียดเกี่ยวกับการแก้ไขเหล่านี้ โปรดดูที่ การรวมตัวจัดสรรหน่วยความจำ ION ) เพื่อให้ OEM สามารถเก็บการแก้ไขดังกล่าวไว้ได้เมื่อใช้ Generic Kernel Image (GKI) นั้น Android Common Kernel v5.4 จะแนะนำเฟรมเวิร์กสำหรับการทำให้ฮีป ION เฉพาะผู้จำหน่ายเป็นโมดูล ในขณะที่ยังคงรักษาไดรเวอร์ ION หลักไว้ รูปภาพต่อไปนี้แสดงเค้าโครงรูปภาพเคอร์เนล .
รูปที่ 1. ไดรเวอร์เคอร์เนล ION แบบโมดูลาร์
ฮีป ION แบบโมดูลาร์มีข้อดีดังต่อไปนี้
- ไดรเวอร์หลัก ION สามารถเป็นส่วนหนึ่งของอิมเมจ GKI ซึ่งช่วยให้สามารถเพิ่มประสิทธิภาพการทำงานที่ไม่ขึ้นอยู่กับอุปกรณ์และแก้ไขข้อบกพร่องเพื่อเข้าถึงอุปกรณ์ทั้งหมดได้
- ไดรเวอร์หลัก ION ในเคอร์เนลทั่วไปสามารถจัดการการลงทะเบียนฮีปและจัดการอินเทอร์เฟซไปยังพื้นที่ผู้ใช้และไคลเอนต์เคอร์เนล โมดูลฮีปของผู้ขายจำเป็นต่อการดำเนินการฮีปแบบกำหนดเองเท่านั้น
- ไดรเวอร์หลัก ION (ซึ่งเป็นส่วนหนึ่งของ GKI) สามารถรวม hooks เพื่อการติดตามการใช้หน่วยความจำที่ง่ายขึ้น ซึ่งเป็นไปไม่ได้เมื่อ 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 ประกอบด้วยการใช้งานแบบโมดูลาร์ของระบบและฮีปการจัดสรรหน่วยความจำที่ต่อเนื่องกัน (CMA) เพื่อใช้เป็นข้อมูลอ้างอิงสำหรับการทำให้เป็นโมดูลของฮีป
การเปลี่ยนแปลงส่วนหัว ION UAPI
ส่วนหัว ION user space API (UAPI) มี ion_heap_id
enum สำหรับใช้ในการกำหนดช่วงของ ID ฮีปสำหรับใช้งานโดยฮีปของผู้จำหน่าย
/**
* 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 เพื่อให้แน่ใจว่าฟีเจอร์ใดๆ ที่ต้องการเข้าถึงฮีปทั่วไป/ไม่ขึ้นกับอุปกรณ์นั้นจะขึ้นอยู่กับการมีอยู่ของมัน ด้วยเหตุนี้ คุณจึงไม่สามารถแทนที่ Heap ID ของ ION_HEAP_SYSTEM
ได้ หากต้องการสร้างฮีประบบที่กำหนดเอง ให้ใช้ ID ฮีปในช่วงที่กำหนดเอง ( ION_HEAP_CUSTOM_START
ถึง ION_HEAP_CUSTOM_END
) เพื่อดำเนินการจัดสรร