Anda dapat menggunakan alat pemantauan antarmuka biner aplikasi (ABI), yang tersedia di
Android 11 dan yang lebih tinggi, untuk menstabilkan kernel Android
dalam kernel. Alat 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 tersebut untuk melacak dan memitigasi perubahan pada KMI.
Alat pemantauan ABI
dikembangkan di AOSP
dan menggunakan
STG (atau
libabigail
di
Android 13 dan yang lebih lama) untuk membuat dan membandingkan
representasi.
Halaman ini menjelaskan tentang alat, proses pengumpulan dan analisis representasi ABI, dan penggunaan representasi tersebut untuk memberikan stabilitas pada ABI dalam kernel. Halaman ini juga memberikan informasi untuk berkontribusi pada perubahan pada kernel Android.
Proses
Menganalisis ABI kernel memerlukan beberapa langkah, yang sebagian besar dapat diotomatiskan:
- Buat kernel dan representasi ABI-nya.
- Menganalisis perbedaan ABI antara build dan referensi.
- Perbarui representasi ABI (jika diperlukan).
- Menggunakan daftar simbol.
Petunjuk berikut berfungsi untuk
kernel yang dapat Anda build menggunakan
toolchain yang didukung (seperti toolchain Clang bawaan). repo manifests
tersedia untuk semua cabang kernel umum Android dan untuk beberapa
kernel khusus perangkat, yang memastikan bahwa toolchain yang benar digunakan saat Anda
mem-build distribusi kernel untuk analisis.
Daftar simbol
KMI tidak menyertakan semua simbol dalam kernel atau bahkan semua dari lebih dari 30.000 simbol yang diekspor. Sebagai gantinya, simbol yang dapat digunakan oleh modul vendor diperinci secara eksplisit dalam kumpulan file daftar simbol yang dikelola secara publik di root hierarki kernel. Gabungan semua simbol dalam semua file daftar simbol menentukan kumpulan simbol KMI yang dipertahankan agar stabil. Contoh file daftar simbol adalah abi_gki_aarch64_db845c, yang mendeklarasikan simbol yang diperlukan untuk DragonBoard 845c.
Hanya simbol yang tercantum dalam daftar simbol serta struktur dan definisi terkait yang dianggap sebagai bagian dari KMI. Anda dapat memposting perubahan pada daftar simbol jika simbol yang Anda butuhkan tidak ada. Setelah ada dalam daftar simbol, dan merupakan bagian dari deskripsi KMI, antarmuka baru akan dipelihara sebagai stabil dan tidak boleh dihapus dari daftar simbol atau diubah setelah cabang dibekukan.
Setiap cabang kernel KMI Common Kernel Android (ACK) memiliki kumpulan daftar simbolnya sendiri. Tidak ada upaya untuk memberikan stabilitas ABI di 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 yang harus dipantau untuk
stabilitas. Daftar simbol utama berisi simbol yang diperlukan oleh modul kernel GKI. Vendor
diharapkan untuk mengirimkan dan memperbarui daftar simbol tambahan untuk memastikan bahwa
antarmuka yang mereka andalkan mempertahankan 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 yang dilaporkan diperlukan untuk vendor atau perangkat tertentu. 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 bertingkat.
Ketika KMI dibekukan, tidak ada perubahan yang diizinkan pada antarmuka KMI yang sudah ada karena mereka stabil. Namun, vendor bebas menambahkan simbol ke KMI kapan saja asalkan penambahan tidak memengaruhi stabilitas ABI yang ada. Simbol yang baru ditambahkan akan dipertahankan agar stabil segera setelah dicantumkan dalam daftar simbol KMI. Simbol tidak boleh dihapus dari daftar untuk kernel kecuali jika dapat dikonfirmasi bahwa tidak ada perangkat yang pernah dikirim dengan dependensi pada simbol tersebut.
Anda dapat membuat daftar simbol KMI untuk perangkat menggunakan petunjuk dari Cara bekerja dengan daftar simbol. Banyak partner mengirimkan satu daftar simbol per ACK, tetapi ini bukan persyaratan yang sulit. Jika membantu pemeliharaan, Anda dapat mengirimkan beberapa daftar simbol.
Memperluas KMI
Meskipun simbol KMI dan struktur terkait dipertahankan agar stabil (artinya perubahan yang merusak antarmuka stabil dalam kernel dengan KMI yang dibekukan tidak dapat diterima), kernel GKI tetap terbuka untuk ekstensi sehingga perangkat yang dikirimkan nanti pada tahun ini tidak perlu menentukan semua dependensinya sebelum KMI dibekukan. Untuk memperluas KMI, Anda dapat menambahkan simbol baru ke KMI untuk fungsi kernel yang diekspor baru atau yang sudah ada, meskipun KMI dibekukan. Patch kernel baru juga dapat diterima jika tidak merusak KMI.
Tentang kerusakan KMI
Kernel memiliki sumber dan biner dibuat dari sumber tersebut.
Cabang kernel yang dipantau ABI menyertakan representasi ABI dari ABI GKI
saat ini (dalam bentuk file .stg
). Setelah biner (vmlinux
, Image
, dan
modul GKI apa pun) di-build, representasi ABI dapat diekstrak dari
biner. Setiap perubahan yang dilakukan pada file sumber kernel dapat memengaruhi biner dan
juga memengaruhi .stg
yang diekstrak. Penganalisis AbiAnalyzer
membandingkan
file .stg
yang di-commit dengan file 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 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 patch ini diterapkan, alat akan keluar dengan kode error non-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 error yang paling umum adalah saat pengemudi 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 memverifikasi terlebih dahulu bahwa simbol diekspor dengan
EXPORT_SYMBOL_GPL(symbol_name)
, lalu memperbarui
representasi XML dan daftar simbol ABI. Misalnya, perubahan berikut menambahkan
fitur Incremental FS baru ke cabang android-12-5.10
, yang
menyertakan pembaruan daftar simbol dan representasi XML ABI.
- Contoh perubahan fitur ada di aosp/1345659.
- Contoh daftar simbol ada di aosp/1346742.
- Contoh perubahan XML ABI ada di aosp/1349377.
Jika simbol diekspor (baik oleh Anda maupun sebelumnya diekspor), tetapi tidak ada driver lain yang menggunakannya, Anda mungkin mendapatkan error build 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 kernel 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 agar tidak mengubah ABI atau memperbarui representasi ABI. Gunakan diagram berikut untuk menentukan pendekatan terbaik untuk situasi Anda.
Gambar 1. Penyelesaian kerusakan ABI
Memfaktorkan ulang kode untuk menghindari perubahan ABI
Lakukan segala upaya untuk menghindari perubahan ABI yang 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 fitur debug, tambahkan
#ifdef
di sekitar kolom (dalam struct dan referensi sumber) dan pastikanCONFIG
yang digunakan untuk#ifdef
dinonaktifkan untuk defconfig produksi dangki_defconfig
. Untuk contoh cara konfigurasi debug dapat ditambahkan ke struct tanpa merusak ABI, lihat patchset ini.Memfaktorkan ulang fitur agar tidak mengubah kernel inti. Jika fitur baru perlu ditambahkan ke ACK untuk mendukung modul partner, coba faktorkan ulang bagian perubahan ABI untuk menghindari perubahan ABI kernel. Untuk contoh penggunaan ABI kernel yang ada guna memberikan kemampuan tambahan tanpa mengubah ABI kernel, lihat Keadilan/1312213.
Memperbaiki ABI yang rusak di Android Gerrit
Jika tidak sengaja merusak ABI kernel, Anda perlu menyelidiki, menggunakan panduan yang diberikan oleh alat pemantauan ABI. Penyebab kerusakan yang paling umum adalah perubahan struktur data dan perubahan CRC simbol terkait, atau karena perubahan opsi konfigurasi yang menyebabkan salah satu hal yang disebutkan di atas. Mulailah dengan mengatasi masalah yang ditemukan oleh alat ini.
Anda dapat mereproduksi temuan ABI secara lokal, lihat Mem-build kernel dan representasi ABI-nya.
Tentang label Lint-1
Jika Anda mengupload perubahan ke cabang yang berisi KMI yang dibekukan atau diselesaikan, perubahan tersebut harus lulus AbiAnalyzer
untuk memastikan perubahan tidak memengaruhi ABI stabil dengan cara yang tidak kompatibel. Selama proses ini, AbiAnalyzer
akan mencari
laporan ABI yang dibuat selama build (build yang diperluas yang melakukan
build normal, lalu beberapa langkah ekstraksi dan perbandingan ABI.
Jika AbiAnalyzer
menemukan laporan yang tidak kosong, laporan tersebut akan menetapkan label Lint-1 dan
perubahan akan diblokir dari pengiriman hingga terselesaikan; hingga set patch menerima
label Lint+1.
Memperbarui ABI kernel
Jika tidak dapat menghindari perubahan ABI, 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:
Tunggu hingga Anda menerima Code-Review +2 untuk patchset.
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 memengaruhi pengujian CTS atau VTS, perubahan tersebut biasanya dapat dipilih untuk ACK apa adanya. Misalnya:
- aosp/1289677 diperlukan agar audio berfungsi.
- aosp/1295945 diperlukan agar USB berfungsi.
Jika perubahan ABI ditujukan untuk fitur yang dapat dibagikan ke ACK, perubahan tersebut dapat dipilih menjadi ACK sebagaimana adanya. Misalnya, perubahan berikut tidak diperlukan untuk pengujian CTS atau VTS, tetapi dapat dibagikan dengan ACK:
- aosp/1250412 adalah perubahan fitur termal.
- AOSP/1288857
adalah perubahan
EXPORT_SYMBOL_GPL
.
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.
Menggunakan stub untuk ACK
Stub hanya diperlukan untuk perubahan kernel inti yang tidak menguntungkan ACK, seperti perubahan performa dan daya. Daftar berikut menjelaskan contoh stub dan pilihan sebagian di ACK untuk GKI.
Core-isolate stub fitur (AOSP/1284493). Kemampuan di ACK tidak diperlukan, tetapi simbol harus ada di ACK agar modul Anda dapat menggunakan simbol ini.
Simbol placeholder untuk modul vendor (aosp/1288860).
Pilihan khusus ABI untuk fitur pelacakan peristiwa
mm
per proses (AOSP/1288454). Patch asli dipilih untuk ACK, lalu dipangkas agar hanya menyertakan perubahan yang diperlukan untuk menyelesaikan perbedaan ABI untuktask_struct
danmm_event_count
. Patch ini juga mengupdate enummm_event_type
untuk berisi anggota akhir.Pemilihan sebagian perubahan ABI struktur termal yang memerlukan lebih dari sekadar menambahkan kolom ABI baru.
Patch aosp/1255544 menyelesaikan perbedaan ABI antara kernel partner dan ACK.
Patch AOS/1291018 memperbaiki masalah fungsional yang ditemukan selama pengujian GKI pada patch sebelumnya. Perbaikan ini mencakup inisialisasi struct parameter sensor untuk mendaftarkan beberapa zona termal ke satu sensor.
CONFIG_NL80211_TESTMODE
Perubahan ABI (aosp/1344321). Patch ini menambahkan perubahan struct yang diperlukan untuk ABI dan memastikan kolom tambahan tidak menyebabkan perbedaan fungsional, sehingga partner dapat menyertakanCONFIG_NL80211_TESTMODE
dalam kernel produksi mereka dan tetap mempertahankan 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 simbol yang tercantum dalam
daftar simbol. Semua simbol lainnya tidak diekspor, dan pemuatan modul yang memerlukan
simbol yang tidak diekspor akan ditolak. Pembatasan ini diterapkan pada waktu build dan
entri yang tidak ada 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.
Menerapkan KMI menggunakan pembuatan versi modul
Kernel Image Kernel Generik (GKI) menggunakan pembuatan versi modul
(CONFIG_MODVERSIONS
) sebagai tindakan tambahan untuk menegakkan kepatuhan KMI saat
runtime. Pembuatan versi modul dapat menyebabkan kegagalan ketidakcocokan cyclic redundancy check (CRC)
saat waktu pemuatan modul jika KMI yang diharapkan dari modul tidak cocok dengan
KMI vmlinux
. Misalnya, berikut 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 pembuatan versi modul
Pembuatan versi modul berguna karena alasan berikut:
Pembuatan versi modul menangkap perubahan pada 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 kolom
fwnode
distruct device
. Kolom ini HARUS buram untuk modul sehingga tidak dapat membuat perubahan pada kolomdevice->fw_node
atau membuat asumsi tentang ukurannya.Namun, jika modul menyertakan
<linux/fwnode.h>
(langsung atau tidak langsung), kolomfwnode
distruct device
tidak lagi buram. Modul kemudian dapat membuat perubahan padadevice->fwnode->dev
ataudevice->fwnode->ops
. Skenario ini bermasalah karena beberapa alasan, yang dinyatakan sebagai berikut:Fungsi ini dapat merusak asumsi yang dibuat oleh kode kernel inti tentang struktur data internalnya.
Jika update kernel mendatang mengubah
struct fwnode_handle
(jenis datafwnode
), modul tidak akan lagi berfungsi dengan kernel baru. Selain itu,stgdiff
tidak akan menampilkan perbedaan apa pun karena modul merusak 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 saat dimuat pada lain waktu oleh kernel baru yang tidak kompatibel. Pembuatan versi modul menambahkan pemeriksaan run-time untuk menghindari pemuatan modul yang tidak kompatibel dengan KMI kernel secara tidak sengaja. Pemeriksaan ini mencegah masalah runtime yang sulit di-debug dan error kernel yang mungkin terjadi akibat ketidakcocokan yang tidak terdeteksi di KMI.
Mengaktifkan pembuatan versi modul akan mencegah semua masalah ini.
Memeriksa ketidakcocokan CRC tanpa mem-booting perangkat
stgdiff
membandingkan dan melaporkan ketidakcocokan CRC antara kernel beserta perbedaan
ABI lainnya.
Selain itu, build kernel lengkap dengan CONFIG_MODVERSIONS
yang 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 jenis ekspor (misalnya,
EXPORT_SYMBOL
versus 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
perbedaan nilai CRC dalam simbol apa pun yang diekspor oleh vmlinux
dan
simbol tersebut digunakan oleh salah satu modul yang Anda muat di perangkat, modul tersebut tidak
akan dimuat.
Jika tidak memiliki semua artefak build, tetapi memiliki file vmlinux
kernel GKI dan kernel, Anda dapat membandingkan nilai CRC untuk simbol
tertentu dengan menjalankan perintah berikut pada kernel dan membandingkan
outputnya:
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
Menyelesaikan ketidakcocokan CRC
Gunakan langkah-langkah berikut untuk mengatasi ketidakcocokan CRC saat memuat modul:
Bangun kernel GKI dan kernel perangkat Anda menggunakan opsi
--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
. LihatKBUILD_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 Anda 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,
, flagKBUILD_SYMTYPES=1
secara implisit sudah ditetapkan.Temukan file
.c
tempat simbol dengan ketidakcocokan CRC diekspor, menggunakan perintah berikut:cd common && git grep EXPORT_SYMBOL.*module_layout kernel/module.c:EXPORT_SYMBOL(module_layout);
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 adalah karakteristik file
.c
:Format file
.c
adalah satu baris (yang berpotensi sangat panjang) per simbol.[s|u|e|etc]#
di awal baris berarti simbol tersebut memiliki jenis data[struct|union|enum|etc]
. Contoh:t#bool typedef _Bool bool
Awalan
#
yang tidak ada di awal baris menunjukkan bahwa simbol adalah fungsi. Contoh:find_module s#module * find_module ( const char * )
Bandingkan kedua file dan perbaiki semua perbedaan.
Kasus 1: Perbedaan karena visibilitas jenis data
Jika satu kernel menyimpan simbol atau jenis data yang buram untuk modul dan kernel
lainnya tidak, perbedaan tersebut akan muncul di antara file .symtypes
dari dua kernel. File .symtypes
dari salah satu kernel memiliki UNKNOWN
untuk simbol dan file .symtypes
dari kernel lainnya memiliki tampilan yang diperluas
dari simbol atau jenis data.
Misalnya, menambahkan baris berikut ke
file include/linux/device.h
di kernel Anda akan menyebabkan ketidakcocokan CRC, salah satunya
adalah untuk module_layout()
:
#include <linux/fwnode.h>
Membandingkan module.symtypes
untuk simbol tersebut, akan menampilkan 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), gabungkan Android Common Kernel terbaru ke dalam
kernel Anda sehingga Anda menggunakan basis kernel GKI terbaru.
Umumnya, kernel GKI memiliki nilai UNKNOWN
, tetapi kernel Anda memiliki
detail internal simbol karena perubahan yang dibuat pada kernel Anda. Hal ini
dikarenakan salah satu file dalam kernel Anda menambahkan #include
yang tidak ada dalam
kernel GKI.
Sering kali, perbaikannya hanya menyembunyikan #include
baru dari genksyms
.
#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif
Atau, untuk mengidentifikasi #include
yang menyebabkan perbedaan, ikuti langkah-langkah
berikut:
Buka file header yang menentukan simbol atau jenis data yang memiliki perbedaan ini. Misalnya, edit
include/linux/fwnode.h
untukstruct fwnode_handle
.Tambahkan kode berikut di bagian atas file header:
#ifdef CRC_CATCH #error "Included from here" #endif
Dalam file
.c
modul yang memiliki ketidakcocokan CRC, tambahkan baris berikut sebagai baris pertama sebelum baris#include
.#define CRC_CATCH 1
Kompilasi modul Anda. Error waktu build yang dihasilkan menunjukkan 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 di kernel Anda, yang tidak ada di kernel GKI.Identifikasi perubahan, kembalikan ke kernel Anda, atau upload ke ACK dan gabungkan.
Kasus 2: Perbedaan karena perubahan jenis data
Jika ketidakcocokan CRC untuk simbol atau jenis data bukan karena perbedaan visibilitas, hal itu disebabkan oleh perubahan aktual (penambahan, penghapusan, atau perubahan) dalam jenis data itu sendiri.
Misalnya, membuat perubahan berikut di kernel akan menyebabkan beberapa ketidakcocokan CRC karena banyak simbol yang terpengaruh secara tidak langsung 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, tampilannya mungkin 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:
Temukan definisi simbol dalam kode sumber (biasanya dalam file
.h
).- Untuk perbedaan simbol antara kernel Anda dan kernel GKI, temukan commit dengan menjalankan perintah berikut:
git blame
- Untuk simbol yang dihapus (saat simbol dihapus dalam hierarki dan Anda juga ingin menghapusnya di hierarki lain), Anda perlu menemukan perubahan yang menghapus baris. Gunakan perintah berikut pada hierarki tempat baris dihapus:
git log -S "copy paste of deleted line/word" -- <file where it was deleted>
Tinjau daftar commit yang ditampilkan untuk menemukan perubahan atau penghapusan. Commit pertama mungkin adalah yang Anda telusuri. Jika tidak, lihat daftar hingga Anda menemukan commit.
Setelah mengidentifikasi perubahan, kembalikan ke kernel atau upload ke ACK dan gabungkan.