Computer >> คอมพิวเตอร์ >  >> การแก้ไขปัญหา >> Android

วิธีอัปเดตเคอร์เนล Android ของคุณเป็น Linux Stable ล่าสุด

เราได้กล่าวถึงคำแนะนำเกี่ยวกับเคอร์เนลของ Android เช่น “วิธีสร้างเคอร์เนลที่กำหนดเอง” และ “เคอร์เนลที่กำหนดเองที่ดีที่สุดสำหรับ Android” แต่วันนี้เราจะแสดงวิธีอัปสตรีมเคอร์เนลของคุณเทียบกับความเสถียรล่าสุดของ Linux

โปรดทราบว่านี่เป็น ขั้นสูง เนื้อหา – หากคุณไม่เคยคอมไพล์เคอร์เนลมาก่อน คุณควรทำตามคำแนะนำ “วิธีสร้างเคอร์เนลแบบกำหนดเอง” ที่ลิงก์ด้านบน และคู่มือนี้จะเกี่ยวข้องกับการเลือกเชอร์รี่และการรวมคอมมิตจากเคอร์เนลที่เสถียรของ Linux ล่าสุดกับเคอร์เนล Android ของคุณ ก่อนที่คุณจะคอมไพล์มัน

การอัพสตรีมเคอร์เนล Android ของคุณเป็น Linux เสถียรล่าสุดมีประโยชน์เชิงบวกมากมาย เช่น การอัปเดตความปลอดภัยและการแก้ไขข้อบกพร่องล่าสุด เราจะอธิบายข้อดีและข้อเสียในคู่มือนี้ในภายหลัง

เคอร์เนล Linux-Stable คืออะไร

วิธีอัปเดตเคอร์เนล Android ของคุณเป็น Linux Stable ล่าสุด

ลินุกซ์เสถียรตามชื่อคือแขนเสถียรของเคอร์เนลลินุกซ์ แขนอีกข้างหนึ่งเรียกว่า “mainline” ซึ่งเป็น master branch . การพัฒนาเคอร์เนล Linux ทั้งหมดเกิดขึ้นใน mainline และโดยทั่วไปจะเป็นไปตามกระบวนการนี้:

  1. Linus Torvalds จะใช้เวลาสองสัปดาห์ในการปะแก้จากผู้ดูแลของเขา
  2. หลังจากสองสัปดาห์นี้ เขาเผยแพร่เคอร์เนล rc1 (เช่น 4.14-rc1)
  3. ในแต่ละสัปดาห์สำหรับ 6-8 สัปดาห์ข้างหน้า เขาจะปล่อยเคอร์เนล RC ใหม่ (เช่น 4.14-rc2, 4.14-rc3 เป็นต้น) ซึ่งมีเฉพาะการแก้ไขข้อผิดพลาดและการถดถอย
  4. เมื่อถือว่าเสถียรแล้ว ก็จะปล่อยเป็น tarball เพื่อดาวน์โหลดในองค์กร (เช่น 4.14)

เมล็ด LTS คืออะไร

ทุกปี Greg จะเลือกเคอร์เนลหนึ่งตัวและคงไว้เป็นเวลาสองปี (LTS) หรือหกปี (ขยาย LTS) สิ่งเหล่านี้ได้รับการออกแบบให้มีผลิตภัณฑ์ที่ต้องการความเสถียร (เช่น โทรศัพท์ Android หรืออุปกรณ์ IOT อื่นๆ) กระบวนการนี้เหมือนกันทุกประการกับข้างต้น เพียงแค่เกิดขึ้นเป็นเวลานานขึ้น ขณะนี้มีเคอร์เนล LTS อยู่ 6 รายการ (ซึ่งสามารถดูได้ที่หน้าเผยแพร่ 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 แต่นั่นไม่ได้รับประกันว่าจะไม่มีข้อขัดแย้งจากไฟล์เหล่านั้นเมื่อรวมเวอร์ชันใหม่เข้าด้วยกัน! เข้าใจว่าแทบ ไม่มีใคร สร้างทุกส่วนของเคอร์เนล ไม่แม้แต่ distros ของ Linux ทั่วไปเช่น Ubuntu หรือ Mint ไม่ได้หมายความว่าคุณไม่ควรแก้ไขเพราะมี แก้ไขไดรเวอร์ที่คุณ ทำ วิ่ง. ยกตัวอย่าง arm/arm64 และ ext4 ซึ่งเป็นสถาปัตยกรรมและระบบไฟล์ Android ที่พบบ่อยที่สุดตามลำดับ ใน 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 arch/arm | 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 | wc -l18

ส่วนที่ใช้เวลานานที่สุดคือการนำเสนอครั้งแรก เมื่อคุณได้รับข้อมูลล่าสุดแล้ว ก็ไม่ต้องใช้เวลาในการรวมเข้ากับรีลีสใหม่ ซึ่งมักจะมีการคอมมิตไม่เกิน 100 รายการ ประโยชน์ที่ได้รับ (ความเสถียรและความปลอดภัยที่ดีขึ้นสำหรับผู้ใช้ของคุณ) ควรทำให้กระบวนการนี้มีความจำเป็น

วิธีการผสานเคอร์เนลที่เสถียรของ Linux เข้ากับเคอร์เนลของ Android

ก่อนอื่น คุณต้องหาว่าอุปกรณ์ Android ของคุณใช้เคอร์เนลเวอร์ชันใด

แม้จะดูเล็กน้อย แต่คุณจำเป็นต้องรู้ว่าต้องเริ่มตรงไหน เรียกใช้คำสั่งต่อไปนี้ในแผนผังเคอร์เนลของคุณ:

สร้างเคอร์เนลเวอร์ชัน

มันจะคืนค่าเวอร์ชันที่คุณใช้อยู่กลับคืนมา ตัวเลขสองตัวแรกจะใช้เพื่อค้นหาสาขาที่คุณต้องการ (เช่น linux-4.4.y สำหรับเคอร์เนล 4.4 ใดๆ) และหมายเลขสุดท้ายจะถูกนำมาใช้เพื่อกำหนดเวอร์ชันที่คุณต้องการเพื่อเริ่มต้นการรวม (เช่น ถ้าคุณใช้ 4.4 .21 คุณจะรวม 4.4.22 ต่อไป)

คว้าเคอร์เนลที่มาล่าสุดจาก kernel.org

kernel.org มีแหล่งเคอร์เนลล่าสุดในที่เก็บ linux-stable ที่ด้านล่างของหน้านั้น จะมีลิงก์ดึงข้อมูลสามลิงก์ จากประสบการณ์ของผม กระจกของ Google มักจะเร็วที่สุดแต่ผลลัพธ์ของคุณอาจแตกต่างกันไป เรียกใช้คำสั่งต่อไปนี้:

git remote add linux-stable https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit fetch linux-stable

ตัดสินใจว่าคุณต้องการรวมเคอร์เนลทั้งหมดหรือเลือกการคอมมิตของเชอร์รี่

ถัดไป คุณจะต้องเลือกว่าต้องการผสานการคอมมิตหรือเลือกเชอร์รี่ นี่คือข้อดีและข้อเสียของแต่ละรายการและเวลาที่คุณอาจต้องการทำ

หมายเหตุ: หากต้นทางเคอร์เนลของคุณอยู่ในรูปของ tarball คุณมักจะต้องเลือกแบบเชอร์รี่ มิฉะนั้น คุณจะได้รับข้อขัดแย้งของไฟล์นับพันเพราะ git กำลังเติมประวัติโดยอิงจากอัปสตรีมล้วนๆ ไม่ใช่สิ่งที่ OEM หรือ CAF เปลี่ยนแปลง เพียงข้ามไปยังขั้นตอนที่ 4

เก็บเชอร์รี่:

ข้อดี:

  • แก้ไขข้อขัดแย้งได้ง่ายกว่า เพราะคุณรู้ดีว่าข้อขัดแย้งอะไรทำให้เกิดปัญหา
  • รีเบสได้ง่ายกว่าเพราะแต่ละคอมมิทเป็นของตัวเอง
  • แบ่งครึ่งได้ง่ายขึ้นหากพบปัญหา

ข้อเสีย:

  • ใช้เวลานานขึ้นเนื่องจากต้องเลือกการคอมมิตแต่ละรายการแยกกัน
  • ดูยากขึ้นเล็กน้อยว่าคอมมิตมาจากอัปสตรีมในแวบแรกหรือไม่

ผสาน

ข้อดี :

  • เร็วกว่าเพราะคุณไม่จำเป็นต้องรอให้แพตช์สะอาดทั้งหมดรวมเข้าด้วยกัน
  • มองเห็นได้ง่ายขึ้นเมื่อคอมมิตมาจากอัปสตรีม เนื่องจากคุณจะไม่เป็นผู้คอมมิต แต่ผู้ดูแลอัปสตรีมจะเป็น

ข้อเสีย:

  • การแก้ไขข้อขัดแย้งอาจทำได้ยากขึ้นเล็กน้อย เนื่องจากคุณจะต้องค้นหาว่าคอมมิตใดทำให้เกิดข้อขัดแย้งโดยใช้ git log/git กล่าวโทษ มันจะไม่บอกคุณโดยตรง
  • การรีเบสนั้นยากเพราะคุณไม่สามารถรีเบสการรวมได้ มันจะเสนอการเลือกคอมมิชชันทั้งหมดทีละรายการ อย่างไรก็ตาม คุณไม่ควรรีเบสบ่อย ๆ แทนที่จะใช้ git revert และ git merge หากเป็นไปได้

ฉันขอแนะนำให้ทำการเลือกแบบเชอร์รี่เพื่อหาข้อขัดแย้งของปัญหาในตอนแรก ทำการผสาน จากนั้นย้อนกลับปัญหาที่เกิดขึ้นในภายหลัง ดังนั้นการอัปเดตจึงง่ายขึ้น (เนื่องจากการผสานจะเร็วขึ้นหลังจากอัปเดตแล้ว)

เพิ่มการคอมมิตไปยังซอร์สของคุณ ทีละเวอร์ชัน

ส่วนที่สำคัญที่สุดของกระบวนการนี้คือส่วนเดียวในแต่ละครั้ง อาจมีโปรแกรมแก้ไขปัญหาในซีรีย์อัปสตรีมของคุณ ซึ่งอาจทำให้เกิดปัญหากับการบูทหรือทำลายบางสิ่ง เช่น เสียงหรือการชาร์จ (อธิบายไว้ในส่วนคำแนะนำและเคล็ดลับ) การเปลี่ยนแปลงเวอร์ชันส่วนเพิ่มมีความสำคัญด้วยเหตุนี้ การค้นหาปัญหาในการคอมมิต 50 ครั้งจะง่ายกว่าการคอมมิตมากกว่า 2,000 รายการสำหรับบางเวอร์ชัน ฉันขอแนะนำให้ทำการรวมทั้งหมดเมื่อคุณทราบปัญหาทั้งหมดที่เกิดขึ้นและการแก้ไขข้อขัดแย้ง

การเก็บเชอร์รี่

รูปแบบ:

git cherry-pick ..

ตัวอย่าง:

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

ผสาน

รูปแบบ:

การผสาน git 

ตัวอย่าง:

git ผสาน v3.10.74

ฉันแนะนำให้ติดตามข้อขัดแย้งในการคอมมิตการรวมโดยนำเครื่องหมาย # ออก

วิธีแก้ไขความขัดแย้ง

เราไม่สามารถให้คำแนะนำทีละขั้นตอนในการแก้ไขข้อขัดแย้งทุกข้อได้ เนื่องจากเกี่ยวข้องกับความรู้ภาษา C ที่ดี แต่นี่เป็นคำแนะนำเล็กน้อย

หากคุณกำลังรวมกิจการ ให้ค้นหาว่าการกระทำใดทำให้เกิดข้อขัดแย้ง คุณสามารถทำสิ่งนี้ได้สองวิธี:

  1. git log -p v$(make kernelversion).. เพื่อรับการเปลี่ยนแปลงระหว่างเวอร์ชันปัจจุบันและเวอร์ชันล่าสุดจากอัปสตรีม แฟล็ก -p จะแสดงการเปลี่ยนแปลงที่ทำโดยแต่ละคอมมิตเพื่อให้คุณเห็นได้
  2. เรียกใช้ git กล่าวโทษในไฟล์เพื่อรับแฮชของคอมมิตแต่ละรายการในพื้นที่ จากนั้นคุณสามารถเรียกใช้ git show –format=fuller เพื่อดูว่าคอมมิตมาจาก mainline/stable, Google หรือ CodeAurora หรือไม่
  • ค้นหาว่าคุณมีคอมมิตอยู่แล้วหรือไม่ ผู้ให้บริการบางราย เช่น Google หรือ CAF จะพยายามค้นหาจุดบกพร่องที่สำคัญในต้นทาง เช่น การแก้ไข Dirty COW และแบ็คพอร์ตของพวกเขาอาจขัดแย้งกับต้นน้ำ คุณสามารถเรียกใช้ git log –grep=”” และดูว่ามันส่งคืนอะไรหรือไม่ หากเป็นเช่นนั้น คุณสามารถข้ามการคอมมิตได้ (หากการเลือกเชอร์รี่โดยใช้ git reset –hard &&git cherry-pick –continue) หรือละเว้นข้อขัดแย้ง (ลบ <<<<<< และทุกอย่างระหว่าง =======และ >>>>>>)
  • ค้นหาว่ามีแบ็คพอร์ตที่ทำให้ความละเอียดเลอะเทอะหรือไม่ Google และ CAF ต้องการแบ็คพอร์ตแพตช์บางอย่างที่ไม่เสถียร ความเสถียรมักจะต้องปรับความละเอียดของ mainline ที่ส่งไปยังไม่มีแพตช์บางตัวที่ Google เลือกใช้แบ็คพอร์ต คุณสามารถดูการคอมมิต mainline ได้โดยการเรียกใช้ git show  (แฮชของ mainline จะมีอยู่ในข้อความคอมมิตของคอมมิตที่เสถียร) หากมีแบ็คพอร์ตมารบกวน คุณสามารถละทิ้งการเปลี่ยนแปลงหรือคุณสามารถใช้เวอร์ชันหลัก (ซึ่งเป็นสิ่งที่คุณจะต้องทำตามปกติ)
  • อ่านสิ่งที่คอมมิตพยายามทำ และดูว่าปัญหาได้รับการแก้ไขแล้วหรือไม่ บางครั้ง CAF อาจแก้ไขจุดบกพร่องโดยไม่ขึ้นกับอัปสตรีม ซึ่งหมายความว่าคุณสามารถเขียนทับการแก้ไขสำหรับอัปสตรีมหรือละทิ้งได้ เช่นเดียวกับด้านบน

มิเช่นนั้น อาจเป็นผลมาจากการเพิ่ม CAF/Google/OEM ซึ่งในกรณีนี้ คุณเพียงแค่ต้องสับเปลี่ยนบางสิ่งรอบๆ

นี่คือ มิเรอร์ของที่เก็บ linux-stable kernel.org บน GitHub ซึ่งง่ายกว่าสำหรับการค้นหารายการคอมมิตและส่วนต่างสำหรับการแก้ไขข้อขัดแย้ง ฉันแนะนำให้ไปที่มุมมองรายการการคอมมิตก่อน และค้นหาปัญหาที่คอมมิตเพื่อดูส่วนต่างดั้งเดิมเพื่อเปรียบเทียบกับปัญหาของคุณ

ตัวอย่าง URL: https://github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

คุณสามารถทำได้โดยใช้บรรทัดคำสั่ง:

บันทึก git .. git show 

การแก้ปัญหาเป็นเรื่องของบริบท สิ่งที่คุณควรทำเสมอคือตรวจสอบให้แน่ใจว่าส่วนต่างสุดท้ายของคุณตรงกับอัปสตรีมโดยเรียกใช้คำสั่งต่อไปนี้ในสองหน้าต่างแยกกัน:

git diff HEADgit diff v$(สร้าง kernelversion)..$(git tag --sort=-taggerdate -l v$(make kernelversion | cut -d . -f 1,2)* | head -n1) 

เปิดใช้งานการเล่นซ้ำ

Git มีคุณสมบัติที่เรียกว่า rerere (ย่อมาจาก Reuse Recorded Resolution) หมายความว่าเมื่อตรวจพบข้อขัดแย้ง มันจะบันทึกวิธีการแก้ไขของคุณ เพื่อให้คุณสามารถนำกลับมาใช้ใหม่ได้ในภายหลัง สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับทั้ง rebasers เรื้อรังที่มีทั้งการรวมและการเลือกเชอร์รี่ เนื่องจากคุณจะต้องเรียกใช้ git add &&git – ดำเนินการต่อเมื่อทำซ้ำการดึงอัพสตรีมเนื่องจากข้อขัดแย้งจะได้รับการแก้ไขว่าคุณแก้ไขอย่างไรก่อนหน้านี้

สามารถเปิดใช้งานได้โดยการรันคำสั่งต่อไปนี้ในเคอร์เนล repo ของคุณ:

git config rerere.enabled true

วิธี git bisect เมื่อรันคอมไพเลอร์หรือข้อผิดพลาดรันไทม์

เนื่องจากคุณจะเพิ่มคอมมิตจำนวนมาก จึงเป็นไปได้มากที่คุณจะแนะนำคอมไพเลอร์หรือข้อผิดพลาดรันไทม์ แทนที่จะยอมแพ้ คุณสามารถใช้เครื่องมือ bisect ในตัวของ git เพื่อหาสาเหตุของปัญหาได้! ตามหลักการแล้ว คุณจะต้องสร้างและแฟลชเคอร์เนลทุกเวอร์ชันเมื่อคุณเพิ่มเข้าไป ดังนั้นการแบ่งครึ่งจะใช้เวลาน้อยลงหากจำเป็น แต่คุณสามารถแบ่งครึ่ง 5,000 คอมมิทโดยไม่มีปัญหาใดๆ

สิ่งที่ 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  ชั่วคราวเพื่อใช้แพตช์ทั้งหมดกับสาขาของคุณสำหรับการแบ่งครึ่งที่เหมาะสม เนื่องจากการแบ่งออกเป็นสองส่วนด้วยการผสานเข้าที่มักจะมีการเช็คเอาต์บน upstream commit ซึ่งหมายความว่าคุณไม่มีคอมมิตเฉพาะของ Android . ฉันสามารถเจาะลึกเรื่องนี้ได้ตามคำขอ แต่เชื่อฉันเถอะ มันเป็นสิ่งจำเป็น เมื่อคุณระบุปัญหาแล้ว คุณสามารถเปลี่ยนกลับหรือเปลี่ยนกลับเป็นการรวมใหม่ได้

อย่าสควอชอัปเดตอัปสตรีม

นักพัฒนาใหม่จำนวนมากถูกล่อลวงให้ทำสิ่งนี้เนื่องจาก "สะอาดกว่า" และ "จัดการได้ง่ายขึ้น" สิ่งนี้แย่มากด้วยเหตุผลบางประการ:

  • เสียงานเขียน มันไม่ยุติธรรมสำหรับนักพัฒนาคนอื่นๆ ที่จะต้องเสียเครดิตสำหรับงานของพวกเขา
  • การผ่าครึ่งเป็นไปไม่ได้ หากคุณสควอชชุดของการคอมมิตและมีบางอย่างเป็นปัญหาในซีรีส์นั้น คุณจะไม่สามารถบอกได้ว่าคอมมิตใดทำให้เกิดปัญหาในสควอช
  • การเลือกเชอร์รี่ในอนาคตยากกว่า หากคุณต้องการรีเบสด้วยซีรีส์ที่ถูกบีบอัด เป็นการยาก/เป็นไปไม่ได้ที่จะบอกได้ว่าความขัดแย้งเกิดจากที่ใด

สมัครรับข่าวสารจากรายชื่อผู้รับจดหมายของเคอร์เนลของลินุกซ์สำหรับการอัปเดตตามเวลา

หากต้องการรับการแจ้งเตือนทุกครั้งที่มีการอัปเดตอัปสตรีม ให้สมัครรับ รายการ linux-kernel-announce . วิธีนี้จะช่วยให้คุณได้รับอีเมลทุกครั้งที่มีการเปิดตัวเคอร์เนลใหม่ คุณจึงสามารถอัปเดตและพุชได้โดยเร็วที่สุด