1.記事一覧
記事は複数回に分けて投稿する予定です。AMD/XilinxのARM64 SoC(ZynqMP Kria K26 SOM)で動作する、AMD/Xilinx公式認定Ubuntuやベアメタル開発を勉強していく覚書きです。
ZynqMP(APU:Cortex-A53,Arm64) 組込みLinux入門編
- 【ZynqMP】1. 認定UbuntuでPLのGPIOを使う
- 【ZynqMP】2. 認定Ubuntuのカーネルビルド
- 【ZynqMP】3. 認定UbuntuのDevicetree変更 ←本記事
ZynqMP(RPU:Cortex-R5,Arm32) RPU入門編
2.【概要】標準のDevicetreeをカスタムする
XilinxのKria K26 SOMボードを搭載した公式評価ボード、KR260を用いたLinuxの勉強記事です。
第1回の【ZynqMP】1.認定UbuntuでPLのGPIOではDevicetree OverlayによるLinux動作中のDevicetree書換えを行いました。今回は元となる、ベースのDevicetreeを変更してみたいと思います。Linux起動中に変更する必要がない部分や、現在無効化されているツリーを有効化してLinux起動したい場合などに必要となります。
この内容は公式のXilinx-Wikiを参考にやっていきます。また、参考情報としてikwzmさんの記事を読んでいただくと良いと思います。
デバイスツリーにシンボル情報を埋め込む|@ikwzm様
また、u-bootのbootパラーメータ環境変数bootargsの設定変更もついでにやってみます。
今回やること
- 実機KR260からデバイスツリーを読み出す
- デバイスツリーを変更する(今回はやりません)
- デバイスツリーをコンパイルして更新する
- bootパラメータbootargsの変更
今回使用する環境
開発ツール | DTC(Device Tree Compiler) |
ターゲットボード | Xilinx社製 Kria KR260 ロボティクススターターキット(SK-KR260-G) SOM : Xilinx社 Kria K26 SOM (Zynq UltraScale+ MPSoCベース) APU : Arm CA53x4 1333MHz arm64 RPU : Arm CR5x2 533MHz armv7-R SDRAM : DDR4 4GB QSPI Firmware : Xilinx download – 2022.2_update1_BOOT.BIN Linux Kernel : v5.15.0-1023-xilinx-zynqmp by 認定Ubuntu OS : Xilinx認定Ubuntu22.04 LTS(arm64) |
3.ベースデバイスツリーを変更する
3-1. 実機からDevicetreeを読み出す
SysFsからDTS(Device Tree Source)を読み出します。
ubuntu@kria:~/$ sudo dtc /sys/firmware/fdt >system.dts
3-2. デバイスツリーソースを見てみる
非常に長いので全ては載せませんが、最後にシンボル情報が出力されているのがわかります。
/dts-v1/; /memreserve/ 0x00000000755e4000 0x0000000003a1bc01; / { compatible = "xlnx,zynqmp-sk-kr260-revB\0xlnx,zynqmp-sk-kr260\0xlnx,zynqmp"; #address-cells = <0x02>; #size-cells = <0x02>; model = "ZynqMP SMK-K26 Rev1/B/A"; clock5 { clock-frequency = <0x17d7840>; #clock-cells = <0x00>; compatible = "fixed-clock"; }; clock4 { clock-frequency = <0x17d7840>; #clock-cells = <0x00>; compatible = "fixed-clock"; }; clock3 { clock-frequency = <0x9502f90>; #clock-cells = <0x00>; compatible = "fixed-clock"; }; [...略] __symbols__ { cpu0 = "/cpus/cpu@0"; cpu1 = "/cpus/cpu@1"; cpu2 = "/cpus/cpu@2"; cpu3 = "/cpus/cpu@3"; CPU_SLEEP_0 = "/cpus/idle-states/cpu-sleep-0"; cpu_opp_table = "/cpu-opp-table"; zynqmp_ipi = "/zynqmp_ipi"; ipi_mailbox_pmu1 = "/zynqmp_ipi/mailbox@ff990400"; dcc = "/dcc"; [...略]
3-3. デバイスツリーのコンパイル
今回は特に改変しませんが、改変したと仮定して新しいデバイスツリーソースをLinuxに組み込んでいきます。まずはデバイスツリーをコンパイルするためのコンパイラを導入します。
認定UbuntuでDTCがプリインストールされていたか、自分で入れたか私は忘れてしまったため、下記コマンドで入っているか確認します。
ubuntu@kria:~$ dtc -v
Version: DTC 1.6.1
入っていなかった場合、第1回の1.認定UbuntuでPLのGPIOを使う>6-1. DTC(Device Tree Compiler)の準備を参考にDTCを導入します。
Devicetree Overlayを使うためにはベースDevicetreeでシンボル情報を出力してコンパイルする必要があります。シンボルを出力できるコンパイラはVer1.4.2以降です。
デバイスツリーソース(DTS)をシンボル出力(-@)でコンパイルします。
DTBのファイル名は”user-override.dtb”にします。
ubuntu@kria:~$ dtc -@ -O dtb -o user-override.dtb system.dts
warningが出力されますが、dtbは生成されます。VivadoのXSCTで生成したデバイスツリーのコンパイルでも同じ様なwarningが出力されます。ちょっと不安になりますが、このまま進めることにします。
3-4. カスタムデバイスツリーの配置
公式Wikiによると、FATパーティションに配置すればu-bootがこちらを優先して読み込む仕様のようです。FATパーティションを探してみます。
ubuntu@kria:~$ df -T
Filesystem Type 1K-blocks Used Available Use% Mounted on
tmpfs tmpfs 400060 3656 396404 1% /run
/dev/sda2 ext4 60281772 11971140 45761764 21% /
tmpfs tmpfs 2000292 0 2000292 0% /dev/shm
tmpfs tmpfs 5120 4 5116 1% /run/lock
/dev/sda1 vfat 1032428 152149 880279 15% /boot/firmware
tmpfs tmpfs 400056 64 399992 1% /run/user/1000
/boot/firmware以下のようです。こちらにuser-override.dtbを配置します。
ubuntu@kria:~$ sudo cp user-override.dtb /boot/firmware/
再起動をすれば、カスタムデバイスツリーが読み込まれます。
3-5. カスタムデバイスツリーがロードされたか確認
user-override.dtbがロードされているか、u-bootのログを見てみます。u-bootのログを取る場合、私の環境ではjtag用のmicro-USBケーブルをPCと接続します。PCはUbuntu20.04で、/dev/ttyUSB1がシリアルコンソールになっていました。以下のコマンドでコンソールのログを取ります。
# Ctrl + cで終了
$ cat /dev/ttyUSB1 |tee ./tty001.log
上記のログ記録を実行しつつ、別端末でSSHにログインし、再起動を実施します。
U-Boot 2022.01 (Jan 25 2023 - 08:10:44 +0000) CPU: ZynqMP Silicon: v3 Detected name: zynqmp-smk-k26-xcl2g-rev1-sck-kr-g-rev1 Model: ZynqMP SMK-K26 Rev1/B/A Board: Xilinx ZynqMP DRAM: 4 GiB PMUFW: v1.1 [...略] Found U-Boot script /boot.scr.uimg 6918 bytes read in 3 ms (2.2 MiB/s) ## Executing script at 20000000 Selecting DT for Kria boards Kria DT: #conf-smk-k26-revA-sck-kr-g-revB Configuring the cma value based on the board type cma=1000M Loading user-override.dtb 43626 bytes read in 5 ms (8.3 MiB/s) Loading image.fit 80231820 bytes read in 5440 ms (14.1 MiB/s) ## Loading kernel from FIT Image at 10000000 ... Using 'conf-smk-k26-revA-sck-kr-g-revB' configuration [...略]
カスタムデバイスツリーがロードされていました。
ログ記録がバグる場合、一度screenなどで/dev/ttyUSB1に入ってから出るをやってからcatするとうまく行きました。理由はよくわかりません。
#一度シリアルコンソールに入る
$ screen /dev/ttyUSB1 115200
# Ctrl + aを押してからkを押して抜ける
4.bootパラメータbootargsを変更する
開発をする上でbootパラメータを変更したいことがあるかと思います(“debug”など)。デバイスツリーを変更するついでにbootパラメータの変更もやってみます。
Kria K26 SOM公式ページによると、u-boot本体はSDカード側ではなく、QSPIにファームウェアとして書き込まれています。u-bootにはbootargs環境変数があり、bootパラメータの値が格納されています。実際にはSDカードのboot.scrスクリプトを読み出す様になっているため、bootargsはこの中に実装されているものと思われます。
今回は公式手順に従い、bootargsを変更してみます。
4-1. 現在適用されているbootパラメータを確認
KR260にSSHでログインし、以下のコマンドで確認します。
ubuntu@kria:~$ cat /proc/cmdline
root=LABEL=writable rootwait earlycon console=ttyPS1,115200 console=tty1 clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio xilinx_tsn_ep.st_pcp=4 cma=1000M
デフォルトのCMAサイズを変更してみます。CMA(Contiguous Memory Allocator)とはDMAバッファを確保する際、物理アドレスが連続した大きな領域を確保できるメモリアロケータです。
4-2. bootargs専用設定ファイルを更新する
公式によると、/etc/default/flash-kernelのファイルの変数を書き換えれば良いようです。
ubuntu@kria:~$ cat /etc/default/flash-kernel
LINUX_KERNEL_CMDLINE=""
LINUX_KERNEL_CMDLINE_DEFAULTS=""
LINUX_KERNEL_CMDLINE
デフォルトのbootargsの内容の後、つまり右側に追記する内容をここに書きます。(おそらくですが、bootargsは右側に書かれているほど優先度が高いです)
LINUX_KERNEL_CMDLINE_DEFAULTS
デフォルトのbootargsの内容の前、つまり左側に追記する内容をここに書きます。
それではCMAを512MBに変更してみます。
# viでもなんでも良いです
ubuntu@kria:~$ sudo nano /etc/default/flash-kernel
# 確認
ubuntu@kria:~$ cat /etc/default/flash-kernel
LINUX_KERNEL_CMDLINE="cma=512M"
LINUX_KERNEL_CMDLINE_DEFAULTS=""
4-3. カスタムbootargsを適用する
次のコマンドで更新します。
ubuntu@kria:~$ sudo flash-kernel
flash-kernel: installing version 5.15.0-1023-xilinx-zynqmp
Couldn't find DTB on the following paths: /etc/flash-kernel/dtbs /usr/lib/linux-image-5.15.0-1023-xilinx-zynqmp /lib/firmware/5.15.0-1023-xilinx-zynqmp/device-tree/
Generating u-boot image... done.
Taking backup of image.fit.
Installing new image.fit.
Generating boot script u-boot image... done.
Taking backup of boot.scr.uimg.
Installing new boot.scr.uimg.
$ sudo reboot
再起動してbootパラメータを確認します。後ろに追記されていました。
ubuntu@kria:~$ cat /proc/cmdline
root=LABEL=writable rootwait earlycon console=ttyPS1,115200 console=tty1 clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio xilinx_tsn_ep.st_pcp=4 cma=1000M cma=512M
/proc/meminfo:Linux上で確認できます。
ubuntu@kria:~$ cat /proc/meminfo |grep Cma
CmaTotal: 524288 kB
CmaFree: 520668 kB
ちなみにu-bootログではcma=1000Mの方が出ていました。これは確認に使えないですね。
U-Boot 2022.01 (Jan 25 2023 - 08:10:44 +0000) CPU: ZynqMP Silicon: v3 Detected name: zynqmp-smk-k26-xcl2g-rev1-sck-kr-g-rev1 Model: ZynqMP SMK-K26 Rev1/B/A Board: Xilinx ZynqMP DRAM: 4 GiB PMUFW: v1.1 [...略] Kria DT: #conf-smk-k26-revA-sck-kr-g-revB Configuring the cma value based on the board type cma=1000M Loading user-override.dtb 43626 bytes read in 6 ms (6.9 MiB/s) Loading image.fit 80231820 bytes read in 5408 ms (14.1 MiB/s) [...略] Starting kernel ... [...略] [ 0.000000] CPU features: detected: ARM erratum 845719 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 1032192 [ 0.000000] Policy zone: Normal [ 0.000000] Kernel command line: root=LABEL=writable rootwait earlycon console=ttyPS1,115200 console=tty1 clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio xilinx_tsn_ep.st_pcp=4 cma=1000M cma=512M [ 0.000000] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear) [ 0.000000] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear) [...略]
4-4. bootargsの内容を間違ってしまった時
Ubuntuが起動する場合
/etc/default/flash-kernelを修正して再度flash-kernelを実行します。flash-kernelは過去に追記した引数を削除してから追記し直します。
#ミスって512Mではなく、512にしてしまった
ubuntu@kria:~$ cat /proc/cmdline
root=LABEL=writable rootwait earlycon console=ttyPS1,115200 console=tty1 clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio xilinx_tsn_ep.st_pcp=4 cma=1000M cma=512
# 間違えた場合はそのまま修正すれば良い
ubuntu@kria:~$ sudo nano /etc/default/flash-kernel
# 確認
ubuntu@kria:~$ cat /etc/default/flash-kernel
LINUX_KERNEL_CMDLINE="512M"
LINUX_KERNEL_CMDLINE_DEFAULTS=""
# 再度flash-kernel
ubuntu@kria:~$ sudo flash-kernel
ubuntu@kria:~$ sudo reboot
#過去に追記したものは消える
ubuntu@kria:~$ cat /proc/cmdline
root=LABEL=writable rootwait earlycon console=ttyPS1,115200 console=tty1 clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio xilinx_tsn_ep.st_pcp=4 cma=1000M cma=512M
Ubuntuが起動しない時
私はこのケースに遭遇したことがないので、確実なことは言えませんが、SDカードのFATパーティションにboot.scr.uimgの中にbootargsがいる(と思われる)ので、boot.scr.uimg.bakが存在すれば差し替えを行うと行けるかもしれません。なければ公式Ubuntuのイメージから取り出したりします。