![systemd.run firstrun.sh 스크립트와 함께 qemu-system-aarch64를 사용하여 Raspberry 이미지를 실행하면 중단됩니다.](https://linux55.com/image/220505/systemd.run%20firstrun.sh%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80%20%ED%95%A8%EA%BB%98%20qemu-system-aarch64%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20Raspberry%20%EC%9D%B4%EB%AF%B8%EC%A7%80%EB%A5%BC%20%EC%8B%A4%ED%96%89%ED%95%98%EB%A9%B4%20%EC%A4%91%EB%8B%A8%EB%90%A9%EB%8B%88%EB%8B%A4..png)
Qemu를 사용하여 Raspberry Pi(+OS)를 에뮬레이션하려고 합니다. OS가 firstrun.sh
시작 시 스크립트를 실행하여 다양한 항목을 구성하기를 원합니다 .
이것이 내가 qemu를 시작하는 방법입니다:
qemu-system-aarch64 \
-M raspi3b \
-cpu cortex-a53 \
-m 1G \
-kernel kernel8.img \
-dtb bcm2710-rpi-3-b-plus.dtb \
-drive "file=2023-05-03-raspios-bullseye-arm64-lite.img,format=raw,index=0,media=disk" \
-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1 systemd.run=/boot/firstrun.sh systemd.run_success_action=none debug systemd.unit=kernel-command-line.target" \
-usb \
-device usb-mouse \
-device usb-kbd \
-device usb-net,netdev=net0 \
-nographic \
-serial mon:stdio \
-netdev user,id=net0,hostfwd=tcp::7777-:22
그러나 systemd 스크립트를 실행하도록 Qemu/kernel을 구성하면 systemd.run=/boot/firstrun.sh
멈춰 부팅을 계속할 수 없습니다.
인쇄된 마지막 줄은 다음과 같습니다.
[ OK ] Finished Command from Kernel Command Line.
[ OK ] Reached target Command from Kernel Command Line
다음은 최소한의 첫 실행 스크립트입니다.
#!/bin/bash
set +e
echo "This is the firstrun script"
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0
정확하게 재현하려면 다음 단계를 따르세요.
# Download image
wget https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64-lite.img.xz
xz --extract 2023-05-03-raspios-bullseye-arm64-lite.img.xz
# Setup image - extract kernel.img and copy firstrun script
mount_dir=/mnt/raspberrypi
free_loopdev="$(sudo losetup -f)"
sudo kpartx -a -v 2023-05-03-raspios-bullseye-arm64-lite.img
loop_mapper=/dev/mapper/$(basename "${free_loopdev}")
sudo mkdir -p "${mount_dir}"
sudo mount "${loop_mapper}p2" "${mount_dir}"
sudo mount "${loop_mapper}p1" "${mount_dir}/boot"
cp "${mount_dir}/boot/kernel8.img" .
cp "${mount_dir}/boot/bcm2710-rpi-3-b-plus.dtb" .
sudo cp firstrun.sh "${mount_dir}/boot"
# Run Qemu with Image
cmdline="rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1 systemd.run=/boot/firstrun.sh systemd.run_success_action=none debug systemd.unit=kernel-command-line.target"
qemu-img resize -f raw "2023-05-03-raspios-bullseye-arm64-lite.img" 4G
qemu-system-aarch64 \
-M raspi3b \
-cpu cortex-a53 \
-m 1G \
-kernel kernel8.img \
-dtb bcm2710-rpi-3-b-plus.dtb \
-drive "file=2023-05-03-raspios-bullseye-arm64-lite.img,format=raw,index=0,media=disk" \
-append "${cmdline}" \
-usb \
-device usb-mouse \
-device usb-kbd \
-device usb-net,netdev=net0 \
-nographic \
-serial mon:stdio \
-netdev user,id=net0,hostfwd=tcp::7777-:22
스크립트를 생략하면 firstrun.sh
시작 프로세스가 제대로 작동합니다.
firstrun.sh를 실행할 때 부팅 프로세스가 계속되지 않는 이유는 무엇입니까?
답변1
을 설정하면 systemd.run
암시적으로 설정됩니다 systemd.unit=kernel-command-line.target
(실제로 명령줄에서 설정함).분명히, 그러나 반드시 필요한 것은 아닙니다). 설정은 systemd.unit
systemd에게 "이렇게 하세요"라고 효과적으로 알려줍니다.바꾸다일반 시작을 수행하십시오."
이것이 바로 상황이 "멈춘" 것처럼 보이는 이유입니다. 스크립트의 첫 번째 실행이 올바르게 실행되고 systemd에 관한 한 다른 일은 일어날 필요가 없습니다.
가장 간단한 해결책은 아마도 firstrun.sh
다음과 같은 방법으로 스크립트를 종료하는 것입니다.
systemctl start --no-block multi-user.target
첫 번째 실행 스크립트가 완료된 후 정상적으로 계속 부팅됩니다.
다음과 같은 스크립트가 주어지면 firstrun.sh
:
#!/bin/sh
set -x
echo "enable ssh"
systemctl enable --now ssh
echo "set root password"
echo 'root:secret' | chpasswd
echo "continue boot"
systemctl start --no-block multi-user.target
root
시스템 부팅이 완료되면 콘솔에 성공적으로 로그인할 수 있습니다. SSH는 호스트 포트 7777에서 활성화됩니다.
귀하의 질문과 관련이 없지만 다음 매개변수를 kpartx
사용하면 -P
이를 피할 수 있습니다 losetup
.
loopdev="$(sudo losetup -fP --show)"
sudo mkdir -p "${mount_dir}"
sudo mount "${loopdev}p2" "${mount_dir}"
sudo mount "${loopdev}p1" "${mount_dir}/boot"
루프 장치 사용을 방지하고 sudo
이를 사용하여 guestfish
이미지를 완전히 조작할 수 있습니다. (a) 원본 이미지의 Copy-On-Write 복제본을 생성한 다음 (b) 이를 구성하기 위해 다음과 같은 작업을 수행합니다.
#!/bin/bash
BASEIMAGE=2023-05-03-raspios-bullseye-arm64-lite.img
# Download image
if ! [ -f "$BASEIMAGE" ]; then
wget https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64-lite.img.xz
xz --extract 2023-05-03-raspios-bullseye-arm64-lite.img.xz
fi
echo "creating work image"
rm -f raspi-work.qcow2
qemu-img create -b "$BASEIMAGE" -F raw -f qcow2 raspi-work.qcow2 4G
echo "copying files"
guestfish -a raspi-work.qcow2 -m /dev/sda2:/ -m /dev/sda1:/boot <<EOF
copy-out /boot/kernel8.img .
copy-out /boot/bcm2710-rpi-3-b-plus.dtb .
copy-in firstrun.sh /boot/
EOF
# ...remainder of script here...