อิมเมจเคอร์เนลทั่วไป (GKI) จะลดการกระจัดกระจายของเคิร์นัลโดยการปรับให้สอดคล้องกับเคอร์เนล Linux เวอร์ชันที่พัฒนาขึ้น แต่ก็มีสาเหตุหลายประการ บางแพตช์ไม่สามารถยอมรับอัปสตรีมได้ และมีกำหนดการของผลิตภัณฑ์ที่ ต้องเป็นไปตามข้อกำหนด ดังนั้นแพตช์บางส่วนจะได้รับการดูแลใน Kernel Common (ACK) ของ Android ต้นทางที่ใช้สร้าง GKI
นักพัฒนาซอฟต์แวร์ต้องส่งการเปลี่ยนแปลงโค้ดจากอัปสตรีมโดยใช้ Linux Kernel Mailing
ระบุ (LKML) เป็นตัวเลือกแรก และส่งการเปลี่ยนแปลงโค้ดไปยัง ACK
android-mainline
Branch เมื่อมีเหตุผลที่ชัดเจนว่าทำไมไม่ใช่อัปสตรีม
ที่ใช้ได้ผลดี ตัวอย่างสาเหตุที่เป็นไปได้และวิธีจัดการมีดังนี้
ส่งแพตช์ไปยัง LKML แล้ว แต่ยังไม่ได้รับการยอมรับทันเวลาสําหรับผลิตภัณฑ์ วิธีจัดการแพตช์นี้
- แสดงหลักฐานว่าส่งแพตช์ไปยัง LKML แล้วและได้รับความคิดเห็นเกี่ยวกับแพตช์ หรือเวลาโดยประมาณที่ส่งแพตช์ไปยัง upstream
- ตัดสินใจเกี่ยวกับการดำเนินการเพื่อลงแพตช์ใน ACK เพื่อรอการอนุมัติ อัปสตรีม แล้วนำออกจาก ACK เมื่อเวอร์ชันอัปสตรีมสุดท้ายคือ รวมเป็น ACK
แพตช์กำหนด
EXPORT_SYMBOLS_GPL()
สำหรับโมดูลผู้ให้บริการ แต่ไม่สามารถ สามารถส่งอัปสตรีม เนื่องจากไม่มีโมดูลในแผนผังที่ใช้ + หากต้องการจัดการกับแพตช์นี้ โปรดระบุรายละเอียดเกี่ยวกับสาเหตุที่ส่งโมดูลไปยังระบบส่วนกลางไม่ได้ และทางเลือกอื่นๆ ที่คุณพิจารณาก่อนที่จะส่งคำขอนี้แพตช์ไม่ได้กว้างพอสำหรับอัปสตรีม และไม่มีเวลาที่จะ เปลี่ยนโครงสร้างภายในโค้ดก่อนเปิดตัวผลิตภัณฑ์ หากต้องการจัดการแพตช์นี้ ให้ระบุ เวลาโดยประมาณที่ใช้ในการส่งแพตช์แบบเปลี่ยนโครงสร้างภายในใหม่ (ขั้นตอน แพตช์จะไม่ได้รับการยอมรับใน ACK หากไม่มีแผนที่จะส่งการเปลี่ยนโครงสร้างภายในโค้ด แพตช์จากอัปสตรีมเพื่อตรวจสอบ)
อัปสตรีมไม่ยอมรับแพตช์เนื่องจาก... <insert reason here> หากต้องการจัดการกับแพตช์นี้ โปรดติดต่อทีมเคอร์เนล Android และทำงานร่วมกับเราเกี่ยวกับตัวเลือกในการรีแฟกทอเรียลแพตช์เพื่อให้ส่งเข้ารับการตรวจสอบและยอมรับในอัปสตรีมได้
มีเหตุผลรองรับอีกมากมาย เมื่อคุณส่งข้อบกพร่องหรือ ใส่เหตุผลที่ถูกต้อง และคาดว่าจะมีการปรับปรุงและการพูดคุย เราตระหนักดีว่า ACK มีแพตช์บางส่วน โดยเฉพาะในระยะเริ่มต้นของ GKI ขณะที่ทุกคนกำลังเรียนรู้วิธีทํางานกับเวอร์ชันที่อัปเดตอยู่ แต่ไม่สามารถผ่อนปรนกำหนดการของผลิตภัณฑ์เพื่อทําเช่นนั้นได้ โปรดทราบว่าข้อกําหนดในการอัปเดตเวอร์ชันจะเข้มงวดมากขึ้นเมื่อเวลาผ่านไป
ข้อกำหนดแพตช์
แพตช์ต้องเป็นไปตามมาตรฐานการเขียนโค้ดเคอร์เนล Linux ที่อธิบายไว้ในซอร์สทรี Linux ไม่ว่าจะส่งไปยัง upstream หรือ 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 รุ่นถัดไป ข้อยกเว้นรวมถึงกรณีที่มีการพอร์ตแพตช์จาก upstream ไปยัง android12-5.4
(เนื่องจากแพตช์มีแนวโน้มที่จะอยู่ใน android-mainline
อยู่แล้ว)
แพตช์จากฝั่งอัปสตรีม
ตามที่ระบุไว้ในการมีส่วนร่วม หลักเกณฑ์ แพตช์ต้นทางสำหรับเคอร์เนล ACK จัดอยู่ในกลุ่มต่อไปนี้ (แสดงรายการ เพื่อให้ได้รับการยอมรับ)
UPSTREAM:
- แพตช์ที่เลือกจาก "android-mainline" มีแนวโน้มที่จะเป็น ยอมรับไว้ใน ACK หากมีกรณีการใช้งานที่สมเหตุสมผลBACKPORT:
- แพตช์จากอัปสตรีมที่ไม่ผ่านการตรวจสอบอย่างละเอียดและไม่ต้องการ การปรับเปลี่ยนยังมีโอกาสได้รับการยอมรับหากมีการใช้งานที่สมเหตุสมผลFROMGIT:
- แพตช์ที่เลือกสรรมาจากสาขาผู้ดูแลที่กำลังเตรียม สำหรับการส่งไปยัง Linux Mainline อาจได้รับการยอมรับหากมี โดยต้องให้เหตุผลทั้งสำหรับเนื้อหาและกำหนดการFROMLIST:
- แพตช์ที่ส่งไปยัง LKML แต่ยังไม่ได้รับการยอมรับในสาขาของผู้ดูแลระบบมีแนวโน้มที่จะไม่ได้รับการยอมรับ เว้นแต่จะมีเหตุผลที่น่าสนใจมากพอที่จะทำให้แพตช์ได้รับการยอมรับ ไม่ว่าจะนำไปใช้ใน Linux เวอร์ชัน upstream หรือไม่ก็ตาม (เราคิดว่าจะไม่ได้รับการยอมรับ) ปัญหาต้องเกี่ยวข้องกับแพตช์FROMLIST
เพื่อให้เราพูดคุยกับทีมเคอร์เนล Android ได้สะดวก
แพตช์เฉพาะสำหรับ Android
หากส่งการเปลี่ยนแปลงที่จำเป็นไปยังต้นทางไม่ได้ คุณลองส่งได้
แพตช์นอกต้นไม้ไปยัง ACK โดยตรง การส่งแพตช์ที่ไม่ใช่ของ Tree กำหนดให้คุณสร้างปัญหาใน IT ที่อ้างอิงถึงแพตช์และเหตุผลที่ส่งแพตช์ไปยัง upstream ไม่ได้ (ดูตัวอย่างในรายการก่อนหน้า)
อย่างไรก็ตาม มีบางกรณีที่ส่งโค้ดไปยังระบบส่วนกลางไม่ได้ เหล่านี้
กรณีต่างๆ มีดังนี้ และต้องเป็นไปตามการสนับสนุน
หลักเกณฑ์
สำหรับแพตช์เฉพาะ Android และติดแท็กด้วยคำนำหน้า ANDROID:
ใน
เรื่อง
การเปลี่ยนแปลง gki_defconfig
การเปลี่ยนแปลง CONFIG
ทั้งหมดที่ทำกับ gki_defconfig
ต้องมีผลกับทั้ง ARM64 และ
เวอร์ชัน x86 เว้นแต่ CONFIG
มีไว้สำหรับสถาปัตยกรรมโดยเฉพาะ วิธีส่งคำขอเปลี่ยนแปลง
เป็น CONFIG
ให้สร้างปัญหาในฝ่ายไอทีเพื่อพูดคุยเรื่องการเปลี่ยนแปลง ช่วง
การเปลี่ยนแปลง CONFIG
ที่มีผลต่ออินเทอร์เฟซโมดูลเคอร์เนล (KMI) หลังจากพ้นช่วง
ตรึง ถูกปฏิเสธ ในกรณีที่พาร์ทเนอร์ขอการตั้งค่าที่ขัดแย้งกันสำหรับการกำหนดค่ารายการเดียว เราจะแก้ไขความขัดแย้งผ่านการพูดคุยเกี่ยวกับข้อบกพร่องที่เกี่ยวข้อง
โค้ดที่ไม่มีอยู่ในส่วนที่ส่งผ่านข้อมูล
คุณจะส่งการแก้ไขโค้ดที่เจาะจง Android อยู่แล้วไปยัง upstream ไม่ได้ ตัวอย่างเช่น แม้ว่าจะมีการบำรุงรักษาไดรเวอร์ Binder ในอัปสตรีม แต่คุณจะส่งการแก้ไขฟีเจอร์การสืบทอดลําดับความสําคัญของไดรเวอร์ Binder ไปยังอัปสตรีมไม่ได้เนื่องจากฟีเจอร์ดังกล่าวมีไว้สําหรับ Android โดยเฉพาะ ระบุในข้อบกพร่องอย่างชัดเจนและแก้ไขว่าทำไม ส่งจากอัปสตรีมไม่ได้ หากเป็นไปได้ ให้แบ่งแพตช์ออกเป็นส่วนย่อยๆ สามารถส่งอัปสตรีมและชิ้นส่วนเฉพาะสำหรับ Android ที่ส่งไม่ได้ อัปสตรีม เพื่อลดจำนวนโค้ดแบบนอกโครงสร้างที่เก็บรักษาไว้ใน ACK
การเปลี่ยนแปลงอื่นๆ ในหมวดหมู่นี้คือการอัปเดตไฟล์ตัวแทน KMI, KMI
รายการสัญลักษณ์, gki_defconfig
, สคริปต์บิลด์หรือการกำหนดค่า หรือสคริปต์อื่นๆ
ที่ไม่มีอัปสตรีม
โมดูลที่อยู่นอกต้นไม้
Upstream Linux ไม่สนับสนุนการสร้างโมดูลนอกโครงสร้างอย่างเต็มที่ นี่เป็นแนวทางที่สมเหตุสมผลเนื่องจากผู้ดูแลระบบ Linux ไม่ได้รับประกันเกี่ยวกับซอร์สโค้ดในเคอร์เนลหรือความเข้ากันได้ของไบนารี และไม่ต้องการรองรับโค้ดที่ไม่ได้อยู่ในต้นไม้ อย่างไรก็ตาม GKI ให้การรับประกัน ABI สำหรับ โมดูลของผู้จำหน่าย เพื่อให้มั่นใจว่าอินเทอร์เฟซ KMI มีความเสถียรสำหรับ ตลอดอายุการใช้งานของเคอร์เนล ดังนั้นจึงมีคลาสการเปลี่ยนแปลงเพื่อรองรับข้อบังคับของผู้ให้บริการซึ่งยอมรับได้สำหรับ ACK แต่ไม่ยอมรับสำหรับ Upstream
ตัวอย่างเช่น ลองพิจารณาแพตช์ที่เพิ่มมาโคร 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
) ที่รองรับตัวควบคุมโหลดได้ คุณสามารถลบล้างตัวควบคุมเริ่มต้น (เช่น ตัวควบคุม schedutil
ของ cpufreq
) สำหรับ
เฟรมเวิร์ก (เช่น กรอบความร้อน) ที่ไม่รองรับตัวกำกับดูแลที่โหลดได้
หรือไดรเวอร์ แต่ยังคงต้องใช้การติดตั้งใช้งานเฉพาะผู้ให้บริการ ให้สร้างปัญหา
ในแผนกไอทีและปรึกษาทีมเคอร์เนลของ Android
เราจะทำงานร่วมกับคุณและผู้ดูแลระบบในอัปสตรีมเพื่อเพิ่มการสนับสนุนที่จำเป็น
ฮุกของผู้ให้บริการ
ในรุ่นก่อนหน้านี้ คุณสามารถเพิ่มการแก้ไขเฉพาะผู้ให้บริการลงใน เคอร์เนลหลัก ซึ่งไม่สามารถทำได้ใน GKI 2.0 เนื่องจากต้องติดตั้งใช้งานโค้ดเฉพาะผลิตภัณฑ์ในโมดูลและระบบจะไม่ยอมรับในเคอร์เนลหลักที่ส่งผ่านข้อมูลหรือใน ACK GKI ยอมรับฮุกของผู้ให้บริการที่อนุญาตให้เรียกใช้โมดูลจากโค้ดเคอร์เนลหลัก เพื่อเปิดใช้ฟีเจอร์ที่มีคุณค่าซึ่งพาร์ทเนอร์ต้องใช้โดยส่งผลกระทบต่อโค้ดเคอร์เนลหลักน้อยที่สุด นอกจากนี้ คุณสามารถเสริมความแข็งแกร่งให้กับโครงสร้างข้อมูลหลัก ฟิลด์ข้อมูลผู้ให้บริการที่พร้อมสำหรับการจัดเก็บข้อมูลเฉพาะผู้ให้บริการเพื่อนำไปใช้ ฟีเจอร์เหล่านี้
ฮุกของผู้ให้บริการมี 2 ตัวแปร (ปกติและแบบจำกัด) ที่อิงจาก
จุดติดตาม (ไม่ใช่การติดตามเหตุการณ์) ที่โมดูลของผู้ให้บริการสามารถแนบได้ ตัวอย่างเช่น แทนที่จะเพิ่มฟังก์ชัน sched_exit()
ใหม่เพื่อทำการบัญชีเมื่อสิ้นสุดการทำงานของแทร็ก ผู้ให้บริการสามารถเพิ่มฮุกใน do_exit()
ที่โมดูลของผู้ให้บริการจะแนบไว้เพื่อประมวลผลได้ ตัวอย่างการใช้งานรวมถึงฮุกของผู้ให้บริการต่อไปนี้
- ฮุกของผู้ให้บริการทั่วไปใช้
DECLARE_HOOK()
เพื่อสร้างฟังก์ชันการติดตามที่มีชื่อtrace_name
โดยที่name
คือตัวระบุที่ไม่ซ้ำกันสำหรับการติดตาม ตามธรรมเนียมแล้ว ชื่อฮุกของผู้ให้บริการปกติจะขึ้นต้นด้วยandroid_vh
ดังนั้นชื่อฮุกsched_exit()
จะเป็นandroid_vh_sched_exit
- ฮุกของผู้ให้บริการแบบจํากัดจําเป็นสําหรับกรณีที่ต้องใช้ฮุกตัวจัดตารางเวลา ซึ่งต้องเรียกใช้ฟังก์ชันที่แนบมาแม้ว่า CPU จะออฟไลน์หรือต้องใช้บริบทแบบ nonatomic ไม่สามารถถอดฮุกของผู้ให้บริการที่ถูกจำกัดออกได้ ดังนั้นโมดูล
ที่ติดอยู่กับฮุกที่จำกัดจะยกเลิกการโหลดไม่ได้ ถูกจำกัด
ชื่อฮุกของผู้ให้บริการขึ้นต้นด้วย
android_rvh
หากต้องการเพิ่มฮุกของผู้ให้บริการ ให้ยื่นปัญหาในทีมไอทีและส่งแพตช์ (เช่นเดียวกับแพตช์สำหรับ Android โดยเฉพาะ จะต้องมีปัญหาและคุณต้องให้เหตุผล) การรองรับ Hook ของผู้ให้บริการจะอยู่ใน 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 */
}
กำหนดฮุกของผู้ให้บริการ
เพิ่มฮุกของผู้ให้บริการไปยังโค้ดเคอร์เนลเป็นจุดติดตามโดยการประกาศโดยใช้
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 และปัจจัยอื่นๆ ต้องกำหนดฮุกในไฟล์ส่วนหัวใน
ไดเรกทอรี 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>
หากต้องการสร้างอินสแตนซ์อินเทอร์เฟซที่จำเป็นสำหรับฮุกของผู้ให้บริการ ให้เพิ่มไฟล์ส่วนหัว
ที่มีการประกาศ Hook ไปยัง drivers/android/vendor_hooks.c
และส่งออก
สัญลักษณ์ ตัวอย่างเช่น โค้ดต่อไปนี้จะประกาศ android_vh_sched_exit()
hook ให้เสร็จสมบูรณ์
#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 ส่งต่อแทน
ประกาศประเภท
แนบกับฮุกของผู้ให้บริการ
หากต้องการใช้ฮุกของผู้ให้บริการ โมดูลของผู้ให้บริการจะต้องลงทะเบียนตัวแฮนเดิลสําหรับฮุก (โดยปกติจะทําในระหว่างการเริ่มต้นโมดูล) ตัวอย่างเช่น โค้ดต่อไปนี้จะแสดงตัวแฮนเดิล foo.ko
ของโมดูลสําหรับ 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);
...
}
ใช้ฮุกของผู้ให้บริการจากไฟล์ส่วนหัว
คุณอาจต้องอัปเดต Hook ของผู้ให้บริการเพื่อใช้ฮุกของผู้ให้บริการจากไฟล์ส่วนหัว
ไฟล์ส่วนหัวที่จะยกเลิกการกำหนด TRACE_INCLUDE_PATH
เพื่อหลีกเลี่ยงข้อผิดพลาดของรุ่นที่ระบุว่า
ไม่พบไฟล์ส่วนหัวของจุดติดตาม ตัวอย่างเช่น
In file included from .../common/init/main.c:111:
In file included from .../common/include/trace/events/initcall.h:74:
.../common/include/trace/define_trace.h:95:10: fatal error: 'trace/hooks/initcall.h' file not found
95 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:90:32: note: expanded from macro 'TRACE_INCLUDE'
90 | # define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
| ^~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:87:34: note: expanded from macro '__TRACE_INCLUDE'
87 | # define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:10:27: note: expanded from macro '__stringify'
10 | #define __stringify(x...) __stringify_1(x)
| ^~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:9:29: note: expanded from macro '__stringify_1'
9 | #define __stringify_1(x...) #x
| ^~
<scratch space>:14:1: note: expanded from here
14 | "trace/hooks/initcall.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
หากต้องการแก้ไขข้อผิดพลาดในการบิลด์ประเภทนี้ ให้ใช้การแก้ไขที่เทียบเท่ากับฮุกของผู้ให้บริการในไฟล์ส่วนหัวที่คุณรวมไว้ ดูข้อมูลเพิ่มเติมได้ที่ https://r.android.com/3066703
diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h
index bc6de7e53d66..039926f7701d 100644
--- a/include/trace/hooks/mm.h
+++ b/include/trace/hooks/mm.h
@@ -2,7 +2,10 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mm
+#ifdef CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH trace/hooks
+#define UNDEF_TRACE_INCLUDE_PATH
+#endif
การกําหนด UNDEF_TRACE_INCLUDE_PATH
บอก include/trace/define_trace.h
ให้ยกเลิกการกําหนด TRACE_INCLUDE_PATH
หลังจากสร้างจุดติดตาม
ฟีเจอร์หลักของเคิร์นัล
หากไม่มีเทคนิคใดๆ ก่อนหน้านี้ที่ช่วยให้คุณสามารถ นำคุณลักษณะจากโมดูลไปใช้ได้ คุณต้องเพิ่มคุณลักษณะนั้นเป็นการแก้ไขเฉพาะสำหรับ Android เคอร์เนล สร้างปัญหาในเครื่องมือติดตามปัญหา (IT) เพื่อเริ่มการสนทนา
Application Programming Interface (UAPI)
- ไฟล์ส่วนหัว UAPI การเปลี่ยนแปลงเป็น ไฟล์ส่วนหัว UAPI ต้องเกิดขึ้นอัปสตรีม เว้นแต่ว่าการเปลี่ยนแปลงจะทำกับอินเทอร์เฟซเฉพาะสำหรับ Android เท่านั้น ใช้ไฟล์ส่วนหัวเฉพาะผู้ให้บริการเพื่อกำหนดอินเทอร์เฟซ ระหว่างโมดูลของผู้ให้บริการและโค้ดพื้นที่ผู้ใช้ของผู้ให้บริการ
- ของโหนด Sysfs โปรดอย่าเพิ่มโหนด Sysfs ใหม่ไปยังเคอร์เนล GKI (การเพิ่มดังกล่าว ใช้ได้ในโมดูลผู้ให้บริการเท่านั้น) โหนด Sysfs ที่ใช้โดย SoC- และ ไลบรารีที่รองรับการใช้งานบนอุปกรณ์และโค้ด Java ที่ประกอบขึ้นเป็นเฟรมเวิร์ก Android เปลี่ยนได้เฉพาะในรูปแบบที่เข้ากันได้เท่านั้น และต้องเปลี่ยนอัปสตรีมหาก ไม่ใช่โหนด Sysf ของ Android โดยเฉพาะ คุณสามารถสร้าง โหนด Syfs เฉพาะผู้ให้บริการที่จะใช้โดยพื้นที่ผู้ใช้ของผู้ให้บริการ โดยค่าเริ่มต้น ระบบจะปฏิเสธการเข้าถึงโหนด sysfs โดยพื้นที่ผู้ใช้โดยใช้ SELinux ขึ้นอยู่กับ ผู้ให้บริการสามารถเพิ่มป้ายกำกับ SELinux ที่เหมาะสมเพื่ออนุญาตการเข้าถึงโดย ของผู้จำหน่ายซอฟต์แวร์
- โหนด DebugFS โมดูลของผู้ให้บริการจะกำหนดโหนดใน
debugfs
สำหรับการแก้ไขข้อบกพร่องเท่านั้น (เนื่องจากระบบไม่ได้เมานต์debugfs
ในระหว่างการทํางานปกติของอุปกรณ์)