Bagaimana kernel memasang partisi root?

29

Pertanyaan saya berkaitan dengan mem-boot sistem Linux dari partisi / boot terpisah. Jika sebagian besar file konfigurasi terletak di partisi / terpisah, bagaimana kernel memasangnya dengan benar pada saat boot?

Elaborasi apa pun tentang ini akan bagus. Saya merasa seolah kehilangan sesuatu yang mendasar. Saya sebagian besar peduli dengan proses dan urutan operasi.

Terima kasih!

EDIT: Saya pikir apa yang perlu saya tanyakan lebih pada baris file dev yang digunakan dalam parameter kernel root. Sebagai contoh, katakan saya berikan param root saya sebagai root = / dev / sda2. Bagaimana kernel memiliki pemetaan file / dev / sda2?

Tuan Shickadance
sumber
Meskipun orang-orang di bawah ini membahas initrd, ada sedikit diskusi tentang mengapa initrd digunakan. Kesan saya adalah karena distribusi seperti Debian ingin menggunakan satu kernel pada banyak mesin berbeda dari arsitektur yang sama, tetapi mungkin perangkat keras yang sangat berbeda. Ini dimungkinkan dengan memodulasi dukungan perangkat keras melalui modul kernel. Initrd tidak memerlukan banyak dukungan perangkat keras untuk mem-boot, dan begitu itu, ia memuat modul perangkat keras yang diperlukan untuk melanjutkan. Elaborasi / koreksi untuk ini dihargai.
Faheem Mitha
Anda tidak dapat melakukan mount / boot tanpa / mount terlebih dahulu, karena tidak ada direktori / boot tanpa /.
psusi

Jawaban:

20

Linux awalnya boot dengan ramdisk (disebut initrd, untuk "INITial RamDisk") sebagai /. Disk ini cukup memiliki cukup untuk dapat menemukan partisi root nyata (termasuk driver dan modul sistem file yang diperlukan). Ini me-mount partisi root ke titik mount sementara pada initrd, kemudian memanggil pivot_root(8)untuk menukar titik mount root dan sementara, meninggalkan initrddalam posisi untuk umountdiedit dan sistem file root yang sebenarnya aktif /.

geekosaurus
sumber
2
Bagaimana jika Anda tidak memiliki initrd seperti LFS (linuxfromscratch.org)?
Tn. Shickadance
@Bapak. Shickadance: Tidak melihat bagaimana LFS melakukan sesuatu, saya kira mereka memastikan kernel memiliki semua modul yang diperlukan dikompilasi (atau dimuat melalui GRUB 2, yang kemungkinannya cukup baru sehingga belum banyak distribusi yang memperhatikannya) jadi dapat mulai pada partisi root yang sebenarnya.
geekosaur
4
@Bapak. Shickadance. Bukan hanya LFS yang tidak memiliki initrd. Siapa pun yang mengkompilasi kernel mereka sendiri memiliki opsi untuk tidak menggunakan initrd, yang saya lakukan di Gentoo.
jonescb
1
@Faheem: modul grub2 tidak sama dengan modul kernel. Saya melihat beberapa kemampuan untuk grub2 untuk memuat modul kernel, tetapi satu hal yang saya tidak tahu adalah apakah itu akan bekerja untuk kernel Linux atau hanya untuk * BSD (di mana bootloader memuat modul kernel normal). Saya menduga kernel perlu diajarkan di mana menemukan peta alamat untuk modul yang dimuat, dan semua orang perlu pindah ke grub2 (grub1 masih standar di beberapa distribusi).
geekosaur
1
Initrd telah digantikan oleh initramfs, karena pivot_root dianggap sebagai peretasan yang kotor.
psusi
41

Pada zaman dahulu, kernel diberi kode keras untuk mengetahui perangkat utama / minor dari root fs dan memasang perangkat itu setelah menginisialisasi semua driver perangkat, yang dibangun ke dalam kernel. The rdevutilitas dapat digunakan untuk mengubah jumlah perangkat root pada gambar kernel tanpa harus mengkompilasi ulang itu.

Akhirnya boot loader datang dan dapat melewati baris perintah ke kernel. Jika root=argumen itu disahkan, itu memberitahu kernel di mana root fs bukan nilai bawaan. Driver diperlukan untuk mengakses yang masih harus dibangun ke dalam kernel. Sementara argumennya terlihat seperti simpul perangkat normal dalam /devdirektori, jelas tidak ada /devdirektori sebelum root fs di-mount, jadi kernel tidak dapat mencari node dev di sana. Sebaliknya, nama-nama perangkat tertentu yang terkenal sulit dikodekan ke dalam kernel sehingga string dapat diterjemahkan ke nomor perangkat. Karena itu, kernel dapat mengenali hal-hal seperti /dev/sda1, tetapi tidak hal-hal yang lebih eksotis seperti /dev/mapper/vg0-rootatau volume UUID.

Kemudian, initrdgambar itu muncul. Bersamaan dengan kernel, boot loader akan memuat initrdgambar, yang merupakan semacam gambar sistem file terkompresi (gzipped ext2 image, gzipped image romfs, squashfs akhirnya menjadi dominan). Kernel akan mendekompres gambar ini ke dalam ramdisk dan me-mount ramdisk sebagai root fs. Gambar ini berisi beberapa driver tambahan dan skrip boot bukan yang asli init. Skrip boot ini melakukan berbagai tugas untuk mengenali perangkat keras, mengaktifkan hal-hal seperti raid arrays dan LVM, mendeteksi UUID, dan mengurai baris perintah kernel untuk menemukan root yang sebenarnya, yang sekarang dapat ditentukan oleh UUID, label volume dan hal-hal canggih lainnya. Kemudian me-mount root nyata fs di /initrd, kemudian mengeksekusi pivot_rootpanggilan sistem untuk memiliki swap kernel /dan/initrd, kemudian exec /sbin/initpada root sebenarnya, yang kemudian akan meng /initrd- unmount dan membebaskan ramdisk.

Akhirnya, hari ini kita punya initramfs. Ini mirip dengan initrd, tetapi alih-alih menjadi image sistem file terkompresi yang dimuat ke dalam ramdisk, ini adalah arsip cpio terkompresi. Tmpfs dipasang sebagai root, dan arsip diekstraksi di sana. Alih-alih menggunakan pivot_root, yang dianggap sebagai hack kotor, initramfsskrip boot me-mount root asli /root, menghapus semua file di root tmpfs, lalu chrootke /root, dan exec /sbin/init.

psusi
sumber
1
Setelah chroot, apakah tmpfs secara otomatis dilepas? Apakah itu hilang begitu saja?
jiggunjer
@ jiggunjer, tidak, masih ada di sana, hanya kosong (selain berisi direktori / root), dan tidak lagi digunakan.
psusi
Saya belajar sesuatu yang baru tentang setiap iterasi root fs yang Anda sebutkan. Jawaban bagus!
jpaugh
3

Kedengarannya seperti Anda bertanya bagaimana kernel "tahu" partisi mana yang merupakan partisi root, tanpa akses ke file konfigurasi di / etc.

Kernel dapat menerima argumen baris perintah seperti program lainnya. GRUB, atau kebanyakan bootloader lain dapat menerima argumen baris perintah sebagai input pengguna, atau menyimpannya dan membuat berbagai kombinasi argumen baris perintah tersedia melalui menu. Bootloader meneruskan argumen baris perintah ke kernel saat memuatnya (saya tidak tahu nama atau mekanisme konvensi ini, tetapi mungkin mirip dengan cara aplikasi menerima argumen baris perintah dari proses panggilan di kernel yang berjalan).

Salah satu opsi baris perintah adalah root, di mana Anda dapat menentukan sistem file root, yaitu root=/dev/sda1.

Jika kernel menggunakan initrd, bootloader bertanggung jawab untuk memberitahu kernel di mana ia berada, atau meletakkan initrd di lokasi memori standar (saya pikir) - itu setidaknya cara kerjanya di Guruplug saya.

Sangat mungkin untuk tidak menentukan satu dan kemudian panik kernel Anda segera setelah mulai mengeluh bahwa itu tidak dapat menemukan sistem file root.

Mungkin ada cara lain untuk meneruskan opsi ini ke kernel.

LawrenceC
sumber
3
Ini adalah penjelasan yang tepat ketika tidak ada initrd / initramfs, tetapi tidak ada bagian dari teka-teki. Biasanya kernel mengidentifikasi perangkat seperti /dev/sda1itu karena itu entri dalam sistem file. Anda dapat melakukan cp -p /dev/sda1 /tmp/foodan /tmp/fooakan mewakili perangkat yang sama. Pada baris perintah kernel, kernel menggunakan parser built-in yang mengikuti konvensi penamaan perangkat yang biasa: sda1berarti partisi pertama dari disk mirip-SCSI pertama.
Gilles 'SO- stop being evil'
@Gilles jadi kernel modern masih tidak bisa menangani pemasangan volume berdasarkan UUID? tanpa initrdatau initramfsmaksud saya. Itu harus berupa partisi "sederhana" dalam /dev/sdxformulir?
jiggunjer
1
@jiggunjer Kernel modern mendukung pencarian volume oleh UUID. Lihat init/do_mounts.c.
Gilles 'SANGAT berhenti menjadi jahat'
1

Grub me-mount /bootpartisi dan kemudian menjalankan kernel. Dalam konfigurasi Grub, ia memberi tahu kernel apa yang harus digunakan sebagai perangkat root.

Misalnya di Grub's menu.lst:

kernel /boot/linux root=/dev/sda2
jonescb
sumber
1

Ayo, GRUB tidak "me-mount" / boot, ia hanya membaca 'menu.lst' dan beberapa modul, itu juga bukan bagian dari kernel LINUX. Ketika Anda memanggil kernel, Anda akan memberikan argumen "root" dengan partisi root. Paling buruk, kernel tahu bahwa just / boot telah di-mount (LOL).

Berikutnya: geekosaur benar, Linux menggunakan ramdisk awal dalam format gambar terkompresi, dan kemudian me-mount sistem file root sebenarnya dengan memanggil pivot_root. Jadi Linux mulai berjalan dari gambar, dan kemudian dari disk drive lokal Anda.

D4RIO
sumber
1
Grub pasti memiliki kemampuan untuk 'me-mount' sistem file, terutama di grub2. Tentu saja, semua itu mampu / lakukan / dengan itu adalah mencari kernel bootable dari satu strip atau yang lain, tapi itu masih meningkat. Juga, linux tidak memerlukan initrd kecuali jika kernel yang Anda buat mengkompilasi driver penting untuk hard drive Anda sebagai modul.
Shadur
5
ibm.com/developerworks/linux/library/l-linuxboot Ini adalah ringkasan yang cukup ringkas tentang apa yang dilakukan Kernel Linux saat boot.
jsbillings
2
@ Safad, dari manual mount : Semua file yang dapat diakses dalam sistem Unix diatur dalam satu pohon besar, hierarki file, di-root di /. File-file ini dapat tersebar di beberapa perangkat. Perintah mount berfungsi untuk melampirkan sistem file yang ditemukan pada beberapa perangkat ke pohon file besar. - Karena sistem file yang digunakan oleh GRUB tidak dilampirkan ke hierarki file, itu BUKAN pemasangan .
D4RIO
1
@ Safad, BTW: Jelas bahwa initrd tidak diperlukan karena itu hanya sistem berkas root yang lain, tetapi umumnya initrd digunakan sebagai root waktu boot yang kecil, karena kernel memuat yang diperlukan untuk boot, kemudian boot, dan akhirnya memuat yang lainnya.
D4RIO
1
@ d4rio Mereka di-mount oleh GRUB, bukan linux - ini akan lebih mudah untuk dipahami ketika Anda menganggap grub sebagai OS microkernel sendiri daripada hanya bootloader.
Shadur
1

Boot loader, baik itu grub atau lilo atau apa pun, memberitahu kernel di mana harus melihat dengan root=flag, dan secara opsional memuat ramdisk awal ke dalam memori melalui initrdsebelum mem-boot kernel.

Kernel kemudian memuat, menguji perangkat keras dan driver perangkatnya dan melihat-lihat sistem untuk mengetahui apa yang dapat dilihatnya (Anda dapat meninjau informasi diagnostik ini dengan mengetik dmesg; saat ini cenderung menggulir dengan cara yang terlalu cepat untuk dilihat) kemudian mencoba untuk me-mount partisi yang disebutkan dalam yang root=parameter.

Jika initrd hadir, itu sudah terpasang terlebih dahulu dan setiap modul / driver perangkat di dalamnya dimuat dan diselidiki sebelum root filesystem dipasang. Dengan cara ini Anda dapat mengkompilasi driver untuk hard drive Anda sebagai modul dan masih bisa boot.

Shadur
sumber