ラベル QEMU の投稿を表示しています。 すべての投稿を表示
ラベル QEMU の投稿を表示しています。 すべての投稿を表示

2021年10月24日日曜日

QEMU + aarch64 版 Ubuntu 18.04 で USB パススルーして V4L2 を試す

aarch64 のプラットフォームで Web カメラを使う機会があるので、エミュレーターで何とかできないか試してみた。

前提

Windows 11 Pro -> x86_64 Ubuntu 18.04 on VirtualBox -> aarch64 Ubuntu 18.04 on QEMU という感じに重ねて、 USB パススルーで Windows から QEMU まで Web カメラを繋げていく。

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04
  • QEMU: QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.38)
  • 各 Ubuntu のインストール手順は省略。最小構成でインストールしている。

VirtualBox のゲストに、ホストの USB を繋げる方法は、Windows 11 上の VirtualBox で、 Ubuntu 18.04 に Web カメラを繋げる - mikoto2000 の日記 の記事参照。

aarch64 版 Ubuntu 18.04 の準備

cortex-a57 の virt VM を作る。

QEMU のインストール

sudo apt-get install -y qemu

これで、 QEMU の VM を作成・実行するためのコマンド一式がインストールされる。

aarch64 Ubuntu 18.04 ネットブート ISO イメージのダウンロード

arm64 版 Ubuntu のネットブートインストーラーのダウンロードページ から、 mini.iso をダウンロード。

wget http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/installer-arm64/current/images/netboot/mini.iso

aarch64 VM 用のディスクイメージ生成

qemu-img コマンドでディスクイメージを作成する。

qemu-img create -f qcow2 storage.qcow2 50G

QEMU 用 UEFI イメージの取得

QEMU 用の UEFI イメージを、 Linaro が公開しているのでそれをダウンロード。

wget https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd

USB パススルーのための情報取得

lsusb で、 Web カメラの Vendor ID, Product ID を特定する。

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 019: ID 1bcf:2281 Sunplus Innovation Technology Inc.
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

今回の場合、 Vendor ID: 0x1bcf, Product ID: 2281 のものが Web カメラ。

USB パススルーをするときに使うので、それぞれをメモ。

aarch64 の QEMU で Ubuntu 18.04 をインストール

ここまでで調達した、インストーラー、UEFI, ディスクイメージを使って QEMU を起動。

sudo qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -m 4096 \
    -bios ./QEMU_EFI.fd \
    -drive if=none,file=storage.qcow2,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -cdrom ./mini.iso \
    -nographic

aarch64 の QEMU で Ubuntu 18.04 を実行

インストールが完了したら、 VirtualBox にパススルーした USB カメラを、 QEMU にパススルーしながら実行する。

sudo qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -m 4096 \
    -bios ./QEMU_EFI.fd \
    -drive if=none,file=storage.qcow2,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -device nec-usb-xhci,id=usb \
    -device usb-host,bus=usb.0,vendorid=0x1bcf,productid=0x2281 \
    -nographic

aarch64 版 Ubuntu で USB が認識されていることを確認

ここでもやはり lsusb で確認。

mikoto@ubuntu:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1bcf:2281 Sunplus Innovation Technology Inc.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Vendor ID: 0x1bcf, Product ID: 0x2281 の、 Web カメラが認識されていることがわかる。

V4L2 の動作確認

ffmpeg を使って、 Web カメラの画像を録画できることを確認する。

aarch64 版 Ubuntu 18.04 に ffmpeg をインストール

sudo apt-get install -y ffmpeg

ffmpeg でカメラから画像生成

sudo ffmpeg -f v4l2 -s 352x288 -i /dev/video0 -f image2 ./output-%6d.jpeg

q で録画を停止して、 ls すると、 jpeg 画像が大量に吐き出されている。

QEMU 上の ffmpeg で生成したファイルを抽出

QEMU を停止し、 x86_64 Ubuntu 上で以下コマンドを実行

# qcow2 ファイルをマウント
sudo modprobe nbd
sudo mkdir /mnt/tmp
sudo qemu-nbd -c /dev/nbd0 ./storage.qcow2
sudo mount -o ro /dev/nbd0p2 /mnt/tmp/

/mnt/tmp に aarch64 Ubuntu のディスクがマウントされるので、 吐き出された jpeg を回収、 Windows と共有しているディレクトリへコピーして Windows 上で jpeg ファイルを確認。

OK.

ディレクトリの共有方法は Windows 11 上の VirtualBox で、 Ubuntu 18.04 とフォルダー共有を行う - mikoto2000 の日記 参照。

# 後始末
sudo umount /mnt/tmp/
sudo killall qemu-nbd

こんな画像が大量に吐き出されていた。

以上。

参考資料

2021年2月3日水曜日

qemu-system-arm で動く Linux を Yocto でビルドする

Yocto Project Quick Build — The Yocto Project ® 3.2.1 documentationqemuarm で試す。

前提

  • OS: Windows 10 Pro
  • Docker: Docker version 20.10.2, build 2291f61
  • 使用する Docker イメージ: debian:buster-slim

作業用コンテナ起動

docker run -it --name myyocto --workdir="/work" debian:buster-slim

必要パッケージのインストール

WORK_DIR=$(pwd)
apt-get update

# Quick Build に記載されているパッケージをインストール
apt-get install -y gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev

# Quick Build には記載されていないが、これが無いとビルド時にエラーが発生した
apt-get install -y python2

# qemu インストール
apt-get install -y qemu-system-arm

yocto の clone とビルド

# yocto を clone
git clone git://git.yoctoproject.org/poky.git
cd poky
git checkout tags/yocto-3.2.1 -b my-yocto-3.2.1

# yocto 環境設定読み込み
source oe-init-build-env

# arm 用のバイナリをビルドするための設定
sed -i -e 's/MACHINE ??= "qemux86-64"/MACHINE ??= "qemuarm"/' conf/local.conf

# root でビルドできるように設定
touch conf/sanity.conf

# 詳細不明だが、エラーが発生した
# エラーになっても 2, 3 回同じコマンドを繰り返すと成功することがある。
# 一発で成功することもある。謎。
bitbake core-image-minimal

ビルド成果物を qemu-system-arm で実行

runqemu を実行すると、「tun モジュールが無い」と怒られたので、 qemu-system-arm コマンドで実行する。

qemu-system-arm -M virt -m 1024 \
  -kernel tmp/deploy/images/qemuarm/zImage \
  -drive if=none,file=tmp/deploy/images/qemuarm/core-image-minimal-qemuarm.ext4,format=raw,id=hd \
  -device virtio-blk-device,drive=hd \
  -netdev user,id=usernet \
  -device virtio-net-device,netdev=usernet \
  -append "root=/dev/vda" \
  -nographic -no-reboot

以上。

参考資料

2021年1月31日日曜日

qemu-system-arm で Debian buster armhf を動かす

Debian installer を使って、 Debian buster armhf をインストールする。

前提

必要ファイルのダウンロード

インストーラー起動用の vmlinuz と initrd をダウンロード。

Invoke-WebRequest http://ftp.debian.org/debian/dists/buster/main/installer-armhf/current/images/netboot/initrd.gz -OutFile initrd.gz
Invoke-WebRequest http://ftp.debian.org/debian/dists/buster/main/installer-armhf/current/images/netboot/vmlinuz -OutFile vmlinuz

qemu-system-arm インストール済みのコンテナを起動

mount コマンドを利用するので、 --privileged オプション付きで起動する。

docker run -it --rm --privileged -v "$(pwd):/work" --workdir="/work" mikoto2000/qemu-system-arm

インストール

ディスクイメージ作成

qemu-img create -f qcow2 hda.qcow2 8G

インストーラー起動

qemu-system-arm -M virt -m 1024 \
  -kernel vmlinuz \
  -initrd initrd.gz \
  -drive if=none,file=hda.qcow2,format=qcow2,id=hd \
  -device virtio-blk-device,drive=hd \
  -netdev user,id=usernet \
  -device virtio-net-device,netdev=usernet \
  -nographic -no-reboot

Debian インストーラーに従ってインストールを行う。

起動用ファイルをディスクイメージから抜き出す

Debian をインストールした qcow2 を raw へ変換

qemu-img convert -O raw hda.qcow2 hda.img

イメージをマウントし、 vmlinuz と initrd をコピー

マウントオフセット確認

START=$(fdisk -l hda.img | grep "*" | grep "hda.img" | awk '{print $3}')
OFFSET=$(($START*512))

マウント

mkdir ./tmp
mount -o loop,offset=$OFFSET hda.img ./tmp

ファイルコピー

cp ./tmp/vmlinuz-4.19.0-13-armmp-lpae ./
cp ./tmp/initrd.img-4.19.0-13-armmp-lpae ./

マウント解除

umount ./tmp

インストールした Debian の起動

コピーした vmlinuz と initrd を使って Debian を起動する。

qemu-system-arm -M virt -m 1024 \
  -kernel vmlinuz-4.19.0-13-armmp-lpae \
  -initrd initrd.img-4.19.0-13-armmp-lpae \
  -drive if=none,file=hda.qcow2,format=qcow2,id=hd \
  -device virtio-blk-device,drive=hd \
  -netdev user,id=usernet \
  -device virtio-net-device,netdev=usernet \
  -append "root=/dev/vda2" \
  -nographic -no-reboot

以上。

参考資料

2021年1月30日土曜日

qemu-system-arm で Raspbian を実行する

qemu-system-arm で Linux を動かしたかったのだが、いまいちやり方がわからん…。

少し調べた範囲だと、カーネルビルドからやっているものばかりで腰が重かったのだが、 Raspbian のイメージが配布されているようなので、とりあえずそれを動かしてみる。

Ubuntu で Raspbian システムを起動(QEMU, qemu-rpi-kernel を使用) を、 nographicqemu-system-arm で試す感じ。

前提

必要ファイルのダウンロード

# カーネル
Invoke-WebRequest https://raw.githubusercontent.com/dhruvvyas90/qemu-rpi-kernel/master/kernel-qemu-4.19.50-buster -OutFile kernel-qemu-4.19.50-buster
# Device Tree
Invoke-WebRequest https://raw.githubusercontent.com/dhruvvyas90/qemu-rpi-kernel/master/versatile-pb-buster.dtb -OutFile versatile-pb-buster.dtb
# イメージアーカイブダウンロード
Invoke-WebRequest -UseBasicParsing http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2020-02-14/2020-02-13-raspbian-buster.zip -OutFile 2020-02-13-raspbian-buster.zip
# イメージアーカイブ展開
Expand-Archive -Path .\2020-02-13-raspbian-buster.zip -DestinationPath .\

コンテナ起動

docker run -it --rm -v "$(pwd):/work" --workdir="/work" mikoto2000/qemu-system-arm

Raspbian 実行

qemu-system-arm -M versatilepb \
    -cpu arm1176 \
    -m 256 \
    -hda 2020-02-13-raspbian-buster.img \
    -dtb versatile-pb-buster.dtb \
    -kernel kernel-qemu-4.19.50-buster \
    -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw " \
    -no-reboot \
    -nographic

初期ログイン情報は以下の通り。

  • user: pi
  • password: raspberry

以上。

参考資料

2020年8月23日日曜日

Debian 10 で TOPPERS/ASP3 in Zig を動かす

前提

  • OS: Windoes 10 Pro 1909
  • Docker :Docker version 19.03.12, build 48a66213fe
  • Docker Image: debian:buster-slim
  • asp3_in_zig: 3d0d9f6bb7bdafaafb5a76529cc8af3ade577e77

docker run -it --rm debian:buster-slim してからの作業。

環境構築

apt-get update
apt-get install -y git curl bzip2 xz-utils make ruby qemu-system-arm gcc-arm-none-eabi

# zig 0.6.0+4e63cae36 を /opt/zig-linux-x86_64-0.6.0+4e63cae36 にインストール
curl -L https://ziglang.org/builds/zig-linux-x86_64-0.6.0+4e63cae36.tar.xz -O
tar xf zig-linux-x86_64-0.6.0+4e63cae36.tar.xz -C /opt
export PATH=$PATH:/opt/zig-linux-x86_64-0.6.0+4e63cae36

# tecsgen 1.7.0 のインストール
curl -L https://www.toppers.jp/download.cgi/tecsgen-1.7.0.tgz -O
tar xf tecsgen-1.7.0.tgz -C /opt

asp3_in_zig の取得とビルド

WORK_DIR=/work
ASP3_DIR=$WORK_DIR/asp3_in_zig

mkdir -p $WORK_DIR
cd $WORK_DIR
git clone https://github.com/toppers/asp3_in_zig.git

cd $ASP3_DIR
git checkout 3d0d9f6bb7bdafaafb5a76529cc8af3ade577e77

mkdir $ASP3_DIR/OBJ-ARM
cd $ASP3_DIR/OBJ-ARM
../configure.rb -G /opt/tecsgen-1.7.0/tecsgen/tecsgen.rb -T ct11mpcore_gcc -O "-DTOPPERS_USE_QEMU"
make

sample1 の実行

root@e5307855eb8c:/work/asp3_in_zig/OBJ-ARM# qemu-system-arm -M realview-eb-mpcore -semihosting -m 128M -nographic -kernel asp
pulseaudio: pa_context_connect() failed
pulseaudio: Reason: Connection refused
pulseaudio: Failed to initialize PA contextaudio: Could not init `pa' audio driver
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM default
alsa: Could not initialize DAC
alsa: Failed to open `default':
alsa: Reason: No such file or directory
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM default
alsa: Could not initialize DAC
alsa: Failed to open `default':
alsa: Reason: No such file or directory
audio: Failed to create voice `lm4549.out'

TOPPERS/ASP3 Kernel in Zig Release 3.6.0 for ARM CT11MPCore (Aug 23 2020, 12:34:09)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2020 by Embedded and Real-Time Systems Laboratory
               Graduate School of Informatics, Nagoya Univ., JAPAN

no time event is processed in hrt interrupt.
System logging task is started.
Sample program starts (exinf = 0).
task1 is running (001).   |
task1 is running (002).   |
task1 is running (003).   |
...(snip)

以上。

参考資料

2020年5月11日月曜日

Docker で FreeRTOS on Xilinx/qemu

gcc-aarch64-none-elfXilinx/qemu の組み合わせで動かすための Makefile ができたので、それを使って実行までやるコマンドをメモ。

前提

実行手順

PowerShell で以下コマンドを実行する。

cd ${WORK_DIR}
git clone --recurse-submodules https://github.com/FreeRTOS/FreeRTOS.git
mkdir FreeRTOS/FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/lib
curl https://gist.githubusercontent.com/mikoto2000/f7fc041c312df882199fce4a07f15488/raw/021dcd00c2f22c8c2f109df7111704d5e8c548a1/Makefile -OutFile FreeRTOS/FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53/Makefile

docker run -it --rm -v "$(pwd)/FreeRTOS:/work" --workdir="/work/FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53" mikoto2000/gcc-aarch64-none-elf:9.2-2019.12 make

docker run -it --rm -v "$(pwd)/FreeRTOS/FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53/obj:/work" --workdir="/work" mikoto2000/qemu-xilinx:2019.1 qemu-system-aarch64 -M arm-generic-fdt -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb -serial mon:stdio -nographic -device loader,file=./FreeRTOSDemo_A53.elf -device loader,addr=0xfd1a0104,data=0x0000000e,data-len=4
図 1: デモ実行結果

以上。

参考資料

2019年9月26日木曜日

TOPPERS/FMP3 を Xilinx/qemu で動かす

この記事を読む前に

この記事を書いた翌日に、「fmp_3.0/target/zybo_z7_gcc/target_user.txt にビルド方法書いてあるよ」って教えてもらえました。

4.システム構築手順と実行手順

4.1 システム構築

ZYBO_Z7用のFMP3カーネルを構築する手順は,「TOPPERS/FMP3カーネル ユーザー
ズマニュアル」の「3.クイックスタートガイド」の章に記述されている通り
である.

シリアルドライバを使用する際には以下のオプションでシリアルドライバと各
種システムサービスをビルド対象とする.

configure.rb -T zybo_z7_gcc -w -S "syslog.o banner.o serial.o chip_serial.o logtask.o xuartps.o"
                         

Xilinx SDKでビルドする場合は,ワークスペースを作成し,zybo_z7_sdkフォルダ
にあるプロジェクトをインポートすることで,サンプルプログラムがビルド可
能である.

fmp3_zybo_z7_gcc-20190830.zipfmp_3.0/target/zybo_z7_gcc/target_user.txt より引用

以上、解散!

背景

xilinx/qemu で動く TOPPERS カーネルの確認メモ - mikoto2000 の日記 で、 「動かなかった(そもそもビルドが成功しない)」と報告した。

しかし、 TOPPERS のメーリングリストにビルドのヒントがあったので再挑戦する。

■ TOPPERS/FMP3, HRMP3 対応

  現状の TOPPERS/FMP3, HRMP3 は、TECS 未対応のために configure.rb
  実行時に -w (OMIT_TECS = true) を指定しなければ、ビルドするこ
  とができません。この状況を一刻も早く改めるべく、TECS WG では、
  これらのカーネルの TECS 対応を行っています。

  本セッションでは、初めに TOPPERS/FMP3, HRMP3 カーネルに TECS を
  適用することのメリットを説明した後、今回初めて対応するクラス
  (プロセッサコアを割付る単位) を TECS でどのように扱うのが妥当か
  を、ご相談させていただくつもりです。

  昨年の TECS のセッションではコアな部分の説明にとどまっておりま
  したが、本年はチュートリアル的な説明をさせていただいた上で、コ
  アな部分のご相談をさせていただくつもりです。TECS や、それらのカー
  ネルをご存じない方がご参加いただいても、なにがしか得らるものが
  あるように配慮いたします。

(toppers-users 1) TOPPERS開発者会議セッション内容のご案内 より引用。

configure.rb -w とすればよいようだ。試す。

環境構築

xilinx/qemu で動く TOPPERS カーネルの確認メモ - mikoto2000 の日記 の「前提」、 「準備」で準備した環境と同じものを使う。

作業記録

-w を付けて configure して make する。

cd /zybo_z7/fmp_3.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_z7_gcc -w
make

...リンクエラーになった。

...(略)
arm-none-eabi-gcc -O2 -Wall -g   -mlittle-endian -mcpu=cortex-a9 -DTOPPERS_OMIT_TECS  -DUSE_BYPASS_IPI_DISPATCH_HANDER -D__TARGET_ARCH_ARM=7  -I. -I../include  -I../target/zybo_z7_gcc -I../arch/arm_gcc/zynq7000 -I../arch/arm_gcc/common -I../arch/gcc -I.. -I../sample -I./gen -I../tecs_kernel -I../tecsgen/tecs -I../tecsg
en/tecs/rpc -L objs -nostdlib  -mlittle-endian -mcpu=cortex-a9   -Wl,-T,../target/zybo_z7_gcc/zybo_z7.ld  -L. -o fmp \
                objs/start.o  objs/sample1.o objs/log_output.o objs/vasyslog.o objs/t_perror.o objs/strerror.o     objs/kernel_cfg.o \
                -lkernel -lc -lgcc
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `syslog':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:253: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `t_perror':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:268: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:268: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:268: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `t_syslog_3':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o:/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:268: more undefined references to `syslog_wri_log' follow
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `main_task':
/zybo_z7/fmp_3.0/mysample/../sample/sample1.c:639: undefined reference to `syslog_msk_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../sample/sample1.c:649: undefined reference to `serial_opn_por'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../sample/sample1.c:654: undefined reference to `serial_ctl_por'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../sample/sample1.c:726: undefined reference to `serial_rea_dat'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `t_syslog_3':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `t_perror':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:268: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/sample1.o: in function `main_task':
/zybo_z7/fmp_3.0/mysample/../sample/sample1.c:934: undefined reference to `syslog_msk_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../sample/sample1.c:938: undefined reference to `syslog_msk_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o: in function `_kernel_inthdr_82':
/zybo_z7/fmp_3.0/mysample/kernel_cfg.c:324: undefined reference to `sio_isr'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x448): undefined reference to `logtask_terminate'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x450): undefined reference to `sio_terminate'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x478): undefined reference to `print_banner'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x490): undefined reference to `print_banner'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:/zybo_z7/fmp_3.0/mysample/kernel_cfg.c:440: undefined reference to `syslog_initialize'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x4a8): undefined reference to `print_banner_copyright'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x4b0): undefined reference to `serial_initialize'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: objs/kernel_cfg.o:(.rodata+0x718): undefined reference to `logtask_main'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(target_kernel_impl.o): in function `_kernel_target_initialize':
/zybo_z7/fmp_3.0/mysample/../target/zybo_z7_gcc/target_kernel_impl.c:201: undefined reference to `sio_initialize'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(target_kernel_impl.o): in function `target_fput_initialize':
/zybo_z7/fmp_3.0/mysample/../target/zybo_z7_gcc/target_kernel_impl.c:252: undefined reference to `sio_opn_por'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../target/zybo_z7_gcc/target_kernel_impl.c:252: undefined reference to `sio_opn_por'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(target_kernel_impl.o): in function `zybo_z7_uart_fput':
/zybo_z7/fmp_3.0/mysample/../target/zybo_z7_gcc/target_kernel_impl.c:264: undefined reference to `sio_snd_chr'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../target/zybo_z7_gcc/target_kernel_impl.c:264: undefined reference to `sio_snd_chr'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(gic_kernel_impl.o): in function `t_syslog_3':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(core_kernel_impl.o): in function `t_syslog_3':
/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:191: undefined reference to `syslog_wri_log'
/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: ./libkernel.a(core_kernel_impl.o):/zybo_z7/fmp_3.0/mysample/../include/t_syslog.h:220: more undefined references to `syslog_wri_log' follow
collect2: error: ld returned 1 exit status
make: *** [Makefile:443: fmp] Error 1

syslog_wri_log が見つからない。これはどこにあるんだろう?

syslog_wri_log を探す

# find /zybo_z7/fmp_3.0 -name "*.c" -print0 | xargs -0 grep syslog_wri_log
/zybo_z7/fmp_3.0/syssvc/syslog.c: *  syslog_wri_logの入口にトレースログマクロを置く.
/zybo_z7/fmp_3.0/syssvc/syslog.c:syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)

syssvc/syslog.c。たしかにビルドログを見てもこれをビルドしている様子はない。どうにかしてビルド対象に入れる必要があるようだ?

とりあえず Makefileconfigure.rb を流し読み。

configure.rb-S オプションがあるようだ。

#  -S <syssvcobjs>              システムサービスのオブジェクトファイル
#                                               (.oファイル名で指定.複数指定可)

試す。

ruby ../configure.rb -T zybo_z7_gcc -w -S syslog.o
make clean
make

またリンクエラー。

serial_*, sio_*, print_banner, logtask_*, xuartps_* が順番に見つからなくなっていったが、同じように find + grep でファイルを特定して -S に追加。

ruby ../configure.rb -T zybo_z7_gcc -w -S "syslog.o serial.o chip_serial.o banner.o logtask.o xuartps.o"
make clean
make

configuration check passed。良い感じ?

qemu で実行。

# qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./fmp

TOPPERS/FMP3 Kernel Release 3.0.0 for ZYBO_Z7 <Zynq-7000, Cortex-A9> (Sep 26 2019, 12:37:57)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

Processor 2 start.
Processor 1 start.
local_inirtn exinf = 2, counter = 1
local_inirtn exinf = 1, counter = 2
Server task 2 starts.
System logging task is started on port 1.
Server task 1 starts.
Sample program starts (exinf = 1).
select tskno 0x11
select cycid 1
select almid 1
select processor 1
select class     1
task1_1 is running on prc1 (001) .   |
task1_1 is running on prc1 (002) .   |
task1_1 is running on prc1 (003) .   |
task1_1 is running on prc1 (004) .   |
task1_1 is running on prc1 (005) .   |
...(略)

動いた。 -S に入れるべきか微妙なオブジェクトファイルを追加してしまっているが、そのあたりはまぁ動いたから良いかということで許して...。

今回はここまで。

更新履歴

日付 更新内容
2019/9/26 新規作成
2019/9/27 ハードウェア依存部のドキュメントにビルド方法が明記されている件について追記

2019年9月9日月曜日

xilinx/qemu で動く TOPPERS カーネルの確認メモ

xilinx/qemu で、 TOPPERS カーネルがどこまで動くかを確認した記録。

前提

debian:buster-slim 環境に、ツール群を一通りそろえて検証した。

起動コマンドは以下。

docker run -it "debian:buster-slim"

準備

必要なパッケージのインストール

# いつもの
apt-get update
apt-get -y upgrade

# qemu ビルドに必要なもの
apt-get install -y build-essential python libglib2.0-dev libgcrypt20-dev zlib1g-dev autoconf automake libtool bison flex libpixman-1-dev

# dtb ビルドに必要なもの
apt-get install -y git device-tree-compiler

# TOPPERS カーネルビルドに必要なもの
apt-get install -y perl ruby

# その他
apt-get install -y curl unzip

xilinx/qemu のビルド

cd /
git clone --recursive https://github.com/Xilinx/qemu.git
cd qemu
./configure --target-list="aarch64-softmmu,microblazeel-softmmu,arm-softmmu" --enable-fdt --disable-kvm --disable-xen
make
make install

devicetree のビルド

xilinx/qemu-devicetree

cd /
git clone --recursive https://github.com/Xilinx/qemu-devicetrees.git
cd qemu-devicetrees
make OUTDIR=/var/dts

Xilinx/linux-xlnx

cd /
git clone https://github.com/Xilinx/linux-xlnx.git
cd linux-xlnx
sed -i -e "s/#include/\/include\//" arch/arm/boot/dts/zynq-zybo.dts
dtc -I dts -O dtb -o /var/dts/zynq-zybo.dtb arch/arm/boot/dts/zynq-zybo.dts

cfg の配置

curl -L https://github.com/mikoto2000/cfg-1/releases/download/1.9.7.2/cfg.tar.gz -O
tar xf cfg.tar.gz -C /usr/local/bin
rm cfg.tar.gz

GNU Arm Embedded Toolchain の配置

GNU-A

Aarch32

cd /
curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-eabi.tar.xz?revision=402e6a13-cb73-48dc-8218-ad75d6be0e01&la=en" -o gcc-arm-8.3-2019.03-x86_64-arm-eabi.tar.xz
tar xf gcc-arm-8.3-2019.03-x86_64-arm-eabi.tar.xz -C /opt/
rm gcc-arm-8.3-2019.03-x86_64-arm-eabi.tar.xz
export PATH=$PATH:/opt/gcc-arm-8.3-2019.03-x86_64-arm-eabi/bin

Aarch64

cd /
curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-aarch64-elf.tar.xz?revision=d678fd94-0ac4-485a-8054-1fbc60622a89&la=en" -o gcc-arm-8.3-2019.03-x86_64-aarch64-elf.tar.xz
tar xf gcc-arm-8.3-2019.03-x86_64-aarch64-elf.tar.xz -C /opt/
rm gcc-arm-8.3-2019.03-x86_64-aarch64-elf.tar.xz
export PATH=$PATH:/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin

GNU-RM

cd /
curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2019q3/RC1.1/gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2?revision=c34d758a-be0c-476e-a2de-af8c6e16a8a2?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,8-2019-q3-update" -o gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2
tar xf gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2 -C /opt/
rm gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2
export PATH=$PATH:/opt/gcc-arm-none-eabi-8-2019-q3-update/bin

確認結果

atk2-sc1-mc

Zynq UltraScale+ MPSoC Cortex-R5

1.4.2(atk2-sc1-mc_zynqmp_r5_gcc-20190620.tar.gz)(動かなかった)

QEMU での実行時にコンソールが無反応。

1.4.2(atk2-sc1-mc_zynqmp_r5_gcc-20170929.tar.gz)(動いた)

ビルド

atk2-sc1-mc_zynqmp_r5_gcc-20190620.tar.gz だと、 QEMU での実行時にコンソールが無反応だったので atk2-sc1-mc_zynqmp_r5_gcc-20170929.tar.gz を使用した。

cd /
curl -L https://toppers.jp/download.cgi/atk2-sc1-mc_zynqmp_r5_gcc-20170929.tar.gz -O
tar xf atk2-sc1-mc_zynqmp_r5_gcc-20170929.tar.gz
rm atk2-sc1-mc_zynqmp_r5_gcc-20170929.tar.gz

cd atk2-sc1-mc_1.4.2/
mkdir mysample
cd mysample
../configure -g /usr/local/bin/cfg -T zynqmp_r5_gcc
make GCC_TARGET=arm-none-eabi
実行
qemu-system-aarch64 -M arm-generic-fdt -nographic -serial mon:stdio -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb -device loader,file=./atk2-sc1-mc,cpu-num=4 -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 -device loader,addr=0xff9a000,data=0x8000218,data-len=4

ASP3

ZYBO-Z7

3.4.0(動いた)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/asp3_zybo_z7_gcc-20190830.zip -O
unzip asp3_zybo_z7_gcc-20190830.zip -d /zybo_z7
rm asp3_zybo_z7_gcc-20190830.zip

cd /zebo_z7/asp_3.4.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_z7_gcc
make
実行
qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./asp

ZYBO

3.4.0(いちおう動いた)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/asp3_zybo_gcc-20190325.zip -O
unzip asp3_zybo_gcc-20190325.zip
rm asp3_zybo_gcc-20190325.zip

cd asp_3.4.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_gcc
make
実行

以下コマンドで QEMU での動作を試した。 カーネル起動まではするが、タスクが想定通りの挙動をしない。

 qemu-system-aarch64 -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./asp

TOPPERS/ASP3 Kernel Release 3.4.0 for ZYBO <Zynq-7000, Cortex-A9> (Sep  8 2019, 12:20:51)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

System logging task is started.
(何も表示されない、反応しない)

以下だとロゴすら表示されない。

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./asp

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./asp -> qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./asp -> qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./asp としたらプログラムが起動した。初期化に問題があるかも。

3.2.0(動かなかった)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/asp3_zynq7000_gcc-20170726.zip -O
unzip asp3_zynq7000_gcc-20170726.zip
rm asp3_zynq7000_gcc-20170726.zip

cd asp_3.2.0
mkdir mysample
cd mysample
ruby -Ku ../configure.rb -T zynq7000_gcc
make
実行

以下コマンドで QEMU での動作を試した。 カーネル起動まではするが、タスクが想定通りの挙動をしない。

 qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./asp

TOPPERS/ASP3 Kernel Release 3.4.0 for ZYBO <Zynq-7000, Cortex-A9> (Sep  8 2019, 12:20:51)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

System logging task is started.
(何も表示されない、反応しない)

以下だとエラー。

 qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./asp

TOPPERS/ASP3 Kernel Release 3.2.0 for Xilinx Zynq-7000(Cortex-A9) (Sep  8 2019, 17:42:57)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2017 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

System logging task is started.
../arch/arm_gcc/common/gic_kernel_impl.c:191: Assertion `TMIN_INTPRI <= intpri && intpri <= TMAX_INTPRI' failed.

いろいろ調整が必要なようだ。

HRP3

ZYBO-Z7

3.1.0(いちおう動いた)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/hrp3_zybo_z7_gcc-20190830.zip -O
unzip hrp3_zybo_z7_gcc-20190830.zip -d /zybo_z7
rm hrp3_zybo_z7_gcc-20190830.zip

cd /zybo_z7/hrp_3.1
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_z7_gcc
make
実行

以下だと何も表示されない。

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp -> qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./hrp -> qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp としたらプログラムが起動した。初期化に問題があるかも。

ZYBO

3.1.0(いちおう動いた)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/hrp3_zybo_gcc-20190325.zip -O
unzip hrp3_zybo_gcc-20190325.zip
rm hrp3_zybo_gcc-20190325.zip

cd /hrp3_3.1.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_gcc
make
実行

以下コマンドで QEMU での動作を試した。 カーネル起動まではするが、タスクが想定通りの挙動をしない。

 qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./hrp

TOPPERS/HRP3 Kernel Release 3.1.0 for ZYBO <Zynq-7000, Cortex-A9> (Sep  8 2019, 11:18:06)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

System logging task is started.
(何も表示されない、反応しない)

以下だとロゴすら表示されない。

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp

qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp -> qemu-system-arm -M xilinx-zynq-a9 -m 1024 -serial null -serial mon:stdio -nographic -kernel ./hrp -> qemu-system-aarch64 -M arm-generic-fdt-7series -dtb /var/dts/zynq-zybo.dtb -serial null -serial mon:stdio -nographic -kernel ./hrp としたらプログラムが起動した。初期化に問題があるかも。

FMP3

ZYBO-Z7

3.0.0(動かなかった)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/fmp3_zybo_z7_gcc-20190830.zip -O
unzip fmp3_zybo_z7_gcc-20190830.zip -d /zybo_z7
rm fmp3_zybo_z7_gcc-20190830.zip

cd /zybo_z7/fmp_3.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_z7_gcc
make

make 時点で make: *** No rule to make target 'sample1.cdl', needed by 'gen/tecsgen.timestamp'. Stop. が発生。

実行

なし。

ZYBO

3.0.0(動かなかった)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/fmp3_zybo_gcc-20190331.tar.gz -O
tar xf fmp3_zybo_gcc-20190331.tar.gz
rm fmp3_zybo_gcc-20190331.tar.gz

cd /fmp3_3.0.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_gcc
make

make 時点で make: *** No rule to make target 'sample1.cdl', needed by 'gen/tecsgen.timestamp'. Stop. が発生。

実行

なし。

HRMP3

ZYBO-Z7

3.0.0(動かなかった)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/hrmp3_zybo_z7_gcc-20190830.zip -O
unzip hrmp3_zybo_z7_gcc-20190830.zip -d /zybo_z7
rm hrmp3_zybo_z7_gcc-20190830.zip

cd cd /zybo_z7/hrmp_3.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_z7_gcc
make

make 時点で make: *** No rule to make target 'sample1.cdl', needed by 'gen/tecsgen.timestamp'. Stop. が発生。

実行

なし。

ZYBO

3.0.0(動かなかった)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/hrmp3_zybo_gcc-20190329.tar.gz -O
tar xf hrmp3_zybo_gcc-20190329.tar.gz
rm hrmp3_zybo_gcc-20190329.tar.gz

cd /hrmp3_3.0.0
mkdir mysample
cd mysample
ruby ../configure.rb -T zybo_gcc
make

make 時点で make: *** No rule to make target 'sample1.cdl', needed by 'gen/tecsgen.timestamp'. Stop. が発生。

実行

なし。

FMP

Zynq UltraScale+ MPSoC Cortex-A53 AArch64

1.4.0(動いた)

ビルド
cd /
curl -L https://toppers.jp/download.cgi/fmp_zynqmp_a53_arm64_gcc-20190125.zip -O
unzip fmp_zynqmp_a53_arm64_gcc-20190125.zip -d a53
rm fmp_zynqmp_a53_arm64_gcc-20190125.zip

cd /a53/fmp_1.4.0/
mkdir mysample
cd mysample
chmod u+x ../configure
../configure -T zynqmp_a53_arm64_gcc -g /usr/local/bin/cfg
make GCC_TARGET=aarch64-elf
実行
qemu-system-aarch64 -M arm-generic-fdt -nographic -serial mon:stdio -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb -device loader,file=./fmp,cpu-num=0 -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4

Zynq UltraScale+ MPSoC Cortex-A53 AArch32(未検証)

QEMU を aarch32 で起動する方法がわからなかったため未検証。

Zynq UltraScale+ MPSoC Cortex-R5

1.4.0(fmp_zynqmp_a53_arm_gcc-20190125.zip)(動かなかった)

QEMU での実行時にコンソールが無反応。

1.4.0(fmp_zynqmp_a53_arm_gcc-20180713.zip)(動いた)

ビルド

fmp_zynqmp_r5_gcc-20190125.zip だと、 QEMU での実行時にコンソールが無反応だったので mp_zynqmp_r5_gcc-20180713.zip を使用した。

cd /
curl -L https://toppers.jp/download.cgi/fmp_zynqmp_r5_gcc-20180713.zip -O
unzip fmp_zynqmp_r5_gcc-20180713.zip -d r5
rm fmp_zynqmp_r5_gcc-20180713.zip

cd /r5/fmp_1.4.0/
mkdir mysample
cd mysample
chmod u+x ../configure
../configure -T zynqmp_r5_gcc -g /usr/local/bin/cfg
make GCC_TARGET=arm-none-eabi ENABLE_G_SYSLOG=true
実行
qemu-system-aarch64 -M arm-generic-fdt -nographic -serial null -serial mon:stdio -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb -device loader,file=./fmp,cpu-num=4 -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 -device loader,addr=0xff9a000,data=0x8000218,data-len=4

まとめに代えて

まとまらん...。

動かなかったものの大半が、 qemu の仕組み・使い方の問題の気がするので、もうちょっとドキュメント読み込んでいかないといけなさそう。

参考資料

2019年3月14日木曜日

Xilinx QEMU で Aarch64 ベアメタルの勉強をするための準備をした

Raspberry Pi 3+ をつかったり、 qemu-system-aarch64 を使ったりして、 ほんのちょっとベアメタルに挑戦したけど、仕切り直ししたくなったので、開発環境の構築からやりなおす。

今回は、環境一式そろえるところから、デバッグできることを確認するところまで。

前提環境

  • OS: Windows 10 Pro

構築予定環境を決める

ビルド環境と実行環境を決める。

ツールチェイン選定

Aarch64 のベアメタルに使えるツールチェインはいくつかあるらしい。

  • GNU Toolchain – Arm Developer
    • Aarch64 は、 GNU-A のやつ
  • Downloads - Linaro
    • aarch64-linux-gnu
      • ベアメタル開発も可能
      • 前勉強したときはこのツールチェインを使っていた
    • aarch64-elf
      • 本当はこっちを使うのが正しかったっぽい???(未検証)

それぞれのツールチェインの目的とか特徴とか言えれば良いのだけれど、そんな知識はない。

なんとなく、 GNU Toolchain – Arm Developer を使っていくことにする。

実行環境選定

この前コンパイルしたXilinx/qemu で実行するのがよさそう。

Raspberry Pi 3 も UltraScale+ も Cortex-A53 っぽいし、 Xilinx Quick Emulator User Guide を読めば比較的簡単にベアメタルプログラムの実行ができそうな気がする。

構成検討

慣れ親しんだ環境でやろうということで、以下の構成とする。

  • ビルド環境
    • OS: Windows 10 Pro
    • ツールチェイン: GNU Toolchain – Arm Developer
    • シェル環境: MSYS2
  • 実行環境

という感じでやっていく。

環境構築

GNU Toolchain をインストール

Windows 用バイナリが 32bit 用のものしかないけど問題ないでしょう。

  1. GNU Toolchain – Arm Developer にアクセス
  2. GNU toolchain for A-Profile -> Downloads を選択
  3. gcc-arm-8.2-2019.01-i686-mingw32-aarch64-elf.tar.xz をダウンロードして任意の場所に展開
    • この記事では ~/app/gcc-arm-8.2-2019.01-i686-mingw32-aarch64-elf に展開
  4. ~/app/gcc-arm-8.2-2019.01-i686-mingw32-aarch64-elf/bin にパスを通す

MSYS2 インストール

MSYS2 homepageから、 msys2-x86_64-20180531.exe をダウンロード。

  1. インストール先フォルダ: C:\msys64_aarch64_gnu_toolchain
  2. スタートメニューのショートカット: MSYS2 64bit Aarch64 GNU Toolchain
  3. pacman -Syu して再起動
  4. pacman -Su

ビルドに必要なパッケージをインストール

make をインストール。

pacman -S make

ツールチェインへパスを通す

MSYS2 上で、次のコマンドを実行し、ツールチェインへのパスを通す。 必要であれば .bashrc への登録もする。

export PATH=$PATH:~/app/gcc-arm-8.2-2019.01-i686-mingw32-aarch64-elf/bin

プログラムの作成

何もせずに無限ループするプログラムを作成する。

プロジェクトディレクトリ構成

first_step/
    +- Makefile : ビルド手順を書くやつ
    +- boot.S   : プログラム本体
    +- memmap   : リンカスクリプト

boot.S

// ブート時のエントリーポイント
.global start
start:
    // スタックポインタの開始位置指定
    mov sp, #0x80000

    // 何もせず無限ループ
    b halt

// 無限ループ
halt:
    wfe
    b halt

memmap

MEMORY
{
    ram : ORIGIN = 0x80000, LENGTH = 0x1000000
}

SECTIONS
{
    .text : { *(.text*) } > ram
    .bss : { *(.bss*) } > ram
}

Makefile

CROSS := aarch64-elf

AS = $(CROSS)-as
LD = $(CROSS)-ld
OBJDUMP = $(CROSS)-objdump
OBJCOPY = $(CROSS)-objcopy

AFLAGS = -g3

all: kernel8.img

boot.o: boot.S
    $(AS) $(AFLAGS) $< -o $@

kernel8.elf : memmap boot.o
    $(LD) boot.o -T memmap -o kernel8.elf

kernel8.img : kernel8.elf
    $(OBJCOPY) $< -O binary kernel8.img

.PHONY: clean
clean:
    rm -rf *.o *.elf *.img

プログラムのビルド

MSYS2 の環境で、プロジェクトディレクトリに移動して make するだけ。 (MSYS2 上での作業)

cd /PATH/TO/first_step
make

ビルドに成功すると、boot.okernel8.elf, kernel8.img が生成される。 QEMU での実行時に必要なのは kernel8.elf

実行とデバッグ

デバッグ用の docker コンテナを立ち上げて、実行とデバッグを行う。

QEMU を GDB 接続待ち状態で起動する

プロジェクトディレクトリをマウントしつつ、デバッグを可能とするオプションを付けてコンテナを起動。 (PowerShell 上での作業)

docker run -it --rm -v "$(pwd):/work" --workdir "/work" --name "work" --cap-add=SYS_PTRACE --security-opt="seccomp=unconfined" mikoto2000/qemu-xilinx

起動したコンテナで、QEMU を実行。

qemu-system-aarch64 -M arm-generic-fdt -nographic -serial mon:stdio -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb -device loader,file=./kernel8.elf,cpu-num=0 -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 -s -S
  • -M arm-generic-fdt: デバイスツリーでマシン定義しますよという指定
  • -nographic: GUI 無しで起動
  • -serial mon:stdio: シリアル通信を QEMU モニタに統合
  • -dtb /var/dts/LATEST/SINGLE_ARCH/zcu102-arm.dtb: マシン情報が記載されたファイルを指定
  • -device loader,file=./kernel8.img,cpu-num=0: どのバイナリをどの CPU で実行するかの指定
  • -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4: Cortex-A53 の CPU0 を開始するための設定(レジスタ CRF_APB.RST_FPD_APU の設定)
  • -s: GDB からの接続を、 localhost:1234 で待ち受ける
  • -S: 起動と同時に一時停止する

詳細は Xilinx Quick Emulator User Guide 参照。

QEMU に GDB で接続する

同じコンテナに接続し、 GDB で QEMU に接続する。 (PowerShell 上での作業)

docker exec -it work /bin/bash

GDB で QEMU に接続。

gdb-multiarch -q --eval-command="target remote localhost:1234" ./kernel8.elf
  • -q: ロゴを表示しない
  • --eval-command="target remote localhost:1234": GDB 起動後に実行するコマンド
    • 今回は、起動のたびに GDB UI 上で接続コマンドを打つのが面倒だったので起動時に渡すようにした

GDB を使ったステップ実行

デバッグ中のターミナルログ

root@4934294dab10:/work# gdb-multiarch -q --eval-command="target remote localhost:1234" ./kernel8.elf
Reading symbols from ./kernel8.elf...done.
Remote debugging using localhost:1234
start () at boot.S:6
6           mov sp, #0x80000
(gdb) b start
Breakpoint 1 at 0x80000: file boot.S, line 6.
(gdb) b halt
Breakpoint 2 at 0x80008: file boot.S, line 12.
(gdb) n

Thread 1 hit Breakpoint 2, halt () at boot.S:12
12          wfe
(gdb)
13          b halt
(gdb)

Thread 1 hit Breakpoint 2, halt () at boot.S:12
12          wfe
(gdb)
13          b halt
(gdb)
...(snip)

作ったプログラムの先頭から実行され、無限ループに入ることが確認できた。

QEMU モニタによるレジスタ確認

GDB によるデバッグ中でも、 QEMU モニタを使って各種情報を取得できる。 試しにレジスタ情報を表示する。

QEMU を起動しているターミナルで、 CTRL-a c と、キーを押すと QEMU モニタに命令を出せるようになる。

(qemu) info registers
PC=000000000008000c  SP=0000000000080000
X00=0000000000000000 X01=0000000000000000 X02=0000000000000000 X03=0000000000000000
X04=0000000000000000 X05=0000000000000000 X06=0000000000000000 X07=0000000000000000
X08=0000000000000000 X09=0000000000000000 X10=0000000000000000 X11=0000000000000000
X12=0000000000000000 X13=0000000000000000 X14=0000000000000000 X15=0000000000000000
X16=0000000000000000 X17=0000000000000000 X18=0000000000000000 X19=0000000000000000
X20=0000000000000000 X21=0000000000000000 X22=0000000000000000 X23=0000000000000000
X24=0000000000000000 X25=0000000000000000 X26=0000000000000000 X27=0000000000000000
X28=0000000000000000 X29=0000000000000000 X30=0000000000000000
PSTATE=400003cd -Z-- EL3h
q00=0000000000000000:0000000000000000 q01=0000000000000000:0000000000000000
q02=0000000000000000:0000000000000000 q03=0000000000000000:0000000000000000
q04=0000000000000000:0000000000000000 q05=0000000000000000:0000000000000000
q06=0000000000000000:0000000000000000 q07=0000000000000000:0000000000000000
q08=0000000000000000:0000000000000000 q09=0000000000000000:0000000000000000
q10=0000000000000000:0000000000000000 q11=0000000000000000:0000000000000000
q12=0000000000000000:0000000000000000 q13=0000000000000000:0000000000000000
q14=0000000000000000:0000000000000000 q15=0000000000000000:0000000000000000
q16=0000000000000000:0000000000000000 q17=0000000000000000:0000000000000000
q18=0000000000000000:0000000000000000 q19=0000000000000000:0000000000000000
q20=0000000000000000:0000000000000000 q21=0000000000000000:0000000000000000
q22=0000000000000000:0000000000000000 q23=0000000000000000:0000000000000000
q24=0000000000000000:0000000000000000 q25=0000000000000000:0000000000000000
q26=0000000000000000:0000000000000000 q27=0000000000000000:0000000000000000
q28=0000000000000000:0000000000000000 q29=0000000000000000:0000000000000000
q30=0000000000000000:0000000000000000 q31=0000000000000000:0000000000000000
FPCR: 00000000  FPSR: 00000000
(qemu)

こんな感じ。

以上。

参考資料