เคอร์เนลลินุกซ์สามารถคอมไพล์ตัวเองได้อย่างไร?


89

ฉันไม่ค่อยเข้าใจกระบวนการคอมไพล์ของเคอร์เนล Linux เมื่อฉันติดตั้งระบบ Linux บนเครื่องของฉัน

นี่คือบางสิ่งที่ทำให้ฉันสับสน:

  1. เคอร์เนลถูกเขียนด้วย C อย่างไรก็ตามเคอร์เนลถูกคอมไพล์โดยไม่ติดตั้งคอมไพเลอร์ได้อย่างไร?
  2. หากคอมไพเลอร์ C ถูกติดตั้งบนเครื่องของฉันก่อนที่จะคอมไพล์เคอร์เนลคอมไพเลอร์จะรวบรวมเองได้อย่างไรโดยไม่ต้องติดตั้งคอมไพเลอร์

ฉันสับสนมากสองสามวันขอบคุณสำหรับการตอบกลับ


เท่าที่ทราบ C-compiler เขียนด้วย assambler บางประเภทโดยคนบ้าและฉลาดที่ห้องปฏิบัติการ AT&T เพื่อรวบรวม UNIX สำหรับคอมพิวเตอร์เครื่องหนึ่ง (โปรดทราบว่าประวัติศาสตร์เริ่มต้นด้วย UNIX ไม่ใช่ linux ดังนั้นฉันกลัวคุณ พลาดบท ... หรือหลายบท!) เรื่องสั้นคือไม่จำเป็นต้องเขียนเคอร์เนล unix ใหม่สำหรับคอมพิวเตอร์ differents ตราบใดที่คอมพิวเตอร์เหล่านั้นมีคอมไพเลอร์ที่เหมาะสมสำหรับภาษา C คอมไพเลอร์เหล่านั้นถูกเขียนใน Assambler เฉพาะของคอมพิวเตอร์เป้าหมาย พูดคร่าวๆว่า "คอมไพเลอร์ตัวแรกเขียนใน assambler ของคอมพิวเตอร์ที่กำหนดจากนั้น UNIX เขียนด้วยภาษา C"
วิกเตอร์

คำตอบ:


208

ไบนารีรอบแรกสำหรับกล่อง Linux ของคุณถูกสร้างขึ้นบนกล่อง Linux อื่น ๆ (อาจ)

ไบนารีสำหรับระบบลินุกซ์ตัวแรกถูกสร้างขึ้นบนแพลตฟอร์มอื่น

ไบนารีสำหรับคอมพิวเตอร์นั้นสามารถติดตามรูทของพวกเขากลับไปยังระบบดั้งเดิมที่สร้างบนแพลตฟอร์มอื่นได้

...

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

...

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

สิ่งที่เจ๋งมาก

กฎคือ "สร้างเครื่องมือเพื่อสร้างเครื่องมือเพื่อสร้างเครื่องมือ ... " เช่นเดียวกับเครื่องมือที่ใช้สภาพแวดล้อมทางกายภาพของเรา หรือที่เรียกว่า "ดึงตัวเองขึ้นมาด้วย bootstraps"


3
ไม่จำเป็นต้องเป็นมลทิน ยังไม่ได้เพิ่มประสิทธิภาพ คอมไพเลอร์ตัวแรกจะได้รับการปรับให้ทำงานบน 386 แต่เวอร์ชันที่คอมไพล์ใหม่จะปรับให้เหมาะกับสถาปัตยกรรมใด ๆ ที่คุณมี
Breton

1
คุณสามารถเพิ่มขั้นตอนที่สามได้หากทุกอย่างเรียบร้อยเอาต์พุตขั้นที่สองควรเท่ากับเอาต์พุตของขั้นตอนที่สาม
อิสมาเอล

27
ไม่ใช่แค่ซอฟต์แวร์ แต่เป็นฮาร์ดแวร์ด้วย ไม่มีทางที่จะสร้าง P4 (หรือ 486) ได้โดยไม่ใช้คอมพิวเตอร์
BCS

1
@BCS: อ๋อใช่ เรามาถึงจุดที่ซอฟต์แวร์และเครื่องมือฮาร์ดแวร์เชื่อมโยงกันอย่างลึกซึ้งและพึ่งพาซึ่งกันและกัน
dmckee --- อดีตผู้ดูแลลูกแมว

4
"ระบบที่ซับซ้อนที่ใช้งานได้มักจะพบว่ามีวิวัฒนาการมาจากระบบง่ายๆที่ใช้งานได้" en.wikipedia.org/wiki/Gall's_law
ajuc

33

ฉันคิดว่าคุณควรแยกแยะระหว่าง:

รวบรวมวี: ในการใช้คอมไพเลอร์ซอร์สโค้ดกระบวนการและผลิตรหัสปฏิบัติการ[1]

และ

ติดตั้งโวลต์: เพื่อเชื่อมต่อการตั้งค่าหรือเตรียมความพร้อมสำหรับการใช้งานบางสิ่งบางอย่าง[2]

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

ตอนนี้คำถามของคุณ:

  1. เคอร์เนลถูกเขียนด้วย C อย่างไรก็ตามเคอร์เนลถูกคอมไพล์โดยไม่ติดตั้งคอมไพเลอร์ได้อย่างไร?

ไม่สามารถคอมไพล์เคอร์เนลได้หากไม่มีคอมไพเลอร์ แต่สามารถติดตั้งได้จากไบนารีที่คอมไพล์

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

แม้ในการแจกแจงแบบ "ตามแหล่งที่มา" เช่น gentoo คุณเริ่มต้นจากการเรียกใช้ไบนารีที่คอมไพล์แล้ว

ดังนั้นคุณสามารถมีชีวิตอยู่ได้ตลอดชีวิตโดยไม่ต้องรวบรวมเมล็ดเพราะคุณมีคนอื่นรวบรวมไว้

  1. หากคอมไพเลอร์ C ถูกติดตั้งบนเครื่องของฉันก่อนที่จะคอมไพล์เคอร์เนลคอมไพเลอร์จะรวบรวมเองได้อย่างไรโดยไม่ต้องติดตั้งคอมไพเลอร์

ไม่สามารถรันคอมไพเลอร์ได้หากไม่มีเคอร์เนล (OS) ดังนั้นเราจึงต้องติดตั้งเคอร์เนลที่คอมไพล์เพื่อรันคอมไพเลอร์ แต่ไม่จำเป็นต้องคอมไพล์เคอร์เนลด้วยตัวเอง

อีกครั้งวิธีปฏิบัติที่พบบ่อยที่สุดคือการติดตั้งไบนารีที่คอมไพเลอร์ของคอมไพเลอร์และใช้เพื่อรวบรวมสิ่งอื่นใด (รวมถึงตัวคอมไพเลอร์เองและเคอร์เนล)

ตอนนี้ปัญหาไก่กับไข่ ไบนารีแรกถูกรวบรวมโดยบุคคลอื่น ... ดูคำตอบที่ยอดเยี่ยมโดย dmckee


14

คำที่อธิบายปรากฏการณ์นี้คือbootstrappingเป็นแนวคิดที่น่าสนใจที่จะอ่านต่อไป หากคุณคิดถึงการพัฒนาแบบฝังจะเห็นได้ชัดว่าอุปกรณ์จำนวนมากเช่นนาฬิกาปลุกไมโครเวฟรีโมทคอนโทรลที่ต้องใช้ซอฟต์แวร์นั้นไม่มีประสิทธิภาพเพียงพอที่จะรวบรวมซอฟต์แวร์ของตนเอง ในความเป็นจริงอุปกรณ์ประเภทนี้มักไม่มีทรัพยากรเพียงพอที่จะเรียกใช้งานจากระยะไกลที่ซับซ้อนเหมือนคอมไพเลอร์

ซอฟต์แวร์ของพวกเขาได้รับการพัฒนาบนเครื่องเดสก์ท็อปแล้วคัดลอกเมื่อได้รับการคอมไพล์แล้ว

หากสิ่งนี้ทำให้คุณสนใจบทความที่อยู่ในใจของฉันคือ: Reflections on Trusting Trust ( pdf ) มันเป็นเรื่องคลาสสิกและอ่านสนุก


1
คุณกำลังสับสนระหว่างการคอมไพล์ข้ามกับ bootstrapping อย่างแรกเกี่ยวข้องกับคอมไพเลอร์ที่มีอยู่บนพีซีเท่านั้นและสร้างรหัสสำหรับสถาปัตยกรรมเป้าหมาย เห็นได้ชัดว่าคุณไม่สามารถทำสิ่งนั้นได้หากไม่มีคอมพิวเตอร์เครื่องอื่นดังนั้นจึงมีปัญหาเรื่องไก่กับไข่ คำตอบสำหรับภาวะที่กลืนไม่เข้าคายไม่ออกคือ bootstrapping ซึ่งใช้คอมไพเลอร์แบบง่ายที่เขียนด้วยลายมือหรือที่มีมาก่อนเพื่อสร้างคอมไพเลอร์ที่ซับซ้อนมากขึ้น
Kevin Vermeer

12

เคอร์เนลไม่ได้รวบรวมตัวเอง - รวบรวมโดยคอมไพเลอร์ C ใน userspace ในสถาปัตยกรรม CPU ส่วนใหญ่ CPU จะมีจำนวนบิตในรีจิสเตอร์พิเศษที่แสดงถึงสิทธิพิเศษที่โค้ดที่รันอยู่ในปัจจุบัน ใน x86 เป็นบิตระดับสิทธิ์ปัจจุบัน (CPL) ในการลงทะเบียนส่วนรหัส (CS) ถ้าบิต CPL มี 00 รหัสกล่าวจะทำงานในแหวนรักษาความปลอดภัย 0ยังเป็นที่รู้จักในโหมดเคอร์เนล ถ้าบิต CPL มี 11 รหัสกล่าวจะทำงานในแหวนรักษาความปลอดภัย 3ยังเป็นที่รู้จักโหมดผู้ใช้ อีกสองชุดค่าผสม 01 และ 10 (วงแหวนรักษาความปลอดภัย 1 และ 2 ตามลำดับ) แทบจะไม่ถูกใช้

กฎเกี่ยวกับสิ่งที่โค้ดทำได้และไม่สามารถทำได้ในโหมดผู้ใช้เทียบกับโหมดเคอร์เนลนั้นค่อนข้างซับซ้อน แต่พอจะพูดได้ว่าโหมดผู้ใช้มีสิทธิ์ลดลงอย่างมาก

ตอนนี้เมื่อผู้คนพูดถึงเคอร์เนลของระบบปฏิบัติการพวกเขาอ้างถึงส่วนของโค้ดของระบบปฏิบัติการที่ทำงานในโหมดเคอร์เนลด้วยสิทธิ์ที่สูงขึ้น โดยทั่วไปผู้เขียนเคอร์เนลพยายามทำให้เคอร์เนลมีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้เพื่อเหตุผลด้านความปลอดภัยดังนั้นรหัสที่ไม่ต้องการสิทธิ์พิเศษจึงไม่มี

คอมไพเลอร์ C เป็นตัวอย่างหนึ่งของโปรแกรมดังกล่าว - ไม่จำเป็นต้องมีสิทธิพิเศษพิเศษที่เสนอโดยโหมดเคอร์เนลดังนั้นจึงทำงานในโหมดผู้ใช้เช่นเดียวกับโปรแกรมอื่น ๆ ส่วนใหญ่

ในกรณีของ Linux เคอร์เนลประกอบด้วยสองส่วนคือซอร์สโค้ดของเคอร์เนลและไฟล์ปฏิบัติการที่คอมไพล์แล้วของเคอร์เนล เครื่องใด ๆ ที่มีคอมไพเลอร์ C สามารถคอมไพล์เคอร์เนลจากซอร์สโค้ดลงในรูปไบนารี คำถามคือจะทำอย่างไรกับภาพไบนารีนั้น

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

หากคุณต้องการคอมไพล์เคอร์เนลของคุณใหม่นั่นเป็นเรื่องที่ยุ่งยากกว่าเล็กน้อย แต่ก็สามารถทำได้


5

มีอันไหนก่อน ไก่หรือไข่?

ไข่มีมาตั้งแต่สมัยไดโนเสาร์ ..

.. บางคนสับสนทุกอย่างโดยบอกว่าแท้จริงแล้วไก่เป็นลูกหลานของสัตว์ร้าย .. เรื่องยาวสั้น ๆ : เทคโนโลยี (ไข่) มีอยู่ก่อนผลิตภัณฑ์ปัจจุบัน (ไก่)

คุณต้องมีเคอร์เนลเพื่อสร้างเคอร์เนลกล่าวคือคุณสร้างเคอร์เนลขึ้นมา

เคอร์เนลแรกสามารถเป็นอะไรก็ได้ที่คุณต้องการ(ควรเป็นสิ่งที่สมเหตุสมผลที่สามารถสร้าง end product ที่คุณต้องการได้ ^ __ ^)

บทช่วยสอนจากการพัฒนาเคอร์เนลของ Branสอนให้คุณพัฒนาและสร้างเคอร์เนลขนาดเล็กซึ่งคุณสามารถทดสอบกับเครื่องเสมือนที่คุณเลือกได้

ความหมาย: คุณเขียนและรวบรวมเคอร์เนลที่ไหนสักแห่งและอ่านบนเครื่องเสมือนที่ว่างเปล่า (ไม่มีระบบปฏิบัติการ)

สิ่งที่เกิดขึ้นกับการติดตั้ง Linux เหล่านั้นเป็นไปตามแนวคิดเดียวกันพร้อมกับความซับซ้อน


5

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

ฉันคิดว่าเคอร์เนล Linux ตัวแรกถูกรวบรวมไว้ในกล่อง Minix แม้ว่าฉันจะไม่แน่ใจในเรื่องนั้น GCC มีให้บริการในเวลานั้น เป้าหมายแรกเริ่มของระบบปฏิบัติการหลายระบบคือการรันคอมไพเลอร์ให้ดีพอที่จะคอมไพล์ซอร์สโค้ดของตัวเอง ยิ่งไปกว่านั้นคอมไพเลอร์ตัวแรกมักเขียนด้วยภาษาแอสเซมบลี แอสเซมเบลอร์แรกถูกเขียนขึ้นโดยคนยากจนที่ต้องเขียนโค้ดเครื่องดิบ

คุณอาจต้องการที่จะตรวจสอบลินุกซ์ตั้งแต่เริ่มต้นโครงการ คุณสร้างระบบสองระบบในหนังสือเล่มนี้: "ระบบชั่วคราว" ที่สร้างขึ้นจากระบบที่คุณไม่ได้สร้างขึ้นเองจากนั้น "ระบบ LFS" ที่สร้างขึ้นบนระบบชั่วคราวของคุณ วิธีการเขียนหนังสือในปัจจุบันคุณสร้างระบบชั่วคราวบนกล่อง Linux อื่น แต่ในทางทฤษฎีคุณสามารถปรับให้เข้ากับระบบชั่วคราวบนระบบปฏิบัติการที่แตกต่างกันโดยสิ้นเชิง


1

หากฉันเข้าใจคำถามของคุณอย่างถูกต้อง วันนี้เคอร์เนลไม่ได้ "รวบรวมตัวเอง" ลินุกซ์ส่วนใหญ่ในปัจจุบันมีการติดตั้งระบบผ่าน linux live cd เคอร์เนลถูกโหลดจากซีดีลงในหน่วยความจำและทำงานตามปกติราวกับว่ามีการติดตั้งลงในดิสก์ ด้วยสภาพแวดล้อมลินุกซ์ที่ทำงานบนระบบของคุณคุณสามารถส่งไฟล์ที่จำเป็นไปยังดิสก์ได้อย่างง่ายดาย

หากคุณกำลังพูดถึงปัญหา bootstrapping; dmckee สรุปออกมาได้ดีทีเดียว

แค่เสนอความเป็นไปได้อื่น...

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