Hoe u uw Android-kernel kunt updaten naar de nieuwste Linux-stabiele

We hebben handleidingen over Android-kernels behandeld, zoals "Hoe een aangepaste kernel te bouwen" en "Beste aangepaste kernels voor Android", maar vandaag gaan we je laten zien hoe je je kernel stroomopwaarts kunt streamen tegen de nieuwste Linux-stabiele.

Weet alsjeblieft dat dit geavanceerde dingen zijn - als je nog nooit eerder een kernel hebt gecompileerd, volg dan de bovenstaande link 'Hoe maak je een aangepaste kernel', en deze gids zal cherry-picking en commits van de nieuwste Linux omvatten: stabiele kernel met uw Android-kernel voordat u deze compileert.

Het upstreamen van uw Android-kernel naar de nieuwste Linux-stal heeft veel positieve voordelen, zoals up-to-date zijn met de nieuwste beveiligingscommits en bugfixes - we zullen enkele van de voor- en nadelen later in deze handleiding uitleggen.

Wat is een Linux-stabiele kernel?

Linux-stabiel, zoals de naam al aangeeft, is de stabiele arm van de Linux-kernel. De andere arm staat bekend als "hoofdlijn", wat de hoofdtak is . Alle Linux-kernelontwikkeling vindt plaats in de hoofdregel en volgt over het algemeen dit proces:

  1. Linus Torvalds neemt twee weken lang een aantal patches van zijn onderhouder.
  2. Na deze twee weken geeft hij een rc1-kernel (bijv. 4.14-rc1) vrij.
  3. Voor elke week voor de komende 6-8 weken zal hij een andere RC-kernel (bijvoorbeeld 4.14-rc2, 4.14-rc3, enz.) Uitbrengen, die ALLEEN bug- en regressiefixes bevat.
  4. Zodra het stabiel wordt geacht, zal het worden vrijgegeven als een tarball voor download op org (bijv. 4.14).

Wat zijn LTS-kernels?

Elk jaar kiest Greg één kernel en bewaart deze gedurende twee jaar (LTS) of zes jaar (uitgebreide LTS). Deze zijn ontworpen om producten te hebben die stabiliteit nodig hebben (zoals Android-telefoons of andere IOT-apparaten). Het proces is exact hetzelfde als hierboven, het gebeurt gewoon voor een langere tijd. Er zijn momenteel zes LTS-kernels (die altijd kunnen worden bekeken op de kernel.org releases-pagina):

  • 4.14 (LTS), onderhouden door Greg Kroah-Hartman
  • 4.9 (LTS), onderhouden door Greg Kroah-Hartman
  • 4.4 (eLTS), onderhouden door Greg Kroah-Hartman
  • 4.1 (LTS), onderhouden door Sasha Levin
  • 3.16 (LTS), onderhouden door Ben Hutchings
  • 3.2 (LTS), onderhouden door Ben Hutchings

Wat zijn de voordelen van het upstreamen van mijn Android-kernel naar Linux Stable?

Wanneer belangrijke kwetsbaarheden worden geopenbaard / verholpen, zijn de stabiele kernels de eersten om ze te krijgen. Uw Android-kernel is dus een stuk veiliger tegen aanvallen, beveiligingsfouten en alleen bugs in het algemeen.

De Linux-stal bevat fixes voor veel stuurprogramma's die mijn Android-apparaat niet gebruikt, is dit meestal niet nodig?

Ja en nee, afhankelijk van hoe u "meestal" definieert. De Linux-kernel kan veel code bevatten die ongebruikt blijft in het Android-systeem, maar dat garandeert niet dat er geen conflicten zullen optreden bij het samenvoegen van nieuwe versies! Begrijp dat vrijwel niemand elk onderdeel van de kernel bouwt, zelfs niet de meest voorkomende Linux-distro's zoals Ubuntu of Mint. Dit betekent niet dat u deze fixes niet zou moeten nemen omdat er fixes zijn voor stuurprogramma's die u wel uitvoert. Neem bijvoorbeeld arm / arm64 en ext4, die respectievelijk de meest voorkomende Android-architectuur en het bestandssysteem zijn. In 4.4, van 4.4.78 (versie van de nieuwste Oreo CAF-tag) tot 4.4.121 (nieuwste upstream-tag), zijn dit de volgende nummers voor de commits van die systemen:

 ~ / 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 

Het meest tijdrovende deel is de eerste opvoeding; als je eenmaal helemaal up-to-date bent, kost het geen tijd om een ​​nieuwe release samen te voegen, die meestal niet meer dan 100 commits bevat. De voordelen die dit met zich meebrengt (meer stabiliteit en betere beveiliging voor uw gebruikers) moeten dit proces echter noodzakelijk maken.

Hoe Linux Stabiele Kernel in een Android-kernel samen te voegen

Eerst moet je uitzoeken welke kernelversie je Android-apparaat gebruikt.

Hoe triviaal dit ook lijkt, het is noodzakelijk om te weten waar u moet beginnen. Voer de volgende opdracht in uw kernelboom uit:

 maak kernelversie 

Het keert terug naar de versie die u gebruikt. De eerste twee nummers zullen worden gebruikt om de branch te bepalen die je nodig hebt (bijv. Linux-4.4.y voor elke 4.4 kernel) en het laatste nummer zal worden gebruikt om te bepalen welke versie je moet beginnen met samenvoegen (bijv. Als je op 4.4 zit .21, u zult vervolgens 4.4.22 samenvoegen).

Pak de nieuwste kernelbron van kernel.org

kernel.org herbergt de nieuwste kernelbron in de linux-stabiele repository. Onderaan die pagina staan ​​drie ophaallinks. Mijn ervaring is dat de spiegel van Google de snelste is, maar uw resultaten kunnen variëren. Voer de volgende opdrachten uit:

 git remote linux-stable toevoegen //kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit fetch linux-stable 

Bepaal of je de hele kernel wilt samenvoegen of kies de commits

Vervolgens moet je kiezen of je de commits of cherry-pick wilt samenvoegen. Hier zijn de voor- en nadelen van elk en wanneer je ze wilt doen.

OPMERKING: Als je kernelbron de vorm heeft van een tarball, zul je hoogstwaarschijnlijk een kers moeten kiezen, anders krijg je duizenden bestandsconflicten omdat git de geschiedenis vult op basis van puur upstream, niet wat de OEM of CAF heeft veranderd. Ga gewoon naar stap 4.

De krenten uit de pap halen:

Voors:

  • Gemakkelijker om conflicten op te lossen, omdat u precies weet welk conflict een probleem veroorzaakt.
  • Gemakkelijker rebasen omdat elke commit op zichzelf staat.
  • Makkelijker in tweeën te delen als er problemen zijn

nadelen:

  • Het duurt langer omdat elke commit individueel moet worden gekozen.
  • Iets moeilijker te zeggen of commit op het eerste gezicht stroomopwaarts komt

samensmelten

Voordelen :

  • Het is sneller omdat u niet hoeft te wachten tot alle schone patches zijn samengevoegd.
  • Het is gemakkelijker om te zien wanneer een commit stroomopwaarts komt, omdat je niet de committer bent, maar de stroomopwaartse beheerder.

nadelen:

  • Conflicten oplossen kan wat moeilijker zijn, omdat je moet opzoeken welke commit het conflict veroorzaakt met behulp van git log / git blame, dit zal je niet direct vertellen.
  • Rebasen is moeilijk omdat je een merge niet kunt rebasen, het biedt aan om alle commit afzonderlijk te selecteren. Je zou echter niet vaak moeten rebasen, in plaats daarvan gebruik je git revert en git merge waar mogelijk.

Ik zou aanraden een cherry-pick te doen om in eerste instantie eventuele probleemconflicten te achterhalen, een samenvoeging te doen en daarna het probleem terug te zetten, zodat bijwerken gemakkelijker is (omdat samenvoegen sneller gaat nadat het up-to-date is).

Voeg de commits toe aan je bron, één versie tegelijk

Het belangrijkste onderdeel van dit proces is het gedeelte met één versie tegelijk. Er is mogelijk een probleempatch in je upstream-serie, die een probleem kan veroorzaken bij het opstarten of iets als geluid of opladen kan breken (uitgelegd in het gedeelte met tips en trucs). Het is daarom belangrijk om incrementele versiewijzigingen aan te brengen, het is gemakkelijker om een ​​probleem te vinden in 50 commits dan meer dan 2000 commits voor sommige versies. Ik zou alleen maar aanraden om volledig samen te voegen als je eenmaal weet dat alle problemen zich voordoen en conflicten worden opgelost.

De krenten uit de pap halen

Formaat:

 git cherry-pick .. 

Voorbeeld:

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

samensmelten

Formaat:

 samenvoegen 

Voorbeeld:

git merge v3.10.74

Ik raad aan de conflicten bij het samenvoegen van commissies bij te houden door de # markeringen te verwijderen.

Conflicten oplossen

We kunnen geen stapsgewijze handleiding geven voor het oplossen van elk conflict, omdat het een goede kennis van de C-taal inhoudt, maar hier zijn een paar tips.

Als je samenvoegt, zoek dan uit welke commit het conflict veroorzaakt. U kunt dit op twee manieren doen:

  1. git log -pv $ (maak kernelversie) .. om de veranderingen tussen je huidige versie en de nieuwste upstream te krijgen. De vlag -p geeft je de wijzigingen die door elke commit zijn gedaan, zodat je het kunt zien.
  2. Voer git blame op het bestand uit om de hashes van elke commit in het gebied te krijgen. Je kunt dan git show –format = fuller uitvoeren om te zien of de committer van mainline / stable, Google of CodeAurora was.
  • Zoek uit of je de commit al hebt. Sommige leveranciers zoals Google of CAF zullen proberen stroomopwaarts te zoeken naar kritieke bugs, zoals de Dirty COW-oplossing, en hun backports kunnen conflicteren met stroomopwaartse problemen. Je kunt git log –grep = ”” uitvoeren en kijken of het iets retourneert. Als dit het geval is, kun je de commit overslaan (als cherry-picking met git reset –hard && git cherry-pick -continue) of de conflicten negeren (verwijder de <<<<< >>>>>).
  • Zoek uit of er een achterpoort is die de resolutie verprutst. Google en CAF backporteren graag bepaalde patches die stabiel niet zouden zijn. Stabiel zal vaak de resolutie van de hoofdlijn moeten aanpassen aan het ontbreken van bepaalde patches die Google kiest voor backport. Je kunt de mainline commit bekijken door git show uit te voeren (de mainline hash zal beschikbaar zijn in het commit bericht van de stabiele commit). Als er een backport is die het verprutst, kunt u de wijzigingen ongedaan maken of de hoofdversie gebruiken (wat u meestal moet doen).
  • Lees wat de commit probeert te doen en kijk of het probleem al is opgelost. Soms kan CAF een bug repareren die onafhankelijk is van upstream, wat betekent dat je de fix voor upstream kunt overschrijven of deze kunt verwijderen, zoals hierboven.

Anders kan het gewoon een gevolg zijn van een CAF / Google / OEM-toevoeging, in welk geval je gewoon wat dingen in de rondte moet schudden.

Hier is een spiegel van de linux-stabiele kernel.org repository op GitHub, die gemakkelijker kan zijn voor het opzoeken van commit-lijsten en diffs voor conflictoplossing. Ik raad aan om eerst naar de lijst met commit-lijsten te gaan en de probleem-commit te lokaliseren om de originele diff te zien om deze met die van jou te vergelijken.

Voorbeeld-URL: //github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

Je kunt het ook doen via de opdrachtregel:

 git log .. git show 

Bij het oplossen van resoluties draait alles om context. Wat u ALTIJD moet doen, is ervoor zorgen dat uw laatste diff overeenkomt met die van de upstream door de volgende opdrachten in twee afzonderlijke vensters uit te voeren:

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

Opnieuw inschakelen inschakelen

Git heeft een functie genaamd rerere (staat voor Opgenomen resolutie hergebruiken), wat betekent dat wanneer het een conflict detecteert, het zal opnemen hoe je het hebt opgelost, zodat je het later opnieuw kunt gebruiken. Dit is vooral handig voor zowel chronische rebasers met zowel samenvoegen als cherry-picking omdat je gewoon git add moet uitvoeren. && git - ga door bij het opnieuw uitvoeren van de stroomopwaartse opvoeding, want het conflict zal worden opgelost zoals je het eerder hebt opgelost.

Het kan worden ingeschakeld door de volgende opdracht in uw kernel-repo uit te voeren:

 git config rerere.enabled true 

Hoe bisect te geven wanneer je een compiler- of runtime-fout tegenkomt

Aangezien je een aanzienlijk aantal commits toevoegt, is het heel goed mogelijk om een ​​compiler- of runtime-fout te introduceren. In plaats van het gewoon op te geven, kun je git's ingebouwde bisect-tool gebruiken om de oorzaak van het probleem te achterhalen! In het ideale geval zult u elke afzonderlijke kernelversie bouwen en flashen terwijl u deze toevoegt, zodat het in tweeën delen korter zal zijn indien nodig, maar u kunt 5000 commits zonder problemen splitsen.

Wat git bisect zal doen is een reeks commits nemen, van waar het probleem aanwezig is tot waar het niet aanwezig was, en vervolgens beginnen met het halveren van het commit bereik, zodat je kunt bouwen en testen en het kunt laten weten of het goed is of niet . Het zal hiermee doorgaan totdat het de commit veroorzaakt die jouw probleem veroorzaakt. Op dat moment kunt u het repareren of terugdraaien.

  1. Start bisecting: git bisect start
  2. Label de huidige revisie als slecht: git bisect bad
  3. Label een revisie als goed: git bisect goed
  4. Bouw met de nieuwe revisie
  5. Vertel git op basis van het resultaat (als het probleem aanwezig is of niet): git bisect good OF git bisect bad
  6. Spoel en herhaal stappen 4-5 totdat het probleem is vastgelegd!
  7. Zet het probleem vast of herstel het.

OPMERKING: Fusies moeten git rebase -i tijdelijk uitvoeren om alle patches op je filiaal toe te passen voor een correcte onderverdeling, omdat het in tweeën splitsen met de samengevoegde fusies vaak uitcheckt naar de upstream commits, wat betekent dat je geen van de Android-specifieke commits hebt. Ik kan hier op verzoek dieper op ingaan, maar geloof me, het is nodig. Nadat je het probleem met commit hebt geïdentificeerd, kun je het terugdraaien of opnieuw in de samenvoeging zetten.

Squash upstream-updates NIET

Veel nieuwe ontwikkelaars komen in de verleiding om dit te doen, omdat het 'schoner' en 'eenvoudiger' te beheren is. Dit is verschrikkelijk om een ​​paar redenen:

  • Auteurschap is verloren. Het is oneerlijk tegenover andere ontwikkelaars dat hun krediet is vastgelegd voor hun werk.
  • Bisecteren is onmogelijk. Als je een reeks commits squasht en er is iets in die serie, is het onmogelijk om te achterhalen welke commit een probleem in een squash veroorzaakte.
  • Toekomstige cherry-picks zijn moeilijker. Als u opnieuw moet rebasen met een geplette reeks, is het moeilijk / onmogelijk om te bepalen waar een conflict uit voortvloeit.

Abonneer u op de Linux Kernel-mailinglijst voor tijdige updates

Abonneer u op de lijst linux-kernel-announce om een ​​melding te ontvangen wanneer er een upstream-update is. Hiermee kun je een e-mail krijgen telkens wanneer een nieuwe kernel wordt vrijgegeven, zodat je zo snel mogelijk kunt updaten en pushen.

Interessante Artikelen