พัฒนารหัสเคอร์เนลสำหรับ GKI

Generic Kernel Image (GKI) ช่วยลดการกระจายตัวของเคอร์เนลโดยการจัดตำแหน่งอย่างใกล้ชิดกับเคอร์เนลลินุกซ์อัปสตรีม อย่างไรก็ตาม มีเหตุผลที่ถูกต้องว่าทำไมแพตช์บางแพตช์จึงไม่สามารถยอมรับได้ และมีกำหนดการของผลิตภัณฑ์ที่ต้องทำให้ตรงตามกำหนดการ ดังนั้นแพตช์บางตัวจึงได้รับการบำรุงรักษาในแหล่งที่มาของ Android Common Kernel (ACK) ซึ่ง GKI ถูกสร้างขึ้น

นักพัฒนาต้องส่งการเปลี่ยนแปลงโค้ดในอัปสตรีมโดยใช้ Linux Kernel Mailing List (LKML) เป็นตัวเลือกแรก และส่งการเปลี่ยนแปลงโค้ดไปยังสาขา ACK android-mainline เฉพาะเมื่อมีเหตุผลที่ชัดเจนว่าทำไมอัปสตรีมจึงไม่สามารถทำงานได้ ตัวอย่างเหตุผลที่ถูกต้องและวิธีจัดการมีดังนี้

  • แพตช์ถูกส่งไปยัง LKML แต่ไม่ได้รับการยอมรับทันเวลาสำหรับการเปิดตัวผลิตภัณฑ์ ในการจัดการแพตช์นี้:

    • แสดงหลักฐานว่าแพตช์ถูกส่งไปยัง LKML และความคิดเห็นที่ได้รับสำหรับแพตช์ หรือเวลาโดยประมาณที่แพตช์จะถูกส่งไปต้นน้ำ
    • ตัดสินใจเกี่ยวกับการดำเนินการเพื่อลงแพตช์ใน ACK ได้รับการอนุมัติอัปสตรีม จากนั้นนำออกจาก ACK เมื่อเวอร์ชันอัปสตรีมสุดท้ายถูกรวมเข้ากับ ACK
  • โปรแกรมแก้ไขกำหนด EXPORT_SYMBOLS_GPL() สำหรับโมดูลผู้ขาย แต่ไม่สามารถส่งอัปสตรีมได้เนื่องจากไม่มีโมดูลในแผนผังที่ใช้สัญลักษณ์นั้น เพื่อจัดการกับแพตช์นี้ ให้ระบุรายละเอียดว่าเหตุใดโมดูลของคุณจึงไม่สามารถส่งอัปสตรีมและทางเลือกอื่นๆ ที่คุณพิจารณาก่อนส่งคำขอนี้

  • แพตช์ไม่ทั่วถึงเพียงพอสำหรับอัปสตรีมและไม่มีเวลาที่จะปรับโครงสร้างใหม่ก่อนที่จะออกผลิตภัณฑ์ ในการจัดการแพตช์นี้ ให้ระบุเวลาโดยประมาณที่จะส่งแพตช์ที่ปรับโครงสร้างใหม่แล้วในอัปสตรีม (แพตช์จะไม่ได้รับการยอมรับใน ACK หากไม่มีแผนที่จะส่งแพตช์ที่ปรับโครงสร้างแล้วที่อัปสตรีมเพื่อตรวจสอบ)

  • อัพสตรีมไม่สามารถยอมรับแพตช์ได้เนื่องจาก... <ใส่เหตุผลที่นี่> หากต้องการจัดการกับแพตช์นี้ โปรดติดต่อทีมเคอร์เนลของ Android และทำงานร่วมกับเราเกี่ยวกับตัวเลือกในการปรับโครงสร้างแพตช์ใหม่เพื่อให้สามารถส่งแพตช์เข้ารับการตรวจสอบและยอมรับอัปสตรีมได้

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

ข้อกำหนดของแพทช์

แพตช์ต้องเป็นไปตามมาตรฐานการเข้ารหัสเคอร์เนลของ Linux ที่อธิบายไว้ใน ซอร์สทรีของ Linux ไม่ว่าจะส่งอัปสตรีมหรือ ACK สคริปต์ scripts/checkpatch.pl รันเป็นส่วนหนึ่งของการทดสอบส่งล่วงหน้าของ Gerrit ดังนั้นให้รันล่วงหน้าเพื่อให้แน่ใจว่าผ่าน ในการรันสคริปต์ checkpatch ด้วยการกำหนดค่าเดียวกันกับการทดสอบ presubmit ให้ใช้ build/static_analysis/checkpatch_presubmit.sh จากการชำระเงิน repo

แพทช์ 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: - แพตช์ cherrypicked จาก 'android-mainline' มีแนวโน้มที่จะได้รับการยอมรับใน ACK หากมีกรณีการใช้งานที่สมเหตุสมผล
  • BACKPORT: - แพตช์จากอัปสตรีมที่ไม่ได้ cherrypick หมดจดและจำเป็นต้องแก้ไขก็มีแนวโน้มที่จะได้รับการยอมรับเช่นกันหากมีกรณีการใช้งานที่สมเหตุสมผล
  • FROMGIT: - อาจยอมรับแพตช์ที่เชอร์รี่เลือกจากสาขาผู้ดูแลเพื่อเตรียมส่งไปยัง Linux mainline หากมีกำหนดส่งที่ใกล้เข้ามา สิ่งเหล่านี้จะต้องสมเหตุสมผลทั้งเนื้อหาและกำหนดการ
  • FROMLIST: - แพตช์ที่ส่งไปยัง LKML แต่ยังไม่ได้รับการยอมรับในสาขาผู้ดูแลยังไม่เป็นที่ยอมรับ เว้นแต่ว่าเหตุผลจะน่าสนใจเพียงพอที่แพตช์จะได้รับการยอมรับไม่ว่าจะลงจอดในอัพสตรีมลินุกซ์หรือไม่ (เราถือว่า ว่าจะไม่) จะต้องมีปัญหาที่เกี่ยวข้องกับแพตช์ FROMLIST เพื่ออำนวยความสะดวกในการพูดคุยกับทีมเคอร์เนลของ Android

แพทช์เฉพาะของ Android

หากคุณไม่สามารถลงจอดการเปลี่ยนแปลงที่จำเป็นในอัปสตรีมได้ คุณสามารถลองส่งแพตช์ภายนอกไปยัง ACK ได้โดยตรง การส่งแพตช์แบบ out-of-tree คุณต้องสร้างปัญหาใน IT ที่อ้างถึงแพตช์และเหตุผลว่าทำไมจึงไม่สามารถส่งแพตช์อัปสตรีมได้ (ดูรายการก่อนหน้าสำหรับตัวอย่าง) อย่างไรก็ตาม มีบางกรณีที่ไม่สามารถส่งโค้ดขึ้นไปด้านบนได้ กรณีเหล่านี้ครอบคลุมดังต่อไปนี้ และต้องเป็นไปตาม แนวทางการสนับสนุน สำหรับแพตช์เฉพาะของ Android และต้องติดแท็กด้วย ANDROID: คำนำหน้าในเรื่อง

เปลี่ยนเป็น gki_defconfig

การเปลี่ยนแปลง CONFIG ทั้งหมดใน gki_defconfig จะต้องนำไปใช้กับทั้งเวอร์ชัน arm64 และ x86 เว้นแต่ว่า CONFIG จะเป็นสถาปัตยกรรมเฉพาะ หากต้องการขอเปลี่ยนแปลงการตั้งค่า CONFIG ให้สร้างปัญหาใน IT เพื่อหารือเกี่ยวกับการเปลี่ยนแปลง การเปลี่ยนแปลง 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 ที่เป็นค่าเริ่มต้น (เช่น Governor schedutil ของ cpufreq สำหรับเฟรมเวิร์ก (เช่น Thermal Framework) ที่ไม่รองรับ Governor หรือไดรเวอร์ที่โหลดได้ แต่ยังต้องการ การใช้งานเฉพาะผู้ขาย สร้างปัญหาใน IT และปรึกษากับ ทีม Android kernel

เราจะทำงานร่วมกับคุณและผู้ดูแลอัปสตรีมเพื่อเพิ่มการสนับสนุนที่จำเป็น

ตะขอผู้ขาย

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

ผู้ขาย hooks มีสองตัวแปร (ปกติและจำกัด) ที่ยึดตามจุดติดตาม (ไม่ใช่เหตุการณ์การติดตาม) ที่โมดูลผู้ขายสามารถแนบได้ ตัวอย่างเช่น แทนที่จะเพิ่มฟังก์ชัน sched_exit() ใหม่เพื่อทำบัญชีเมื่อออกจากงาน ผู้ขายสามารถเพิ่ม hook ใน do_exit() ที่โมดูลผู้ขายสามารถแนบเพื่อการประมวลผลได้ การใช้งานตัวอย่างประกอบด้วย hooks ของผู้ขายต่อไปนี้

  • hooks ของผู้ขายปกติใช้ DECLARE_HOOK() เพื่อสร้างฟังก์ชัน tracepoint ด้วยชื่อ trace_ name โดยที่ name เป็นตัวระบุเฉพาะสำหรับการติดตาม ตามแบบแผน ชื่อ hook ของผู้ขายปกติจะขึ้นต้นด้วย android_vh ดังนั้นชื่อสำหรับ sched_exit() hook จะเป็น android_vh_sched_exit
  • จำเป็นต้องใช้ hooks ของผู้จำหน่ายแบบจำกัดสำหรับกรณีต่างๆ เช่น hooks ของตัวกำหนดตารางเวลาที่ต้องเรียกใช้ฟังก์ชันที่แนบมา แม้ว่า CPU จะออฟไลน์อยู่หรือต้องการบริบทแบบ nonatomic ไม่สามารถปลด hooks ของผู้จำหน่ายแบบจำกัดได้ ดังนั้นโมดูลที่ต่อกับ hook แบบจำกัดจึงไม่สามารถยกเลิกการโหลดได้ อนุญาตให้แนบได้เพียงไฟล์เดียวเท่านั้น ดังนั้นความพยายามอื่น ๆ ในการแนบจึงล้มเหลวด้วย -EBUSY ชื่อ hook ของผู้ขายที่ถูกจำกัดขึ้นต้นด้วย android_rvh

หากต้องการเพิ่ม Vendor Hook ให้ยื่นปัญหาใน IT และส่งแพตช์ (เช่นเดียวกับแพตช์เฉพาะของ Android ทั้งหมด จะต้องมีปัญหาเกิดขึ้นและคุณต้องระบุเหตุผล) รองรับ vendor 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

เพิ่มผู้ขาย 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 มิฉะนั้น จะไม่ปลอดภัยที่จะอ้างอิงพอยน์เตอร์ทึบแสงหรือใช้โครงสร้างในบริบทที่มีขนาด การรวมที่ให้คำจำกัดความทั้งหมดของโครงสร้างข้อมูลดังกล่าวควรอยู่ในส่วน #ifndef __GENKSYMS__ ของ drivers/android/vendor_hooks.c ไฟล์ส่วนหัวใน include/trace/hooks ไม่ควรรวมไฟล์ส่วนหัวของเคอร์เนลที่มีข้อกำหนดประเภทเพื่อหลีกเลี่ยงการเปลี่ยนแปลง CRC ซึ่งทำลาย KMI แทนที่จะส่งต่อประกาศประเภท

แนบกับตะขอผู้ขาย

ในการใช้ผู้ขาย hooks โมดูลผู้ขายจำเป็นต้องลงทะเบียนตัวจัดการสำหรับ hook (โดยทั่วไปจะทำระหว่างการเริ่มต้นโมดูล) ตัวอย่างเช่น โค้ดต่อไปนี้แสดงตัวจัดการโมดูล 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);
    ...
}

คุณสมบัติเคอร์เนลหลัก

หากไม่มีเทคนิคใดๆ ก่อนหน้านี้ที่ช่วยให้คุณนำฟีเจอร์จากโมดูลไปใช้ได้ คุณต้องเพิ่มฟีเจอร์นั้นเป็นการแก้ไขเฉพาะ Android ให้กับเคอร์เนลหลัก สร้างปัญหาในตัวติดตามปัญหา (IT) เพื่อเริ่มการสนทนา

อินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชันผู้ใช้ (UAPI)

  • ไฟล์ส่วนหัวของ UAPI การเปลี่ยนแปลง ไฟล์ส่วนหัวของ UAPI จะต้องเกิดขึ้นที่ต้นทาง ยกเว้นการเปลี่ยนแปลงนั้นเกิดขึ้นกับอินเทอร์เฟซเฉพาะของ Android ใช้ไฟล์ส่วนหัวเฉพาะของผู้ขายเพื่อกำหนดอินเทอร์เฟซระหว่างโมดูลผู้ขายและรหัสพื้นที่ผู้ใช้ของผู้ขาย
  • โหนด sysfs อย่าเพิ่มโหนด sysfs ใหม่ให้กับเคอร์เนล GKI (การเพิ่มดังกล่าวใช้ได้เฉพาะในโมดูลผู้จำหน่ายเท่านั้น) โหนด sysfs ที่ใช้โดยไลบรารี SoC และอุปกรณ์ที่ไม่เชื่อเรื่องพระเจ้า และโค้ด Java ที่ประกอบด้วยเฟรมเวิร์ก Android สามารถเปลี่ยนแปลงได้ด้วยวิธีที่เข้ากันได้เท่านั้น และต้องเปลี่ยนที่อัปสตรีมหากไม่ใช่โหนด sysfs เฉพาะของ Android คุณ สามารถ สร้างโหนด sysfs เฉพาะผู้ขายเพื่อใช้โดย userspace ของผู้ขาย ตามค่าเริ่มต้น การเข้าถึงโหนด sysfs โดย userspace จะถูกปฏิเสธโดยใช้ SELinux ขึ้นอยู่กับผู้จำหน่ายที่จะเพิ่มฉลาก SELinux ที่เหมาะสมเพื่อให้ซอฟต์แวร์ของผู้จำหน่ายที่ได้รับอนุญาตสามารถเข้าถึงได้
  • โหนด DebugFS โมดูลผู้จำหน่ายสามารถกำหนดโหนดใน debugfs สำหรับการดีบักเท่านั้น (เนื่องจาก debugfs ไม่ได้ติดตั้งระหว่างการทำงานปกติของอุปกรณ์)