Perbedaan dalam pelaksanaan init dengan embedded initramfs eksternal?

10

Saya sedang membangun sistem Linux yang sangat minimal yang hanya terdiri dari kernel (v4.1-rc5) dan sebuah initramfs yang diisi dengan busybox (v1.23.2). Ini berfungsi dengan baik untuk sebagian besar, tetapi saya mengamati perbedaan dalam perilaku pelaksanaan perintah di / init apakah saya menggunakan initramfs yang tertanam vs yang eksternal.

Skrip / init adalah:

#!/bin/sh

dmesg -n 1

mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
    setsid cttyhack /bin/sh
done

Kemudian saya mengatur opsi CONFIG_INITRAMFS_SOURCE di kernel .config ke direktori yang berisi semua folder untuk initramfs, atau saya jalankan

find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz

untuk membangunnya.

Ketika saya kemudian mengkompilasi kernel, baik dengan atau tanpa set CONFIG_INITRAMFS_SOURCE, saya berakhir dengan dua varian sistem saya:

  1. bzImage dengan initramfs tertanam

  2. bzImage + rootfs.cpio.gz (initramfs eksternal)

ketika saya sekarang mulai menggunakan mereka qemu

qemu-system-x86_64 -enable-kvm -kernel bzImage

atau

qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz

Saya mendapatkan perbedaan perilaku:

dengan versi 2 (initramfs eksternal) semuanya berfungsi dengan baik, "Selamat Datang" ditampilkan dan saya mendapatkan prompt. Namun dengan versi 1 (embedded initramfs) saya mendapatkan peringatan

unable to open an initial console

"Selamat datang" tidak ditampilkan, dan saya mendapatkan prompt saya.

Sejauh yang saya mengerti prosesnya, kedua versi initramfs harus berisi file yang sama, karena saya membangunnya (atau meminta kernel membangunnya) dari folder yang sama.

Saya ingin tahu apakah ada yang bisa membantu saya dengan penjelasan untuk perilaku ini?

* PEMBARUAN *

seperti yang dikatakan mikeserv dalam komentar, Kernel menyertakan initramfs minimum yang tertanam per default. Ini masih ada saat menggunakan yang eksternal, tetapi akan ditimpa jika Anda menanamkan milik Anda sendiri. Saya menemukan bahwa bertentangan dengan spesifikasi, ini memang tidak kosong, tetapi berisi folder dev, folder root dan perangkat / dev / console. Perangkat ini kemudian digunakan ketika menggunakan initramfs eksternal, tetapi ditimpa jika Anda menanamkannya sendiri. Jadi, Anda harus menyertakan perangkat / dev / console di sumber initramfs Anda mknod -m 622 initramfs_src/dev/console c 5 1saat menyematkan perangkat Anda sendiri.

Terima kasih banyak kepada mikeserv, frostschutz dan JdeBP karena telah membantu saya memahami hal itu!

clw
sumber
Di mana izin yang Anda setel untuk /dev/consolebawaan? Saya pikir perbedaannya mungkin tentang siapa yang melakukan pengepakan dalam dua kasus.
mikeserv
Pertanyaan serupa tentu saja adalah stackoverflow.com/questions/10437995 .
JdeBP
@mikeserv perangkat konsol memiliki izin dan kepemilikan yang identik di kedua build.
CLW
@ JdeBP Saya tidak yakin apakah itu sama, karena dalam kedua kasus saya boot, dapatkan prompt dan memiliki perangkat konsol. Hanya itu di satu init yang mengeksekusi gema dan yang lain tidak bisa.
CLW
1
Bagaimana bisa izinnya sama di initramfs jika Anda bahkan tidak memilikinya sama sekali?
mikeserv

Jawaban:

2

Apakah mereka benar-benar identik?

Yang built-in Anda dapat menemukan /usr/src/linux/usr/initramfs_data.cpio.gzatau mengekstraknya dari bzImage seperti dijelaskan di sini: https://wiki.gentoo.org/wiki/Custom_Initramfs#Salvaging

Jika Anda menggunakan bawaan itu dan menggunakannya sebagai eksternal, apakah itu berfungsi?

Jika masih berbeda, apakah kernel itu sendiri identik? (bandingkan /proc/config.gzuntuk keduanya)

Seharusnya ada beberapa perbedaan. Saya tidak tahu bahwa kernel peduli dari mana initramfs berasal. Saya akan segera menduga qemumenggunakan pengaturan yang berbeda ketika melewati -initrdparameter ...

Pada sidenote, /initpenampilanmu seperti cangkangnya yang tak terbatas bagiku. setsidtidak exec. Apakah aku salah?

frostschutz
sumber
1
Jawaban ini sepertinya adalah semua pertanyaan.
JdeBP
1
@JdeBP: Anda tidak berpikir empat dimensi!
frostschutz
1
@ frostschutz Terima kasih banyak atas balasan Anda! Ketika saya menggunakan initramfs yang dibangun oleh kernel (usr / initramfs_data.cpio.gz) sebagai eksternal berfungsi dengan baik juga! Juga, ketika saya memasok kernel yang dikompilasi dengan initramfs tertanam dengan eksternal, peringatan muncul, meskipun eksternal harus menimpa embedded ( kernel.org/doc/Documentation/filesystems/… ). Jadi mungkin juga bukan qemu -initrd tetapi sesuatu di dalam kernel itu sendiri. Saya tidak mengubah apa pun selain CONFIG_INITRAMFS_SOURCE ..
clw
@frostschutz Menjawab Anda On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?: Loop meniru getty atau alat serupa, sejak panggilan shblok sampai keluar shell.
stefanjunker
@stefanjunker dan itu akan baik-baik saja, kecuali setsid tidak menghalangi sama sekali ...
frostschutz
1

Anda juga mungkin tertarik dengan bagaimana Buildroot 2018.02 berurusan dengan ini.

Setiap kali Anda menggunakan initramfs ( BR2_TARGET_ROOTFS_INITRAMFS=y) atau initrd ( BR2_TARGET_ROOTFS_CPIO=n), ia menambahkan yang berikut ini /initke rootfs Anda https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/init

#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init "$@"

Salinan dilakukan oleh https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk :

# devtmpfs does not get automounted when initramfs is used.
# Add a pre-init script to mount it before running init
define ROOTFS_CPIO_ADD_INIT
    if [ ! -e $(TARGET_DIR)/init ]; then \
        $(INSTALL) -m 0755 fs/cpio/init $(TARGET_DIR)/init; \
    fi
endef

Juga berguna untuk mengetahui bahwa path init adalah /inituntuk initramfs, tidak seperti yang /sbin/initlain: Apa yang dapat membuat passing init = / path / ke / program ke kernel tidak memulai program seperti init?

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
sumber