Computer >> 컴퓨터 >  >> 문제 해결 >> Android

Android 커널을 최신 Linux 안정 버전으로 업데이트하는 방법

"사용자 지정 커널을 빌드하는 방법" 및 "Android를 위한 최고의 사용자 지정 커널"과 같은 Android 커널에 대한 가이드를 다루었지만 오늘은 최신 Linux 안정 버전에 대해 커널을 업스트림하는 방법을 보여 드리겠습니다.

이것은 고급이라는 점을 알아두십시오. 물건 – 이전에 커널을 컴파일한 적이 없다면 위에 링크된 "사용자 지정 커널을 빌드하는 방법" 가이드를 따라야 합니다. 이 가이드에는 최신 Linux 안정 커널에서 커밋을 선별하여 Android 커널과 병합하는 작업이 포함됩니다. 컴파일하기 전에.

Android 커널을 최신 Linux 안정 버전으로 업스트림하면 최신 보안 커밋 및 버그 수정으로 업데이트되는 등 많은 긍정적인 이점이 있습니다. 이 가이드의 뒷부분에서 장단점에 대해 설명하겠습니다.

Linux 안정 커널이란 무엇입니까?

Android 커널을 최신 Linux 안정 버전으로 업데이트하는 방법

이름에서 알 수 있듯이 Linux-stable은 Linux 커널의 안정적인 팔입니다. 다른 부분은 마스터 브랜치인 "메인라인"으로 알려져 있습니다. . 모든 Linux 커널 개발은 메인라인에서 이루어지며 일반적으로 다음 프로세스를 따릅니다.

  1. Linus Torvalds는 2주 동안 유지 관리자로부터 많은 패치를 받을 것입니다.
  2. 2주 후에 그는 rc1(예:4.14-rc1) 커널을 출시합니다.
  3. 향후 6-8주 동안 매주 버그 및 회귀 수정 사항만 포함된 다른 RC(예:4.14-rc2, 4.14-rc3 등) 커널을 출시할 예정입니다.
  4. 안정적인 것으로 간주되면 org(예:4.14)에서 다운로드할 수 있는 tarball로 릴리스됩니다.

LTS 커널이란 무엇입니까?

매년 Greg는 하나의 커널을 선택하여 2년(LTS) 또는 6년(Extended LTS) 동안 유지 관리합니다. 안정성이 필요한 제품(예:Android 휴대폰 또는 기타 IOT 장치)을 갖도록 설계되었습니다. 프로세스는 위와 완전히 동일하며 더 오랜 시간 동안 발생합니다. 현재 6개의 LTS 커널(kernel.org 릴리스 페이지에서 항상 볼 수 있음)이 있습니다. ):

  • 4.14(LTS) , Greg Kroah-Hartman이 유지 관리
  • 4.9(LTS) , Greg Kroah-Hartman이 유지 관리
  • 4.4(eLTS) , Greg Kroah-Hartman이 유지 관리
  • 4.1(LTS) , Sasha Levin이 유지
  • 3.16(LTS) , Ben Hutchings가 유지
  • 3.2(LTS) , Ben Hutchings가 유지

Android 커널을 Linux Stable로 업스트림하면 어떤 이점이 있습니까?

중요한 취약점이 공개/수정되면 안정적인 커널이 가장 먼저 취약점을 얻습니다. 따라서 Android 커널은 공격, 보안 결함 및 일반적인 버그에 대해 훨씬 더 안전합니다.

Linux 안정에는 내 Android 기기에서 사용하지 않는 많은 드라이버에 대한 수정 사항이 포함되어 있습니다. 이것은 대부분 불필요하지 않습니까?

"대부분"을 정의하는 방법에 따라 예와 아니오가 있습니다. Linux 커널에는 Android 시스템에서 사용되지 않는 많은 코드가 포함될 수 있지만 새 버전을 병합할 때 해당 파일에서 충돌이 발생하지 않는다는 보장은 없습니다! 거의 아무도 Ubuntu 또는 Mint와 같은 가장 일반적인 Linux 배포판도 포함하지 않고 커널의 모든 단일 부분을 빌드합니다. 있다. 드라이버 수정 운영. 가장 일반적인 Android 아키텍처 및 파일 시스템인 arm/arm64 및 ext4를 예로 들어 보겠습니다. 4.4에서는 4.4.78(최신 Oreo CAF 태그 버전)에서 4.4.121(최신 업스트림 태그)까지 해당 시스템의 커밋에 대해 다음 숫자가 표시됩니다.

nathan@flashbox ~/kernels/linux-stable (마스터) $ git log --format=%h v4.4.78..v4.4.121 | wc -l2285 nathan@flashbox ~/kernels/linux-stable(마스터) $ git log --format=%h v4.4.78..v4.4.121 아치/팔 | wc -l58 nathan@flashbox ~/kernels/linux-stable(마스터) $ git log --format=%h v4.4.78..v4.4.121 arch/arm64 | wc -l22 nathan@flashbox ~/kernels/linux-stable(마스터) $ git log --format=%h v4.4.78..v4.4.121 fs/ext4 | 화장실 -l18

가장 시간이 많이 걸리는 부분은 초기 육성입니다. 최신 상태가 되면 일반적으로 100개 이하의 커밋을 포함하는 새 릴리스에 병합하는 데 시간이 전혀 걸리지 않습니다. 그러나 이것이 가져오는 이점(사용자를 위한 더 나은 안정성과 더 나은 보안)을 위해서는 이 프로세스가 필요합니다.

Linux 안정 커널을 Android 커널로 병합하는 방법

먼저 Android 기기에서 실행 중인 커널 버전을 파악해야 합니다.

이것이 사소해 보이지만 어디서부터 시작해야 하는지 아는 것이 필요합니다. 커널 트리에서 다음 명령을 실행하십시오.

커널 버전 만들기

사용 중인 버전을 반환합니다. 처음 두 숫자는 필요한 분기를 파악하는 데 사용되며(예:4.4 커널의 경우 linux-4.4.y) 마지막 숫자는 병합을 시작하는 데 필요한 버전을 결정하는 데 사용됩니다(예:4.4 .21, 다음에 4.4.22를 병합합니다.

kernel.org에서 최신 커널 소스 가져오기

kernel.org에는 linux-stable 저장소의 최신 커널 소스가 있습니다. 해당 페이지 하단에 3개의 가져오기 링크가 있습니다. 내 경험상 Google의 미러가 가장 빠른 경향이 있지만 결과는 다를 수 있습니다. 다음 명령을 실행하십시오.

git remote add linux-stable https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit linux-stable 가져오기

전체 커널을 병합할지 아니면 커밋을 선택하여 병합할지 결정합니다.

다음으로 커밋을 병합할지 체리픽을 병합할지 선택해야 합니다. 다음은 각각의 장단점과 언제 수행해야 하는지 알려드립니다.

참고: 커널 소스가 tarball 형식인 경우 체리 선택해야 할 가능성이 큽니다. 그렇지 않으면 git이 OEM 또는 CAF가 변경된 내용이 아닌 순전히 업스트림을 기반으로 기록을 채우고 있기 때문에 수천 개의 파일 충돌이 발생합니다. 4단계로 건너뛰세요.

체리 따기:

장점:

  • 문제를 일으키는 충돌이 무엇인지 정확히 알 수 있으므로 충돌을 더 쉽게 해결할 수 있습니다.
  • 각 커밋이 자체적으로 수행되므로 쉽게 리베이스할 수 있습니다.
  • 문제가 발생할 경우 이등분하기 더 쉬움

단점:

  • 각 커밋을 개별적으로 선택해야 하므로 시간이 더 오래 걸립니다.
  • 커밋이 업스트림에서 온 것인지 언뜻 보기에 구별하기가 조금 더 어렵습니다.

병합

장점 :

  • 깨끗한 패치가 모두 병합될 때까지 기다릴 필요가 없으므로 더 빠릅니다.
  • 커미터가 아닌 업스트림 유지 관리자가 되므로 커밋이 업스트림에서 왔는지 확인하기가 더 쉽습니다.

단점:

  • git log/gitblame을 사용하여 충돌을 일으키는 커밋을 찾아야 하므로 충돌 해결이 조금 더 어려울 수 있습니다. 직접 알려주지는 않습니다.
  • 리베이스는 병합을 리베이스할 수 없기 때문에 어렵습니다. 모든 커밋을 개별적으로 선택하도록 제안합니다. 그러나 자주 리베이스해서는 안 되며 대신 가능하면 git revert 및 git merge를 사용하세요.

초기에 문제 충돌을 파악하기 위해 선별 작업을 수행하고 병합을 수행한 다음 나중에 문제 커밋을 되돌리면 업데이트가 더 쉬워집니다(최신 업데이트 후 병합이 더 빠르기 때문에).

한 번에 한 버전씩 소스에 커밋 추가

이 프로세스에서 가장 중요한 부분은 한 번에 하나씩 버전을 만드는 것입니다. 업스트림 시리즈에 문제 패치가 있을 수 있습니다. 이 패치는 부팅에 문제를 일으키거나 사운드 또는 충전과 같은 문제를 일으킬 수 있습니다(팁 및 트릭 섹션에 설명됨). 이러한 이유로 증분 버전 변경을 수행하는 것이 중요합니다. 일부 버전의 경우 2000개 이상의 커밋보다 50개 커밋에서 문제를 찾는 것이 더 쉽습니다. 문제 커밋과 충돌 해결을 모두 알고 있는 경우에만 전체 병합을 수행하는 것이 좋습니다.

체리 따기

형식:

git cherry-pick ..

예:

자식 체리 픽 v3.10.73..v3.10.74

병합

형식:

git 병합 

예:

자식 병합 v3.10.74

# 마커를 제거하여 병합 커밋의 충돌을 추적하는 것이 좋습니다.

충돌 해결 방법

C 언어에 대한 좋은 지식이 필요하기 때문에 모든 충돌을 해결하기 위한 단계별 가이드를 제공할 수는 없지만 몇 가지 힌트가 있습니다.

병합하는 경우 충돌을 일으키는 커밋을 파악하십시오. 다음 두 가지 방법 중 하나를 수행할 수 있습니다.

  1. git log -p v$(make kernelversion).. 현재 버전과 업스트림의 최신 버전 간의 변경 사항을 가져옵니다. -p 플래그는 각 커밋에 의해 수행된 변경 사항을 제공하므로 볼 수 있습니다.
  2. 파일에 대해 gitblame을 실행하여 해당 영역의 각 커밋에 대한 해시를 가져옵니다. 그런 다음 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-stable kernel.org 저장소의 미러입니다. 충돌 해결을 위해 커밋 목록과 diff를 찾는 것이 더 쉬울 수 있습니다. 먼저 커밋 목록 보기로 이동하고 문제 커밋을 찾아 원본 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$(커널버전 만들기)..$(git tag --sort=-taggerdate -l v$(커널버전 만들기 | cut -d . -f 1,2)* | 헤드 -n1) 

다시 사용 설정

Git에는 rerere(Reuse Recorded Resolution의 약자)라는 기능이 있습니다. 즉, 충돌을 감지하면 나중에 재사용할 수 있도록 해결 방법을 기록합니다. git add 만 실행하면 되므로 병합 및 선택을 모두 포함하는 만성 리베이스러 모두에 특히 유용합니다. &&git –업스트림 불러오기를 다시 실행할 때 이전에 해결했던 방식으로 충돌이 해결되므로 계속하세요.

커널 리포지토리에서 다음 명령을 실행하여 활성화할 수 있습니다.

git config rerere.enabled true

컴파일러 또는 런타임 오류가 발생할 때 git bisect를 실행하는 방법

상당한 수의 커밋을 추가할 것이라는 점을 감안할 때 컴파일러 또는 런타임 오류가 발생할 가능성이 매우 높습니다. 그냥 포기하는 대신 git의 내장 bisect 도구를 사용하여 문제의 근본 원인을 파악할 수 있습니다! 이상적으로는 추가할 때 모든 단일 커널 버전을 빌드하고 플래시하므로 필요한 경우 이등분하는 데 시간이 덜 걸리지만 문제 없이 5000개 커밋을 이등분할 수 있습니다.

git bisect가 하는 일은 문제가 있는 곳부터 문제가 없는 곳까지 커밋 범위를 취한 다음 커밋 범위를 절반으로 줄이기 시작하여 빌드 및 테스트하고 좋은지 여부를 알릴 수 있도록 하는 것입니다. . 문제를 일으키는 커밋을 뱉을 때까지 이 작업을 계속합니다. 이 시점에서 수정하거나 되돌릴 수 있습니다.

  1. 이등분하기 시작: git bisect start
  2. 현재 버전에 잘못된 라벨 지정: git bisect bad
  3. 수정본에 좋은 라벨 지정: git bisect good
  4. 새 버전으로 빌드
  5. 결과에 따라(문제가 있는지 여부) git에게 다음과 같이 알립니다. git bisect good 또는 git bisect bad
  6. 문제 커밋이 발견될 때까지 4-5단계를 헹구고 반복합니다!
  7. 문제 커밋을 되돌리거나 수정합니다.

참고: 적절한 이등분을 위해 모든 패치를 분기에 적용하려면 병합을 일시적으로 실행해야 합니다. 병합을 사용하여 이등분하면 종종 업스트림 커밋을 체크아웃하므로 Android 전용 커밋이 없습니다. . 요청 시 이에 대해 더 자세히 설명할 수 있지만 저를 믿으십시오. 필요합니다. 문제 커밋을 식별하면 병합으로 되돌리거나 리베이스할 수 있습니다.

업스트림 업데이트를 스쿼시하지 마십시오.

많은 신규 개발자들이 "더 깨끗하고" 관리하기 쉽기 때문에 이 작업을 하고 싶어합니다. 이것은 몇 가지 이유로 끔찍합니다.

  • 저작권이 상실되었습니다. 다른 개발자들이 자신의 작업에 대해 크레딧을 박탈당하는 것은 불공평합니다.
  • 이등분은 불가능합니다. 일련의 커밋을 스쿼시하고 해당 시리즈에 문제가 있는 경우 스쿼시에서 어떤 커밋이 문제를 일으켰는지 말할 수 없습니다.
  • 미래의 체리픽은 더 어렵다. 찌그러진 시리즈로 리베이스해야 하는 경우 충돌이 어디에서 발생하는지 말하기가 어렵거나 불가능합니다.

적시 업데이트를 위해 Linux 커널 메일링 리스트에 가입

업스트림 업데이트가 있을 때마다 알림을 받으려면 linux-kernel-announce list를 구독하세요. . 이렇게 하면 새 커널이 출시될 때마다 이메일을 받을 수 있으므로 최대한 빨리 업데이트하고 푸시할 수 있습니다.