लिनक्स कर्नेल initrd को सही ढंग से नहीं ढूंढ रहा है


11

मैंने एक लिनक्स कर्नेल संकलित किया था और मैं इसे QEMU में डीबग करना चाहता था। मैंने कमांड करने से बूट करने के लिए एक फाइल बनाई

$ qemu-img create -f raw disk.img 200M
$ mkfs.ext2 -F disk.img
# mkdir /mnt/rootfs
# mount -o loop disk.img /mnt/rootfs

फिर मैंने किया qemu -kernel bzImage -initrd disk.imgऔर नीचे स्क्रीन है जो कहता है:

Kernel panic - not syncing: VFS: unable to mount root fs on unknown block

मेरी QEMU स्क्रीन

मैंने क्या गलत किया है और मैं इसे ठीक करने के लिए क्या कर सकता हूं?



इस रूप में एक ही त्रुटि संदेश, लेकिन उन तक पहुंचने के लिए उठाए गए कदमों को निर्दिष्ट नहीं करता है: unix.stackexchange.com/questions/48302/…
Ciro Santilli 冠状,, 六四

जवाबों:


8

कर्नेल आपको बता रहा है, कि यह नहीं पता है कि कौन सा डिवाइस रूट फाइल सिस्टम रखता है। आपका लूप माउंट आवश्यक नहीं है। (जारी रखने से पहले इसे अनमाउंट करें)।

जैसे कमांड का प्रयास करें

qemu -kernel bzImage -hda disk.img -append root=/dev/sda

-hda disk.imgपैरामीटर qemu बताता है एक डिस्क अपने डिवाइस के आधार पर अनुकरण करने के लिए disk.img

-append root=/dev/sdaस्विच qemu द्वारा प्रयोग किया जाता है यह की जड़ डिवाइस के बारे में गिरी बताने के लिए। यह root=/dev/sdaकर्नेल कमांडलाइन को जोड़कर किया जाता है । आप अपनी कर्नेल की कर्नेल कमांडलाइन से इसकी तुलना कर सकते हैं cat /proc/cmdline(यह सुरक्षित है)। आपको एक rootपैरामीटर भी देखना चाहिए ।


मैं फ़ाइलों को कैसे अनमाउंट करूंगा?
कोडरहैम 21

umount /mnt/rootfs
t-8ch 21

जब मैं ऐसा करता हूं कि मुझे umount मिलता है: / mnt / rootfs आरोहित नहीं है (mtab के अनुसार)
Coder404

संभवतः Coder404 उस मशीन के लिए एक डिस्क संलग्न नहीं करना चाहता है और बस में चलाता initहै initrd। यहाँ आप disk.imgदोनों को हार्ड डिस्क के रूप में पास कर रहे हैं और initrdइसका कोई मतलब नहीं है।
स्टीफन चेजलस

@StephaneChazelas संकेत के बारे में धन्यवाद -initrdकि वहाँ नहीं होना चाहिए था।
t-8ch

8

क्या हो रहा है कि आप "अप्रचलित" तरीके से लिनक्स को बूट करने की कोशिश कर रहे हैं। यह वह जगह है जहां initrdएक रैमडिस्क एक संपीड़ित cpio संग्रह के विपरीत है जो कर्म्फ द्वारा एक रैमफ्स में अनपैक्ड है, और अंतिम डिवाइस पर स्विच करने के लिए पुराने तरीके के साथ है।

उस मोड में, कर्नेल डिस्क की नकल करता है। एक रैमडिस्क के रूप में रूट फाइल सिस्टम के रूप में और फिर /linuxrcवहाँ निष्पादित होता है। आपके मामले में सबसे अधिक संभावना है, ऐसी कोई फ़ाइल नहीं है। जब /linuxrc(जो कि वास्तविक रूट फाइलसिस्टम के लिए ब्लॉक डिवाइस को लाने के लिए जो कुछ भी आवश्यक हो) बाहर निकलता है, तो कर्नेल वास्तविक रूट फाइल सिस्टम को मापता है।

ऊपर दिए गए संदेश बताते हैं कि यह रैम डिस्क को सफलतापूर्वक माउंट करता है (1,0: 1 के लिए है ram, इसलिए /dev/ram0) लेकिन वास्तविक रूट फाइल सिस्टम / देव / sda1 (8,1: 8 है sd, 1 है a1) नहीं। मुमकिन है क्योंकि आपने कर्नेल कमांड लाइन ( -append) निर्दिष्ट नहीं की थी , जो कि /dev/sda1कॉनफ़ाइल संकलन के समय या उपयोग किए गए CONFIG_CMDLINE से आती है rdev

यदि आपका disk.img एक छोटे लिनक्स वितरण के साथ कहने के लिए रूट फाइल सिस्टम को समाहित करने के लिए है /sbin/init..., तो आप शायद इसके बजाय इसे लिखना चाहते हैं:

kvm -kernel kernel.img -initrd disk.img -append 'root=/dev/ram0`

फिर, कर्नेल राम डिस्क को वास्तविक रूट फाइल सिस्टम के रूप में मानेगा (हालांकि आप अभी भी pivot_rootएक दूसरे के लिए कर सकते हैं )।

कर्नेल संदेशों को अधिक आसानी से देखने में सक्षम होने के लिए, मैं धारावाहिक आउटपुट का उपयोग करने की सलाह दूंगा:

kvm -kernel kernel.img -initrd disk.img -nographic -append "root=/dev/ram0 console=ttyS0"

एक विकल्प के रूप में आप एक init ramdisk के बजाय एक init ramfs का उपयोग कर सकते हैं:

mkdir -p RAMFS/{bin,dev} 
cd RAMFS/bin
cp /bin/busybox .
"$PWD/busybox" --install .
cd ..
cp -a /dev/{null,tty,zero,console} dev
printf '%s\n' "#! /bin/sh" "exec /bin/sh" > init
chmod +x init
find . | cpio -oHnewc | gzip > ../initramfs.gz
cd ..
kvm -kernel kernel.img -initrd initramfs.gz

(बशर्ते busyboxस्टैटिकली लिंक्ड वर्ज़न है) और आपको उस कर्नेल में एक शेल और अन्य बिजीबॉक्स यूटिलिटीज़ मिलेंगी)।

ध्यान दें कि कर्नेल अब उस मोड में या उसके /initविपरीत चलता है।/linuxrc/sbin/init


दिखाए गए आउटपुट के लाइन 3 से पता चलता है कि कर्नेल इनट्रामाडिस्क के ext2 फाइल सिस्टम को माउंट करता है। तो यह शायद एक लापता मॉड्यूल नहीं है।
t-8ch

अरे हाँ, मैं चूक गया था, धन्यवाद @ t-8ch। मुझे लगता है कि मुझे पता है कि क्या हो रहा है और मैंने अपना जवाब अपडेट कर दिया है।
स्टीफन चेजालस

0

CONFIG_BLK_DEV_INITRD=y

यह कर्नेल विन्यास विकल्प भी आवश्यक है। यह लिनक्स कर्नेल पर initrd समर्थन को सक्षम करता है।

सौभाग्य से Buildroot इसे हमारे लिए डिफ़ॉल्ट रूप से सेट करता है जब BR2_TARGET_ROOTFS_CPIO=yदिया जाता है।

फिर आप qemu -initrdविकल्प के साथ QEMU में CPIO पास करते हैं । मेरा पूरा QEMU कमांड है:

./buildroot/output.x86_64~/host/usr/bin/qemu-system-x86_64 -m 128M -monitor telnet::45454,server,nowait -netdev user,hostfwd=tcp::45455-:45455,id=net0 -smp 1  -M pc -append ' nopat nokaslr norandmaps printk.devkmsg=on printk.time=y console=ttyS0' -device edu -device lkmc_pci_min -device virtio-net-pci,netdev=net0 -kernel ./buildroot/output.x86_64~/images/bzImage  -nographic  -initrd './buildroot/output.x86_64~/images/rootfs.cpio'

यहाँ एक न्यूनतर पूरी तरह से स्वचालित Buildroot + QEMU उदाहरण है: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/b3868a3b009f2ab446d3db3d173bbb7c697##ititrd

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