Bagaimana Linux memuat gambar 'initrd'?

13

Saya sudah mencoba memahami proses booting, tetapi hanya ada satu hal yang terjadi di kepala saya ..

Segera setelah kernel Linux di-boot dan sistem file root (/) di-mount, program dapat dijalankan dan modul kernel selanjutnya dapat diintegrasikan untuk menyediakan fungsi tambahan. Untuk memasang sistem file root, kondisi tertentu harus dipenuhi. Kernel membutuhkan driver yang sesuai untuk mengakses perangkat di mana sistem file root berada (terutama driver SCSI). Kernel juga harus berisi kode yang diperlukan untuk membaca sistem file (ext2, reiserfs, romfs, dll.). Dapat dibayangkan bahwa sistem file root sudah dienkripsi. Dalam hal ini, kata sandi diperlukan untuk me-mount sistem file.

Ramdisk awal (juga disebut initdisk atau initrd) memecahkan masalah yang dijelaskan di atas. Kernel Linux menyediakan opsi untuk memiliki sistem file kecil yang dimuat ke disk RAM dan menjalankan program di sana sebelum sistem file root yang sebenarnya dipasang. Pemuatan initrd ditangani oleh boot loader (GRUB, LILO, dll.). Boot loader hanya perlu rutin BIOS untuk memuat data dari media boot. Jika boot loader dapat memuat kernel, itu juga dapat memuat ramdisk awal. Pengemudi khusus tidak diperlukan.

Jika / boot bukan partisi yang berbeda, tetapi ada di partisi /, maka seharusnya boot loader tidak memerlukan driver SCSI, untuk mengakses gambar 'initrd' dan gambar kernel? Jika Anda dapat mengakses gambar secara langsung, lalu mengapa kita membutuhkan driver SCSI?

rpthms
sumber

Jawaban:

20

Nighpher, saya akan mencoba menjawab pertanyaan Anda, tetapi untuk deskripsi yang lebih komprehensif tentang proses boot, coba artikel IBM .

Ok, saya berasumsi, bahwa Anda menggunakan GRUB atau GRUB2 sebagai bootloader untuk penjelasan. Pertama, ketika BIOS mengakses disk Anda untuk memuat bootloader, ia menggunakan rutinitas bawaannya untuk akses disk, yang disimpan dalam interupsi 13 jam yang terkenal. Bootloader (dan kernel pada tahap setup) menggunakan rutinitas tersebut ketika mereka mengakses disk. Perhatikan bahwa BIOS berjalan dalam mode real (16 bit) mode prosesor, sehingga tidak dapat mengatasi lebih dari 2 ^ 20 byte RAM (2 ^ 20 bukan 2 ^ 16 karena setiap alamat dalam mode nyata terdiri dari segment_address * 16 + offset , di mana alamat segmen dan offset 16-bit, lihat http://en.wikipedia.org/wiki/X86_memory_segmentation ). Dengan demikian, rutinitas ini tidak dapat mengakses lebih dari 1 MiB RAM, yang merupakan batasan ketat dan ketidaknyamanan utama.

BIOS memuat kode bootloader langsung dari MBR - 512 byte pertama dari disk Anda dan menjalankannya. Jika Anda menggunakan GRUB, kode itu adalah GRUB tahap 1. Kode itu memuat GRUB tahap 1.5, yang terletak di ruang disk 32 KiB pertama, yang disebut wilayah kompatibilitas DOS atau dari alamat tetap sistem file. Tidak perlu memahami sistem file untuk melakukan ini, karena bahkan tahap 1.5 ada dalam sistem file, itu adalah kode "mentah" dan dapat langsung dimuat ke RAM dan dieksekusi: http://www.pixelbeat.org/ docs / disk / . Memuat stage1.5 dari disk ke RAM menggunakan rutinitas akses disk BIOS.

masukkan deskripsi gambar di sini

Stage1.5 berisi utilitas filesystem, sehingga ia dapat membaca stage2 dari filesystem (well, masih menggunakan BIOS 13h untuk membaca dari disk ke RAM, tetapi sekarang ia dapat menguraikan informasi sistem file tentang inodes dll. Dan mendapatkan kode mentah dari disk). BIOS yang lebih lama mungkin tidak dapat mengakses seluruh HD karena keterbatasan dalam mode pengalamatan disk - mereka mungkin menggunakan sistem Cylinder-Head-Sector, tidak dapat mengatasi lebih dari 8 GiB ruang disk pertama: http: //en.wikipedia. org / wiki / Cylinder-head-sector .

Stage2 memuat kernel ke dalam RAM (sekali lagi, menggunakan utilitas disk BIOS). Jika kernel 2.6+, kernel ini juga memiliki initramfs yang dikompilasi, jadi tidak perlu memuatnya. Jika ini adalah kernel yang lebih lama, bootloader juga memuat gambar initrd mandiri ke dalam memori, sehingga kernel bisa memasangnya dan mendapatkan driver untuk memasang sistem file nyata dari disk.

Masalahnya adalah kernel (dan ramdisk) memiliki berat lebih dari 1 MiB, sehingga untuk memuatnya ke RAM Anda harus memuat kernel ke 1 MiB pertama, kemudian lompat ke mode terproteksi (32 bit), pindahkan kernel yang dimuat ke memori tinggi (gratis 1 MiB pertama untuk mode real), lalu kembali ke mode real (16 bit) lagi, dapatkan ramdisk dari disk ke 1 MiB pertama (jika kernel initrd dan yang lebih lama terpisah), mungkin beralih ke mode terproteksi (32 bit) lagi, letakkan di tempat yang seharusnya, mungkin kembali ke mode nyata (atau tidak: /programming/4821911/does-grub-switch-to-protected-mode ) dan jalankan kode kernel. Peringatan: Saya tidak sepenuhnya yakin tentang ketelitian dan ketepatan bagian deskripsi ini.

Sekarang, ketika Anda akhirnya menjalankan kernel, Anda sudah memilikinya dan ramdisk dimuat ke RAM oleh bootloader , jadi kernel dapat menggunakan utilitas disk dari ramdisk untuk me-mount sistem file root Anda dan root pivot untuk itu. driver ramfs hadir di kernel, sehingga dapat memahami isi initramfs, tentu saja.

Boris Burkov
sumber
Tidak bisakah bootlader hanya memuat kernel dalam potongan, alih-alih beralih ke mode yang dilindungi ?? Dan apa perlunya membebaskan 1 MB itu .. (Maaf .. tidak bisa mengerti itu ..)
rpthms
Kebutuhan untuk membebaskan 1MiB pertama adalah sebagai berikut: bootloader dapat mengakses hard drive Anda hanya dalam mode nyata, karena itu mengaksesnya dengan utilitas BIOS, yang merupakan mode nyata (mereka beroperasi pada argumen 16-bit dan menggunakan operasi 16-bit). Mode nyata tidak melihat RAM apa pun kecuali dengan 1 MiB pertama. Tetapi Anda perlu memuat kernel + initramfs ke dalam RAM dan mereka mengambil ~ 5 MiB ruang dalam RAM. Utilitas-utilitas BIOS itu hanya tidak akan dapat memeras 5 MiB ke dalam 1 MiB pertama. Jadi, bootloader harus menyalinnya dari disk ke 1 MiB pertama, kemudian pergi ke mode terproteksi dan memindahkannya dari 1 MB RAM pertama ke RAM yang lebih tinggi. Apakah sekarang lebih jelas? :)
Boris Burkov
1
Keseluruhan tahap 1 / 1.5 / 2 adalah grub legacy.
psusi
1
@ CMCDragonkai Ya, stage2 bootloader ada di sistem file (yaitu, di /bootpartisi). Kernel tidak dimuat pada saat ini - ini adalah grub's stage1.5, yang mengakses stage2 di sistem /bootfile (misalnya dalam /boot/grubfile) melalui driver sistem file minimalis. Kernel juga dapat membaca dari /bootpartisi, tetapi akan terjadi nanti, setelah eksekusi kode grub2 dan memuat kernel dan setelah kernel membaca initramfs. Apakah Anda berbicara tentang init.shinitramf? Itu berada di /bootpartisi hard drive Anda, kemudian stage2 dari grub memasukkannya ke dalam RAM dan Kernel membacanya dari RAM.
Boris Burkov
1
Initrd harus berupa file terpisah. Initramfs yang lebih baru dapat ditautkan ke kernel, tetapi tidak harus - ia juga dapat dimuat sebagai file terpisah oleh bootloader. Karena file initramfs didefinisikan sebagai urutan arsip cpio, beberapa bootloader (misalnya iPXE) bahkan memungkinkan banyak file initramfs, yang akan dimuat ke dalam memori satu per satu. Juga, beberapa distribusi Linux menggunakan nama file gaya initrd untuk kompatibilitas mundur, meskipun teknologi sebenarnya yang digunakan sekarang adalah initramfs.
telcoM
1

Saya percaya, itu bermuara pada fitur apa yang mendukung bootloader tertentu. Misalnya. ia tidak harus mengetahui filesystem tertentu dari partisi gabungan (boot + root) Anda. Jika demikian, Anda hanya perlu membuat partisi boot terpisah dalam kondisi sedemikian rupa sehingga berfungsi dengan bootloader Anda, dan kerumitan lain tentang cara memasang partisi root Anda ditinggalkan di kernel dan gambar initrd di-boot dari partisi boot. Bootloader memang tahu cara mengakses perangkat SCSI (dan perangkat lain juga, tergantung pada apa yang digunakan bootloader) baik dengan menggunakan driver itu sendiri atau dengan memanfaatkan rutinitas BIOS. Selain itu, ia tahu cara membaca beberapa sistem file, dll.

Pertimbangkan misalnya. Cara booting UEFI, di mana sebenarnya UEFI firmware sudah tahu cara mengakses partisi EFI, membacanya dan memuat kernel linux dari sana tanpa perlu bootloader menengah. Dalam hal ini gambar linux terpisah dari partisi root dan firmware UEFI tidak harus mengetahui semua sistem file eksotis untuk mengaksesnya. Saya percaya pemisahan "boot" gambar dari partisi "root" masuk akal. Jika tidak untuk hal lain maka ini adalah keharusan ketika mengatur enkripsi sistem file root.

Miroslav Koškár
sumber
0

Sebagai catatan, jika bootloader tidak memuat initrd, ada baiknya untuk menguji bootloader lain; Saya baru saja mengalami situasi seperti ini ketika LILO diam-diam mengabaikan initrd ukuran medium yang ditentukan dengan benar (<4Mb; rootfs ext4 tunggal pada SSD SATA; GPT) dan GRUB 2.00 berhasil.

Proses boot berakhir dengan cepat dengan tipikal

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
Michael Shigorin
sumber