การย้าย Linux ไปยังข้อกำหนดแพลตฟอร์มอื่น [ปิด]


28

ฉันรู้ว่า Linux สามารถใช้งานได้และได้รับการจัดพอร์ตสำหรับแพลตฟอร์มที่แตกต่างกันเช่น X86, ARM, PowerPC เป็นต้น

อย่างไรก็ตามในแง่ของการพอร์ตสิ่งที่จำเป็นต้องมี?

ความเข้าใจของฉันคือว่า Linux เป็นซอฟต์แวร์ที่เขียนใน C. ดังนั้นเมื่อพอร์ต Linux เดิมจาก X86 ถึง ARM หรืออื่น ๆ มันไม่ได้เป็นเพียงเรื่องของการรวบรวมรหัสกับคอมไพเลอร์สำหรับสถาปัตยกรรมเป้าหมายที่เฉพาะเจาะจงอีกครั้ง?

วางไดรเวอร์อุปกรณ์สำหรับอุปกรณ์ต่อพ่วงที่แตกต่างกันสิ่งอื่น ๆ ที่จะต้องทำเมื่อย้ายพอร์ต Linux ไปยังสถาปัตยกรรมใหม่ คอมไพเลอร์ไม่ได้ดูแลทุกอย่างสำหรับเราหรือไม่?


11
เราสามารถสมมติว่าคุณดูที่แหล่งเคอร์เนลเฉพาะสถาปัตยกรรมได้หรือไม่ git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/…
Kusalananda

คำตอบ:


57

แม้ว่าโค้ดส่วนใหญ่ในเคอร์เนลลินุกซ์จะถูกเขียนด้วยภาษา C แต่ก็ยังมีอีกหลายส่วนของรหัสนั้นซึ่งเฉพาะเจาะจงกับแพลตฟอร์มที่ใช้งานและจำเป็นต้องคำนึงถึงสิ่งนั้น

ตัวอย่างหนึ่งของสิ่งนี้คือหน่วยความจำเสมือนซึ่งทำงานในลักษณะเดียวกันกับสถาปัตยกรรมส่วนใหญ่ (ลำดับชั้นของตารางหน้า) แต่มีรายละเอียดเฉพาะสำหรับแต่ละสถาปัตยกรรม (เช่นจำนวนของระดับในแต่ละสถาปัตยกรรมและเพิ่มขึ้นแม้ใน x86 ด้วย แนะนำชิปใหม่ที่มีขนาดใหญ่ขึ้น) โค้ดเคอร์เนล Linux แนะนำมาโครเพื่อจัดการกับการข้ามผ่านลำดับชั้นเหล่านี้ที่คอมไพเลอร์บนสถาปัตยกรรมที่มีตารางเพจในระดับน้อยลง (เพื่อให้โค้ดนั้นเขียนด้วย C แต่ให้รายละเอียดของสถาปัตยกรรม พิจารณา.)

พื้นที่อื่น ๆ มีความเฉพาะเจาะจงมากสำหรับแต่ละสถาปัตยกรรมและจำเป็นต้องจัดการด้วยรหัสเฉพาะส่วนโค้ง ส่วนใหญ่เกี่ยวข้องกับรหัสในภาษาแอสเซมบลีแม้ว่า ตัวอย่างคือ:

  • การสลับบริบท : การสลับบริบทเกี่ยวข้องกับการบันทึกค่าของการลงทะเบียนทั้งหมดสำหรับกระบวนการที่จะถูกสลับและคืนค่าการลงทะเบียนจากชุดที่บันทึกไว้ของกระบวนการที่กำหนดเวลาไว้ใน CPU แม้แต่จำนวนและชุดของรีจิสเตอร์ก็มีความเฉพาะในแต่ละสถาปัตยกรรม โดยทั่วไปรหัสนี้จะนำไปใช้ในการประกอบเพื่อให้สามารถเข้าถึงการลงทะเบียนได้อย่างเต็มที่และเพื่อให้แน่ใจว่ามันจะทำงานได้อย่างรวดเร็วที่สุดเนื่องจากประสิทธิภาพของการสลับบริบทอาจมีความสำคัญต่อระบบ

  • การเรียกใช้ระบบ : กลไกที่รหัสผู้ใช้สามารถเรียกใช้การเรียกระบบได้มักจะเฉพาะกับสถาปัตยกรรม (และบางครั้งแม้แต่กับซีพียูรุ่นที่เฉพาะเจาะจงเช่น Intel และ AMD แนะนำคำแนะนำที่แตกต่างกันสำหรับซีพียูรุ่นเก่าอาจขาดคำแนะนำเหล่านั้น สำหรับสิ่งเหล่านั้นจะยังคงไม่เหมือนใคร)

  • ตัวจัดการขัดจังหวะ : รายละเอียดของวิธีการจัดการการขัดจังหวะ (การขัดจังหวะฮาร์ดแวร์) มักจะเป็นแพลตฟอร์มเฉพาะและมักจะต้องมีกาวระดับการประกอบเพื่อจัดการประชุมเรียกเฉพาะที่ใช้สำหรับแพลตฟอร์ม นอกจากนี้ primitives สำหรับการเปิด / ปิดการใช้งานอินเตอร์รัปต์มักเป็นแบบเฉพาะแพลตฟอร์มและต้องการรหัสแอสเซมบลีเช่นกัน

  • การกำหนดค่าเริ่มต้น : รายละเอียดของวิธีการกำหนดค่าเริ่มต้นมักจะรวมถึงรายละเอียดที่เฉพาะเจาะจงกับแพลตฟอร์มและมักจะต้องมีรหัสแอสเซมบลีบางอย่างเพื่อจัดการจุดเข้าสู่เคอร์เนล บนแพลตฟอร์มที่มี CPU หลายตัว (SMP) รายละเอียดเกี่ยวกับวิธีนำ CPU อื่น ๆ ออนไลน์นั้นมักจะใช้เฉพาะแพลตฟอร์มเช่นกัน

  • การล็อกแบบดั้งเดิม : การใช้งานการล็อกแบบดั้งเดิม (เช่น spinlocks) มักจะเกี่ยวข้องกับรายละเอียดเฉพาะแพลตฟอร์มเช่นกันเนื่องจากสถาปัตยกรรมบางอย่างให้ (หรือต้องการ) คำสั่ง CPU ที่แตกต่างกันเพื่อนำไปใช้อย่างมีประสิทธิภาพ บางตัวจะใช้การทำงานแบบปรมาณูซึ่งบางตัวจะมี cmpxchg ที่สามารถทดสอบ / อัปเดตแบบอะตอมมินิ (แต่ล้มเหลวหากมีนักเขียนคนอื่นเข้ามาก่อน) ส่วนคนอื่น ๆ จะมีตัวดัดแปลง "ล็อค" เป็นคำสั่ง CPU สิ่งเหล่านี้มักจะเกี่ยวข้องกับการเขียนรหัสแอสเซมบลีเช่นกัน

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

บางคนน่าแปลกใจจริงตัวอย่างเช่นคุณจะเห็นว่าจำนวนการโทรของระบบที่มีอยู่ในแต่ละสถาปัตยกรรมนั้นแตกต่างกันและการโทรของระบบบางอย่างจะมีอยู่ในสถาปัตยกรรมบางอย่าง (แม้ใน x86 รายการ syscalls จะแตกต่างกันระหว่างเคอร์เนลแบบ 32 บิตและ 64 บิต)

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


7
เขียนดีมาก! การเปลี่ยนแปลงในจำนวนของ syscalls ส่วนใหญ่เกี่ยวข้องกับประวัติ: พอร์ตใหม่รวมถึง syscalls ที่ถูกต้องในเวลาที่พอร์ตพวกเขาไม่รำคาญกับกระเป๋าประวัติศาสตร์ที่มีอยู่ในพอร์ตที่มีอายุมากกว่าดังนั้น syscalls คัดค้านมักจะไม่ปรากฏในพอร์ต ใหม่กว่าการคัดค้าน (นั่นไม่ครอบคลุมทุกสถานการณ์ ... )
Stephen Kitt

10

นอกเหนือจากการย้ายเคอร์เนล Linux คุณจะต้องกำหนดapplication binary interface (ABI) สำหรับโปรแกรม "พื้นที่ผู้ใช้" และพอร์ตเลเยอร์ต่ำสุดของสแต็กซอฟต์แวร์พื้นที่ผู้ใช้ โดยทั่วไปแล้ว Linux จะใช้กับส่วนประกอบพื้นที่ผู้ใช้ระดับต่ำจากโครงการ GNU ซึ่งสำคัญที่สุดคือ:

  • คอมไพเลอร์ C, ประกอบและลิงเกอร์: GCCและGNU binutils สำหรับสถาปัตยกรรม CPU ใหม่ทั้งหมดคุณต้องพอร์ตซอฟต์แวร์นี้ก่อนที่คุณจะเริ่มย้ายเคอร์เนลเนื่องจากเคอร์เนลเป็นโปรแกรม C และต้องถูกคอมไพล์ หากมีการสนับสนุน "แบ็คเอนด์" สำหรับซีพียูของแพลตฟอร์มอยู่แล้วไม่ใช่กับ Linux ในฐานะเคอร์เนลระบบปฏิบัติการคุณมีงานที่ต้องทำน้อยกว่ามากและคุณอาจไม่สามารถเลื่อนงานส่วนใหญ่ไปได้จนกว่าเคอร์เนลจะทำงานและ วิ่ง.
  • ไลบรารีรันไทม์ C: " GNU libc " ไลบรารีนี้รวมถึงรหัสที่ทำให้การโทรของระบบและติดต่อโดยตรงกับเคอร์เนล
  • ไลบรารี่ "foreign function interface" libffiซึ่งเป็นส่วนประกอบสำคัญของล่ามภาษาระดับสูงจำนวนมากและทำงานหนึ่งในงานที่เหลือไม่กี่งานที่ต้องใช้ภาษาแอสเซมบลีที่เขียนด้วยมือจำนวนเล็กน้อย

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


1

คุณต้องบอกเคอร์เนลเกี่ยวกับฮาร์ดแวร์ที่คุณพอร์ต หน้าที่ของเคอร์เนลคือการเชื่อมต่อโดยตรงกับฮาร์ดแวร์ดังนั้นเพื่อให้มันทำงานได้อย่างถูกต้องเคอร์เนลจำเป็นต้องรู้เกี่ยวกับ CPU ออสซิลเลเตอร์ (นาฬิกา) และอุปกรณ์ต่อพ่วงใด ๆ เช่นพอร์ตอนุกรมต่างๆ (SPI, CAN, I2C เป็นต้น)

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.