호스트 시스템 구성

호스트 시스템 구성

현재 블록 장치 드라이버를 구현하여 커널 프로그래밍을 시작하고 있습니다. "간단한" 구현을 할 수 있으며 블록 하위 시스템이 제공하는 기능에 대해 자세히 알아보고 싶습니다.

이를 위해 커널 장치 코드에서 실수를 할 때마다 개발 OS가 충돌하는 것을 방지하기 위해 qemu를 사용하여 내 OS를 에뮬레이트하고 싶습니다.

호스트 시스템 구성

내 워크스테이션에서는 커널 4.9.0을 실행하는 Debian 9를 사용하고 있습니다.

$ uname -a
Linux PC325 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux

미러디스크 제작

가상 머신을 생성하기 위해 500M 원시 이미지를 생성했습니다.dd if=/dev/zero of=vm-image.raw bs=1M count=512

그런 다음 다음 명령을 사용하여 ext4로 포맷합니다.mkfs.ext4 vm-image.raw


@meuh 댓글 이후 업데이트됨:
그런 다음 다음과 같이 디스크 이미지를 채웁니다.

mount vm-image.raw /mnt
mkdir /mnt/dev /mnt/lib /mnt/proc /mnt/root /mnt/run /mnt/sbin /mnt/sys
cp -r /etc /mnt/
cp -r /lib/systemd /mnt/lib
ln -s /lib/systemd/systemd /mnt/sbin/init

이제 에뮬레이트된 OS를 부팅하려고 하는데 구성하는 데 몇 가지 문제가 있습니다.

명령 실행

$ qemu-system-x86_64 -k fr -kernel /boot/vmlinuz-$(uname -r) -initrd /boot/initrd.img-$(uname -r) -hda vm/vm-image.raw -append "initrd=/boot/initrd.img-$(uname -r) root=/dev/sda rw console=ttyS0" -nographic

가이드 추적

[...] Kernel boot sequence [...]

Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ... done.
Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... [    2.015241] tsc: Refined TSC clocksource calibration: 3392.292 MHz
[    2.016768] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x30e5dd94d34, max_idle_ns: 440795304975 ns
[    2.895630] random: fast init done
Begin: Waiting for suspend/resume device ... Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
[   11.111765] random: crng init done
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
Begin: Running /scripts/local-block ... done.
done.
Gave up waiting for suspend/resume device
done.
Begin: Will now check root file system ... fsck from util-linux 2.29.2
[/sbin/fsck.ext4 (1) -- /dev/sda] fsck.ext4 -a -C0 /dev/sda 
/dev/sda: clean, 3607/32768 files, 12617/131072 blocks
done.
[   35.528453] EXT4-fs (sda): mounted filesystem with ordered data mode. Opts: (null)
done.
Begin: Running /scripts/local-bottom ... done.
Begin: Running /scripts/init-bottom ... done.
run-init: /sbin/init: No such file or directory
[   35.569247] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[   35.569247] 
[   35.570469] CPU: 0 PID: 1 Comm: run-init Not tainted 4.9.0-6-amd64 #1 Debian 4.9.82-1+deb9u3
[   35.571599] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[   35.572695]  0000000000000000 ffffffff9792e074 ffff974c05e14d00 ffffa66e8003feb8
[   35.573741]  ffffffff9777cfbd ffff974c00000010 ffffa66e8003fec8 ffffa66e8003fe60
[   35.574780]  a4112d94e56af84a ffff974c05e14d80 0000000000000100 ffff974c05e84490
[   35.575793] Call Trace:
[   35.576132]  [<ffffffff9792e074>] ? dump_stack+0x5c/0x78
[   35.576815]  [<ffffffff9777cfbd>] ? panic+0xe4/0x23f
[   35.577453]  [<ffffffff9767c2de>] ? do_exit+0xade/0xae0
[   35.578136]  [<ffffffff978058b4>] ? vfs_write+0x144/0x190
[   35.578830]  [<ffffffff9767c313>] ? SyS_exit+0x13/0x20
[   35.579510]  [<ffffffff97603b7f>] ? do_syscall_64+0x8f/0xf0
[   35.580223]  [<ffffffff97c113b8>] ? entry_SYSCALL_64_after_swapgs+0x42/0xb0
[   35.581209] Kernel Offset: 0x16600000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[   35.582584] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[   35.582584] 

질문

1 - 플로피 장치를 읽으려고 합니다.

부팅 시 커널이 존재하지 않거나 읽을 수 없는 플로피 장치에서 데이터를 읽으려고 시도하는 것 같습니다. 30번의 시도 후에 커널이 포기했기 때문에 심각한 문제는 아니었지만 부팅 순서가 30초 정도 느려졌습니다.

옵션을 사용하여 qemu를 실행 해 보았지만 -no-fd-bootchk아무 것도 변경되지 않았습니다.


고쳐 쓰다:
-fda floppy.img1ko의 제로화된 원시 이미지로서 floppy.img플로피 관련 오류 메시지를 정확하게 억제하고 부팅 시 최대 20초를 절약합니다. 그러나 부트 추적에서 볼 수 있듯이 /scripts/local-block여전히 여러 번 실행되며 다음 단계로 이동하는 데 최대 10초가 걸립니다.


2 - 시스템을 초기화할 수 없습니다.


@meuh 댓글 이후 업데이트됨:

커널이 유효한 초기화 스크립트를 찾을 수 없는 것 같습니다. 그러나 /sbin/init디스크 이미지에 존재하며 에 대한 심볼릭 링크입니다 /lib/systemd/systemd.

커널 패닉이 발생하는데 원인이 무엇인지 모르겠습니다.


질문

저는 qemu를 처음 접했고 에뮬레이션 시스템이 작동하는 데 거의 가까워진 것 같지만 더 이상 얻을 수 없습니다.

매개변수를 사용해 보았지만 완전히 부팅하고 initramdisk 프롬프트 대신 bash 프롬프트를 표시하는 솔루션을 찾을 수 없었습니다.

@meuh 댓글 이후 업데이트됨:
시스템을 초기화하려면 디스크 이미지에 무엇을 복사해야 합니까?

답변1

일반적으로 사람들은 iso 또는 기존 qemu 이미지에서 qemu를 설치하기 때문에 아직 이 작업을 수행하지 않았으므로 다음보다 더 쉬운 방법이 있을 수 있습니다. 누락된 것은 필요한 파일 시스템과 거의 동일합니다.chroot.

한 가지 시도해 볼 점은

sudo debootstrap --arch=amd64 unstable ~/debian-tree/

약 300MB 크기의 파일을 삭제하고 압축을 푼 후 시스템 컨테이너로 "실행"하여 테스트할 수 있습니다.

sudo systemd-nspawn -D ~/debian-tree/ -b

바라보다 man machinectl. qemu 이미지를 블록 장치로 만들어 마운트할 수 있습니다.

sudo apt-get install qemu-utils
sudo modprobe nbd
ls /dev/nbd*   # gives /dev/nbd0  /dev/nbd1 ...
sudo qemu-nbd -c /dev/nbd0 /my/vm-image
sudo mount /dev/nbd0 /mnt/...  # nbd0p1 if you have partitioned
sudo rsync -HSaxX ~/debian-tree/ /mnt/... 

그리고 이 트리를 거기에 복사하세요. qemu를 실행할 때 충돌을 방지하려면 일반적으로 더 큰 VM 크기를 제공해야 합니다.

qemu-system-x86_64 -m 512M ... -machine pc,accel=kvm  -cpu host -enable-kvm

사용하면 -boot d플로피 디스크에 대한 액세스를 피할 수 있습니다.

관련 정보