Generic Kernel Image (GKI) ช่วยลดการกระจายตัวของเคอร์เนลโดยการจัดตำแหน่งอย่างใกล้ชิดกับเคอร์เนล Linux อัปสตรีม อย่างไรก็ตาม มีสาเหตุที่ถูกต้องว่าทำไมจึงไม่ยอมรับแพตช์บางตัวในต้นทาง และมีกำหนดการของผลิตภัณฑ์ที่ต้องปฏิบัติตาม ดังนั้นแพตช์บางรายการจึงได้รับการบำรุงรักษาในแหล่งที่มาของ Android Common Kernel (ACK) ที่ใช้สร้าง GKI
นักพัฒนาจะต้องส่งการเปลี่ยนแปลงโค้ดอัปสตรีมโดยใช้ Linux Kernel Mailing List (LKML) เป็นตัวเลือกแรก และส่งการเปลี่ยนแปลงโค้ดไปยังสาขา android-mainline
ACK เฉพาะเมื่อมีเหตุผลที่ชัดเจนว่าทำไมอัปสตรีมไม่สามารถใช้งานได้ ตัวอย่างของเหตุผลที่ถูกต้องและวิธีการจัดการมีดังต่อไปนี้
โปรแกรมแก้ไขถูกส่งไปยัง LKML แต่ไม่ได้รับการยอมรับทันเวลาสำหรับการเปิดตัวผลิตภัณฑ์ วิธีจัดการกับแพตช์นี้:
- แสดงหลักฐานว่าได้ส่งโปรแกรมแก้ไขไปยัง LKML และความคิดเห็นที่ได้รับสำหรับโปรแกรมแก้ไข หรือเวลาโดยประมาณที่โปรแกรมแก้ไขจะถูกส่งต้นทาง
- ตัดสินใจเลือกแนวทางดำเนินการเพื่อนำแพตช์ลง ACK ให้ได้รับการอนุมัติอัปสตรีม จากนั้นนำออกจาก ACK เมื่อเวอร์ชันอัปสตรีมสุดท้ายถูกรวมเข้ากับ ACK
โปรแกรมแก้ไขกำหนด
EXPORT_SYMBOLS_GPL()
สำหรับโมดูลผู้ขาย แต่ไม่สามารถส่งอัปสตรีมได้เนื่องจากไม่มีโมดูลในแผนผังที่ใช้สัญลักษณ์นั้น ในการจัดการกับแพตช์นี้ โปรดระบุรายละเอียดว่าทำไมโมดูลของคุณจึงไม่สามารถส่งอัปสตรีมได้ และทางเลือกอื่นที่คุณพิจารณาก่อนที่จะส่งคำขอนี้แพตช์นี้ไม่ทั่วถึงเพียงพอสำหรับอัพสตรีม และไม่มีเวลาที่จะปรับโครงสร้างใหม่ก่อนที่จะออกผลิตภัณฑ์ ในการจัดการแพตช์นี้ ให้ระบุเวลาโดยประมาณที่แพตช์ที่ปรับโครงสร้างใหม่จะถูกส่งต้นทาง (แพตช์จะไม่ได้รับการยอมรับใน ACK หากไม่มีแผนที่จะส่งแพตช์ที่ปรับโครงสร้างใหม่ต้นทางเพื่อรับการตรวจทาน)
อัพสตรีมไม่สามารถยอมรับแพตช์ได้เนื่องจาก... <ใส่เหตุผลที่นี่> ในการจัดการกับแพตช์นี้ โปรดติดต่อทีมเคอร์เนล Android และทำงานร่วมกับเราเกี่ยวกับตัวเลือกต่างๆ ในการปรับโครงสร้างแพตช์ใหม่ เพื่อให้สามารถส่งเข้ารับการตรวจสอบและยอมรับอัปสตรีมได้
มีเหตุผลที่เป็นไปได้อีกมากมาย เมื่อคุณส่งจุดบกพร่องหรือแพทช์ของคุณ ให้ระบุเหตุผลที่ถูกต้องและคาดว่าจะมีการทำซ้ำและการอภิปราย เราตระหนักดีว่า ACK จะมีแพตช์บางส่วน โดยเฉพาะอย่างยิ่งในช่วงแรกของ GKI ในขณะที่ทุกคนกำลังเรียนรู้วิธีการทำงานต้นน้ำ แต่ไม่สามารถผ่อนปรนกำหนดการของผลิตภัณฑ์ให้ทำเช่นนั้นได้ คาดว่าข้อกำหนดการอัปสตรีมจะเข้มงวดมากขึ้นเมื่อเวลาผ่านไป
ข้อกำหนดของแพทช์
แพตช์ต้องเป็นไปตามมาตรฐานการเข้ารหัสเคอร์เนล Linux ที่อธิบายไว้ใน แผนผังต้นทางของ Linux ไม่ว่าจะส่งอัปสตรีมหรือส่งไปยัง ACK ก็ตาม สคริปต์ scripts/checkpatch.pl
ทำงานเป็นส่วนหนึ่งของการทดสอบส่งล่วงหน้าของ Gerrit ดังนั้นให้รันสคริปต์ล่วงหน้าเพื่อให้แน่ใจว่าผ่าน หากต้องการรันสคริปต์ checkpatch ด้วยการกำหนดค่าเดียวกันกับการทดสอบก่อนส่ง ให้ใช้ //build/kernel/static_analysis:checkpatch_presubmit
สำหรับรายละเอียด โปรดดูที่ build/kernel/kleaf/docs/checkpatch.md
ACK แพตช์
แพตช์ที่ส่งไปยัง ACK จะต้องเป็นไปตามมาตรฐานการเข้ารหัสเคอร์เนล Linux และ แนวทางการสนับสนุน คุณต้องรวมแท็ก Change-Id
ไว้ในข้อความยืนยัน หากคุณส่งแพตช์ไปยังหลายสาขา (เช่น android-mainline
และ android12-5.4
) คุณต้องใช้ Change-Id
เดียวกันสำหรับอินสแตนซ์ทั้งหมดของแพตช์
ส่งแพตช์ไปที่ LKML ก่อนเพื่อรับการตรวจสอบอัปสตรีม หากแพทช์คือ:
- ยอมรับต้นน้ำ โดยจะรวมเข้ากับ
android-mainline
โดยอัตโนมัติ - ไม่ยอมรับอัปสตรีม ให้ส่งไปที่
android-mainline
โดยมีการอ้างอิงถึงการส่งอัปสตรีมหรือคำอธิบายว่าทำไมจึงไม่ส่งไปที่ LKML
หลังจากยอมรับแพตช์อัปสตรีมหรือใน android-mainline
แล้ว ก็สามารถแบ็กพอร์ตไปยัง ACK ที่ใช้ LTS ที่เหมาะสมได้ (เช่น android12-5.4
และ android11-5.4
สำหรับแพตช์ที่แก้ไขโค้ดเฉพาะของ Android) การส่งไปยัง android-mainline
ช่วยให้สามารถทดสอบกับผู้สมัครอัปสตรีมรีลีสใหม่และรับประกันว่าแพตช์จะอยู่ใน ACK ที่ใช้ LTS ถัดไป ข้อยกเว้นรวมถึงกรณีที่แพตช์อัปสตรีมถูกแบ็คพอร์ตไปยัง android12-5.4
(เนื่องจากแพตช์มีแนวโน้มที่จะอยู่ใน android-mainline
อยู่แล้ว)
แพทช์ต้นน้ำ
ตามที่ระบุไว้ใน แนวทางการสนับสนุน แพตช์อัปสตรีมที่กำหนดไว้สำหรับเคอร์เนล ACK จะจัดอยู่ในกลุ่มต่อไปนี้ (แสดงรายการตามลำดับความเป็นไปได้ที่จะได้รับการยอมรับ)
-
UPSTREAM:
- แพตช์ที่เชอร์รี่เลือกจาก 'android-mainline` มีแนวโน้มที่จะได้รับการยอมรับใน ACK หากมีกรณีการใช้งานที่สมเหตุสมผล -
BACKPORT:
- แพตช์จากอัปสตรีมที่ไม่ได้เก็บเชอร์รี่อย่างหมดจดและจำเป็นต้องมีการดัดแปลงก็มีแนวโน้มที่จะได้รับการยอมรับหากมีกรณีการใช้งานที่สมเหตุสมผล -
FROMGIT:
- แพตช์ที่เชอร์รี่เลือกจากสาขาผู้ดูแลเพื่อเตรียมส่งไปยัง Linux mainline อาจได้รับการยอมรับหากมีกำหนดเวลาที่กำลังจะมาถึง สิ่งเหล่านี้จะต้องสมเหตุสมผลทั้งสำหรับเนื้อหาและกำหนดการ -
FROMLIST:
- แพตช์ที่ส่งไปยัง LKML แต่ยังไม่ได้รับการยอมรับในสาขาผู้ดูแล แต่ก็ไม่น่าจะได้รับการยอมรับ เว้นแต่การให้เหตุผลนั้นน่าสนใจเพียงพอที่แพตช์จะได้รับการยอมรับไม่ว่าจะลงจอดใน Linux อัปสตรีมหรือไม่ (เราถือว่า ว่าจะไม่) ต้องมีปัญหาที่เกี่ยวข้องกับแพตช์FROMLIST
เพื่ออำนวยความสะดวกในการหารือกับทีมเคอร์เนล Android
แพทช์เฉพาะสำหรับ Android
หากคุณไม่สามารถดำเนินการเปลี่ยนแปลงที่จำเป็นได้ที่ต้นทาง คุณสามารถลองส่งแพตช์นอกแผนผังไปที่ ACK ได้โดยตรง การส่งแพตช์ที่ไม่อยู่ในลำดับต้นๆ คุณต้องสร้างปัญหาในฝ่ายไอทีที่อ้างอิงแพตช์และเหตุผลว่าเหตุใดจึงไม่สามารถส่งแพตช์อัปสตรีมได้ (ดูตัวอย่างในรายการก่อนหน้า) อย่างไรก็ตาม มีบางกรณีที่ไม่สามารถส่งรหัสต้นทางได้ กรณีเหล่านี้ครอบคลุมดังต่อไปนี้ และต้องเป็นไปตาม หลักเกณฑ์การสนับสนุน สำหรับแพตช์เฉพาะของ Android และติดแท็กด้วยคำนำหน้า ANDROID:
ในหัวเรื่อง
เปลี่ยนเป็น gki_defconfig
การเปลี่ยนแปลง CONFIG
ทั้งหมดใน gki_defconfig
จะต้องนำไปใช้กับทั้งเวอร์ชัน arm64 และ x86 เว้นแต่ว่า CONFIG
จะเป็นสถาปัตยกรรมเฉพาะ หากต้องการขอเปลี่ยนแปลงการตั้งค่า CONFIG
ให้สร้างปัญหาในฝ่ายไอทีเพื่อหารือเกี่ยวกับการเปลี่ยนแปลง การเปลี่ยนแปลง CONFIG
ใดๆ ที่ส่งผลต่อ Kernel Module Interface (KMI) หลังจากที่ถูกแช่แข็งจะถูกปฏิเสธ ในกรณีที่พันธมิตรร้องขอการตั้งค่าที่ขัดแย้งกันสำหรับการกำหนดค่าเดียว เราจะแก้ไขข้อขัดแย้งผ่านการหารือเกี่ยวกับจุดบกพร่องที่เกี่ยวข้อง
รหัสที่ไม่มีต้นน้ำ
การแก้ไขโค้ดที่เป็นเฉพาะของ Android อยู่แล้วไม่สามารถส่งอัปสตรีมได้ ตัวอย่างเช่น แม้ว่าไดรเวอร์ Binder จะได้รับการดูแลต้นทาง แต่การแก้ไขคุณลักษณะการสืบทอดลำดับความสำคัญของไดรเวอร์ Binder จะไม่สามารถส่งต้นทางได้ เนื่องจากเป็นคุณลักษณะเฉพาะของ Android ระบุข้อบกพร่องให้ชัดเจนและแก้ไขสาเหตุที่ไม่สามารถส่งโค้ดอัปสตรีมได้ หากเป็นไปได้ ให้แยกแพตช์ออกเป็นส่วนๆ ที่สามารถส่งอัปสตรีมได้ และส่วนเฉพาะของ Android ที่ไม่สามารถส่งอัปสตรีมได้ เพื่อลดจำนวนโค้ดที่ไม่อยู่ในแผนผังที่เก็บรักษาไว้ใน ACK
การเปลี่ยนแปลงอื่นๆ ในหมวดหมู่นี้คือการอัปเดตไฟล์การแสดง KMI รายการสัญลักษณ์ KMI gki_defconfig
สคริปต์บิวด์หรือการกำหนดค่า หรือสคริปต์อื่นๆ ที่ไม่มีต้นทาง
โมดูลนอกแผนผัง
Upstream Linux ไม่สนับสนุนการสร้างโมดูลนอกแผนผังอย่างจริงจัง นี่เป็นตำแหน่งที่สมเหตุสมผล เนื่องจากผู้ดูแล Linux ไม่รับประกันเกี่ยวกับซอร์สในเคอร์เนลหรือความเข้ากันได้ของไบนารี และไม่ต้องการรองรับโค้ดที่ไม่ได้อยู่ในแผนผัง อย่างไรก็ตาม GKI ให้ การรับประกัน ABI สำหรับโมดูลของผู้จำหน่าย เพื่อให้มั่นใจว่าอินเทอร์เฟซ KMI มีความเสถียรตลอดอายุการใช้งานของเคอร์เนลที่รองรับ ดังนั้นจึงมีการเปลี่ยนแปลงระดับหนึ่งเพื่อสนับสนุนโมดูลของผู้จัดจำหน่ายที่ยอมรับได้สำหรับ ACK แต่ไม่ยอมรับสำหรับอัปสตรีม
ตัวอย่างเช่น พิจารณาแพตช์ที่เพิ่มมาโคร EXPORT_SYMBOL_GPL()
โดยที่โมดูลที่ใช้การส่งออกไม่อยู่ในแผนผังต้นทาง แม้ว่าคุณจะต้องพยายามขอ EXPORT_SYMBOL_GPL()
อัปสตรีมและจัดหาโมดูลที่ใช้สัญลักษณ์ที่ส่งออกใหม่ หากมีเหตุผลที่ถูกต้องว่าทำไมโมดูลจึงไม่ถูกส่งอัปสตรีม คุณสามารถส่งโปรแกรมแก้ไขไปที่ ACK แทนได้ คุณต้องระบุเหตุผลว่าเหตุใดโมดูลจึงไม่สามารถอัปสตรีมในปัญหาได้ (อย่าขอตัวแปรที่ไม่ใช่ GPL EXPORT_SYMBOL()
.)
การกำหนดค่าที่ซ่อนอยู่
โมดูลในแผนผังบางโมดูลจะเลือกการกำหนดค่าที่ซ่อนอยู่ซึ่งไม่สามารถระบุใน gki_defconfig
ได้โดยอัตโนมัติ ตัวอย่างเช่น CONFIG_SND_SOC_TOPOLOGY
จะถูกเลือกโดยอัตโนมัติเมื่อมีการกำหนดค่า CONFIG_SND_SOC_SOF=y
เพื่อรองรับการสร้างโมดูลนอกแผนผัง GKI มีกลไกในการเปิดใช้งานการกำหนดค่าที่ซ่อนอยู่
หากต้องการเปิดใช้งานการกำหนดค่าที่ซ่อนอยู่ ให้เพิ่มคำสั่ง select
ใน init/Kconfig.gki
เพื่อให้ระบบเลือกโดยอัตโนมัติตามการกำหนดค่าเคอร์เนล CONFIG_GKI_HACKS_TO_FIX
ซึ่งเปิดใช้งานใน gki_defconfig
ใช้กลไกนี้สำหรับการกำหนดค่าที่ซ่อนอยู่เท่านั้น หากไม่ได้ซ่อนการกำหนดค่าไว้ จะต้องระบุการกำหนดค่านั้นใน gki_defconfig
อย่างชัดเจนหรือเป็นการขึ้นต่อกัน
ผู้ว่าราชการโหลดได้
สำหรับเฟรมเวิร์กเคอร์เนล (เช่น cpufreq
) ที่รองรับ Governor ที่โหลดได้ คุณสามารถแทนที่ Governor ที่เป็นค่าเริ่มต้นได้ (เช่น schedutil
Governor ของ cpufreq
สำหรับเฟรมเวิร์ก (เช่น กรอบงานระบายความร้อน) ที่ไม่รองรับ Governor หรือไดรเวอร์ที่โหลดได้ แต่ยังต้องการ การใช้งานเฉพาะผู้ขาย สร้างปัญหาในด้านไอทีและปรึกษากับ ทีมเคอร์เนล Android
เราจะทำงานร่วมกับคุณและผู้ดูแลต้นน้ำเพื่อเพิ่มการสนับสนุนที่จำเป็น
ตะขอผู้ขาย
ในรีลีสที่ผ่านมา คุณสามารถเพิ่มการแก้ไขเฉพาะผู้จำหน่ายลงในเคอร์เนลหลักได้โดยตรง สิ่งนี้เป็นไปไม่ได้กับ GKI 2.0 เนื่องจากต้องใช้รหัสเฉพาะผลิตภัณฑ์ในโมดูล และจะไม่ได้รับการยอมรับในเคอร์เนลหลักต้นทางหรือใน ACK เพื่อเปิดใช้งานคุณสมบัติเพิ่มมูลค่าที่พันธมิตรพึ่งพาโดยมีผลกระทบน้อยที่สุดต่อโค้ดเคอร์เนลหลัก GKI ยอมรับ hooks ของผู้จำหน่ายที่อนุญาตให้เรียกใช้โมดูลจากโค้ดเคอร์เนลหลักได้ นอกจากนี้ โครงสร้างข้อมูลที่สำคัญสามารถเสริมด้วยฟิลด์ข้อมูลผู้ขายที่พร้อมใช้งานเพื่อจัดเก็บข้อมูลเฉพาะของผู้ขายเพื่อใช้คุณลักษณะเหล่านี้
Hook ของผู้จัดจำหน่ายมีสองรูปแบบ (ปกติและแบบจำกัด) ซึ่งขึ้นอยู่กับจุดติดตาม (ไม่ใช่การติดตามเหตุการณ์) ที่โมดูลผู้จัดจำหน่ายสามารถแนบได้ ตัวอย่างเช่น แทนที่จะเพิ่มฟังก์ชัน sched_exit()
ใหม่เพื่อทำการบัญชีเมื่อออกจากงาน ผู้ขายสามารถเพิ่ม hook ใน do_exit()
ที่โมดูลผู้ขายสามารถแนบไปกับการประมวลผลได้ การใช้งานตัวอย่างรวมถึง hooks ของผู้ขายต่อไปนี้
- hook ของผู้ขายปกติใช้
DECLARE_HOOK()
เพื่อสร้างฟังก์ชันจุดติดตามด้วยชื่อtrace_ name
โดยที่name
เป็นตัวระบุที่ไม่ซ้ำกันสำหรับการติดตาม ตามธรรมเนียมแล้ว ชื่อ vendor hook ปกติจะขึ้นต้นด้วยandroid_vh
ดังนั้นชื่อของsched_exit()
hook จะเป็นandroid_vh_sched_exit
- hook ของผู้จำหน่ายแบบจำกัดเป็นสิ่งจำเป็นสำหรับกรณีต่างๆ เช่น hooks ของตัวกำหนดเวลาซึ่งจะต้องเรียกใช้ฟังก์ชันที่แนบมาแม้ว่า CPU จะออฟไลน์หรือต้องการบริบทที่ไม่ใช่อะตอมมิกก็ตาม hook ของผู้ขายแบบจำกัดไม่สามารถถอดออกได้ ดังนั้นโมดูลที่ต่อกับ hook แบบจำกัดจะไม่สามารถยกเลิกการโหลดได้ ชื่อ hook ของผู้จำหน่ายที่ถูกจำกัดขึ้นต้นด้วย
android_rvh
หากต้องการเพิ่ม vendor hook ให้ยื่นปัญหาในฝ่ายไอทีและส่งแพตช์ (เช่นเดียวกับแพตช์เฉพาะ Android ทั้งหมด จะต้องมีปัญหาอยู่และคุณต้องระบุเหตุผล) การสนับสนุน hooks ของผู้ขายมีอยู่ใน ACK เท่านั้น ดังนั้นอย่าส่งแพตช์เหล่านี้ไปยัง Linux อัปสตรีม
เพิ่มฟิลด์ผู้ขายให้กับโครงสร้าง
คุณสามารถเชื่อมโยงข้อมูลผู้ขายกับโครงสร้างข้อมูลหลักได้โดยการเพิ่มช่อง android_vendor_data
โดยใช้มาโคร ANDROID_VENDOR_DATA()
ตัวอย่างเช่น เพื่อสนับสนุนคุณลักษณะที่มีมูลค่าเพิ่ม ให้ผนวกเขตข้อมูลเข้ากับโครงสร้างตามที่แสดงในตัวอย่างโค้ดต่อไปนี้
เพื่อหลีกเลี่ยงความขัดแย้งที่อาจเกิดขึ้นระหว่างฟิลด์ที่ผู้ขายต้องการและฟิลด์ที่ OEM ต้องการ OEM จะต้องไม่ใช้ฟิลด์ที่ประกาศโดยใช้มาโคร ANDROID_VENDOR_DATA()
OEM จะต้องใช้ ANDROID_OEM_DATA()
เพื่อประกาศช่อง android_oem_data
แทน
#include <linux/android_vendor.h>
...
struct important_kernel_data {
[all the standard fields];
/* Create vendor data for use by hook implementations. The
* size of vendor data is based on vendor input. Vendor data
* can be defined as single u64 fields like the following that
* declares a single u64 field named "android_vendor_data1" :
*/
ANDROID_VENDOR_DATA(1);
/*
* ...or an array can be declared. The following is equivalent to
* u64 android_vendor_data2[20]:
*/
ANDROID_VENDOR_DATA_ARRAY(2, 20);
/*
* SoC vendors must not use fields declared for OEMs and
* OEMs must not use fields declared for SoC vendors.
*/
ANDROID_OEM_DATA(1);
/* no further fields */
}
กำหนด hooks ของผู้ขาย
เพิ่ม vendor hooks ให้กับโค้ดเคอร์เนลเป็นจุดติดตามโดยการประกาศโดยใช้ DECLARE_HOOK()
หรือ DECLARE_RESTRICTED_HOOK()
จากนั้นเพิ่มลงในโค้ดเป็นจุดติดตาม ตัวอย่างเช่น หากต้องการเพิ่ม trace_android_vh_sched_exit()
ให้กับฟังก์ชันเคอร์เนล do_exit()
ที่มีอยู่:
#include <trace/hooks/exit.h>
void do_exit(long code)
{
struct task_struct *tsk = current;
...
trace_android_vh_sched_exit(tsk);
...
}
ฟังก์ชัน trace_android_vh_sched_exit()
จะตรวจสอบในขั้นต้นเมื่อมีบางสิ่งแนบอยู่เท่านั้น อย่างไรก็ตาม หากโมดูลผู้จำหน่ายลงทะเบียนตัวจัดการโดยใช้ register_trace_android_vh_sched_exit()
ฟังก์ชันที่ลงทะเบียนไว้จะถูกเรียกใช้ ตัวจัดการจะต้องทราบถึงบริบทที่เกี่ยวข้องกับการล็อคที่ถูกระงับ สถานะ RCS และปัจจัยอื่นๆ hook ต้องถูกกำหนดไว้ในไฟล์ส่วนหัวในไดเร็กทอรี include/trace/hooks
ตัวอย่างเช่น โค้ดต่อไปนี้ให้การประกาศที่เป็นไปได้สำหรับ trace_android_vh_sched_exit()
ในไฟล์ include/trace/hooks/exit.h
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_SCHED_H
#include <trace/hooks/vendor_hooks.h>
/*
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
struct task_struct;
DECLARE_HOOK(android_vh_sched_exit,
TP_PROTO(struct task_struct *p),
TP_ARGS(p));
#endif /* _TRACE_HOOK_SCHED_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
หากต้องการสร้างอินสแตนซ์อินเทอร์เฟซที่จำเป็นสำหรับ vendor hook ให้เพิ่มไฟล์ส่วนหัวพร้อมกับการประกาศ hook ไปยัง drivers/android/vendor_hooks.c
และส่งออกสัญลักษณ์ ตัวอย่างเช่น โค้ดต่อไปนี้ทำให้การประกาศของ hook android_vh_sched_exit()
เสร็จสมบูรณ์
#ifndef __GENKSYMS__
/* struct task_struct */
#include <linux/sched.h>
#endif
#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <trace/hooks/exit.h>
/*
* Export tracepoints that act as a bare tracehook (i.e. have no trace
* event associated with them) to allow external modules to probe
* them.
*/
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_exit);
หมายเหตุ : โครงสร้างข้อมูลที่ใช้ภายในการประกาศ hook จำเป็นต้องได้รับการกำหนดอย่างสมบูรณ์เพื่อรับประกันความเสถียรของ ABI มิฉะนั้นจะไม่ปลอดภัยที่จะอ้างอิงพอยน์เตอร์ทึบแสงหรือใช้โครงสร้างในบริบทที่มีขนาด การ include ซึ่งให้คำจำกัดความแบบเต็มของโครงสร้างข้อมูลดังกล่าวควรอยู่ภายในส่วน #ifndef __GENKSYMS__
ของ drivers/android/vendor_hooks.c
ไฟล์ส่วนหัวใน include/trace/hooks
ไม่ควรรวมไฟล์ส่วนหัวเคอร์เนลที่มีคำจำกัดความประเภท เพื่อหลีกเลี่ยงการเปลี่ยนแปลง CRC ซึ่งจะทำให้ KMI เสียหาย แทนที่จะส่งต่อประกาศประเภท
ติดเข้ากับตะขอของผู้ขาย
หากต้องการใช้ hooks ของผู้ขาย โมดูลผู้ขายจำเป็นต้องลงทะเบียนตัวจัดการสำหรับ hook (โดยทั่วไปจะทำระหว่างการเริ่มต้นโมดูล) ตัวอย่างเช่น โค้ดต่อไปนี้แสดงโมดูล foo.ko
handler สำหรับ trace_android_vh_sched_exit()
#include <trace/hooks/sched.h>
...
static void foo_sched_exit_handler(void *data, struct task_struct *p)
{
foo_do_exit_accounting(p);
}
...
static int foo_probe(..)
{
...
rc = register_trace_android_vh_sched_exit(foo_sched_exit_handler, NULL);
...
}
คุณสมบัติเคอร์เนลหลัก
หากไม่มีเทคนิคก่อนหน้านี้ที่ทำให้คุณสามารถใช้คุณลักษณะจากโมดูลได้ คุณจะต้องเพิ่มคุณลักษณะดังกล่าวเป็นการดัดแปลงเฉพาะของ Android ให้กับเคอร์เนลหลัก สร้างปัญหาในตัวติดตามปัญหา (IT) เพื่อเริ่มการสนทนา
ส่วนต่อประสานการเขียนโปรแกรมแอปพลิเคชันผู้ใช้ (UAPI)
- ไฟล์ส่วนหัว UAPI การเปลี่ยนแปลง ไฟล์ส่วนหัว UAPI จะต้องเกิดขึ้นที่ต้นทาง เว้นแต่การเปลี่ยนแปลงนั้นเกิดขึ้นกับอินเทอร์เฟซเฉพาะของ Android ใช้ไฟล์ส่วนหัวเฉพาะของผู้จำหน่ายเพื่อกำหนดอินเทอร์เฟซระหว่างโมดูลของผู้จำหน่ายและรหัสพื้นที่ผู้ใช้ของผู้จำหน่าย
- โหนด sysfs อย่าเพิ่มโหนด sysfs ใหม่ให้กับเคอร์เนล GKI (การเพิ่มดังกล่าวใช้ได้เฉพาะในโมดูลของผู้ขายเท่านั้น) โหนด sysfs ที่ใช้โดย SoC- และไลบรารีที่ไม่เชื่อเรื่องอุปกรณ์และโค้ด Java ที่ประกอบด้วยเฟรมเวิร์ก Android สามารถเปลี่ยนแปลงได้ในวิธีที่เข้ากันได้เท่านั้น และจะต้องเปลี่ยนอัปสตรีมหากไม่ใช่โหนด sysfs เฉพาะของ Android คุณ สามารถ สร้างโหนด sysfs เฉพาะผู้จำหน่ายเพื่อใช้โดยพื้นที่ผู้ใช้ของผู้จำหน่าย ตามค่าเริ่มต้น การเข้าถึงโหนด sysfs โดยพื้นที่ผู้ใช้จะถูกปฏิเสธโดยใช้ SELinux ขึ้นอยู่กับผู้จำหน่ายที่จะเพิ่มป้ายกำกับ SELinux ที่เหมาะสมเพื่ออนุญาตการเข้าถึงโดยซอฟต์แวร์ของผู้จำหน่ายที่ได้รับอนุญาต
- โหนด DebugFS โมดูลผู้จำหน่ายสามารถกำหนดโหนดใน
debugfs
สำหรับการดีบักเท่านั้น (เนื่องจากdebugfs
ไม่ได้ถูกเมาท์ระหว่างการทำงานปกติของอุปกรณ์)