はじめに
「Zynq MPSoCで、コンピュータを学ぼう」のその2です。
- その1 : Xilinx社のZynqUltrascale+ MPSoC について
- その2 : Zynq Ultrascale+ MPSoC がどのように立ち上がっていくのか
- その3 : Linux の dts を見て、どのようなハードウェアを使っているのか?
- その4 : Linux の デバイスドライバについて
- その5 : Programmable Logic
- その6 : QEMU (Zynq Ultrascale+ MPSoC の実物が無くても、Linuxが立ち上がる)
Linux の dts を見て、どのようなハードウェアを使っているのか?
Linux のソースコードを調べるポイントとしては、次の2つです。
- dts ファイルの中を見て、どのようなハードウェアを使っているのか?
- dts ファイルの中で使っているハードウェアのデバイスドライバは何をやっているのか?
今回は、この2つの内、最初の dts ファイルの中を見ていきます。
dts って何?
dts とは、device tree source の略です。Qiita に説明があります。
dts を DTC (Device Tree Compiler) というソフトウェアでコンパイルしたのが、DTB (Device Tree Blob) です。この DTB ファイルを Linux で使います。
Linuxで使っている DTB ファイルは、DTC にて逆アセンブルしてくれます。
Xilinx社に関係する dts の場所は、
にあります。
- Ultra96 v1用 : avnet-ultra96-rev1.dts
- Kria KV260用 : zynqmp-sm-k26-revA.dts / zynqmp-smk-k26-revA.dts
の dts があります。
Ultra96 v1用の avnet-ultra96-rev1.dts を見てみます。zynqmp-zcu100-revC.dts という dts ファイルを include しています。
/dts-v1/; #include "zynqmp-zcu100-revC.dts" / { model = "Avnet Ultra96 Rev1"; compatible = "avnet,ultra96-rev1", "avnet,ultra96", "xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100", "xlnx,zynqmp"; };
zynqmp-zcu100-revC.dts の最初で、zynqmp.dtsi ファイルを include しています。
/dts-v1/; #include "zynqmp.dtsi" #include "zynqmp-clk-ccf.dtsi" #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/pinctrl-zynqmp.h> #include <dt-bindings/phy/phy.h>
zynqmp-sm-k26-revA.dts でも同様に zynqmp.dtsi ファイルを include しています。
zynqmp.dtsi の中を覗いてみますと、下記の cpus に、ARM Cortex-A53x4 のエントリーがあります。
#include <dt-bindings/dma/xlnx-zynqmp-dpdma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/power/xlnx-zynqmp-power.h> #include <dt-bindings/reset/xlnx-zynqmp-resets.h> / { compatible = "xlnx,zynqmp"; #address-cells = <2>; #size-cells = <2>; cpus { #address-cells = <1>; #size-cells = <0>; cpu0: cpu@0 { compatible = "arm,cortex-a53"; device_type = "cpu"; enable-method = "psci"; operating-points-v2 = <&cpu_opp_table>; reg = <0x0>; cpu-idle-states = <&CPU_SLEEP_0>; }; cpu1: cpu@1 { compatible = "arm,cortex-a53"; device_type = "cpu"; enable-method = "psci"; reg = <0x1>; operating-points-v2 = <&cpu_opp_table>; cpu-idle-states = <&CPU_SLEEP_0>; }; cpu2: cpu@2 { compatible = "arm,cortex-a53"; device_type = "cpu"; enable-method = "psci"; reg = <0x2>; operating-points-v2 = <&cpu_opp_table>; cpu-idle-states = <&CPU_SLEEP_0>; }; cpu3: cpu@3 { compatible = "arm,cortex-a53"; device_type = "cpu"; enable-method = "psci"; reg = <0x3>; operating-points-v2 = <&cpu_opp_table>; cpu-idle-states = <&CPU_SLEEP_0>; }; idle-states { entry-method = "psci"; CPU_SLEEP_0: cpu-sleep-0 { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x40000000>; local-timer-stop; entry-latency-us = <300>; exit-latency-us = <600>; min-residency-us = <10000>; }; }; };
cpus の cpu0 を詳しく見てみます。cpuX: cpu@X の X は、コアの番号です。compatible の部分がどんなコアかを示すもので、"arm,cortex-a53"、つまり、ARM Cortex-A53 だということを示しています。
cpu0: cpu@0 { compatible = "arm,cortex-a53"; device_type = "cpu"; enable-method = "psci"; operating-points-v2 = <&cpu_opp_table>; reg = <0x0>; cpu-idle-states = <&CPU_SLEEP_0>; };
この中のポイントは、enable-method です。これは、省エネの時にどのような方法を行って制御するのかを示すもので、ここでは、"psci" となっています。psci とは、Power State Coordination Interface の略で、サスペンド、シャットダウン、リブートなど、Arm プロセッサのシステ ム電源ステータスを制御するための標準インターフェイスです。psci のエントリーは、下記のようになっています。"arm,psic-0.2", method が "smc" です。
psci { compatible = "arm,psci-0.2"; method = "smc"; };
PSCIについては、下記のスライドにまとめていますので、参考にしてくださいね。
www.slideshare.net
PSCIは、ARM v8 64ビットの標準的な省エネ機能を実現するソフトウェアです。ただし、サーバーやAppleのM1シリーズ/M2 に関しては、"psci" にはなっていません。M1 (t8103) の dts ファイル (t8103.dts) の cpu0 のエントリーを見てみます。enable-method は、"spin-table" になっています。
cpu0: cpu@0 { compatible = "apple,icestorm"; device_type = "cpu"; reg = <0x0 0x0>; enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ };
"spin-table" の時の処理は、下記の smp_spin_table.c がそのようです。
おわりに
2016年2月20日(金)のZynq Ultrasclae+ MPSoC 勉強会で使った資料です。
この時には、Zynq Ultrascale+ MPSoC の実物はまだリリースされていませんでした。
こちらには、前半はブートの説明、後半はLinuxの説明をしています。
参考までに