Pemantauan ABI Kernel Android

Anda dapat menggunakan aplikasi alat Pemantauan Antarmuka Biner (ABI), yang tersedia di Android 11 dan lebih tinggi, untuk menstabilkan ABI dalam kernel kernel Android. Perkakas ini mengumpulkan dan membandingkan representasi ABI dari biner kernel yang ada (modul vmlinux + GKI). Representasi ABI ini adalah file .stg dan daftar simbol. Antarmuka tempat representasi memberikan tampilan disebut Kernel Module Interface (KMI). Anda dapat menggunakan alat ini untuk melacak dan memitigasi perubahan pada KMI.

Alat pemantauan ABI dikembangkan di AOSP dan menggunakan STG (atau libabigail di Android 13 dan lebih rendah) untuk menghasilkan dan membandingkan representasi.

Halaman ini menjelaskan alat, proses pengumpulan dan analisis representasi ABI, dan penggunaan representasi tersebut untuk memberikan stabilitas pada ABI dalam kernel. Halaman ini juga menyediakan informasi untuk memberikan kontribusi perubahan pada kernel Android.

Proses

Menganalisis ABI kernel memerlukan beberapa langkah, yang sebagian besar dapat dilakukan secara otomatis:

  1. Bangun kernel dan representasi ABI-nya .
  2. Analisis perbedaan ABI antara build dan referensi .
  3. Perbarui representasi ABI (jika diperlukan) .
  4. Bekerja dengan daftar simbol .

Petunjuk berikut dapat digunakan untuk kernel apa pun yang dapat Anda buat menggunakan rantai alat yang didukung (seperti rantai alat Clang bawaan). repo manifests tersedia untuk semua cabang kernel umum Android dan untuk beberapa kernel khusus perangkat, manifes ini memastikan bahwa rantai alat yang benar digunakan saat Anda membuat distribusi kernel untuk analisis.

Daftar simbol

KMI tidak menyertakan semua simbol di kernel atau bahkan 30.000+ simbol yang diekspor. Sebaliknya, simbol-simbol yang dapat digunakan oleh modul vendor secara eksplisit tercantum dalam sekumpulan file daftar simbol yang dikelola secara publik di akar pohon kernel. Gabungan semua simbol di semua file daftar simbol mendefinisikan kumpulan simbol KMI yang dipertahankan sebagai stabil. Contoh file daftar simbol adalah abi_gki_aarch64_db845c , yang mendeklarasikan simbol yang diperlukan untuk DragonBoard 845c .

Hanya simbol-simbol yang terdaftar dalam daftar simbol dan struktur serta definisi terkait yang dianggap sebagai bagian dari KMI. Anda dapat memposting perubahan pada daftar simbol Anda jika simbol yang Anda perlukan tidak ada. Setelah antarmuka baru ada dalam daftar simbol, dan merupakan bagian dari deskripsi KMI, antarmuka tersebut dipertahankan sebagai antarmuka yang stabil dan tidak boleh dihapus dari daftar simbol atau diubah setelah cabang dibekukan.

Setiap cabang kernel KMI Android Common Kernel (ACK) memiliki kumpulan daftar simbolnya sendiri. Tidak ada upaya yang dilakukan untuk memberikan stabilitas ABI antara cabang kernel KMI yang berbeda. Misalnya, KMI untuk android12-5.10 sepenuhnya independen dari KMI untuk android13-5.10 .

Alat ABI menggunakan daftar simbol KMI untuk membatasi antarmuka mana yang harus dipantau stabilitasnya. Daftar simbol utama berisi simbol-simbol yang diperlukan oleh modul kernel GKI. Vendor diharapkan mengirimkan dan memperbarui daftar simbol tambahan untuk memastikan bahwa antarmuka yang mereka andalkan menjaga kompatibilitas ABI. Misalnya, untuk melihat daftar daftar simbol untuk android13-5.15 , lihat https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android

Daftar simbol berisi simbol-simbol yang dilaporkan diperlukan untuk vendor atau perangkat tertentu. Daftar lengkap yang digunakan oleh alat ini merupakan gabungan dari semua file daftar simbol KMI. Alat ABI menentukan detail setiap simbol, termasuk tanda tangan fungsi dan struktur data bertingkat.

Ketika KMI dibekukan, tidak ada perubahan yang diperbolehkan pada antarmuka KMI yang ada; mereka stabil. Namun vendor bebas menambahkan simbol pada KMI kapan saja selama penambahan tersebut tidak mempengaruhi kestabilan ABI yang ada. Simbol yang baru ditambahkan dipertahankan stabil segera setelah dikutip oleh daftar simbol KMI. Simbol tidak boleh dihapus dari daftar kernel kecuali dapat dipastikan bahwa tidak ada perangkat yang pernah dikirimkan dengan ketergantungan pada simbol tersebut.

Anda dapat membuat daftar simbol KMI untuk perangkat menggunakan instruksi dari Cara bekerja dengan daftar simbol . Banyak mitra mengirimkan satu daftar simbol per ACK, namun ini bukanlah persyaratan yang sulit. Jika ini membantu pemeliharaan, Anda dapat mengirimkan beberapa daftar simbol.

Perluas KMI

Meskipun simbol KMI dan struktur terkait dipertahankan sebagai stabil (artinya perubahan yang merusak antarmuka stabil pada kernel dengan KMI yang dibekukan tidak dapat diterima) kernel GKI tetap terbuka untuk ekstensi sehingga perangkat yang dikirimkan pada akhir tahun tidak perlu mendefinisikan semuanya. ketergantungan mereka sebelum KMI dibekukan. Untuk memperluas KMI, Anda dapat menambahkan simbol baru ke KMI untuk fungsi kernel baru atau yang sudah ada yang diekspor, meskipun KMI dibekukan. Patch kernel baru juga dapat diterima jika tidak merusak KMI.

Tentang kerusakan KMI

Kernel memiliki sumber dan biner dibangun dari sumber tersebut. Cabang kernel yang dipantau ABI menyertakan representasi ABI dari GKI ABI saat ini (dalam bentuk file .stg ). Setelah biner ( vmlinux , Image dan modul GKI apa pun) dibuat, representasi ABI dapat diekstraksi dari biner. Setiap perubahan yang dilakukan pada file sumber kernel dapat mempengaruhi biner dan pada gilirannya juga mempengaruhi .stg yang diekstraksi. Penganalisis AbiAnalyzer membandingkan file .stg yang dikomit dengan file yang diekstraksi dari artefak build dan menetapkan label Lint-1 pada perubahan di Gerrit jika menemukan perbedaan semantik.

Tangani kerusakan ABI

Sebagai contoh, patch berikut menyebabkan kerusakan ABI yang sangat jelas:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 42786e6364ef..e15f1d0f137b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -657,6 +657,7 @@ struct mm_struct {
                ANDROID_KABI_RESERVE(1);
        } __randomize_layout;
 
+       int tickle_count;
        /*
         * The mm_cpumask needs to be at the end of mm_struct, because it
         * is dynamically sized based on nr_cpu_ids.

Saat Anda menjalankan ABI build dengan menerapkan patch ini, perkakas akan keluar dengan kode kesalahan bukan nol dan melaporkan perbedaan ABI yang serupa dengan ini:

function symbol 'struct block_device* I_BDEV(struct inode*)' changed
  CRC changed from 0x8d400dbd to 0xabfc92ad

function symbol 'void* PDE_DATA(const struct inode*)' changed
  CRC changed from 0xc3c38b5c to 0x7ad96c0d

function symbol 'void __ClearPageMovable(struct page*)' changed
  CRC changed from 0xf489e5e8 to 0x92bd005e

... 4492 omitted; 4495 symbols have only CRC changes

type 'struct mm_struct' changed
  byte size changed from 992 to 1000
  member 'int tickle_count' was added
  member 'unsigned long cpu_bitmap[0]' changed
    offset changed by 64

Perbedaan ABI terdeteksi pada waktu pembuatan

Alasan paling umum terjadinya kesalahan adalah ketika driver menggunakan simbol baru dari kernel yang tidak ada dalam daftar simbol mana pun.

Jika simbol tidak disertakan dalam daftar simbol ( android/abi_gki_aarch64 ), Anda harus terlebih dahulu memverifikasi bahwa simbol tersebut diekspor dengan EXPORT_SYMBOL_GPL( symbol_name ) lalu memperbarui representasi ABI XML dan daftar simbol. Misalnya, perubahan berikut menambahkan fitur FS Inkremental baru ke cabang android-12-5.10 , yang mencakup pembaruan daftar simbol dan representasi ABI XML.

Jika simbol diekspor (baik oleh Anda atau sebelumnya diekspor) tetapi tidak ada driver lain yang menggunakannya, Anda mungkin mendapatkan kesalahan build yang serupa dengan berikut ini.

Comparing the KMI and the symbol lists:
+ build/abi/compare_to_symbol_list out/$BRANCH/common/Module.symvers out/$BRANCH/common/abi_symbollist.raw
ERROR: Differences between ksymtab and symbol list detected!
Symbols missing from ksymtab:
Symbols missing from symbol list:
 - simple_strtoull

Untuk mengatasinya, perbarui daftar simbol KMI di kernel Anda dan ACK (lihat Memperbarui representasi ABI ). Untuk contoh memperbarui ABI XML dan daftar simbol di ACK, lihat aosp/1367601 .

Mengatasi kerusakan kernel ABI

Anda dapat menangani kerusakan kernel ABI dengan memfaktorkan ulang kode agar tidak mengubah ABI atau memperbarui representasi ABI . Gunakan bagan berikut untuk menentukan pendekatan terbaik untuk situasi Anda.

Bagan Alir Kerusakan ABI

Gambar 1. Resolusi kerusakan ABI

Refactor kode untuk menghindari perubahan ABI

Lakukan segala upaya untuk menghindari modifikasi ABI yang ada. Dalam banyak kasus, Anda dapat memfaktorkan ulang kode Anda untuk menghapus perubahan yang memengaruhi ABI.

  • Memfaktorkan ulang perubahan bidang struct. Jika perubahan mengubah ABI untuk fitur debug, tambahkan #ifdef di sekitar kolom (dalam struct dan referensi sumber) dan pastikan CONFIG yang digunakan untuk #ifdef dinonaktifkan untuk produksi defconfig dan gki_defconfig . Untuk contoh bagaimana konfigurasi debug dapat ditambahkan ke struct tanpa merusak ABI, lihat patchset ini .

  • Fitur refactoring untuk tidak mengubah kernel inti. Jika fitur baru perlu ditambahkan ke ACK untuk mendukung modul mitra, cobalah memfaktorkan ulang bagian ABI dari perubahan untuk menghindari modifikasi pada kernel ABI. Untuk contoh penggunaan kernel ABI yang ada untuk menambahkan fungsionalitas tambahan tanpa mengubah kernel ABI, lihat aosp/1312213 .

Perbaiki ABI yang rusak di Android Gerrit

Jika Anda tidak sengaja merusak kernel ABI, maka Anda perlu menyelidikinya, menggunakan panduan yang disediakan oleh alat pemantauan ABI. Penyebab paling umum dari kerusakan adalah perubahan struktur data dan perubahan simbol CRC yang terkait, atau karena perubahan opsi konfigurasi yang menyebabkan hal-hal tersebut di atas. Mulailah dengan mengatasi masalah yang ditemukan oleh alat ini.

Anda dapat mereproduksi temuan ABI secara lokal, lihat Membangun kernel dan representasi ABI-nya .

Tentang label Lint-1

Jika Anda mengunggah perubahan ke cabang yang berisi KMI yang dibekukan atau diselesaikan, perubahan tersebut harus melewati AbiAnalyzer untuk memastikan perubahan tidak memengaruhi ABI stabil dengan cara yang tidak kompatibel. Selama proses ini, AbiAnalyzer mencari laporan ABI yang dibuat selama build (build diperluas yang menjalankan build normal dan kemudian beberapa langkah ekstraksi dan perbandingan ABI.

Jika AbiAnalyzer menemukan laporan yang tidak kosong, AbiAnalyzer akan menyetel label Lint-1 dan perubahan diblokir dari pengiriman hingga diselesaikan; hingga patchset menerima label Lint+1.

Perbarui Kernel ABI

Jika modifikasi ABI tidak dapat dihindari, maka Anda harus menerapkan perubahan kode, representasi ABI, dan daftar simbol ke ACK. Agar Lint menghapus -1 dan tidak merusak kompatibilitas GKI, ikuti langkah-langkah berikut:

  1. Unggah perubahan kode ke ACK .

  2. Tunggu untuk menerima Tinjauan Kode +2 untuk set tambalan.

  3. Perbarui representasi referensi ABI .

  4. Gabungkan perubahan kode Anda dan perubahan pembaruan ABI.

Unggah perubahan kode ABI ke ACK

Memperbarui ACK ABI tergantung pada jenis perubahan yang dilakukan.

  • Jika perubahan ABI terkait dengan fitur yang memengaruhi pengujian CTS atau VTS, perubahan tersebut biasanya dapat dipilih ke ACK apa adanya. Misalnya:

  • Jika perubahan ABI ditujukan untuk fitur yang dapat dibagikan dengan ACK, perubahan tersebut dapat dipilih ke ACK apa adanya. Misalnya, perubahan berikut tidak diperlukan untuk pengujian CTS atau VTS namun boleh dibagikan dengan ACK:

  • Jika perubahan ABI memperkenalkan fitur baru yang tidak perlu disertakan dalam ACK, Anda dapat memperkenalkan simbol ke ACK menggunakan stub seperti yang dijelaskan di bagian berikut.

Gunakan rintisan untuk ACK

Stub harus diperlukan hanya untuk perubahan kernel inti yang tidak menguntungkan ACK, seperti perubahan kinerja dan daya. Daftar berikut merinci contoh stub dan sebagian cherry-pick di ACK untuk GKI.

  • Rintisan fitur isolasi inti ( aosp/1284493 ). Fungsionalitas di ACK tidak diperlukan, tetapi simbol harus ada di ACK agar modul Anda dapat menggunakan simbol-simbol ini.

  • Simbol placeholder untuk modul vendor ( aosp/1288860 ).

  • Fitur pelacakan peristiwa per proses mm pilihan khusus ABI ( aosp/1288454 ). Patch asli dipilih ke ACK dan kemudian dipangkas untuk hanya menyertakan perubahan yang diperlukan untuk menyelesaikan perbedaan ABI untuk task_struct dan mm_event_count . Patch ini juga memperbarui enum mm_event_type untuk memuat anggota akhir.

  • Pilihan parsial perubahan ABI struktur termal yang memerlukan lebih dari sekadar menambahkan bidang ABI baru.

    • Patch aosp/1255544 menyelesaikan perbedaan ABI antara kernel mitra dan ACK.

    • Patch aosp/1291018 memperbaiki masalah fungsional yang ditemukan selama pengujian GKI pada patch sebelumnya. Perbaikannya termasuk menginisialisasi struktur parameter sensor untuk mendaftarkan beberapa zona termal ke satu sensor.

  • CONFIG_NL80211_TESTMODE Perubahan ABI ( aosp/1344321 ). Patch ini menambahkan perubahan struktur yang diperlukan untuk ABI dan memastikan kolom tambahan tidak menyebabkan perbedaan fungsional, sehingga mitra dapat menyertakan CONFIG_NL80211_TESTMODE di kernel produksi mereka dan tetap mempertahankan kepatuhan GKI.

Terapkan KMI saat runtime

Kernel GKI menggunakan opsi konfigurasi TRIM_UNUSED_KSYMS=y dan UNUSED_KSYMS_WHITELIST=<union of all symbol lists> , yang membatasi simbol yang diekspor (seperti simbol yang diekspor menggunakan EXPORT_SYMBOL_GPL() ) ke simbol yang terdaftar di daftar simbol. Semua simbol lainnya tidak diekspor, dan pemuatan modul yang memerlukan simbol yang tidak diekspor ditolak. Pembatasan ini diberlakukan pada waktu pembuatan dan entri yang hilang akan ditandai.

Untuk tujuan pengembangan, Anda dapat menggunakan build kernel GKI yang tidak menyertakan pemangkasan simbol (artinya semua simbol yang biasanya diekspor dapat digunakan). Untuk menemukan build ini, cari build kernel_debug_aarch64 di ci.android.com .

Terapkan KMI menggunakan pembuatan versi modul

Kernel Generic Kernel Image (GKI) menggunakan pembuatan versi modul ( CONFIG_MODVERSIONS ) sebagai tindakan tambahan untuk menegakkan kepatuhan KMI saat runtime. Pembuatan versi modul dapat menyebabkan kegagalan ketidakcocokan pemeriksaan redundansi siklik (CRC) pada waktu buka modul jika KMI yang diharapkan dari sebuah modul tidak cocok dengan KMI vmlinux . Misalnya, berikut ini adalah kegagalan umum yang terjadi pada waktu pemuatan modul karena ketidakcocokan CRC untuk simbol module_layout() :

init: Loading module /lib/modules/kernel/.../XXX.ko with args ""
XXX: disagrees about version of symbol module_layout
init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args ''

Penggunaan versi modul

Pembuatan versi modul berguna karena alasan berikut:

  • Pembuatan versi modul menangkap perubahan dalam visibilitas struktur data. Jika modul mengubah struktur data buram, yaitu struktur data yang bukan bagian dari KMI, modul akan rusak setelah perubahan struktur di masa mendatang.

    Sebagai contoh, pertimbangkan bidang fwnode di struct device . Bidang ini HARUS buram bagi modul sehingga modul tidak dapat membuat perubahan pada bidang device->fw_node atau membuat asumsi tentang ukurannya.

    Namun, jika sebuah modul menyertakan <linux/fwnode.h> (secara langsung atau tidak langsung), maka bidang fwnode di struct device tidak lagi buram. Modul kemudian dapat membuat perubahan pada device->fwnode->dev atau device->fwnode->ops . Skenario ini bermasalah karena beberapa alasan, yang dinyatakan sebagai berikut:

    • Hal ini dapat mematahkan asumsi yang dibuat oleh kode kernel inti tentang struktur data internalnya.

    • Jika pembaruan kernel di masa mendatang mengubah struct fwnode_handle (tipe data fwnode ), maka modul tidak lagi berfungsi dengan kernel baru. Selain itu, stgdiff tidak akan menunjukkan perbedaan apa pun karena modul melanggar KMI dengan memanipulasi struktur data internal secara langsung dengan cara yang tidak dapat ditangkap hanya dengan memeriksa representasi biner.

  • Modul saat ini dianggap tidak kompatibel dengan KMI ketika dimuat di kemudian hari oleh kernel baru yang tidak kompatibel. Pembuatan versi modul menambahkan pemeriksaan run-time untuk menghindari pemuatan modul yang tidak kompatibel dengan KMI dengan kernel secara tidak sengaja. Pemeriksaan ini mencegah masalah runtime yang sulit di-debug dan kerusakan kernel yang mungkin diakibatkan oleh ketidakcocokan yang tidak terdeteksi di KMI.

Mengaktifkan pembuatan versi modul akan mencegah semua masalah ini.

Periksa ketidakcocokan CRC tanpa mem-boot perangkat

stgdiff membandingkan dan melaporkan ketidakcocokan CRC antar kernel serta perbedaan ABI lainnya.

Selain itu, build kernel lengkap dengan CONFIG_MODVERSIONS diaktifkan akan menghasilkan file Module.symvers sebagai bagian dari proses build normal. File ini memiliki satu baris untuk setiap simbol yang diekspor oleh kernel ( vmlinux ) dan modul. Setiap baris terdiri dari nilai CRC, nama simbol, namespace simbol, vmlinux atau nama modul yang mengekspor simbol, dan tipe ekspor (misalnya, EXPORT_SYMBOL versus EXPORT_SYMBOL_GPL ).

Anda dapat membandingkan file Module.symvers antara build GKI dan build Anda untuk memeriksa perbedaan CRC pada simbol yang diekspor oleh vmlinux . Jika ada perbedaan nilai CRC pada simbol apa pun yang diekspor oleh vmlinux dan simbol tersebut digunakan oleh salah satu modul yang Anda muat di perangkat Anda, modul tidak akan dimuat.

Jika Anda tidak memiliki semua artefak build, namun memiliki file vmlinux dari kernel GKI dan kernel Anda, Anda dapat membandingkan nilai CRC untuk simbol tertentu dengan menjalankan perintah berikut pada kedua kernel dan membandingkan hasilnya:

nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>

Misalnya, perintah berikut memeriksa nilai CRC untuk simbol module_layout :

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Selesaikan ketidakcocokan CRC

Gunakan langkah-langkah berikut untuk mengatasi ketidakcocokan CRC saat memuat modul:

  1. Bangun kernel GKI dan kernel perangkat Anda menggunakan opsi --kbuild_symtypes seperti yang ditunjukkan pada perintah berikut:

    tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
    

    Perintah ini menghasilkan file .symtypes untuk setiap file .o . Lihat KBUILD_SYMTYPES di Kleaf untuk detailnya.

    Untuk Android 13 dan yang lebih rendah, buat kernel GKI dan kernel perangkat Anda dengan menambahkan KBUILD_SYMTYPES=1 ke perintah yang Anda gunakan untuk membuat kernel, seperti yang ditunjukkan dalam perintah berikut:

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    

    Saat menggunakan build_abi.sh, flag KBUILD_SYMTYPES=1 sudah disetel secara implisit.

  2. Temukan file .c yang mengekspor simbol dengan ketidakcocokan CRC, menggunakan perintah berikut:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. File .c memiliki file .symtypes yang sesuai di GKI, dan artefak build kernel perangkat Anda. Temukan file .c menggunakan perintah berikut:

    cd out/$BRANCH/common && ls -1 kernel/module.*
    kernel/module.o
    kernel/module.o.symversions
    kernel/module.symtypes
    

    Berikut ciri-ciri file .c :

    • Format file .c adalah satu baris (berpotensi sangat panjang) per simbol.

    • [s|u|e|etc]# di awal baris berarti simbolnya bertipe data [struct|union|enum|etc] . Misalnya:

      t#bool typedef _Bool bool
      
    • Awalan # yang hilang di awal baris menunjukkan bahwa simbol tersebut adalah suatu fungsi. Misalnya:

      find_module s#module * find_module ( const char * )
      
  4. Bandingkan kedua file dan perbaiki semua perbedaannya.

Kasus 1: Perbedaan karena visibilitas tipe data

Jika salah satu kernel menyimpan simbol atau tipe data yang buram terhadap modul dan kernel lainnya tidak, perbedaan tersebut akan muncul di antara file .symtypes dari kedua kernel. File .symtypes dari salah satu kernel memiliki simbol UNKNOWN dan file .symtypes dari kernel lain memiliki tampilan simbol atau tipe data yang diperluas.

Misalnya, menambahkan baris berikut ke file include/linux/device.h di kernel Anda menyebabkan ketidakcocokan CRC, salah satunya adalah untuk module_layout() :

 #include <linux/fwnode.h>

Membandingkan module.symtypes untuk simbol tersebut, memperlihatkan perbedaan berikut:

 $ diff -u <GKI>/kernel/module.symtypes <your kernel>/kernel/module.symtypes
  --- <GKI>/kernel/module.symtypes
  +++ <your kernel>/kernel/module.symtypes
  @@ -334,12 +334,15 @@
  ...
  -s#fwnode_handle struct fwnode_handle { UNKNOWN }
  +s#fwnode_reference_args struct fwnode_reference_args { s#fwnode_handle * fwnode ; unsigned int nargs ; t#u64 args [ 8 ] ; }
  ...

Jika kernel Anda memiliki nilai UNKNOWN dan kernel GKI memiliki tampilan simbol yang diperluas (sangat tidak mungkin), maka gabungkan Android Common Kernel terbaru ke dalam kernel Anda sehingga Anda menggunakan basis kernel GKI terbaru.

Dalam kebanyakan kasus, kernel GKI memiliki nilai UNKNOWN , namun kernel Anda memiliki detail internal simbol tersebut karena perubahan yang dilakukan pada kernel Anda. Ini karena salah satu file di kernel Anda menambahkan #include yang tidak ada di kernel GKI.

Seringkali, perbaikannya sesederhana menyembunyikan #include baru dari genksyms .

#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif

Jika tidak, untuk mengidentifikasi #include yang menyebabkan perbedaan, ikuti langkah-langkah berikut:

  1. Buka file header yang mendefinisikan simbol atau tipe data yang memiliki perbedaan ini. Misalnya, edit include/linux/fwnode.h untuk struct fwnode_handle .

  2. Tambahkan kode berikut di bagian atas file header:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. Dalam file .c modul yang memiliki ketidakcocokan CRC, tambahkan baris berikut sebagai baris pertama sebelum baris #include mana pun.

    #define CRC_CATCH 1
    
  4. Kompilasi modul Anda. Kesalahan waktu pembuatan yang dihasilkan menunjukkan rangkaian file header #include yang menyebabkan ketidakcocokan CRC ini. Misalnya:

    In file included from .../drivers/clk/XXX.c:16:`
    In file included from .../include/linux/of_device.h:5:
    In file included from .../include/linux/cpu.h:17:
    In file included from .../include/linux/node.h:18:
    .../include/linux/device.h:16:2: error: "Included from here"
    #error "Included from here"
    

    Salah satu tautan dalam rantai #include ini disebabkan oleh perubahan yang dilakukan pada kernel Anda, yang tidak ada di kernel GKI.

  5. Identifikasi perubahannya, kembalikan ke kernel Anda atau unggah ke ACK dan gabungkan .

Kasus 2: Perbedaan karena perubahan tipe data

Jika ketidakcocokan CRC untuk simbol atau tipe data bukan disebabkan oleh perbedaan visibilitas, maka hal tersebut disebabkan oleh perubahan aktual (penambahan, penghapusan, atau perubahan) pada tipe data itu sendiri.

Misalnya, melakukan perubahan berikut pada kernel Anda akan menyebabkan beberapa ketidakcocokan CRC karena banyak simbol yang secara tidak langsung terpengaruh oleh jenis perubahan ini:

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -259,7 +259,7 @@ struct iommu_ops {
     void (*iotlb_sync)(struct iommu_domain *domain);
     phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
     phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
  -        dma_addr_t iova);
  +        dma_addr_t iova, unsigned long trans_flag);
     int (*add_device)(struct device *dev);
     void (*remove_device)(struct device *dev);
     struct iommu_group *(*device_group)(struct device *dev);

Satu ketidakcocokan CRC adalah untuk devm_of_platform_populate() .

Jika Anda membandingkan file .symtypes untuk simbol tersebut, mungkin akan terlihat seperti ini:

 $ diff -u <GKI>/drivers/of/platform.symtypes <your kernel>/drivers/of/platform.symtypes
  --- <GKI>/drivers/of/platform.symtypes
  +++ <your kernel>/drivers/of/platform.symtypes
  @@ -399,7 +399,7 @@
  ...
  -s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t ) ; int
    ( * add_device ) ( s#device * ) ; ...
  +s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t , unsigned long ) ; int ( * add_device ) ( s#device * ) ; ...

Untuk mengidentifikasi tipe yang diubah, ikuti langkah-langkah berikut:

  1. Temukan definisi simbol dalam kode sumber (biasanya dalam file .h ).

    • Untuk mengetahui perbedaan simbol sederhana antara kernel Anda dan kernel GKI, temukan penerapannya dengan menjalankan perintah berikut:
    git blame
    
    • Untuk simbol yang dihapus (di mana simbol dihapus di pohon dan Anda juga ingin menghapusnya di pohon lain), Anda perlu mencari perubahan yang menghapus baris tersebut. Gunakan perintah berikut pada pohon tempat baris tersebut dihapus:
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Tinjau daftar komitmen yang dikembalikan untuk menemukan perubahan atau penghapusan. Komit pertama mungkin adalah yang Anda cari. Jika tidak, periksa daftarnya sampai Anda menemukan komitnya.

  3. Setelah Anda mengidentifikasi perubahannya, kembalikan perubahan tersebut ke kernel Anda atau unggah ke ACK dan gabungkan .