Pemantauan ABI kernel Android

Anda dapat menggunakan alat pemantauan antarmuka biner aplikasi (ABI), yang tersedia di Android 11 dan yang lebih baru, untuk menstabilkan in-kernel ABI kernel Android. Alat ini mengumpulkan dan membandingkan representasi ABI dari biner kernel yang ada (vmlinux+ modul GKI). ABI ini adalah file .stg dan daftar simbol. Antarmuka pada yang memberikan tampilan disebut Kernel Module Interface (KMI). Anda dapat menggunakan alat tersebut untuk melacak dan memitigasi perubahan pada KMI.

Alat pemantauan ABI dikembangkan di AOSP dan menggunakan STG (atau libabigail inci Android 13 dan yang lebih lama) untuk membuat dan membandingkan dan representasi.

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

Proses

Menganalisis ABI kernel memerlukan beberapa langkah, yang sebagian besar dapat diotomatiskan:

  1. Buat kernel dan representasi ABI-nya.
  2. Menganalisis perbedaan ABI antara build dan referensi.
  3. Memperbarui representasi ABI (jika diperlukan).
  4. Bekerja dengan daftar simbol.

Petunjuk berikut dapat digunakan untuk semua kernel yang dapat Anda bangun menggunakan yang didukung (seperti toolchain Clang bawaan). repo manifests tersedia untuk semua cabang {i>kernel<i} umum Android dan untuk beberapa {i>kernel<i} khusus perangkat, mereka memastikan bahwa toolchain yang benar digunakan saat Anda membangun distribusi {i> kernel<i} untuk analisis.

Daftar simbol

KMI tidak memasukkan semua simbol dalam {i>kernel<i} atau bahkan semua 30.000+ simbol yang diekspor. Sebaliknya, simbol yang dapat digunakan oleh modul vendor adalah secara eksplisit tercantum dalam serangkaian file daftar simbol yang dikelola secara publik di {i>root<i} dari pohon {i>kernel<i}. Penyatuan semua simbol di semua file daftar simbol mendefinisikan seperangkat simbol KMI yang dipelihara sebagai stabil. Contoh file daftar simbol bernilai abi_gki_aarch64_db845c, yang mendeklarasikan simbol yang diperlukan untuk DragonBoard 845c.

Hanya simbol-simbol yang terdaftar dalam sebuah daftar simbol dan struktur yang terkait serta definisi dianggap sebagai bagian dari KMI. Anda dapat memposting perubahan ke daftar simbol jika simbol yang Anda butuhkan tidak ada. Setelah antarmuka baru daftar simbol, dan merupakan bagian dari deskripsi KMI, mereka dijaga agar tetap stabil dan tidak boleh dihapus dari daftar simbol atau diubah setelah cabang dibekukan.

Setiap cabang {i>kernel<i} KMI {i>Common Kernel<i} (ACK) Android memiliki seperangkat simbolnya sendiri daftar. Tidak ada upaya yang dilakukan untuk memberikan stabilitas ABI antara kernel KMI yang berbeda yang berbeda. Misalnya, KMI untuk android12-5.10 benar-benar independen dari KMI untuk android13-5.10.

Alat ABI menggunakan daftar simbol KMI untuk membatasi antarmuka mana yang harus dipantau stabilitas. Tujuan daftar simbol utama berisi simbol yang dibutuhkan oleh modul {i>kernel<i} GKI. Vendor adalah diharapkan untuk mengirimkan dan memperbarui daftar simbol tambahan untuk memastikan bahwa antarmuka yang mengandalkan 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 suatu vendor atau perangkat. Daftar lengkap yang digunakan oleh alat ini adalah gabungan dari semua File daftar simbol KMI. Alat ABI menentukan detail setiap simbol, termasuk tanda tangan fungsi dan struktur data tersarang.

Ketika KMI dibekukan, tidak ada perubahan yang diizinkan pada antarmuka KMI yang ada; stabil. Namun, vendor bebas menambahkan simbol ke KMI kapan saja selama penambahan tidak mempengaruhi stabilitas ABI yang ada. Baru ditambahkan disimpan sebagai stabil segera setelah dikutip oleh daftar simbol KMI. Simbol tidak boleh dihapus dari daftar untuk {i>kernel<i} kecuali jika dapat dikonfirmasi bahwa tidak ada perangkat yang pernah dikirim dengan ketergantungan pada simbol itu.

Anda dapat membuat daftar simbol KMI untuk perangkat menggunakan instruksi dari Cara menggunakan daftar simbol. Banyak partner mengirimkan satu daftar simbol per ACK, tetapi ini bukan persyaratan yang sulit. Jika membantu dalam pemeliharaan, Anda dapat mengirimkan beberapa daftar simbol.

Memperluas KMI

Sementara simbol KMI dan struktur terkait dipertahankan sebagai stabil (makna perubahan yang merusak antarmuka stabil dalam {i> kernel<i} dengan KMI yang dibekukan tidak bisa diterima), {i>kernel<i} GKI tetap terbuka untuk ekstensi sehingga perangkat yang dikirim di akhir tahun tidak perlu mendefinisikan semua dependensi mereka sebelum KMI dibekukan. Untuk memperluas KMI, Anda dapat menambahkan simbol baru ke KMI untuk fungsi {i>kernel<i} yang diekspor, walaupun KMI dibekukan. Kernel baru {i>patch<i} mungkin juga diterima jika mereka tidak merusak KMI.

Tentang kerusakan KMI

Kernel memiliki sumber dan biner dibuat dari sumber tersebut. Cabang kernel yang dipantau ABI menyertakan representasi ABI dari GKI saat ini ABI (dalam bentuk file .stg). Setelah biner (vmlinux, Image, dan modul GKI) dibangun, representasi ABI dapat diekstrak dari biner. Setiap perubahan yang dibuat pada file sumber {i> kernel<i} dapat memengaruhi biner dan juga memengaruhi .stg yang diekstrak. Penganalisis AbiAnalyzer membandingkan file .stg yang di-commit dengan yang diekstrak dari artefak build dan menetapkan Label Lint-1 pada perubahan di Gerrit jika menemukan perbedaan semantik.

Menangani kerusakan ABI

Sebagai contoh, patch berikut memperkenalkan 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, alat akan keluar dengan kode error yang bukan nol dan melaporkan perbedaan ABI yang mirip 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 build

Alasan paling umum untuk error adalah saat {i>driver<i} menggunakan simbol baru dari {i>kernel<i} yang tidak ada dalam daftar simbol apa pun.

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

Jika simbol diekspor (baik oleh Anda maupun sebelumnya diekspor) tetapi tidak menggunakan {i>driver<i} lain, Anda mungkin mendapatkan {i>build error<i} yang mirip 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 {i>kernel<i} dan ACK (lihat Memperbarui representasi ABI). Untuk contoh pembaruan XML ABI dan daftar simbol di ACK, lihat AOSP/1367601.

Mengatasi kerusakan ABI kernel

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

Diagram Alir Kerusakan ABI

Gambar 1. Resolusi kerusakan ABI

Memfaktorkan ulang kode untuk menghindari perubahan ABI

Berusahalah untuk menghindari modifikasi ABI yang sudah ada. Dalam banyak kasus, Anda dapat memfaktorkan ulang kode untuk menghapus perubahan yang memengaruhi ABI.

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

  • Memfaktorkan ulang fitur agar tidak mengubah kernel inti. Jika fitur baru perlu ditambahkan ke ACK untuk mendukung modul partner, coba memfaktorkan ulang ABI dari perubahan guna menghindari modifikasi ABI {i>kernel<i}. Untuk contoh penggunaan ABI kernel yang ada untuk memberikan kemampuan tambahan tanpa mengubah ABI kernel merujuk ke AOSP/1312213.

Memperbaiki ABI yang rusak di Android Gerrit

Jika Anda tidak sengaja merusak ABI {i>kernel<i}, maka Anda perlu menyelidikinya, menggunakan panduan yang disediakan oleh alat pemantauan ABI. Paling umum penyebab kerusakan adalah perubahan struktur data dan simbol CRC yang terkait perubahan, atau karena perubahan opsi konfigurasi yang menyebabkan hal-hal yang disebutkan di atas. Mulailah dengan mengatasi masalah yang ditemukan oleh alat tersebut.

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

Tentang label Lint-1

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

Jika menemukan laporan yang tidak kosong, AbiAnalyzer akan menetapkan label Lint-1 dan perubahan diblokir dari pengiriman hingga diselesaikan; hingga {i>patchset<i} tersebut menerima Label lint+1.

Mengupdate ABI kernel

Jika memodifikasi ABI tidak bisa dihindari, maka Anda harus menerapkan perubahan kode, representasi ABI, dan daftar simbol ke ACK. Untuk membuat Lint hapus -1 dan tidak merusak kompatibilitas GKI, ikuti langkah-langkah berikut:

  1. Mengupload perubahan kode ke ACK.

  2. Tunggu untuk menerima Code-Review +2 untuk patchset.

  3. Memperbarui representasi ABI referensi.

  4. Gabungkan perubahan kode Anda dan perubahan update ABI.

Mengupload perubahan kode ABI ke ACK

Pembaruan ABI ACK bergantung pada jenis perubahan yang dilakukan.

  • Jika perubahan ABI terkait dengan fitur yang mempengaruhi pengujian CTS atau VTS, perubahan biasanya dapat dipilih sendiri ke ACK sebagaimana adanya. Contoh:

  • Jika perubahan ABI adalah untuk fitur yang dapat dibagikan dengan ACK, {i>change<i} dapat dipilih menjadi ACK sebagaimana adanya. Misalnya, perubahan berikut tidak diperlukan untuk uji CTS atau VTS tetapi dapat dibagikan dengan ACK:

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

Menggunakan stub untuk ACK

Stub hanya diperlukan untuk perubahan {i>kernel<i} inti yang tidak bermanfaat ACK, seperti performa dan perubahan daya. Contoh detail daftar berikut {i>rintisan<i} dan {i>ceri-cap<i} parsial di ACK untuk GKI.

  • Bagian fitur core-isolate (AOSP/1284493). Kemampuan dalam 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 mm per proses khusus ABI (AOSP/1288454). {i>Patch<i} asli dipilih untuk memilih ACK, lalu dipangkas agar hanya menyertakan perubahan yang diperlukan guna menyelesaikan perbedaan ABI untuk task_struct dan mm_event_count. Patch ini juga memperbarui enum mm_event_type untuk memuat para anggota akhir.

  • Memilih sebagian perubahan ABI termal struct yang membutuhkan lebih dari menambahkan kolom ABI baru.

    • Dikebiri AOS/1255544 menyelesaikan perbedaan ABI antara {i>kernel<i} mitra dan ACK.

    • Dikebiri AOS/1291018 memperbaiki masalah fungsional yang ditemukan selama pengujian GKI pada {i>patch<i} sebelumnya. Perbaikan ini mencakup inisialisasi struct parameter sensor untuk didaftarkan beberapa zona termal ke satu sensor.

  • CONFIG_NL80211_TESTMODE perubahan ABI (AOSP/1344321). Patch ini menambahkan perubahan struct yang diperlukan untuk ABI dan kolom tambahan tidak menyebabkan perbedaan fungsi, sehingga partner dapat menyertakan CONFIG_NL80211_TESTMODE dalam kernel produksinya dan tetap menjaga kepatuhan GKI.

Menerapkan 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 yang tercantum dalam daftar simbol. Semua simbol lainnya tidak diekspor, dan memuat modul yang memerlukan simbol yang tidak diekspor ditolak. Batasan ini diberlakukan pada waktu build dan entri yang hilang ditandai.

Untuk tujuan pengembangan, Anda dapat menggunakan {i>kernel<i} GKI yang tidak termasuk pemangkasan simbol (artinya semua simbol yang biasanya diekspor dapat digunakan). Untuk menemukan build ini, cari build kernel_debug_aarch64 berdasarkan ci.android.com.

Menerapkan KMI menggunakan pembuatan versi modul

Kernel Image Kernel Generik (GKI) menggunakan pembuatan versi modul (CONFIG_MODVERSIONS) sebagai tindakan tambahan untuk menegakkan kepatuhan KMI di waktu beroperasi. Pembuatan versi modul dapat menyebabkan ketidakcocokan cyclic redundancy check (CRC) kegagalan pada waktu muat modul jika KMI modul yang diharapkan tidak sesuai dengan vmlinux KMI. Misalnya, berikut ini adalah kegagalan yang umum 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 pembuatan versi modul

Pembuatan versi modul berguna karena alasan berikut:

  • Pembuatan versi modul mendeteksi perubahan dalam visibilitas struktur data. Modul If mengubah struktur data buram, yaitu, struktur data yang bukan bagian dari {i>KMI<i}, mereka bisa rusak setelah perubahan struktur di masa depan.

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

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

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

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

  • Modul saat ini dianggap tidak kompatibel dengan KMI ketika dimuat di kemudian hari oleh {i>kernel<i} baru yang tidak kompatibel. Pembuatan versi modul menambahkan pemeriksaan waktu proses ke menghindari pemuatan modul yang tidak kompatibel dengan KMI dengan {i>kernel<i} secara tidak sengaja. Pemeriksaan ini mencegah masalah runtime yang sulit di-debug dan error kernel yang mungkin mengakibatkan inkompatibilitas yang tidak terdeteksi di KMI.

Mengaktifkan pembuatan versi modul akan mencegah semua masalah ini.

Periksa ketidakcocokan CRC tanpa melakukan booting perangkat

stgdiff membandingkan dan melaporkan ketidakcocokan CRC antara kernel bersama dengan Perbedaan ABI.

Selain itu, build kernel penuh dengan CONFIG_MODVERSIONS diaktifkan akan menghasilkan Module.symvers sebagai bagian dari proses build normal. File ini memiliki satu untuk setiap simbol yang diekspor oleh kernel (vmlinux) dan modul. Masing-masing terdiri dari nilai CRC, nama simbol, namespace simbol, vmlinux atau nama modul yang mengekspor simbol, dan jenis ekspor (misalnya, EXPORT_SYMBOL vs. EXPORT_SYMBOL_GPL).

Anda dapat membandingkan file Module.symvers antara build GKI dan build Anda untuk memeriksa perbedaan CRC dalam simbol yang diekspor oleh vmlinux. Jika ada adalah selisih nilai CRC dalam simbol apa pun yang diekspor oleh vmlinux dan yang digunakan oleh salah satu modul yang Anda muat di perangkat Anda, modul tidak memuat halaman.

Jika Anda tidak memiliki semua artefak build, tetapi memiliki file vmlinux {i>kernel<i} GKI dan {i>kernel<i}, Anda dapat membandingkan nilai CRC untuk dengan menjalankan perintah berikut pada kedua {i>kernel<i} dan membandingkan {i>output<i}:

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

Misalnya, perintah berikut memeriksa nilai CRC untuk module_layout simbol:

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Mengatasi ketidakcocokan CRC

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

  1. Membangun kernel GKI dan kernel perangkat Anda menggunakan --kbuild_symtypes seperti yang ditunjukkan dalam 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 mengetahui detailnya.

    Untuk Android 13 dan yang lebih lama, build kernel GKI dan kernel perangkat Anda dengan menambahkan KBUILD_SYMTYPES=1 ke perintah yang gunakan untuk membangun 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,, tanda KBUILD_SYMTYPES=1 akan ditetapkan 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. Temukan file .c menggunakan perintah berikut berikut:

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

    Berikut adalah karakteristik file .c:

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

    • [s|u|e|etc]# di awal garis berarti simbol merupakan jenis data [struct|union|enum|etc]. Contoh:

      t#bool typedef _Bool bool
      
    • Awalan # yang tidak ada di awal baris menunjukkan bahwa simbol tersebut adalah fungsi. Contoh:

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

Kasus 1: Perbedaan karena visibilitas jenis data

Jika satu {i>kernel<i} membuat simbol atau tipe data tidak tembus pandang terhadap modul dan {i>kernel<i} tidak, perbedaan itu muncul di antara file .symtypes dari kedua {i>kernel<i}. File .symtypes dari salah satu kernel memiliki UNKNOWN untuk simbol dan file .symtypes dari kernel lain memiliki tampilan yang diperluas dari simbol atau tipe data.

Misalnya, menambahkan baris berikut ke elemen 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, mengekspos hal berikut perbedaan:

 $ 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 yang diperluas simbol (sangat tidak mungkin), kemudian gabungkan Kernel Umum Android terbaru ke dalam {i>kernel<i} sehingga Anda menggunakan basis {i>kernel<i} GKI terbaru.

Umumnya, kernel GKI memiliki nilai UNKNOWN, tetapi kernel Anda memiliki detail internal simbol karena perubahan yang dilakukan pada {i>kernel<i} Anda. Ini adalah karena salah satu file dalam {i>kernel<i} Anda menambahkan #include yang tidak ada di {i>kernel<i} GKI.

Sering kali, perbaikan hanya menyembunyikan #include baru dari genksyms.

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

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

  1. Buka file {i>header<i} yang mendefinisikan simbol atau tipe data yang memiliki ini perbedaan. 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 mengikuti sebagai baris pertama sebelum salah satu baris #include.

    #define CRC_CATCH 1
    
  4. Kompilasi modul Anda. Error waktu build yang dihasilkan menampilkan rantai file header #include yang menyebabkan ketidakcocokan CRC ini. Contoh:

    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 link dalam rantai #include ini disebabkan oleh perubahan yang dilakukan pada {i>kernel<i}, yang hilang di {i>kernel<i} GKI.

  5. Identifikasi perubahan, kembalikan pada {i>kernel<i} Anda atau menguploadnya ke ACK dan menggabungkannya.

Kasus 2: Perbedaan karena perubahan jenis data

Jika ketidakcocokan CRC untuk simbol atau tipe data bukan karena perbedaan visibilitas, maka itu karena perubahan yang sebenarnya (penambahan, penghapusan, atau perubahan) tipe data itu sendiri.

Misalnya, membuat perubahan berikut pada {i>kernel<i} menyebabkan beberapa CRC ketidakcocokan 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, maka 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 jenis yang diubah, ikuti langkah-langkah berikut:

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

    • Untuk perbedaan simbol antara {i> kernel<i} dan {i>kernel<i} GKI, temukan commit dengan menjalankan perintah berikut:
    git blame
    
    • Untuk simbol yang dihapus (ketika simbol dihapus di hierarki dan Anda juga ingin menghapusnya di pohon lain), Anda perlu menemukan perubahan yang menghapus garis. Gunakan perintah berikut pada hierarki tempat baris dihapus:
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Tinjau daftar commit yang ditampilkan untuk menemukan perubahan atau penghapusan. Tujuan commit pertama mungkin adalah yang Anda cari. Jika tidak, buka menelusuri daftar sampai Anda menemukan commit.

  3. Setelah Anda mengidentifikasi perubahan, kembalikan di {i>kernel<i} atau upload ke ACK dan dapatkan digabungkan.