Jak zaktualizować jądro Androida do najnowszej stabilnej wersji systemu Linux

Omówiliśmy przewodniki po jądrach systemu Android, takie jak „Jak zbudować niestandardowe jądro” i „Najlepsze niestandardowe jądra dla Androida”, ale dzisiaj pokażemy, jak przesłać jądro do najnowszej stabilnej wersji systemu Linux.

Pamiętaj, że są to rzeczy zaawansowane - jeśli nigdy wcześniej nie skompilowałeś jądra, powinieneś postępować zgodnie z przewodnikiem „Jak zbudować niestandardowe jądro”, do którego link znajduje się powyżej, a ten przewodnik będzie polegał na wybieraniu i łączeniu zatwierdzeń z najnowszego systemu Linux- stabilne jądro z jądrem Androida przed jego skompilowaniem.

Upstreaming twojego jądra Androida do najnowszej stabilnej wersji Linuksa ma wiele pozytywnych korzyści, takich jak aktualizowanie najnowszych poprawek bezpieczeństwa i poprawek błędów - wyjaśnimy niektóre zalety i wady w dalszej części tego przewodnika.

Co to jest jądro stabilne w systemie Linux?

Stabilny dla systemu Linux, jak sama nazwa wskazuje, jest stabilną częścią jądra systemu Linux. Drugie ramię nazywane jest „linią główną”, która jest gałęzią główną . Cały proces tworzenia jądra Linuksa odbywa się w linii głównej i zazwyczaj następuje ten proces:

  1. Linus Torvalds weźmie kilka łat od swoich opiekunów przez dwa tygodnie.
  2. Po tych dwóch tygodniach wypuszcza jądro rc1 (np. 4.14-rc1).
  3. Na każdy tydzień przez następne 6-8 tygodni wyda kolejne jądro RC (np. 4.14-rc2, 4.14-rc3 itp.), Które zawiera TYLKO poprawki błędów i regresji.
  4. Gdy zostanie uznany za stabilny, zostanie wydany jako archiwum do pobrania na org (np. 4.14).

Co to są jądra LTS?

Każdego roku Greg wybiera jedno jądro i utrzymuje je przez dwa lata (LTS) lub sześć lat (rozszerzony LTS). Zostały zaprojektowane z myślą o produktach wymagających stabilności (takich jak telefony z Androidem lub inne urządzenia IOT). Proces jest dokładnie taki sam jak powyżej, po prostu trwa dłużej. Obecnie istnieje sześć jąder LTS (które zawsze można wyświetlić na stronie wydań kernel.org):

  • 4.14 (LTS), utrzymywany przez Grega Kroah-Hartmana
  • 4.9 (LTS), utrzymywany przez Grega Kroah-Hartmana
  • 4.4 (eLTS), utrzymywany przez Grega Kroah-Hartmana
  • 4.1 (LTS), utrzymywany przez Sasha Levin
  • 3.16 (LTS), utrzymywany przez Ben Hutchings
  • 3.2 (LTS), utrzymywany przez Ben Hutchings

Jakie są korzyści z przesłania mojego jądra Androida do stabilnego systemu Linux?

Kiedy ważne luki są ujawniane / naprawiane, stabilne jądra są pierwszymi, które je zdobywają. W ten sposób jądro Androida będzie znacznie bezpieczniejsze przed atakami, lukami w zabezpieczeniach i zwykłymi błędami.

Stabilna wersja systemu Linux zawiera poprawki dla wielu sterowników, których nie używa moje urządzenie z Androidem, czy nie jest to w większości niepotrzebne?

Tak i nie, w zależności od tego, jak zdefiniujesz „głównie”. Jądro Linux może zawierać dużo kodu, który nie jest używany w systemie Android, ale to nie gwarantuje, że podczas łączenia nowych wersji nie będzie konfliktów z tymi plikami! Zrozum, że praktycznie nikt nie buduje każdej części jądra, nawet najczęstszych dystrybucji Linuksa, takich jak Ubuntu czy Mint. Nie oznacza to, że nie powinieneś brać tych poprawek, ponieważ istnieją poprawki dla sterowników, które uruchamiasz. Weźmy na przykład arm / arm64 i ext4, które są najczęściej najpopularniejszą architekturą systemu Android i systemem plików. W 4.4, od 4.4.78 (wersja najnowszego tagu Oreo CAF) do 4.4.121 (najnowszy tag upstream), są to następujące liczby zatwierdzeń tych systemów:

 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 | wc -l2285 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm | wc -l58 ~ / kernels / Linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm64 | wc -l22 ~ / kernels / Linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 fs / ext4 | wc -l18 

Najbardziej czasochłonna jest wstępna rozmowa; kiedy jesteś już na bieżąco, łączenie się w nowej wersji, która zwykle zawiera nie więcej niż 100 zatwierdzeń, zajmuje niewiele czasu. Korzyści wynikające z tego (większa stabilność i większe bezpieczeństwo użytkowników) powinny jednak wymagać tego procesu.

Jak połączyć stabilne jądro Linuksa w jądro Androida

Najpierw musisz dowiedzieć się, która wersja jądra działa na twoim urządzeniu z Androidem.

Choć wydaje się to banalne, trzeba wiedzieć, od czego zacząć. Uruchom następujące polecenie w drzewie jądra:

 wykonaj wersję jądra 

Wróci wersja, na której jesteś. Pierwsze dwie liczby zostaną wykorzystane do ustalenia potrzebnej gałęzi (np. Linux-4.4.y dla dowolnego jądra 4.4), a ostatnia liczba zostanie użyta do ustalenia, którą wersję należy rozpocząć od scalenia (np. Jeśli korzystasz z wersji 4.4 .21, scalisz 4.4.22 dalej).

Pobierz najnowsze źródło jądra z kernel.org

kernel.org zawiera najnowsze źródło jądra w repozytorium stabilnym dla systemu Linux. U dołu tej strony będą trzy linki pobierania. Z mojego doświadczenia wynika, że ​​lustro Google jest najszybsze, ale wyniki mogą się różnić. Uruchom następujące polecenia:

 git zdalne dodaj stabilny dla Linux-a //kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit pobierz stabilny dla Linux-a 

Zdecyduj, czy chcesz scalić całe jądro, czy też wybrać zatwierdzenia

Następnie musisz wybrać, czy chcesz scalić zatwierdzenia, czy wybrać cherry. Oto zalety i wady każdego z nich i kiedy możesz chcieć je wykonać.

UWAGA: Jeśli twoje źródło jądra jest w postaci tarballa, najprawdopodobniej będziesz musiał wybrać cherry-pick, w przeciwnym razie dostaniesz tysiące konfliktów plików, ponieważ git zapełnia historię wyłącznie na wcześniejszym etapie, a nie tym, co ma producent OEM lub CAF zmienione. Wystarczy przejść do kroku 4.

Zbieranie wiśni:

Plusy:

  • Łatwiejsze rozwiązywanie konfliktów, ponieważ dokładnie wiesz, jaki konflikt powoduje problem.
  • Łatwiej jest dokonać bazowania, ponieważ każde zatwierdzenie działa samodzielnie.
  • Łatwiej jest podzielić na dwie części, jeśli napotkasz problemy

Cons:

  • Trwa to dłużej, ponieważ każde zatwierdzenie musi być indywidualnie wybrane.
  • Na pierwszy rzut oka niewiele trudniej stwierdzić, czy zatwierdzenie pochodzi z góry

Łączyć

Plusy :

  • Jest szybszy, ponieważ nie musisz czekać na połączenie wszystkich czystych łatek.
  • Łatwiej jest zobaczyć, kiedy zatwierdzenie jest z góry, ponieważ nie będziesz sprawcą, a opiekun będzie.

Cons:

  • Rozwiązywanie konfliktów może być nieco trudniejsze, ponieważ będziesz musiał sprawdzić, które zatwierdzenie powoduje konflikt za pomocą git log / git winny, nie powie ci to bezpośrednio.
  • Rebasing jest trudny, ponieważ nie możesz rebase scalić, zaoferuje wybranie wszystkich zatwierdzeń indywidualnie. Jednak nie powinieneś często powtarzać, korzystając z git revert i git merge, jeśli to możliwe.

Poleciłbym zrobić dokładny wybór, aby początkowo rozwiązać wszelkie konflikty problemów, wykonać scalenie, a następnie wycofać zatwierdzenia problemu, aby aktualizacja była łatwiejsza (ponieważ scalanie jest szybsze po aktualizacji).

Dodaj zatwierdzenia do źródła, jedna wersja na raz

Najważniejszą częścią tego procesu jest jedna wersja na raz. W twojej wcześniejszej serii MOŻE występować problem, który może powodować problemy z uruchamianiem lub zepsuć coś takiego jak dźwięk lub ładowanie (wyjaśnione w sekcji porad i wskazówek). Wprowadzanie przyrostowych zmian wersji jest ważne z tego powodu, dla niektórych wersji łatwiej jest znaleźć problem w 50 zatwierdzeniach niż w 2000 r. Poleciłbym wykonanie pełnego scalenia tylko wtedy, gdy poznasz wszystkie zatwierdzone problemy i rozwiązania konfliktów.

Zbieranie wiśni

Format:

 git cherry-pick .. 

Przykład:

git cherry-pick v3.10.73..v3.10.74

Łączyć

Format:

 Git Merge 

Przykład:

git merge v3.10.74

Zalecam śledzenie konfliktów w zatwierdzeniach scalania poprzez usunięcie znaczników #.

Jak rozwiązywać konflikty

Nie możemy dać instrukcji krok po kroku dla rozwiązania każdego pojedynczego konfliktu, ponieważ wymaga dobrej znajomości języka C, ale oto kilka wskazówek.

Jeśli łączysz się, dowiedz się, jakie zmiany powodują konflikt. Możesz to zrobić na dwa sposoby:

  1. git log -pv $ (make kernelversion) .. aby uzyskać zmiany między twoją aktualną wersją a najnowszą z upstream. Flaga -p podaje zmiany dokonane przez każde zatwierdzenie, dzięki czemu można zobaczyć.
  2. Uruchom git winę na pliku, aby uzyskać skróty każdego zatwierdzenia w obszarze. Następnie możesz uruchomić git show –format = fuller, aby sprawdzić, czy committer pochodzi z linii głównej / stabilnej, Google lub CodeAurora.
  • Sprawdź, czy masz już zatwierdzenie. Niektórzy dostawcy, tacy jak Google czy CAF, będą próbować szukać błędów krytycznych, takich jak poprawka Dirty COW, a ich backporty mogą powodować konflikty z poprzednimi. Możesz uruchomić git log –grep = ”” i sprawdzić, czy coś zwróci. Jeśli tak, możesz pominąć zatwierdzenie (jeśli wybieranie wiśni za pomocą git reset –hard && git cherry-pick –kontynuuj) lub zignoruj ​​konflikty (usuń <<<<< >>>>>).
  • Dowiedz się, czy nie było backportu, który zakłóca rozdzielczość. Google i CAF lubią backportować niektóre łatki, których stabilna nie zrobiłaby. Stabilny często będzie musiał dostosować rozdzielczość głównego zatwierdzenia do absurcji niektórych poprawek, które Google wybiera do backportu. Możesz spojrzeć na główne zatwierdzenie, uruchamiając git show (skrót główny będzie dostępny w komunikacie zatwierdzenia stabilnego zatwierdzenia). Jeśli istnieje problem z backportem, możesz albo odrzucić zmiany, albo użyć wersji głównej (co zwykle będziesz musiał zrobić).
  • Przeczytaj, co próbuje zrobić zatwierdzenie, i sprawdź, czy problem został już rozwiązany. Czasami CAF może naprawić błąd niezależny od upstream, co oznacza, że ​​możesz albo zastąpić ich poprawkę dla upstream, albo odrzucić ją, jak wyżej.

W przeciwnym razie może to wynikać z dodania CAF / Google / OEM, w którym to przypadku trzeba po prostu przetasować niektóre elementy.

Oto lustro repozytorium kernel.org stabilnego dla Linuxa na GitHub, które może być łatwiejsze do wyszukiwania list zatwierdzeń i różnic w celu rozwiązywania konfliktów. Polecam najpierw przejść do widoku listy zatwierdzeń i zlokalizować problem z zatwierdzeniem, aby zobaczyć oryginalny plik różnicowy, aby porównać go z twoim.

Przykładowy adres URL: //github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

Możesz to również zrobić za pomocą wiersza poleceń:

 git log .. git show 

Rozwiązywanie problemów polega na kontekście. To, co powinieneś ZAWSZE upewnić się, że twój końcowy plik różnicowy pasuje do nadrzędnego, uruchamiając następujące polecenia w dwóch osobnych oknach:

 git diff HEAD git diff v $ (make kernelversion) .. $ (git tag --sort = -taggerdate -lv $ (make kernelversion | cut -d. -f 1, 2) * | head -n1) 

Włącz rerere

Git ma funkcję o nazwie rerere (skrót od Reuse Recorded Resolution), co oznacza, że ​​gdy wykryje konflikt, zapisze sposób jego rozwiązania, abyś mógł go później użyć ponownie. Jest to szczególnie przydatne w przypadku zarówno przewlekłych rebaserów z łączeniem i wybieraniem, ponieważ wystarczy uruchomić git add. && git - kontynuuj przy ponownym uruchamianiu programu upstream, ponieważ konflikt zostanie rozwiązany tak, jak poprzednio.

Można go włączyć, uruchamiając następujące polecenie w repozytorium jądra:

 git config rerere.enabled true 

Jak git bisect po uruchomieniu na kompilatorze lub błąd w czasie wykonywania

Biorąc pod uwagę, że dodasz znaczną liczbę zatwierdzeń, bardzo możliwe jest wprowadzenie błędu kompilatora lub środowiska wykonawczego. Zamiast po prostu się poddać, możesz użyć wbudowanego narzędzia git, aby ustalić przyczynę problemu! Idealnie, będziesz budował i flashował każdą wersję jądra, kiedy ją dodasz, więc dzielenie zajmie mniej czasu, jeśli zajdzie taka potrzeba, ale możesz podzielić na 5000 powtórzeń bez żadnych problemów.

To, co zrobi git bisect, to pobranie szeregu zatwierdzeń, od miejsca, w którym występuje problem, do miejsca, w którym go nie było, a następnie rozpoczęcie zmniejszania zakresu zatwierdzeń o połowę, co pozwala budować i testować oraz informować, czy jest dobre czy nie . Będzie to kontynuowało, aż wypluje zatwierdzenie powodujące problem. W tym momencie możesz to naprawić lub cofnąć.

  1. Zacznij dzielić: git bisect start
  2. Oznacz bieżącą wersję jako złą: git bisect bad
  3. Oznacz poprawkę jako dobrą: git bisect good
  4. Kompilacja z nową wersją
  5. Na podstawie wyniku (jeśli problem występuje, czy nie), powiedz git: git bisect good LUB git bisect bad
  6. Płucz i powtarzaj kroki 4-5, aż do znalezienia zatwierdzenia problemu!
  7. Cofnij lub napraw zatwierdzenie problemu.

UWAGA: Fuzje będą musiały tymczasowo uruchomić git rebase -i, aby zastosować wszystkie łatki do twojego oddziału w celu prawidłowego podziału na segmenty, ponieważ dzielenie z połączeniami na miejscu często razy kasuje do zatwierdzeń poprzedzających, co oznacza, że ​​nie masz żadnych zatwierdzeń dla Androida. Mogę pogłębić tę kwestię na żądanie, ale zaufaj mi, jest to potrzebne. Po zidentyfikowaniu zatwierdzenia problemu możesz przywrócić go lub scalić.

NIE zgniataj wcześniejszych aktualizacji

Wielu nowych programistów ma na to ochotę, ponieważ jest to „czystsze” i „łatwiejsze” w zarządzaniu. Jest to okropne z kilku powodów:

  • Autorstwo zostało utracone. Niesprawiedliwe jest, aby inni deweloperzy zaciągali kredyt za swoją pracę.
  • Przecinanie jest niemożliwe. Jeśli zgniatasz serię zatwierdzeń i coś jest problemem w tej serii, nie można powiedzieć, jakie zatwierdzenie spowodowało problem w squashu.
  • Przyszłe wybory wiśniowe są trudniejsze. Jeśli musisz dokonać zmiany bazy za pomocą zgniecionej serii, trudno / nie wiadomo, skąd bierze się konflikt.

Subskrybuj listę mailingową jądra Linux, aby otrzymywać aktualne aktualizacje

Aby otrzymywać powiadomienia za każdym razem, gdy pojawia się aktualizacja, zapisz się na listę linux-kernel-announce. Umożliwi to otrzymywanie wiadomości e-mail za każdym razem, gdy nowe jądro zostanie wydane, abyś mógł aktualizować i wypychać tak szybko, jak to możliwe.

Ciekawe Artykuły