Как обновить ядро ​​Android до последней стабильной версии Linux

Мы рассмотрели руководства по ядрам Android, такие как «Как создать собственное ядро» и «Лучшие настраиваемые ядра для Android», но сегодня мы собираемся показать вам, как выполнить апстрим вашего ядра по сравнению с последними версиями. Linux стабильный.

Пожалуйста, знайте, что это продвинутый материал – если вы никогда раньше не компилировали ядро, вам следует следовать руководству «Как создать собственный Ядро », ссылка на которую приведена выше, и это руководство будет включать выбор и объединение коммитов из последнего стабильного ядра Linux с ядром Android перед его компиляцией.

Обновление вашего ядра Android до последней стабильной версии Linux имеет множество положительных преимуществ, таких как наличие последних изменений безопасности и исправлений ошибок – мы объясним некоторые из плюсов и минусы далее в этом руководстве.

Что такое стабильное ядро ​​Linux?

Как обновить ядро ​​Android до последней стабильной версии Linux

Linux-stable, как следует из названия, является стабильной ветвью ядра Linux. эл. Другая ветвь известна как «основная ветвь», которая является главной ветвью . Вся разработка ядра Linux происходит в основной линии и обычно следует этому процессу:

  1. Линус Торвальдс получит кучу исправлений от своих сопровождающих в течение двух недель.
  2. По истечении этих двух недель он выпускает ядро ​​rc1 (например, 4.14-rc1).
  3. Каждую неделю в течение следующих 6-8 недель он будет выпускать еще один RC (например, 4.14). -rc2, 4.14-rc3 и т. д.), которое содержит ТОЛЬКО исправления ошибок и регрессий.
  4. Как только оно будет признано стабильным, оно будет выпущено в виде архива для загрузки в org (например, 4.14).

Что такое ядра LTS?

Каждый год Грег выбирает одно ядро ​​и поддерживает его для любого из двух. лет (LTS) или шесть лет (продленный LTS). Они предназначены для продуктов, которым нужна стабильность (например, телефоны Android или другие устройства IOT). Процесс такой же, как и выше, только длится дольше. В настоящее время существует шесть ядер LTS (которые всегда можно просмотреть на странице выпусков kernel.org ):

  • 4.14 (LTS) , поддерживается Грегом Кроа-Хартманом.
  • 4.9 (LTS) , поддерживается Грегом Кроа-Хартманом.
  • 4.4 (eLTS) , поддерживается Грегом Кроа-Хартманом
  • 4.1 (LTS) , поддерживается Сашей Левином
  • 3.16 (LTS) , поддерживается Беном Хатчингсом.
  • 3.2 (LTS) , поддерживается Бен Хатчингс

Каковы преимущества апстриминга моего ядра Android до Linux Stable?

При наличии важных уязвимостей раскрыты/исправлены, стабильные ядра получают их первыми. Таким образом, ваше ядро ​​Android будет намного безопаснее против атак, недостатков безопасности и просто ошибок в целом.

Стабильная версия Linux включает исправления для многих драйверов, которых не поддерживает мое устройство Android. не используете, разве в этом нет необходимости?

Да и нет, в зависимости от того, как вы определяете «в основном». Ядро Linux может включать в себя много кода, который не используется в системе Android, но это не гарантирует, что при слиянии новых версий этих файлов не будет конфликтов! Поймите, что практически никто не собирает каждую часть ядра, даже самые распространенные дистрибутивы Linux, такие как Ubuntu или Mint. Это не означает, что вам не следует принимать эти исправления, потому что для драйверов, которые вы ДЕЙСТВИТЕЛЬНО используете ЕСТЬ исправления. Возьмем для примера arm/arm64 и ext4, которые являются наиболее распространенной архитектурой и файловой системой Android соответственно. В 4.4, от 4.4.78 (версия последнего тега Oreo CAF) до 4.4.121 (последний тег восходящего потока), это следующие числа для коммитов этих систем:

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

Самая трудоемкая часть – это начальная установка; как только вы будете полностью обновлены, вам совсем не понадобится время для слияния с новым выпуском, который обычно содержит не более 100 коммитов. Преимущества, которые это дает (большая стабильность и лучшая безопасность для ваших пользователей), должны потребовать этого процесса.

Как объединить стабильное ядро ​​Linux в ядро ​​Android

Сначала вам нужно выяснить, с какой версией ядра работает ваше устройство Android.

Каким бы тривиальным это ни казалось, необходимо знать, с чего вам нужно начать. Выполните следующую команду в дереве ядра:

 make kernelversion 

Она вернет ту версию, на которой вы работаете. Первые два числа будут использоваться для определения нужной вам ветки (например, linux-4.4.y для любого ядра 4.4), а последний номер будет использоваться для определения того, с какой версии вам нужно начать слияние (например, если вы используете 4.4. .21, далее вы объедините 4.4.22).

Загрузите последний исходный код ядра с kernel.org.

kernel .org содержит последний исходный код ядра в стабильном репозитории linux. Внизу страницы будут три ссылки для получения. По моему опыту, зеркало Google обычно самое быстрое, но ваши результаты могут отличаться. Выполните следующие команды:

 git remote add linux-stable https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit fetch linux-  стабильный 

Решите, хотите ли вы объединить все ядро ​​или выбрать коммиты.

Затем вам нужно будет выбрать если вы хотите объединить коммиты или вишневый выбор. Вот плюсы и минусы каждого, и когда вы можете захотеть их сделать.

ПРИМЕЧАНИЕ: Если исходный код вашего ядра находится в форме tarball, вам, скорее всего, придется выбирать, иначе вы получите тысячи конфликтов файлов. потому что git заполняет историю исключительно на основе восходящего потока, а не того, что изменили OEM или CAF. Просто переходите к шагу 4.

Сбор вишни:

Плюсы:

  • Легче разрешать конфликты, поскольку вы точно знаете, какой конфликт вызывает проблему.
  • Легче перебазировать, поскольку каждая фиксация выполняется сама по себе.
  • Легче разделить пополам при возникновении проблем

Минусы:

  • Требуется больше времени, поскольку каждый коммит нужно выбирать индивидуально.
  • С первого взгляда немного сложнее определить, совершена ли фиксация из восходящего потока

Merge

Плюсы :

  • Это быстрее, так как вам не нужно ждать, пока все чистые исправления объединятся.
  • Легче увидеть, когда фиксация совершена из апстрима, так как вы не будете коммиттером, а сопровождающий апстрима будет.

Минусы:

  • Разрешение конфликтов может быть немного сложнее, чем вы нужно будет найти, какая фиксация вызывает конфликт, используя git log/git blame, это не будет t прямо скажу вам.
  • Перебазирование сложно, так как вы не можете перебазировать слияние, оно предложит выбрать все коммиты по отдельности. Однако вам не следует часто выполнять ребазирование, вместо этого используйте git revert и git merge там, где это возможно.

Я бы рекомендовал сделать выборку, чтобы сначала выяснить любые конфликты проблем, выполнив merge, затем отмените фиксацию проблемных коммитов впоследствии, чтобы упростить обновление (поскольку слияние происходит быстрее после обновления).

Добавьте коммиты в свой источник, по одной версии за раз

Самая важная часть этого процесса – одна версия за раз. В вашей серии апстрима МОЖЕТ быть исправление проблемы, которое может вызвать проблемы с загрузкой или сломать что-то вроде звука или зарядки (объяснено в разделе советов и приемов). По этой причине важно вносить инкрементные изменения версий, легче найти проблему в 50 фиксациях, чем в более чем 2000 фиксациях для некоторых версий. Я бы рекомендовал выполнить полное слияние только после того, как вы узнаете все коммиты проблем и разрешения конфликтов.

Выбор вишни

Формат:

 git cherry-pick .. 

Пример:

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

Слияние

Формат:

 git merge  

Пример:

git merge v3.10.74

Я рекомендую отслеживать конфликты в коммитах слияния, удаляя маркеры #.

Как разрешать конфликты

Мы не можем дать пошаговое руководство по разрешению каждого отдельного конфликта, поскольку оно требует хорошего знания языка C, но вот несколько советов.

Если вы выполняете слияние, выясните, какая фиксация вызывает конфликт. Вы можете сделать это одним из двух способов:

  1. git log -pv $ (make kernelversion) .. , чтобы получить изменения между вашей текущей версией и последней из апстрима. . Флаг -p предоставит вам изменения, сделанные каждой фиксацией, чтобы вы могли видеть.
  2. Запустите git blame для файла, чтобы получить хэши каждой фиксации в области. Затем вы можете запустить git show –format = fuller, чтобы узнать, был ли коммиттер из mainline/stable, Google или CodeAurora.
  • Выясните, есть ли у вас уже фиксация. Некоторые поставщики, такие как Google или CAF, будут пытаться искать критические ошибки, такие как исправление Dirty COW, и их резервные копии могут конфликтовать с исходными. Вы можете запустить git log –grep = ”” и посмотреть, вернет ли он что-нибудь. Если это так, вы можете пропустить фиксацию (при выборе вишни с помощью git reset –hard && git cherry-pick –continue) или игнорировать конфликты (удалить >>>>>).
  • Выясните, был ли бэкпорт, который мешает разрешению. Google и CAF хотят перенести некоторые патчи, которых не было в стабильной версии. В Stable часто требуется адаптировать разрешение основного коммита к отсутствию определенных патчей, которые Google выбирает для резервного копирования. Вы можете посмотреть на основной коммит, запустив git show (основной хеш будет доступен в сообщении о фиксации стабильного коммита). Если есть обратный порт, который мешает, вы можете либо отменить изменения, либо использовать основную версию (что вам обычно нужно делать).
  • Прочтите, что пытается сделать коммит сделайте и посмотрите, устранена ли проблема. Иногда CAF может исправить ошибку независимо от апстрима, то есть вы можете либо перезаписать их исправление для апстрима, либо отказаться от него, как указано выше.

В противном случае это может быть просто результатом CAF /Google/OEM, и в этом случае вам просто нужно перетасовать кое-что.

Вот зеркало стабильного linux репозитория kernel.org на GitHub, который может быть проще для поиска списков коммитов и различий для разрешения конфликтов. Я рекомендую сначала перейти к просмотру списка коммитов и найти проблемный коммит, чтобы увидеть исходный diff и сравнить его с вашим.

Пример URL: https://github.com/ nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

Вы также можете сделать это через командную строку:

 git log  ..   git show  

Решение разрешений зависит только от контекста. Что вы должны ВСЕГДА делать, так это убедиться, что ваш окончательный diff соответствует исходному, выполнив следующие команды в двух отдельных окнах:

 git diff HEADgit diff v $ (make kernelversion) .. $ (git tag -  sort = -taggerdate -lv $ (сделать версию ядра | вырезать -d. -f 1,2) * |  head -n1) 

Enable rerere

В Git есть функция rerere (расшифровывается как Reuse Recorded Resolution), что означает, что когда он обнаруживает конфликт, он записывает, как вы его разрешили, чтобы вы могли повторно использовать его позже. Это особенно полезно как для хронических ребазеров со слиянием, так и с выбором вишни, поскольку вам просто нужно будет запустить git add. && git –продолжить при повторном выполнении восходящего вызова, поскольку конфликт будет разрешен так, как вы его разрешили ранее.

Его можно включить, выполнив следующую команду в репозитории ядра. :

 git config rerere.enabled true 

Как выполнить git bisect при работе с компилятором или ошибкой времени выполнения

Учитывая, что вы будете добавлять значительное количество коммитов, вы вполне можете ввести ошибку компилятора или времени выполнения. Вместо того, чтобы просто сдаваться, вы можете использовать встроенный в git инструмент пополам, чтобы выяснить основную причину проблемы! В идеале вы будете собирать и обновлять каждую версию ядра по мере ее добавления, поэтому деление пополам займет меньше времени, если это необходимо, но вы можете без проблем разделить 5000 коммитов.

Что будет делать git bisect, так это взять диапазон коммитов, от того, где присутствует проблема, до того, где ее не было, а затем начать сокращать вдвое диапазон коммитов, позволяя вам создавать и тестировать и сообщать ему, хорошо это или нет. Он будет продолжать это, пока не выплюнет фиксацию, вызывающую вашу проблему. На этом этапе вы можете либо исправить это, либо отменить.

  1. Начать деление пополам: git bisect start
  2. Отметить текущую версию как плохую: git bisect bad
  3. Отметить ревизию как хорошую: git bisect good
  4. Построить с новой ревизией
  5. На основе результата (если проблема присутствует или нет), сообщите git: git bisect good OR git bisect bad
  6. Промойте и повторяйте шаги 4-5, пока проблема не будет зафиксирована!
  7. Отмените или исправьте фиксацию проблемы.

ПРИМЕЧАНИЕ. При слияниях потребуется временно запустить git rebase -i , чтобы применить все патчи к вашей ветке для правильного деления пополам, так как деление пополам с выполненными слияниями часто приводит к проверке на восходящие коммиты, что означает, что у вас нет никаких коммитов, специфичных для Android. Я могу более подробно остановиться на этом по запросу, но поверьте мне, это необходимо. Как только вы определили фиксацию проблемы, вы можете отменить ее или перебазировать ее в слияние.

НЕ сжимайте апстрим-обновления

Многие новые разработчики склонны делать это, поскольку это «чище» и «проще» в управлении. Это ужасно по нескольким причинам:

  • Авторство потеряно. Несправедливо по отношению к другим разработчикам получать кредиты за их работу.
  • Деление пополам невозможно. Если вы раздавите серию коммитов, и в этой серии возникнет какая-то проблема, невозможно будет сказать, какая фиксация вызвала проблему в сквоше.
  • Дальнейшие варианты выбора сложнее. Если вам нужно выполнить перебазирование с помощью сжатой серии, трудно/невозможно определить, откуда возникает конфликт.

Подпишитесь на список рассылки ядра Linux, чтобы своевременно обновления

Чтобы получать уведомления всякий раз, когда есть апстрим обновления, подпишитесь на список linux-kernel-announce . Это позволит вам получать электронное письмо каждый раз при выпуске нового ядра, чтобы вы могли обновлять и загружать его как можно быстрее.

Источник