बाहरी बनाम initramfs के साथ init के निष्पादन में अंतर?


10

मैं एक बहुत ही कम से कम लिनक्स प्रणाली का निर्माण कर रहा हूं, जिसमें बस कर्नेल (v4.1-rc5) और एक इनट्राम्रॉफ़ व्यस्त है जो व्यस्त बॉक्स (v1.23.2) के साथ है। यह अधिकांश भाग के लिए ठीक काम करता है, लेकिन मैं / init में कमांड निष्पादन के व्यवहार में अंतर का निरीक्षण करता हूं कि क्या मैं एक बाहरी initramfs बनाम बाहरी का उपयोग कर रहा हूं।

/ Init स्क्रिप्ट है:

#!/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

तब मैं या तो CONFIG_INITRAMFS_SOURCE विकल्प कर्नेल में सेट कर देता हूं। Initramfs के लिए सभी फ़ोल्डर युक्त निर्देशिका में, या मैं चलाता हूं

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

इसे बनाने के लिए।

जब मैं कर्नेल संकलित करता हूं, तो CONFIG_INITRAMFS_SOURCE सेट के साथ या उसके बिना, मैं अपने सिस्टम के दो वेरिएंट के साथ समाप्त होता हूं:

  1. Inzramfs के साथ bzImage एम्बेडेड

  2. bzImage + rootfs.cpio.gz (बाहरी initramfs)

जब मैं अब उन का उपयोग शुरू करते हैं qemu

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

या

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

मुझे व्यवहार में निम्नलिखित अंतर मिलते हैं:

संस्करण 2 (बाहरी initramfs) के साथ सब कुछ ठीक काम करता है, "वेलकम" प्रदर्शित होता है और मुझे एक संकेत मिलता है। हालांकि संस्करण 1 के साथ (initramfs एम्बेडेड) मुझे चेतावनी मिलती है

unable to open an initial console

"आपका स्वागत है" प्रदर्शित नहीं होता है, और मुझे मेरा संकेत मिलता है।

जहां तक ​​मैं इस प्रक्रिया को समझता हूं, initramfs के उन दो संस्करणों में समान फाइलें होनी चाहिए, क्योंकि मैं इसे एक समान फ़ोल्डर से बनाता हूं (या कर्नेल का निर्माण करता हूं)।

मुझे आश्चर्य है कि क्या कोई इस व्यवहार के लिए स्पष्टीकरण के साथ मेरी मदद कर सकता है?

* अपडेट करें *

जैसा कि mikeserv ने टिप्पणी में कहा है, कर्नेल में एक न्यूनतम एम्बेडेड initramfs प्रति डिफ़ॉल्ट शामिल है। यह तब भी मौजूद होता है जब किसी बाहरी का उपयोग किया जाता है, लेकिन यदि आप अपना स्वयं का एम्बेड करते हैं, तो यह ओवरराइट हो जाता है। मैंने पाया कि विनिर्देश के विपरीत, यह वास्तव में खाली नहीं है, लेकिन इसमें एक देव फ़ोल्डर, एक रूट फ़ोल्डर और / देव / कंसोल डिवाइस है। यह डिवाइस तब बाहरी इनट्राम्राम्स का उपयोग करते समय उपयोग किया जाता है, लेकिन यदि आप अपना स्वयं का एम्बेड करते हैं तो यह ओवरराइट हो जाता है। तो आपको अपने initramfs स्रोत में / dev / कंसोल डिवाइस को शामिल करना होगा mknod -m 622 initramfs_src/dev/console c 5 1जब अपना स्वयं का एम्बेड करना हो।

मेरी मदद करने के लिए mikeserv, frostschutz और JdeBP को बहुत-बहुत धन्यवाद!


/dev/consoleआपके द्वारा निर्मित बिल्‍ट पर क्‍या अनुमतियाँ सेट की गई हैं ? मुझे लगता है कि अंतर हो सकता है कि दो मामलों में पैकिंग कौन करता है।
अभिजात वर्ग

इसी तरह का एक सवाल बिल्कुल stackoverflow.com/questions/10437995 का है
JdeBP

@mikeserv कंसोल डिवाइस में दोनों बिल्ड में समान अनुमतियाँ और स्वामित्व है।
सीएलडब्ल्यू

@JdeBP मुझे यकीन नहीं है कि अगर यह समान है, क्योंकि दोनों मामलों में मैं बूट करता हूं, एक संकेत मिलता है और एक कंसोल डिवाइस है। केवल यह कि एक init इको निष्पादित करता है और दूसरे में यह नहीं हो सकता है।
सीएलडब्ल्यू

1
अगर आपके पास यह बिल्कुल भी नहीं था तो इनट्रैमफोर्स में अनुमतियाँ समान कैसे हो सकती हैं?
मिकसेर

जवाबों:


2

क्या वे वास्तव में समान हैं?

अंतर्निहित एक जिसे आप /usr/src/linux/usr/initramfs_data.cpio.gzयहां बताए अनुसार bzImage से प्राप्त या निकाल सकते हैं : https://wiki.gentoo.org/wiki/Custom_Initramfs#Salvaging

यदि आप उस बिल्ट-इन का उपयोग करते हैं और इसे बाहरी के रूप में उपयोग करते हैं, तो क्या यह काम करता है?

यदि यह अभी भी अलग है, तो क्या कर्नेल स्वयं समान है? ( /proc/config.gzदोनों के लिए तुलना करें )

कुछ अंतर होना चाहिए। मुझे पता नहीं है कि कर्नेल परवाह करता है कि इनट्रैमफ कहां से आया है। मैं जल्द ही पैरामीटर qemuपारित करते समय अलग-अलग सेटिंग्स का उपयोग करने का संदेह करता हूं -initrd...

एक पहेली पर, आपका /initरूप मेरे लिए उसके अनंत गोले की तरह दिखता है। setsidनहीं है exec। क्या मै गलत हु?


1
यह उत्तर सभी प्रश्नों से लगता है।
जेडबीपी

1
@ जेडेबीपी: आप चौथा-डिमेंशली नहीं सोच रहे हैं!
फ्रॉस्ट्सचुट्ज़

1
@frostschutz आपके उत्तर के लिए बहुत बहुत धन्यवाद! जब मैं initramfs का उपयोग करता हूं तो कर्नेल बनाता है (usr / initramfs_data.cpio.gz) बाहरी रूप में यह ठीक काम करता है! इसके अलावा, जब मैं उस कर्नेल की आपूर्ति करता हूं जो एक बाहरी एक के साथ एम्बेडेड इनट्रामाफ़्स के साथ संकलित किया गया था, तो चेतावनी दिखाई देती है, भले ही बाहरी को एम्बेडेड ( kernel.org/doc/Documentation/filesystems/… ) को अधिलेखित करना चाहिए । तो शायद यह भी नहीं qemu -initrd लेकिन कर्नेल के भीतर ही कुछ है। मैंने फिर कुछ नहीं बदला, CONFIG_INITRAMFS_SOURCE हालांकि ..
clw

@frostschutz आपका उत्तर देना On a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?: लूप की नकल या इसी तरह के उपकरण, चूंकि कॉल उस shब्लॉक से बाहर निकलता है।
स्टेफंजंकर

@stefanjunker और यह ठीक होगा, सेटिस्ड को छोड़कर यह बिल्कुल भी ब्लॉक नहीं होता ...
frostschutz

1

आपको इस बात में भी दिलचस्पी हो सकती है कि Buildroot 2018.02 इससे कैसे निपटता है।

जब भी आप initramfs ( BR2_TARGET_ROOTFS_INITRAMFS=y) या initrd ( BR2_TARGET_ROOTFS_CPIO=n) का उपयोग करते हैं, तो यह /initआपके rootfs के लिए निम्नलिखित जोड़ता है 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 "$@"

प्रतिलिपि 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

यह जानना भी उपयोगी है कि इनिट पथ /initinitramfs के लिए है, /sbin/initअन्यथा इसके विपरीत : क्या कर्नेल को प्रोग्राम प्रारंभ नहीं कर सकता है?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.