Linux 커널이 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/...
치로 틸리冠状病毒审查六四事件法轮功

답변:


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매개 변수 가 표시되어야합니다 .


파일을 어떻게 마운트 해제합니까?
Coder404

umount /mnt/rootfs
t-8ch

그렇게하면 umount가 나타납니다. / mnt / rootfs가 마운트되지 않았습니다 (mtab에
따름

아마도 Coder404는 해당 시스템에 디스크를 연결하고 단지를 실행하지 않는 initinitrd. 여기서는 disk.img둘 다 하드 디스크와 initrd의미가없는 디스크로 전달합니다 .
Stéphane Chazelas

@StephaneChazelas -initrd거기에 없었어야 할 힌트에 대해 감사드립니다 .
t-8ch

8

무슨 일이 일어나고 있는지 "구식"방식으로 리눅스를 부팅하려고합니다. initrd램 디스크에서 커널에 의해 압축이 풀린 압축 된 cpio 아카이브와는 달리 램 디스크 가있는 곳 이며, 엔드 디바이스로 전환하는 오래된 방법이 있습니다.

이 모드에서 커널은 disk.img를 루트 파일 시스템으로 램 디스크로 마운트 한 다음 /linuxrc거기서 실행 합니다. 귀하의 경우에는 그러한 파일이 없습니다. 시 /linuxrc종료 (실제 루트 파일 시스템의 블록 장치를 가지고하는 것이 필요 무엇이든 가정되는) 커널은 실제 루트 파일 시스템을 마운트합니다.

위의 메시지는 램 디스크를 성공적으로 마운트하지만 (1,0 : 1은을위한 ram것이므로 /dev/ram0) 실제 루트 파일 시스템 / dev / sda1 (8,1 : 8은 sd, 1은 a1) 이 아니라는 것을 보여줍니다 . 커널 명령 줄 ( -append)을 지정하지 않았기 때문에 /dev/sda1커널 컴파일 타임에 또는을 사용하여 전달 된 CONFIG_CMDLINE에서 가져옵니다 rdev.

disk.img에 /sbin/init...를 사용 하여 작은 Linux 배포판과 같은 루트 파일 시스템을 포함 하려는 경우 대신 다음과 같이 작성하십시오.

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 램 디스크 대신 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정적으로 링크 된 버전이 제공됨 ) 해당 커널에 셸 및 다른 busybox 유틸리티가 제공됩니다.

커널은 이제 해당 모드 /init와 반대로 /linuxrc또는 /sbin/init해당 모드에서 실행 됩니다.


표시된 출력의 3 행은 커널이 initramdisk의 ext2 파일 시스템을 마운트했음을 보여줍니다. 따라서 모듈이 누락되지 않았을 것입니다.
t-8ch

오 예, @ t-8ch 덕분에 그것을 놓쳤습니다. 나는 무슨 일이 일어나고 있는지 알고 내 대답을 업데이트했다고 생각합니다.
Stéphane Chazelas

0

CONFIG_BLK_DEV_INITRD=y

이 커널 설정 옵션도 필요합니다. Linux 커널에서 initrd를 지원합니다.

Luckly Buildroot는 기본적으로 BR2_TARGET_ROOTFS_CPIO=y제공됩니다.

그런 다음 qemu -initrd옵션 을 사용하여 CPIO를 QEMU에 전달하십시오 . 내 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/b3868a3b009f2ab44fa6d3db3d174930b3cf7b69#initrd

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.