Android çekirdeklerinin çekirdek içi ABI'sini sabitlemek için Android 11 ve sonraki sürümlerde kullanılabilen uygulama ikili arayüzü (ABI) izleme araçlarını kullanabilirsiniz. Araç, mevcut çekirdek ikililerinden (vmlinux
+ GKI modülleri) ABI temsillerini toplayıp karşılaştırır. Bu ABI temsilleri, .stg
dosyaları ve simge listeleridir. Temsilasyonun görünüm sunduğu arayüze çekirdek modülü arayüzü (KMI) denir. KMI'deki değişiklikleri izlemek ve azaltmak için bu araçları kullanabilirsiniz.
ABI izleme araçları AOSP'de geliştirilir ve temsiller oluşturmak ve karşılaştırmak için STG'yi (veya Android 13 ve önceki sürümlerde libabigail
) kullanır.
Bu sayfada, araç seti, ABI temsillerini toplama ve analiz etme süreci ve çekirdek içi ABI'ye kararlılık sağlamak için bu tür temsillerin kullanımı açıklanmaktadır. Bu sayfada, Android çekirdeklerine değişiklik katkıda bulunma hakkında da bilgi verilmektedir.
Süreç
Çekirdeğin ABI'sini analiz etmek için birden fazla adım gerekir. Bu adımların çoğu otomatikleştirilebilir:
- Çekirdeği ve ABI temsilini derleyin.
- Derleme ile referans arasındaki ABI farklılıklarını analiz edin.
- ABI temsilini güncelleyin (gerekirse).
- Sembol listeleriyle çalışın.
Aşağıdaki talimatlar, desteklenen bir araç zinciri (önceden derlenmiş Clang araç zinciri gibi) kullanarak derleyebileceğiniz tüm çekirdekler için geçerlidir. repo manifests
, tüm Android ortak çekirdek dalları ve cihaza özgü çeşitli çekirdekler için kullanılabilir. Analiz için çekirdek dağıtımı oluştururken doğru araç zincirinin kullanılmasını sağlar.
Sembol listeleri
KMI, çekirdekteki tüm simgeleri, hatta dışa aktarılan 30.000'den fazla sembolün hepsini içermez. Bunun yerine, tedarikçi modülleri tarafından kullanılabilen semboller, çekirdek ağacının kökünde herkese açık olarak tutulan bir dizi sembol listesi dosyasında açıkça listelenir. Tüm simge listesi dosyalarındaki tüm simgelerin birleşimi, sabit olarak tutulan KMI simge grubunu tanımlar. Örnek sembol listesi dosyası, DragonBoard 845c için gerekli simgeleri açıklayan abi_gki_aarch64_db845c dosyasıdır.
Yalnızca bir simge listesinde listelenen simgeler ve ilgili yapıları ile tanımları KMI'nın bir parçası olarak kabul edilir. İhtiyacınız olan semboller yoksa simge listelerinizde değişiklik yayınlayabilirsiniz. KMI açıklamasının bir parçası olan yeni arayüzler, simge listesinde yer aldıktan sonra kararlı olarak korunur ve simge listesinden kaldırılmamalı veya dal dondurulduktan sonra değiştirilmemelidir.
Her Android Ortak Çekirdek (ACK) KMI çekirdek dalının kendi simge listesi vardır. Farklı KMI çekirdek dalları arasında ABI kararlılığı sağlamaya çalışılmaz. Örneğin, android12-5.10
için KMI, android13-5.10
için KMI'den tamamen bağımsızdır.
ABI araçları, kararlılık için hangi arayüzlerin izlenmesi gerektiğini sınırlamak amacıyla KMI simge listelerini kullanır. Ana simge listesi, GKI çekirdek modüllerinin gerektirdiği sembolleri içerir. Tedarikçi firmaların, güvendikleri arayüzlerin ABI uyumluluğunu korumasını sağlamak için ek simge listeleri göndermesi ve güncellemesi beklenir. Örneğin, android13-5.15
için simge listelerinin listesini görmek isterseniz https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android
bölümüne bakın.
Simge listesi, belirli bir tedarikçi veya cihaz için gerekli olduğu bildirilen simgeleri içerir. Araçlar tarafından kullanılan tüm KMI simge listesi dosyalarının birleşiminden yararlanılır. ABI araçları, işlev imzası ve iç içe yerleştirilmiş veri yapıları da dahil olmak üzere her sembolün ayrıntılarını belirler.
KMI dondurulduğunda mevcut KMI arayüzlerinde değişiklik yapılmasına izin verilmez. Bu arayüzler kararlıdır. Ancak eklemeler mevcut ABI'nın kararlılığını etkilemediği sürece tedarikçiler dilediği zaman KMI'ya sembol ekleyebilir. Yeni eklenen semboller, bir KMI sembol listesi tarafından belirtildiği anda sabit olarak korunur. Hiçbir cihazın bu sembolün bağımlılığını içerecek şekilde gönderilmediği doğrulanmadığı sürece semboller bir çekirdek listesinden kaldırılmamalıdır.
Simge listeleriyle çalışma başlıklı makaledeki talimatları kullanarak bir cihaz için KMI simge listesi oluşturabilirsiniz. Birçok iş ortağı, ACK başına bir sembol listesi gönderir ancak bu zorunlu bir gereklilik değildir. Bakım konusunda yardımcı olması için birden fazla simge listesi gönderebilirsiniz.
KMI'yı genişletin
KMI sembolleri ve ilgili yapılar kararlı olarak korunurken (yani dondurulmuş bir KMI'ye sahip çekirdekteki kararlı arayüzleri bozan değişiklikler kabul edilemez) GKI çekirdeği, yılın ilerleyen dönemlerinde piyasaya sürülen cihazların KMI dondurulmadan önce tüm bağımlılıkları tanımlaması gerekmemesi için uzantılara açık kalır. KMI'yi genişletmek için KMI dondurulmuş olsa bile yeni veya mevcut dışa aktarılan çekirdek işlevleri için KMI'ye yeni simgeler ekleyebilirsiniz. KMI'yi bozmayan yeni çekirdek yamaları da kabul edilebilir.
KMI kesintileri hakkında
Çekirdeklerin kaynakları vardır ve ikili dosyalar bu kaynaklardan oluşturulur.
ABI tarafından izlenen çekirdek dalları, mevcut GKI ABI'sinin ABI temsilini (.stg
dosyası biçiminde) içerir. İkili dosyalar (vmlinux
, Image
ve tüm GKI modülleri) oluşturulduktan sonra, ikili dosyalardan bir ABI temsili ayıklanabilir. Bir çekirdek kaynak dosyasında yapılan herhangi bir değişiklik, ikili dosyaları etkileyebilir ve bu da ayıklanan .stg
dosyasını etkileyebilir. AbiAnalyzer
analizörü, taahhüt edilen .stg
dosyasını derleme yapılarından ayıklanan dosyayla karşılaştırır ve anlamsal bir fark bulursa Gerrit'te değişiklik için Lint-1 etiketi ayarlar.
ABI'de kesintileri ele alma
Örneğin, aşağıdaki yama oldukça bariz bir ABI kesintisini ortaya çıkarmıştır:
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.
Bu yamanın uygulandığı derleme ABI'sini çalıştırdığınızda araç, sıfır olmayan bir hata koduyla çıkar ve aşağıdakine benzer bir ABI farkı bildirir:
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
Derleme zamanında ABI farklılıkları algılandı
Hataların en yaygın nedeni, bir sürücünün çekirdekteki ve simge listelerinin hiçbirinde bulunmayan yeni bir simge kullanmasıdır.
Sembol, simge listesinde (android/abi_gki_aarch64
) yoksa önce EXPORT_SYMBOL_GPL(symbol_name)
ile dışa aktarıldığını doğrulamanız, ardından ABI XML gösterimini ve simge listesini güncellemeniz gerekir. Örneğin, aşağıdaki değişiklikler android-12-5.10
dalına yeni Artımlı FS özelliğini ekler. Bu özellik, simge listesini ve ABI XML temsilini güncellemeyi içerir.
- Özellik değişikliği örneği aosp/1345659 adresindedir.
- Sembol listesi örneği aosp/1346742 adresindedir.
- ABI XML değişiklik örneği aosp/1349377 adresindedir.
Simge dışa aktarılmışsa (sizin tarafınızdan veya daha önce dışa aktarılmışsa) ancak başka bir sürücü tarafından kullanılmıyorsa aşağıdakine benzer bir derleme hatası alabilirsiniz.
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
Sorunu çözmek için hem çekirdek hem de ACK'deki KMI simge listesini güncelleyin (ABI temsilini güncelleme bölümüne bakın). ACK'de ABI XML ve simge listesini güncellemeyle ilgili bir örnek için aosp/1367601 adresine bakın.
Çekirdek ABI kesintilerini çözme
ABI'yi değiştirmeyecek şekilde kodu yeniden düzenleyerek veya ABI temsilini güncelleyerek çekirdek ABI'si bozulmalarıyla başa çıkabilirsiniz. Durumunuza en uygun yaklaşımı belirlemek için aşağıdaki grafiği kullanın.
Şekil 1. ABI kesintisi çözümü
ABI değişikliklerini önlemek için kodu yeniden yapılandırın
Mevcut ABI'da değişiklik yapmamak için elinizden geleni yapın. Çoğu durumda, ABI'yi etkileyen değişiklikleri kaldırmak için kodunuzu yeniden yapılandırabilirsiniz.
Yapı alanındaki değişiklikleri yeniden düzenleme Bir değişiklik, bir hata ayıklama özelliğinin ABI'sini değiştiriyorsa alanların etrafına (yapılar ve kaynak referanslarında) bir
#ifdef
ekleyin ve#ifdef
için kullanılanCONFIG
'nin üretim defconfig vegki_defconfig
için devre dışı olduğundan emin olun. Bir hata ayıklama yapılandırmasının ABI'yi bozmadan bir yapıya nasıl eklenebileceğine dair bir örnek için bu yama grubuna bakın.Temel çekirdeği değiştirmemek için özellikleri yeniden yapılandırın. İş ortağı modüllerini desteklemek için ACK'ye yeni özellikler eklenmesi gerekiyorsa çekirdek ABI'sini değiştirmemek için değişikliğin ABI bölümünü yeniden yapılandırmayı deneyin. Çekirdek ABI'sini değiştirmeden ek özellikler eklemek için mevcut çekirdek ABI'sini kullanma örneği için aosp/1312213 adresine bakın.
Android Gerrit'te bozuk ABI'yi düzeltme
Kernel ABI'yi kasıtlı olarak bozmadıysanız ABI izleme araçları tarafından sağlanan kılavuzu kullanarak incelemeniz gerekir. Kesintinin en yaygın nedenleri, değiştirilen veri yapıları ve ilişkili simge CRC değişiklikleri ya da yukarıdakilerden herhangi birine yol açan yapılandırma seçeneği değişiklikleridir. Araç tarafından bulunan sorunları gidererek başlayın.
ABI bulgularını yerel olarak yeniden oluşturabilirsiniz. Çekirdek ve ABI temsilini oluşturma bölümüne bakın.
Lint-1 etiketleri hakkında
Dondurulmuş veya kesinleşmiş bir KMI içeren bir dala değişiklik yüklerseniz değişikliklerin kararlı ABI'yı uyumsuz bir şekilde etkilememesi için değişikliklerin AbiAnalyzer
tarafından iletilmesi gerekir. Bu işlem sırasında AbiAnalyzer
, derleme sırasında oluşturulan ABI raporunu (normal derlemeyi ve ardından bazı ABI ayıklama ve karşılaştırma adımlarını gerçekleştiren genişletilmiş bir derleme) arar.
AbiAnalyzer
boş olmayan bir rapor bulursa Lint-1 etiketini ayarlar ve değişiklik, çözülene kadar (yama grubu Lint+1 etiketi alana kadar) gönderilemez.
Çekirdek ABI'sını güncelleme
ABI'da değişiklik yapılması kaçınılmazsa kod değişikliklerinizi, ABI temsilini ve simge listesini ACK'ye uygulamanız gerekir. Lint'in -1'i kaldırmasını ve GKI uyumluluğunu bozmamasını sağlamak için şu adımları uygulayın:
Yama grubu için Code-Review +2 almayı bekleyin.
Kod değişikliklerinizi ve ABI güncelleme değişikliğini birleştirin.
ABI kod değişikliklerini ACK'ye yükleme
ACK ABI'nin güncellenmesi, yapılan değişikliğin türüne bağlıdır.
Bir ABI değişikliği, CTS veya VTS testlerini etkileyen bir özellikle ilgiliyse değişiklik genellikle olduğu gibi ACK için seçilebilir. Örneğin:
- Sesin çalışması için aosp/1289677 sürümünün yüklü olması gerekir.
- USB'nin çalışması için aosp/1295945 sürümünün yüklü olması gerekir.
ACK ile paylaşılabilen bir özellik için ABI değişikliği söz konusuysa bu değişiklik ACK'ye olduğu gibi seçilebilir. Örneğin, CTS veya VTS testi için aşağıdaki değişiklikler gerekli değildir ancak ACK ile paylaşılabilir:
- aosp/1250412, termal bir özellik değişikliğidir.
- aosp/1288857,
EXPORT_SYMBOL_GPL
değişikliğidir.
Bir ABI değişikliği, ACK'ye dahil edilmesi gerekmeyen yeni bir özellik sunuyorsa aşağıdaki bölümde açıklandığı gibi bir taslak kullanarak simgeleri ACK'ye ekleyebilirsiniz.
ACK için saplama kullanın
Stub'lar yalnızca ACK'ye fayda sağlamayan temel çekirdek değişiklikleri (ör. performans ve güç değişiklikleri) için gerekli olmalıdır. Aşağıdaki listede, GKI için ACK'deki taslaklar ve kısmi seçmeler örnekleri ayrıntılı olarak açıklanmıştır.
Core-isolate özellik taslağı (aosp/1284493). ACK'deki özellikler gerekli değildir ancak modüllerinizin bu sembolleri kullanabilmesi için ACK'de sembollerin bulunması gerekir.
Tedarikçi modülü için yer tutucu simgesi (aosp/1288860).
İşlem başına
mm
etkinlik izleme özelliğinin yalnızca ABI'de kullanılabilen seçkin bir bölümü (aosp/1288454). Orijinal yama, ACK için özenle seçildi ve ardından yalnızcatask_struct
vemm_event_count
için ABI farkını çözmek üzere gerekli değişiklikleri içerecek şekilde kısaltıldı. Bu yama,mm_event_type
sıralamasını son üyeleri içerecek şekilde de günceller.Yalnızca yeni ABI alanlarının eklenmesini gerektiren termal yapı ABI değişikliklerinin kısmi olarak seçilmesi.
aosp/1255544 düzeltme eki, iş ortağının çekirdeği ile ACK arasındaki ABI farklılıklarını çözmüştür.
aosp/1291018 yaması, önceki yamanın GKI testi sırasında bulunan işlevsel sorunları düzeltti. Bu çözüm, tek bir sensöre birden fazla termal alt bölge kaydetmek için sensör parametresi struct'ın başlatılmasını içeriyordu.
CONFIG_NL80211_TESTMODE
ABI değişiklikleri (aosp/1344321). Bu yama, ABI için gerekli yapı değişikliklerini ekledi ve ek alanların işlevsel farklılıklara neden olmamasını sağladı. Böylece iş ortakları, üretim çekirdeklerineCONFIG_NL80211_TESTMODE
öğesini dahil ederken GKI uygunluğunu korudu.
Çalışma zamanında KMI'yi zorunlu kılma
GKI çekirdekleri, dışa aktarılan sembolleri (EXPORT_SYMBOL_GPL()
kullanılarak dışa aktarılan semboller gibi) bir sembol listesinde listelenenlerle sınırlayan TRIM_UNUSED_KSYMS=y
ve UNUSED_KSYMS_WHITELIST=<union
of all symbol lists>
yapılandırma seçeneklerini kullanır. Diğer tüm semboller dışa aktarılmaz ve dışa aktarılmamış bir sembol gerektiren modülün yüklenmesi reddedilir. Bu kısıtlama derleme sırasında uygulanır ve eksik girişler işaretlenir.
Geliştirme amacıyla, simge kırpma içermeyen bir GKI çekirdek derlemesi kullanabilirsiniz (yani genellikle dışa aktarılan tüm semboller kullanılabilir). Bu derlemeleri bulmak için ci.android.com adresinde kernel_debug_aarch64
derlemelerini arayın.
Modül sürümlendirmesini kullanarak KMI'yi zorunlu kılma
Genel Çekirdek Görüntüsü (GKI) çekirdekleri, KMI uyumluluğunu çalışma zamanında zorunlu kılmak için ek bir önlem olarak modül sürümlendirmesini (CONFIG_MODVERSIONS
) kullanır. Bir modülün beklenen KMI'si vmlinux
KMI ile eşleşmiyorsa modül sürümü oluşturma, modül yükleme zamanında döngüsel yedeklilik kontrolü (CRC) uyuşmazlığı hatasına neden olabilir. Örneğin, aşağıdaki hata, module_layout()
sembolünün CRC uyuşmazlığı nedeniyle modül yükleme zamanında ortaya çıkan tipik bir hatadır:
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 ''
Modül sürüm oluşturmanın kullanım alanları
Modül sürümlendirme aşağıdaki nedenlerden dolayı kullanışlıdır:
Modül sürümlendirmesi, veri yapısı görünürlüğünde yapılan değişiklikleri yakalar. Modüller opak veri yapılarını (yani KMI'nin parçası olmayan veri yapıları) değiştirirse yapıda daha sonra yapılacak değişikliklerden sonra bozulurlar.
Örneğin,
struct device
içindekifwnode
alanını ele alalım. Bu alan, modüllerindevice->fw_node
alanlarında değişiklik yapamamaları veya boyutu hakkında varsayımlarda bulunmamaları için modüller tarafından opak OLMALIDIR.Ancak bir modül
<linux/fwnode.h>
(doğrudan veya dolaylı olarak) içeriyorsastruct device
içindekifwnode
alanı artık modül için opak değildir. Modül daha sonradevice->fwnode->dev
veyadevice->fwnode->ops
'te değişiklik yapabilir. Bu senaryo, aşağıdaki gibi çeşitli nedenlerden dolayı sorunludur:Çekirdek çekirdek kodunun dahili veri yapılarıyla ilgili varsayımlarını bozabilir.
Gelecekteki bir çekirdek güncellemesi
struct fwnode_handle
'ü (fwnode
veri türü) değiştirirse modül artık yeni çekirdekle çalışmaz. Ayrıca modül, dahili veri yapılarını doğrudan manipüle ederek KMI'yı bozduğundanstgdiff
herhangi bir fark göstermez. Bu manipülasyonlar yalnızca ikili gösterim incelenerek yakalanamaz.
Mevcut bir modülün, daha sonraki bir tarihte uyumsuz yeni bir çekirdek tarafından yüklenmesi KMI ile uyumlu olmadığı kabul edilir. Modül sürümlendirme, çekirdekle KMI uyumlu olmayan bir modülün yanlışlıkla yüklenmesini önlemek için çalışma zamanında bir kontrol ekler. Bu kontrol, KMI'de algılanmayan bir uyumsuzluktan kaynaklanabilecek, hata ayıklamanın zor olduğu çalışma zamanı sorunlarını ve çekirdek kilitlenmelerini önler.
Modül sürümlendirmeyi etkinleştirmek tüm bu sorunları önler.
Cihazı başlatmadan CRC uyuşmazlıklarını kontrol edin
stgdiff
, çekirdekler arasındaki CRC uyuşmazlıklarını ve diğer ABI farklılıklarını karşılaştırır ve raporlar.
Ayrıca, CONFIG_MODVERSIONS
etkinleştirilmiş tam çekirdek derlemesi, normal derleme işleminin parçası olarak bir Module.symvers
dosyası oluşturur. Bu dosyada, çekirdek (vmlinux
) ve modüller tarafından dışa aktarılan her simge için bir satır bulunur. Her satır; CRC değeri, sembol adı, sembol ad alanı, simgeyi dışa aktaran vmlinux
veya modül adı ve dışa aktarma türünden (örneğin, EXPORT_SYMBOL
yerine EXPORT_SYMBOL_GPL
) oluşur.
vmlinux
tarafından dışa aktarılan simgelerde CRC farklılıkları olup olmadığını kontrol etmek için GKI derlemesi ile derlemeniz arasındaki Module.symvers
dosyalarını karşılaştırabilirsiniz. vmlinux
tarafından dışa aktarılan herhangi bir sembolde CRC değer farkı varsa ve bu simge cihazınıza yüklediğiniz modüllerden biri tarafından kullanılıyorsa modül yüklenmez.
Tüm derleme yapılarını kullanamıyorsanız ancak GKI çekirdeği ve çekirdeğinizin vmlinux
dosyalarına sahipseniz aşağıdaki komutu her iki çekirdekte de çalıştırıp çıktıları karşılaştırarak belirli bir sembolün CRC değerlerini karşılaştırabilirsiniz:
nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>
Örneğin, aşağıdaki komut module_layout
sembolünün CRC değerini kontrol eder:
nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout
CRC uyuşmazlıklarını giderme
Modül yüklerken CRC uyuşmazlığını çözmek için aşağıdaki adımları uygulayın:
Aşağıdaki komutta gösterildiği gibi
--kbuild_symtypes
seçeneğini kullanarak GKI çekirdeğini ve cihaz çekirdeğinizi oluşturun:tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
Bu komut, her
.o
dosyası için bir.symtypes
dosyası oluşturur. Ayrıntılar için Kleaf'tekiKBUILD_SYMTYPES
bölümüne bakın.Android 13 ve önceki sürümlerde, aşağıdaki komutta gösterildiği gibi çekirdeği oluşturmak için kullandığınız komutun başına
KBUILD_SYMTYPES=1
ekleyerek GKI çekirdeğini ve cihaz çekirdeğinizi oluşturun:KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
build_abi.sh,
kullanıldığındaKBUILD_SYMTYPES=1
işareti zaten dolaylı olarak ayarlanmıştır.Aşağıdaki komutu kullanarak, CRC uyuşmazlığı olan simgenin dışa aktarıldığı
.c
dosyasını bulun:cd common && git grep EXPORT_SYMBOL.*module_layout kernel/module.c:EXPORT_SYMBOL(module_layout);
.c
dosyasının GKI'da ve cihaz çekirdek derleme yapılarında karşılık gelen bir.symtypes
dosyası vardır. Aşağıdaki komutları kullanarak.c
dosyasını bulun:cd out/$BRANCH/common && ls -1 kernel/module.* kernel/module.o kernel/module.o.symversions kernel/module.symtypes
.c
dosyasının özellikleri şunlardır:.c
dosyasının biçimi, simge başına bir (muhtemelen çok uzun) satırdır.Satırın başındaki
[s|u|e|etc]#
, sembolün veri türü[struct|union|enum|etc]
olduğunu gösterir. Örnek:t#bool typedef _Bool bool
Satırın başında
#
ön eklerinin eksik olması, sembolün bir işlev olduğunu gösterir. Örnek:find_module s#module * find_module ( const char * )
İki dosyayı karşılaştırın ve tüm farklılıkları düzeltin.
1. Örnek: Veri türünün görünürlüğünden kaynaklanan farklılıklar
Bir çekirdek, bir simgeyi veya veri türünü modüller için opak tutarken diğer çekirdek bunu yapmazsa bu fark, iki çekirdeğin .symtypes
dosyaları arasında görünür. Çekirdeklerden birindeki .symtypes
dosyası simge için UNKNOWN
değerine ve diğer çekirdekteki .symtypes
dosyası simge veya veri türünün genişletilmiş görünümüne sahiptir.
Örneğin, aşağıdaki satırı çekirdeğinize ait include/linux/device.h
dosyasına eklemek CRC uyuşmazlıklarına neden olur. Bunlardan biri module_layout()
içindir:
#include <linux/fwnode.h>
Söz konusu simgenin module.symtypes
değerini karşılaştırdığımızda aşağıdaki farklılıkları görürüz:
$ 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 ] ; }
...
Çekirdeğinizin değeri UNKNOWN
ise ve GKI çekirdeğinde sembolün genişletilmiş görünümü varsa (çok olası değildir) en son GKI çekirdek tabanını kullanmanız için en son Android Ortak Çekirdeği'ni çekirdeğinizle birleştirin.
Çoğu durumda, GKI çekirdeği UNKNOWN
değerine sahiptir ancak çekirdeğinizde yapılan değişiklikler nedeniyle çekirdeğiniz sembolün dahili ayrıntılarını içerir. Bunun nedeni, çekirdeğinize ait dosyalardan birinin GKI çekirdeğinde bulunmayan bir #include
eklemesidir.
Çoğu zaman, çözüm yeni #include
öğesini genksyms
'dan gizlemekle sınırlıdır.
#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif
Aksi takdirde, farka neden olan #include
değerini belirlemek için aşağıdaki adımları uygulayın:
Bu farkı içeren simgeyi veya veri türünü tanımlayan başlık dosyasını açın. Örneğin,
include/linux/fwnode.h
içinstruct fwnode_handle
değerini düzenleyin.Üstbilgi dosyasının en üstüne aşağıdaki kodu ekleyin:
#ifdef CRC_CATCH #error "Included from here" #endif
CRC uyuşmazlığı olan modülün
.c
dosyasına,#include
satırlarından önce ilk satır olarak aşağıdakileri ekleyin.#define CRC_CATCH 1
Modülünüzü derleyin. Sonuç olarak ortaya çıkan derleme zamanı hatası, bu CRC uyuşmazlığına neden olan
#include
üstbilgi dosyası zincirini gösterir. Örnek: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"
Bu
#include
zincirindeki bağlantılardan biri, çekirdeğinizde yapılan ve GKI çekirdeğinde bulunmayan bir değişiklikten kaynaklanıyor.Değişikliği belirleyin, çekirdekte geri alın veya ACK'ye yükleyip birleştirmesini sağlayın.
2. durum: Veri türü değişikliklerinden kaynaklanan farklılıklar
Bir simge veya veri türü için CRC uyuşmazlığı, görünürlüğdeki bir farklılıktan kaynaklanmıyorsa veri türünde yapılan gerçek değişikliklerden (eklemeler, kaldırmalar veya değişiklikler) kaynaklanır.
Örneğin, çekirdeğinizde aşağıdaki değişikliği yapmak birçok sembol bu tür bir değişiklikten dolaylı olarak etkilendiği için birkaç CRC uyuşmazlığına neden olur:
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);
Bir CRC uyuşmazlığı devm_of_platform_populate()
içindir.
Bu simgenin .symtypes
dosyalarını karşılaştırırsanız simge aşağıdaki gibi görünebilir:
$ 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 * ) ; ...
Değiştirilen türü belirlemek için aşağıdaki adımları uygulayın:
Kaynak kodundaki simgenin tanımını bulun (genellikle
.h
dosyalarında).- Çekirdeğiniz ile GKI çekirdeği arasındaki sembol farkları için aşağıdaki komutu çalıştırarak kaydı bulun:
git blame
- Silinen simgeler için (bir simgenin bir ağaçta silindiği ve diğer ağaçta da silinmesini istediğiniz durumlar) satırı silen değişikliği bulmanız gerekir. Satırın silindiği ağaçta aşağıdaki komutu kullanın:
git log -S "copy paste of deleted line/word" -- <file where it was deleted>
Değişikliği veya silme işlemini bulmak için döndürülen taahhüt listesini inceleyin. Muhtemelen aradığınız ilk taahhüttür. Görünmüyorsa kaydı bulana kadar listeyi gözden geçirin.
Değişikliği belirledikten sonra çekirdeğinizde geri alın veya ACK'ye yükleyip birleştirin.