Możesz użyć narzędzi do monitorowania interfejsu binarnego aplikacji (ABI), które są dostępne
Androida 11 lub nowszego, aby ustabilizować system w jądrze.
interfejs ABI jąder Androida. Narzędzie zbiera i porównuje reprezentacje ABI
z istniejących plików binarnych jądra (vmlinux
+ moduły GKI). Te interfejsy ABI
reprezentacje to pliki .stg
i listy symboli. Interfejs włączony
który przedstawia widok, nazywany jest interfejsem modułu jądra.
(KMI). Za pomocą tych narzędzi możesz śledzić i ograniczać zmiany w KMI.
Narzędzie do monitorowania ABI to:
opracowane w AOSP
i zastosowania
STG (lub
libabigail
w
Androida 13 i starszych wersji), aby wygenerować i porównać
reprezentacji.
Na tej stronie opisujemy narzędzie, czyli proces gromadzenia i analizowania interfejsu ABI. oraz stosowanie takich reprezentacji w celu zapewnienia stabilności i interfejs ABI działający w jądrze. Ta strona zawiera również informacje na temat wprowadzania zmian do jąder Androida.
Proces
Analiza interfejsu ABI jądra składa się z wielu kroków, z których większość z nich można zautomatyzować:
- Utwórz jądro i jego reprezentację ABI.
- Przeanalizuj różnice w interfejsie ABI między kompilacją a plikiem referencyjnym.
- Zaktualizuj reprezentację interfejsu ABI (w razie potrzeby).
- Praca z listami symboli.
Poniższe instrukcje sprawdzają się w przypadku
jądro, które możesz skompilować
obsługiwane narzędzie (np. gotowy łańcuch narzędzi Clang). repo manifests
są dostępne we wszystkich gałęziach jądra systemu Android oraz
działających na konkretnych urządzeniach, gwarantują one użycie
właściwego łańcucha narzędzi
aby utworzyć dystrybucję jądra do analizy.
Listy symboli
KMI nie zawiera wszystkich symboli w jądrze,a nawet wszystkich z ponad 30 tys. wyeksportowanych symboli. Symbole, których mogą używać moduły dostawców, to jawnie wymienione w zestawie plików z listą symboli udostępnianych publicznie w katalogu głównym z jedna jądra systemu. Suma wszystkich symboli we wszystkich plikach z listą symboli określa zestaw symboli KMI utrzymywany jako stabilny. Przykładowy plik z listą symboli to Abi_gki_aarch64_db845c deklaruje symbole wymagane dla argumentu DragonBoard 845c
Tylko symbole wymienione na liście symboli i powiązane z nimi struktury są uznawane za część KMI. Możesz opublikować zmiany w swoich jeśli nie ma potrzebnych symboli. Po udostępnieniu nowych interfejsów są częścią opisu KMI i są utrzymywane na stabilnym poziomie i nie można ich usuwać z listy symboli ani modyfikować po zablokowany.
Każda gałąź jądra systemu KMI Androida Common jądra (ACK) ma własny zestaw symboli
list. Nie podjęto próby zapewnienia stabilności ABI między różnymi jądrami KMI.
gałęzie. Na przykład wskaźnik KMI dla lokalizacji android12-5.10
jest całkowicie niezależny od:
wskaźnik KMI dla firmy android13-5.10
.
Narzędzia ABI wykorzystują listy symboli KMI do ograniczenia, które interfejsy muszą być monitorowane
i stabilności.
główna lista symboli
zawiera symbole wymagane przez moduły jądra GKI. Dostawcy
będzie przesyłać i aktualizować dodatkowe listy symboli, aby
a interfejsy, na których bazują,
zachowują zgodność z interfejsem ABI. Aby na przykład wyświetlić listę
list symboli dla android13-5.15
, patrz
https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android
.
Lista symboli zawiera symbole, które mają być wymagane w przypadku danego dostawcy lub urządzenia. Ich kompletna lista uwzględnia wszystkie Pliki z listą symboli KMI. Narzędzia ABI określają szczegóły każdego symbolu, w tym podpis funkcji i zagnieżdżone struktury danych.
Gdy KMI jest zablokowany, nie można wprowadzać żadnych zmian w istniejących interfejsach KMI. są stabilne. Dostawcy mogą jednak w dowolnym momencie dodawać symbole do KMI O ile dodatki nie wpływają na stabilność interfejsu ABI. Nowo dodana utrzymują się jak najbardziej stabilne po umieszczeniu na liście symboli KMI. Symbolów nie należy usuwać z listy jądra, jeśli nie można tego potwierdzić że żadne urządzenie jeszcze nie zostało dostarczone z zależności od tego symbolu.
Możesz wygenerować listę symboli KMI dla danego urządzenia, postępując zgodnie z instrukcjami z Jak korzystać z list symboli. Wielu partnerów przesyła po 1 liście symboli na każde potwierdzenie, ale nie jest to absolutnie wymagane. Jeśli ułatwi to konserwację, możesz przesłać kilka list symboli.
Rozszerzenie KMI
Symbole KMI i powiązane z nimi struktury pozostają stabilne (tzn. zmian powodujących uszkodzenie stabilnych interfejsów w jądrze z zablokowanym KMI nie można jądro GKI pozostaje otwarte dla rozszerzeń, dzięki czemu urządzenia pod koniec roku, nie muszą definiować wszystkich zależności, zablokowany. Aby rozszerzyć wskaźnik KMI, można dodać do KMI nowe symbole dla nowych lub z wyeksportowanych funkcji jądra, nawet jeśli wskaźnik KMI jest zablokowany. Nowe jądro poprawki mogą być też akceptowane, jeśli nie wpływają negatywnie na wskaźnik KMI.
Awarie KMI
Jądro ma źródła i na ich podstawie są tworzone pliki binarne.
Gałęzie jądra monitorowane przez ABI zawierają reprezentację bieżącego interfejsu GKI przez interfejs ABI
ABI (w postaci pliku .stg
). Po plikach binarnych (vmlinux
, Image
i
modułów GKI), reprezentację ABI można wyodrębnić z
pliki binarne. Wszelkie zmiany wprowadzone w pliku źródłowym jądra mogą mieć wpływ na pliki binarne i
ma również wpływ na wyodrębnione .stg
. Analizator AbiAnalyzer
porównuje
zatwierdzony plik .stg
z tym wyodrębnionym z artefaktów kompilacji i ustawia
Etykieta Lint-1 dotycząca zmiany w Gerrit, jeśli znajdzie różnicę semantyczną.
Obsługa awarii ABI
Przykład: ta poprawka wprowadza bardzo oczywisty błąd interfejsu ABI:
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.
Gdy uruchomisz interfejs ABI z zastosowaną poprawką, narzędzie zakończy działanie za pomocą niezerowy kod błędu i zgłoszona różnica w interfejsie ABI podobna do tej:
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
Różnice w interfejsie ABI wykryte podczas kompilacji
Najczęstszą przyczyną błędów jest używanie przez kierowcę nowego symbolu z jądra systemu, którego nie ma na żadnej liście symboli.
Jeśli symbolu nie ma na liście symboli (android/abi_gki_aarch64
),
musisz najpierw sprawdzić, czy dane są eksportowane
EXPORT_SYMBOL_GPL(symbol_name)
, a następnie zaktualizuj
Reprezentacja ABI XML i lista symboli. Na przykład te zmiany powodują dodanie
nową funkcję przyrostowej szybkości aktualizacji w gałęzi android-12-5.10
,
obejmuje aktualizację listy symboli i reprezentacji interfejsu ABI XML.
- Przykład zmiany funkcji jest w aosp/1345659.
- Przykład listy symboli jest dostępny aosp/1346742.
- Przykład zmiany ABI XML jest w aosp/1349377.
Jeśli symbol został wyeksportowany (przez Ciebie lub wcześniej), ale nie został wyeksportowany z innego sterownika, może wystąpić błąd kompilacji podobny do poniższego.
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
Aby rozwiązać ten problem, zaktualizuj listę symboli KMI zarówno w jądrze, jak i w potwierdzeniu potwierdzenia (zobacz Zaktualizuj reprezentację interfejsu ABI). Przykład: aktualizacji kodu XML ABI i listy symboli w pliku ACK, zapoznaj się z artykułem ACK aosp/1367601.
Napraw błędy ABI jądra
Możesz poradzić sobie z awariami interfejsu ABI jądra przez zrefaktoryzowanie kodu, aby nie zmieniał ABI lub aktualizowanie reprezentacji interfejsu ABI. Użyj następujących aby wybrać najlepsze podejście w danej sytuacji.
Rysunek 1. Rozwiązywanie problemów z interfejsem ABI
Refaktoryzacja kodu w celu uniknięcia zmian w interfejsie ABI
Postaraj się unikać modyfikowania istniejącego interfejsu ABI. W wielu przypadkach zrefaktoryzować kod, aby usunąć zmiany, które wpływają na interfejs ABI.
Zmiany w polu struktury refaktoryzacyjnej. Jeśli zmiana modyfikuje interfejs ABI na potrzeby debugowania , dodaj
#ifdef
wokół pól (w elementach struct i źródło plików referencyjnych) i upewnij się, że portCONFIG
używany w obiekcie#ifdef
jest wyłączony dla defconfig produkcji igki_defconfig
. Oto przykład, można dodać do struktury bez naruszania interfejsu ABI. Zapoznaj się z tym artykułem patchset.Funkcje refaktoryzacyjne pozwalające nie wprowadzać zmian w podstawowym jądrze. Jeśli nowe funkcje wymagają należy dodać do potwierdzenia w celu obsługi modułów partnerów, spróbuj zrefaktoryzować interfejs ABI. tej zmiany, by uniknąć modyfikowania interfejsu ABI jądra. Na przykład za pomocą funkcji interfejsu ABI jądra, aby dodać więcej możliwości bez zmiany odniesienie do interfejsu ABI jądra aosp/1312213.
Naprawianie uszkodzonego interfejsu ABI na Androidzie Gerrit
Jeśli nie celowo naruszyłeś interfejs ABI jądra, musisz to zbadać, na podstawie wskazówek dostarczonych przez narzędzia do monitorowania ABI. Najczęstsze przyczyny awarii to zmienione struktury danych i powiązany symbol CRC zmian opcji konfiguracji lub zmian opcji konfiguracji, które prowadzą do wystąpienia któregokolwiek z wyżej wymienionych problemów. Zacznij od rozwiązania problemów wykrytych przez narzędzie.
Wyniki ABI możesz odtworzyć lokalnie: zobacz Utwórz jądro i jego reprezentację ABI.
Informacje o etykietach Lint-1
Jeśli prześlesz zmiany do gałęzi zawierającej zablokowany lub sfinalizowany wskaźnik KMI,
zmiany muszą przejść przez AbiAnalyzer
, aby zapewnić, że zmiany nie wpłyną na stabilną
ABI w niezgodny sposób. W trakcie tego procesu AbiAnalyzer
szuka
Raport ABI utworzony podczas kompilacji (rozszerzona kompilacja, która wykonuje
a potem kilka kroków wyodrębniania i porównania za pomocą interfejsu ABI.
Jeśli AbiAnalyzer
znajdzie niepusty raport, ustawi etykietę Lint-1 i
możliwość przesłania zmiany jest blokowana do czasu rozwiązania problemu; dopóki zbiór poprawek nie otrzyma
Etykieta Lint + 1.
Aktualizowanie interfejsu ABI jądra
Jeśli modyfikacja interfejsu ABI jest nieunikniona, należy wprowadzić zmiany w kodzie, reprezentację ABI i listę symboli do potwierdzenia. Aby uzyskać dostęp do Lint usuń wartość -1, nie naruszając zgodności z GKI. Wykonaj te czynności:
Poczekaj na otrzymanie weryfikacji kodu +2 dla zestawu poprawek.
Połącz zmiany w kodzie i aktualizację ABI.
Prześlij zmiany kodu ABI do potwierdzenia
Aktualizacja interfejsu ACK ABI zależy od typu wprowadzanej zmiany.
Jeśli zmiana interfejsu ABI jest powiązana z funkcją, która wpływa na testy CTS lub VTS, można zwykle wybierać jako potwierdzenie na potwierdzenie. Na przykład:
- Aosp/1289677 jest niezbędna do działania dźwięku.
- Aosp/1295945 USB jest niezbędne do działania.
Jeśli zmiana interfejsu ABI dotyczy funkcji, którą można udostępnić do potwierdzenia, można wybrać jako potwierdzenie w niezmienionej formie. Na przykład te zmiany nie są wymagane do testów CTS ani VTS, ale można je udostępnić ACK:
- Aosp/1250412 oznacza zmianę obiektu termicznego.
- Aosp/1288857
to zmiana o
EXPORT_SYMBOL_GPL
.
Jeśli zmiana w interfejsie ABI wprowadza nową funkcję, której nie trzeba uwzględniać w możesz użyć kodu potwierdzenia, tak jak to opisano w w następnej sekcji.
Użyj wycinków z kodem ACK
Fragmenty muszą być konieczne tylko po wprowadzeniu zmian w rdzeniu jądra, które nie przynoszą korzyści potwierdzenia, na przykład o wydajności i zasilaniu. Poniżej znajdziesz przykłady szczegółowych informacji wycinków i częściowych wycinków wiśni w ACK dla GKI.
Odizolowany fragment kodu (aosp/1284493). Możliwości w potwierdzeniu nie są konieczne, ale muszą być obecne symbole zatwierdź, aby moduły mogły używać tych symboli.
Symbol zastępczy modułu dostawcy (Aosp/1288860).
Wybór funkcji śledzenia zdarzeń
mm
na potrzeby poszczególnych procesów (aosp/1288454). Oryginalna poprawka została wybrana jako ACK, a następnie przycięta, aby zawierała niezbędne zmiany w celu rozwiązania różnic w interfejsach ABI w tych interfejsach:task_struct
imm_event_count
Ta poprawka aktualizuje też enummm_event_type
o z ostatnich członków.Częściowy wybór zmian w interfejsie ABI struktury termicznej, które wymagały więcej niż tylko dodając nowe pola ABI.
Poprawka Aosp/1255544 rozwiązano różnice w interfejsach ABI między jądrem partnera a potwierdzeniem.
Poprawka Aosp/1291018 naprawiliśmy problemy funkcjonalne występujące podczas testowania GKI w poprzedniej poprawce. Poprawka obejmuje zainicjowanie struktury parametru czujnika w celu rejestracji do jednego czujnika.
CONFIG_NL80211_TESTMODE
zmiana interfejsu ABI (aosp/1344321). Ta poprawka dodała niezbędne zmiany struct dla interfejsu ABI i zapewniła, że dodatkowe pola nie spowodowały różnicy funkcjonalnej, umożliwiając partnerom do włączenia interfejsuCONFIG_NL80211_TESTMODE
w jedna produkcyjne zachowania zgodności z GKI.
Egzekwuj KMI w czasie działania
Jądro GKI używają opcji konfiguracji TRIM_UNUSED_KSYMS=y
i UNUSED_KSYMS_WHITELIST=<union
of all symbol lists>
, które ograniczają eksportowanie symboli
(np. symboli eksportowanych przy użyciu EXPORT_SYMBOL_GPL()
) do tych, które zostały wymienione na
listę symboli. Pozostałe symbole nie są eksportowane, a moduł wymaga
niewyeksportowany symbol jest odrzucany. To ograniczenie jest egzekwowane w czasie kompilacji
brakujące wpisy są oznaczane.
Do celów programistycznych możesz użyć kompilacji jądra GKI, która nie zawiera
– możesz użyć wszystkich zwykle eksportowanych symboli). Aby znaleźć:
tych kompilacji, szukaj kompilacji kernel_debug_aarch64
ci.android.com
Wymuszanie KMI za pomocą obsługi wersji modułów
Jądro obrazu jądra (GKI) używają obsługi wersji modułu
(CONFIG_MODVERSIONS
) jako dodatkowego środka egzekwowania zgodności z KMI na stronie
w środowisku wykonawczym. Obsługa wersji modułu może powodować niezgodność z cyklicznym sprawdzaniem nadmiarowości (CRC)
błędów w czasie wczytywania modułu, jeśli oczekiwana wartość KMI modułu nie jest zgodna z
vmlinux
KMI. Na przykład ten problem to typowa awaria, która występuje w
czas wczytywania modułu z powodu niezgodności CRC dla symbolu 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 ''
Zastosowania obsługi wersji modułów
Obsługa wersji modułu jest przydatna z tych powodów:
Obsługa wersji modułu wykrywa zmiany w widoczności struktury danych. Jeżeli moduły i nieprzezroczystych struktur danych, czyli struktur danych, które nie są częścią KMI, po kolejnych zmianach w strukturze łamią zasady.
Weźmy na przykład
fwnode
polu wstruct device
. To pole MUSI być nieprzezroczyste dla modułów, aby nie można było w nich wprowadzać zmiandevice->fw_node
lub oszacować jego rozmiar.Jeśli jednak moduł zawiera tag
<linux/fwnode.h>
(bezpośrednio lub pośrednio): polefwnode
wstruct device
nie jest już dla niego nieprzezroczyste. moduł może następnie wprowadzać zmiany w elemenciedevice->fwnode->dev
lubdevice->fwnode->ops
Ten scenariusz jest problematyczny z kilku powodów, stwierdza się w następujący sposób:Może złamać założenia, na które opiera się podstawowy kod jądra, struktury danych.
Jeśli przyszła aktualizacja jądra zmieni
struct fwnode_handle
(dane typufwnode
), moduł nie będzie już działać z nowym jądrem. Co więcej, modułstgdiff
nie pokaże żadnych różnic, ponieważ moduł ulega awarii KMI przez bezpośrednie manipulowanie wewnętrznymi strukturami danych w sposób można przechwycić tylko na podstawie reprezentacji binarnej.
Bieżący moduł zostanie uznany za niezgodny z KMI, gdy zostanie wczytany później w ramach nowego, niezgodnego jądra systemu. Obsługa wersji modułu dodaje kontrolę środowiska wykonawczego do uniknąć przypadkowego wczytania modułu, który jest niezgodny z jądrem KMI. Ta kontrola zapobiega trudnym do debugowania problemów w czasie działania i awariom jądra, które mogą wynika z niewykrytej niezgodności w KMI.
Włączenie obsługi wersji modułów zapobiega tym problemom.
Sprawdź niezgodności CRC bez uruchamiania urządzenia
stgdiff
porównuje i zgłasza niezgodności CRC między jądrami i innymi
Różnice w interfejsie ABI.
Dodatkowo pełna kompilacja jądra z włączoną obsługą CONFIG_MODVERSIONS
generuje
Module.symvers
w ramach normalnego procesu kompilacji. Ten plik zawiera jedną
dla każdego symbolu wyeksportowanego przez jądro (vmlinux
) i moduły. Każdy
wiersz składa się z wartości CRC, nazwy symbolu, przestrzeni nazw symbolu, znaku vmlinux
lub
nazwy modułu, z którego jest eksportowany symbol, oraz typu eksportu (np.
EXPORT_SYMBOL
w porównaniu z EXPORT_SYMBOL_GPL
).
Możesz porównać pliki Module.symvers
między kompilacją GKI a kompilacją
aby sprawdzić różnice w kodach CRC w symbolach eksportowanych przez vmlinux
. Jeśli
to różnica wartości CRC w dowolnym symbolu eksportowanym przez vmlinux
oraz, który
jest używany przez jeden z modułów wczytywanych do urządzenia, moduł nie jest
strony.
Jeśli nie masz wszystkich artefaktów kompilacji, ale masz pliki vmlinux
z jądra systemu GKI i jądra, możesz porównywać wartości CRC dla określonego
przez uruchomienie poniższego polecenia w obu jądrach i porównanie
dane wyjściowe:
nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>
Na przykład poniższe polecenie sprawdza wartość CRC dla: module_layout
symbol:
nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout
Rozwiąż problemy z niezgodnością CRC
Aby rozwiązać problem niezgodności CRC podczas wczytywania modułu:
Utwórz jądro GKI i jądro urządzenia za pomocą
--kbuild_symtypes
jak w tym poleceniu:tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
To polecenie generuje plik
.symtypes
dla każdego pliku.o
. ZobaczKBUILD_SYMTYPES
w Kleaf .W przypadku Androida 13 lub starszego utwórz jądro GKI. i jądro urządzenia, dodając na początku polecenia
KBUILD_SYMTYPES=1
użyj do skompilowania jądra, jak pokazano w tym poleceniu:KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Jeśli używasz
build_abi.sh,
, flagaKBUILD_SYMTYPES=1
jest domyślnie ustawiona już teraz.Znajdź plik
.c
, w którym eksportowany jest symbol z niezgodnością CRC, używając kodu następujące polecenie:cd common && git grep EXPORT_SYMBOL.*module_layout kernel/module.c:EXPORT_SYMBOL(module_layout);
Plikowi
.c
ma odpowiedni plik.symtypes
w GKI, a artefaktów kompilacji jądra urządzenia. Znajdź plik.c
za pomocą tego polecenia:cd out/$BRANCH/common && ls -1 kernel/module.* kernel/module.o kernel/module.o.symversions kernel/module.symtypes
Plik
.c
ma te cechy:Format pliku
.c
to jeden (potencjalnie bardzo długi) wiersz na symbol.[s|u|e|etc]#
na początku wiersza oznacza, że symbol jest typu danych.[struct|union|enum|etc]
Na przykład:t#bool typedef _Bool bool
Brak prefiksu
#
na początku wiersza oznacza, że symbol jest funkcją. Na przykład:find_module s#module * find_module ( const char * )
Porównaj oba pliki i wyeliminuj wszystkie różnice.
Przypadek 1: różnice wynikające z widoczności typu danych
jeśli jedno jądro pozostawia symbol lub typ danych nieprzezroczyste dla modułów, a drugie jest nieprzezroczyste.
jądro nie działa, ta różnica pojawia się między plikami .symtypes
.
tych dwóch jąder. Plik .symtypes
z jednego z jąder zawiera UNKNOWN
dla symbolu, a plik .symtypes
z drugiego jądra ma widok rozwinięty
symbolu lub typu danych.
Na przykład dodanie tego wiersza do
include/linux/device.h
w jądrze powoduje niezgodności CRC. Jedna z tych
jest dla module_layout()
:
#include <linux/fwnode.h>
Porównanie module.symtypes
dla tego symbolu powoduje ujawnienie tych elementów
różnice:
$ 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 ] ; }
...
Jeśli jądro ma wartość UNKNOWN
, a jądro GKI ma widok rozwinięty
(to bardzo mało prawdopodobne), a następnie scal najnowszy system Android Common Jądro
z jądra systemu, aby korzystać z najnowszej wersji bazy GKI.
W większości przypadków jądro GKI ma wartość UNKNOWN
, a jądro ma wartość
z wewnętrznych szczegółów symbolu powodowanych przez zmiany wprowadzone w jądrze. To jest
ponieważ jeden z plików w jądrze dodał element #include
, którego nie ma w
przez jądro GKI.
Zazwyczaj rozwiązaniem problemu jest ukrywanie nowego elementu #include
w interfejsie genksyms
.
#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif
W przeciwnym razie wykonaj te czynności, aby zidentyfikować element #include
powodujący różnicę.
kroki:
Otwórz plik nagłówka, który definiuje symbol lub typ danych z tym symbolem różnicy. Na przykład edytuj pole
include/linux/fwnode.h
dla atrybutustruct fwnode_handle
Na początku pliku nagłówka dodaj następujący kod:
#ifdef CRC_CATCH #error "Included from here" #endif
W pliku
.c
modułu, w którym występuje niezgodność CRC, dodaj parametr jako pierwszy wiersz przed dowolnym z wierszy#include
.#define CRC_CATCH 1
Skompiluj moduł. Powstały błąd w czasie kompilacji pokazuje łańcuch pliku nagłówka
#include
, który doprowadził do niezgodności CRC. Na przykład: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"
Jedno z ogniw w tym łańcuchu połączeń
#include
jest spowodowane zmianą wprowadzoną w Google, którego brakuje w jądrze GKI.Zidentyfikuj zmianę, cofnij ją w jądrze lub prześlij je do ACK i połącz je ze swoim kontem.
Przypadek 2: różnice wynikające ze zmian typu danych
Jeśli niezgodność CRC dla symbolu lub typu danych nie wynika z różnicy w wynika z faktycznych zmian (dodatków, usunięć lub zmian) w typ danych.
Na przykład wprowadzenie poniższej zmiany w jądrze spowoduje wygenerowanie kilku CRC niezgodności, ponieważ ten typ zmiany pośrednio wpływa na wiele symboli:
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);
Jedna niezgodność CRC dotyczy devm_of_platform_populate()
.
Porównując pliki .symtypes
dotyczące tego symbolu, może ono wyglądać tak:
$ 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 * ) ; ...
Aby zidentyfikować zmieniony typ, wykonaj te czynności:
Znajdź definicję tego symbolu w kodzie źródłowym (zwykle w plikach
.h
).- W przypadku różnic pod względem symboli między jądrem systemu a jądrem GKI znaleźć zatwierdzenie, uruchamiając to polecenie:
git blame
- Usunięte symbole (gdy symbol jest usunięty z drzewa, a ponadto w innym drzewie, musisz znaleźć zmianę, usunął ten wiersz. Użyj poniższego polecenia na drzewie, w którym wiersz usunięto:
git log -S "copy paste of deleted line/word" -- <file where it was deleted>
Przejrzyj zwrócona listę zatwierdzeń, aby znaleźć zmianę lub usunięcie. pierwsze zatwierdzenie jest prawdopodobnie tym, którego szukasz. Jeśli nie, kliknij przejrzeć listę, aż znajdziesz zatwierdzenie.
Po zidentyfikowaniu zmiany przywróć ją w jądrze lub prześlij do ACK i pobierz scalone.