เคอร์เนลจะเมาต์พาร์ติชั่นรูทอย่างไร?


29

คำถามของฉันเกี่ยวกับการบูทระบบ Linux จากพาร์ติชั่น / บูตแยกต่างหาก หากไฟล์การตั้งค่าส่วนใหญ่อยู่บนพาร์ติชั่น / พาร์ติชั่นเคอร์เนลจะทำการเมาท์อย่างถูกต้องได้อย่างไรในเวลาบูท?

รายละเอียดเกี่ยวกับเรื่องนี้จะดีมาก ฉันรู้สึกว่าฉันขาดอะไรบางอย่างพื้นฐานไป ฉันส่วนใหญ่เกี่ยวข้องกับกระบวนการและคำสั่งของการดำเนินงาน

ขอบคุณ!

แก้ไข: ฉันคิดว่าสิ่งที่ฉันต้องถามมีมากกว่าตามบรรทัดของไฟล์ dev ที่ใช้ในพารามิเตอร์รูตเคอร์เนล ตัวอย่างเช่นสมมติว่าฉันให้รูทพารามิเตอร์ของฉันเป็นรูท / dev / sda2 เคอร์เนลมีการแม็พไฟล์ / dev / sda2 อย่างไร


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

คุณไม่สามารถเมานต์ / บูตโดยไม่ต้อง / เมานต์ก่อนเนื่องจากไม่มีไดเร็กทอรี / boot ที่ไม่มี /
psusi

คำตอบ:


20

ลินุกซ์แรกรองเท้าที่มี ramdisk (ที่เรียกว่าinitrdสำหรับ "แรมดิสก์เริ่ม") /ในฐานะ ดิสก์นี้มีเพียงพอที่จะสามารถค้นหาพาร์ติชันรูทจริง (รวมถึงไดรเวอร์และโมดูลระบบไฟล์ใด ๆ ที่จำเป็น) มันเมาท์พาร์ทิชันรากลงบนจุดเมานท์ชั่วคราวบนinitrdแล้วเรียกpivot_root(8)สลับรากและชั่วคราวคะแนนติดออกinitrdในฐานะที่จะเป็นเอ็ดและระบบแฟ้มรากจริงบนumount/


2
ถ้าคุณไม่มี initrd เช่น LFS (linuxfromscratch.org) ล่ะ
Mr. Shickadance

@นาย. Shickadance: ไม่ได้ดูว่า LFS ทำสิ่งต่าง ๆ ได้อย่างไรฉันจะเดาว่าพวกเขาทำให้แน่ใจว่าเคอร์เนลมีโมดูลที่จำเป็นทั้งหมดที่คอมไพล์แล้ว (หรือโหลดผ่าน GRUB 2 ซึ่งมีความเป็นไปได้ใหม่ที่พอจะไม่สังเกตเห็น) สามารถเริ่มบนพาร์ติชันรูทที่แท้จริง
geekosaur

4
@นาย. Shickadance มันไม่ใช่แค่ LFS ที่ไม่มี initrd ทุกคนที่รวบรวมเคอร์เนลของตัวเองมีตัวเลือกที่จะไม่ใช้ initrd ซึ่งเป็นสิ่งที่ฉันทำกับ Gentoo
jonescb

1
@Faheem: โมดูล grub2 ไม่เหมือนกับโมดูลเคอร์เนล ฉันเห็นความสามารถบางอย่างสำหรับ grub2 ในการโหลดโมดูลเคอร์เนล แต่สิ่งหนึ่งที่ฉันไม่ทราบว่าจะทำงานกับเคอร์เนล Linux หรือสำหรับ * BSD เท่านั้น (โดยที่ bootloader กำลังโหลดโมดูลเคอร์เนลเป็นปกติ) ฉันสงสัยว่าเคอร์เนลจำเป็นต้องได้รับการสอนที่จะค้นหาแผนที่ที่อยู่สำหรับโมดูลที่โหลดและทุกคนต้องย้ายไปที่ grub2 (grub1 ยังคงเป็นมาตรฐานในการแจกแจงบางส่วน)
geekosaur

1
initrd ถูกแทนที่ด้วย initramfs เนื่องจาก pivot_root ถือเป็นแฮ็คที่สกปรก
psusi

41

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

ในที่สุดบูตโหลดเดอร์มาพร้อมและสามารถส่งบรรทัดคำสั่งไปยังเคอร์เนล หากมีการroot=ส่งผ่านอาร์กิวเมนต์นั่นจะบอกเคอร์เนลว่ารูท fs นั้นเป็นค่าของบิวด์อิน ไดรเวอร์ที่จำเป็นในการเข้าถึงที่ยังต้องถูกสร้างไว้ในเคอร์เนล ในขณะที่อาร์กิวเมนต์ดูเหมือนว่าโหนดอุปกรณ์ปกติใน/devไดเรกทอรีไม่มี/devไดเรกทอรีก่อนที่จะติดตั้งรูท fs ดังนั้นเคอร์เนลจึงไม่สามารถค้นหาโหนด dev ที่นั่นได้ แต่ชื่ออุปกรณ์ที่รู้จักกันดีบางอย่างจะถูกเข้ารหัสอย่างหนักในเคอร์เนลเพื่อให้สามารถแปลสตริงเป็นหมายเลขอุปกรณ์ได้ ด้วยเหตุนี้เคอร์เนลจึงสามารถรับรู้สิ่งต่าง ๆ เช่น/dev/sda1แต่ไม่แปลกใหม่เช่น/dev/mapper/vg0-rootหรือ UUID ปริมาณ

ต่อinitrdมาภาพก็เข้ามา พร้อมกับเคอร์เนลบูตโหลดเดอร์จะโหลดinitrdอิมเมจซึ่งเป็นอิมเมจระบบไฟล์บีบอัดบางชนิด (อิมเมจ gzipped ext2, อิมเมจ gzipped romfs ในที่สุดสควอชก็จะกลายเป็นส่วนสำคัญ) เคอร์เนลจะคลายการบีบอัดอิมเมจนี้เป็น ramdisk และติด ramdisk เป็น root fs initภาพนี้มีไดรเวอร์เพิ่มเติมบางอย่างและสคริปต์บูตแทนของจริง สคริปต์การบูตเหล่านี้ทำงานต่าง ๆ เพื่อรับรู้ฮาร์ดแวร์เปิดใช้งานสิ่งต่าง ๆ เช่นอาร์เรย์การตรวจค้นและ LVM ตรวจจับ UUID และแยกบรรทัดคำสั่งเคอร์เนลเพื่อค้นหารูทจริงซึ่งสามารถระบุได้โดย UUID ฉลากระดับเสียงและสิ่งอื่น ๆ ขั้นสูง จากนั้นเมานต์รูทจริง fs /initrdจากนั้นดำเนินการpivot_rootเรียกระบบเพื่อให้มีการแลกเปลี่ยนเคอร์เนล/และ/initrdจากนั้น/sbin/initดำเนินการกับรูทจริงซึ่งจะยกเลิกการต่อเชื่อม/initrdและเพิ่ม ramdisk

initramfsในที่สุดวันนี้เรามี สิ่งนี้คล้ายกับinitrdแต่แทนที่จะเป็นอิมเมจระบบไฟล์ที่ถูกบีบอัดที่โหลดลงใน ramdisk มันเป็นไฟล์เก็บถาวร cpio ที่ถูกบีบอัด tmpfs ถูกเมาท์เป็นรูทและไฟล์เก็บถาวรถูกแตกออกมา แทนที่จะใช้pivot_rootซึ่งถือว่าเป็นแฮ็คที่สกปรกinitramfsสคริปต์การบูตจะเมานต์รูทจริง/rootลบไฟล์ทั้งหมดในรูท tmpfs จากนั้นchrootเข้า/rootและเอ็กซีคิ้ว/sbin/initท์


1
หลังจาก chroot tmpfs จะถูก unmount โดยอัตโนมัติหรือไม่? มันหายไปเหรอ?
jiggunjer

@ jiggunjer ไม่มันยังอยู่ที่นั่นมันว่างเปล่า (นอกเหนือจากการมีไดเรกทอรี / root) และไม่ได้ใช้อีกต่อไป
psusi

ฉันเรียนรู้สิ่งใหม่เกี่ยวกับการวนซ้ำ fs ที่คุณกล่าวถึงทุกครั้ง คำตอบที่ดี!
jpaugh

3

ดูเหมือนว่าคุณกำลังถามว่าเคอร์เนล "รู้" พาร์ติชั่นใดเป็นพาร์ติชั่นรูท, โดยไม่ต้องเข้าถึงไฟล์กำหนดค่าใน / etc.

เคอร์เนลสามารถรับอาร์กิวเมนต์บรรทัดคำสั่งเหมือนกับโปรแกรมอื่น ๆ GRUB หรือ bootloaders อื่น ๆ ส่วนใหญ่สามารถยอมรับอาร์กิวเมนต์บรรทัดคำสั่งเป็นอินพุตของผู้ใช้หรือเก็บไว้และทำการรวมอาร์กิวเมนต์บรรทัดคำสั่งต่าง ๆ ไว้ในเมนู bootloader ส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยังเคอร์เนลเมื่อโหลด (ฉันไม่ทราบชื่อหรือกลไกของการประชุมนี้ แต่มันอาจคล้ายกับวิธีที่แอปพลิเคชันรับอาร์กิวเมนต์บรรทัดคำสั่งจากกระบวนการเรียกใช้ในเคอร์เนลที่กำลังทำงาน)

หนึ่งในบรรดาตัวเลือกบรรทัดคำสั่งที่คุณสามารถระบุระบบแฟ้มรากคือrootroot=/dev/sda1

หากเคอร์เนลใช้ initrd ตัว bootloader จะรับผิดชอบในการบอกเคอร์เนลว่ามันอยู่ที่ไหนหรือวาง initrd ไว้ในตำแหน่งหน่วยความจำมาตรฐาน (ฉันคิดว่า) - อย่างน้อยก็เป็นวิธีการทำงานบน Guruplug ของฉัน

เป็นไปได้ทั้งหมดที่จะไม่ระบุหนึ่งอันแล้วให้เคอร์เนลของคุณตื่นตระหนกทันทีหลังจากเริ่มบ่นว่าไม่สามารถหาระบบไฟล์รูทได้

อาจมีวิธีอื่นในการส่งตัวเลือกนี้ไปยังเคอร์เนล


3
นี่คือคำอธิบายที่ถูกต้องเมื่อไม่มี initrd / initramfs แต่มันขาดส่วนหนึ่งของปริศนา โดยปกติเคอร์เนลจะระบุอุปกรณ์เช่น/dev/sda1เพราะเป็นรายการในระบบไฟล์ คุณสามารถทำได้cp -p /dev/sda1 /tmp/fooและ/tmp/fooจะแสดงอุปกรณ์เดียวกัน บนบรรทัดคำสั่งเคอร์เนลเคอร์เนลใช้ตัวแยกวิเคราะห์ในตัวซึ่งเป็นไปตามหลักการตั้งชื่ออุปกรณ์ตามปกติ: sda1หมายถึงพาร์ติชันแรกของดิสก์ที่เหมือน SCSI แผ่นแรก
Gilles 'หยุดความชั่วร้าย'

@Gilles เมล็ดที่ทันสมัยยังคงไม่สามารถจัดการกับการติดตั้งระดับเสียงตาม UUID หรือไม่ ไม่มีinitrdหรือinitramfsฉันหมายถึง จะต้องมีพาร์ทิชัน "แบบง่าย" ใน/dev/sdxรูปแบบหรือไม่
jiggunjer

1
@jiggunjer ทันสมัยเมล็ดจะสนับสนุนการค้นหาไดรฟ์โดย UUID init/do_mounts.cดู
Gilles 'ดังนั้นหยุดความชั่วร้าย'

1

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

ตัวอย่างเช่นใน Grub's menu.lst:

kernel /boot/linux root=/dev/sda2

1

C'mon, GRUB ไม่ได้ "mount" / boot, มันแค่อ่าน 'menu.lst' และบางโมดูล, มันไม่ได้เป็นส่วนหนึ่งของเคอร์เนลของ LINUX เมื่อคุณเรียกเคอร์เนลคุณจะผ่านอาร์กิวเมนต์ "root" ด้วยพาร์ติชันรูท ที่เลวร้ายที่สุดเคอร์เนลรู้ว่าเพิ่ง / boot ได้รับการติดตั้ง (LOL)

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


1
Grub แน่นอนที่สุดมีความสามารถในการ 'mount' ระบบแฟ้มโดยเฉพาะใน grub2 แน่นอนสิ่งที่มันสามารถทำได้ / ทำ / กับมันคือการมองหาเมล็ดที่สามารถบูตได้ของแถบใดแถบหนึ่งหรืออีกอัน แต่ก็ยังคงติดตั้งอยู่ นอกจากนี้ linux ไม่ต้องการการเริ่มต้นเว้นแต่ว่าเคอร์เนลของคุณจะรวบรวมไดรเวอร์ที่จำเป็นสำหรับฮาร์ดไดรฟ์ของคุณเป็นโมดูล
Shadur

5
ibm.com/developerworks/linux/library/l-linuxbootนี่เป็นข้อมูลสรุปโดยย่อเกี่ยวกับสิ่งที่เคอร์เนล Linux ทำเมื่อเริ่มระบบ
jsbillings

2
@Shadur จากmanpage เชื่อมต่อ : ไฟล์ทั้งหมดที่สามารถเข้าถึงได้ในระบบ Unix จะถูกจัดเรียงในแผนผังขนาดใหญ่หนึ่งลำดับชั้นของไฟล์โดยรูทที่ / ไฟล์เหล่านี้สามารถแพร่กระจายผ่านอุปกรณ์ต่าง ๆ ได้ คำสั่ง mount ทำหน้าที่เชื่อมต่อระบบไฟล์ที่พบในอุปกรณ์บางตัวกับแผนผังไฟล์ขนาดใหญ่ - ตั้งแต่ filesystems ใช้โดยด้วงจะไม่ยึดติดกับลำดับชั้นของไฟล์ก็ไม่ได้ติดตั้ง
D4RIO

1
@Shadur, BTW: เห็นได้ชัดว่า initrd ไม่จำเป็นเนื่องจากเป็นเพียงระบบไฟล์รูทอื่น แต่โดยทั่วไปจะใช้เป็นรูทเวลาบูตเล็กน้อยเนื่องจากเคอร์เนลโหลดสิ่งที่จำเป็นในการบูตจากนั้นบู๊ตและโหลดทุกอย่างอื่น
D4RIO

1
@ d4rio พวกเขากำลังติดตั้งโดย GRUB ไม่ใช่ linux - มันง่ายกว่าที่จะเข้าใจเมื่อคุณคิดว่าด้วงเป็น microkernel OS ของมันเองไม่ใช่แค่ bootloader
Shadur

1

ตัวโหลดการบูตไม่ว่าจะเป็นด้วงหรือไลโลหรืออะไรก็ตามบอกเคอร์เนลว่าจะดูที่root=ธงและเลือกโหลด ramdisk เริ่มต้นลงในหน่วยความจำผ่านทางinitrdก่อนที่จะทำการบูตเคอร์เนล

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

หากมี initrd อยู่จะถูกเมาท์ก่อนและโมดูล / ไดรเวอร์อุปกรณ์ใด ๆ ที่อยู่ในนั้นจะถูกโหลดและตรวจสอบก่อนที่จะติดตั้งระบบไฟล์รูท วิธีนี้คุณสามารถรวบรวมไดรเวอร์สำหรับฮาร์ดไดรฟ์ของคุณเป็นโมดูลและยังสามารถบู๊ตได้

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