はじめに
「Zynq MPSoCで、コンピュータを学ぼう」のその4です。
- その1 : Xilinx社のZynqUltrascale+ MPSoC について
- その2 : Zynq Ultrascale+ MPSoC がどのように立ち上がっていくのか
- その3 : Linux の dts を見て、どのようなハードウェアを使っているのか?
- その4 : Linux の デバイスドライバについて
- その5 : Programmable Logic
- その6 : QEMU (Zynq Ultrascale+ MPSoC の実物が無くても、Linuxが立ち上がる)
Linux のデバイスドライバ
前回は、Linux の dts ファイルの cpus のところで、CPUを見てみました。CPUと同様に各デバイスドライバも dts ファイルの中に書いてあります。
zynqmp.dtsi ファイルの GPU の部分を見ています。
gpu エントリーとして、0xfd4b0000 がレジスタのベースアドレスです。デバイスドライバとして、compatible にある "arm,mali-400", "arm,mali-utgard" を使います。ARM社のGPU Mali-400 (mali-utgard)のデバイスドライバを使います。Zynq Ultrascale+ MPSのEGとEVには、Mali-400MP2が載っています。MP2とは、GPUコアが2個載っています。そのことを示しているのが、clock-names の中の "gpu_pp0" と "gpu_pp1" です。この gpu_pp がGPUコアに対応します。
gpu: gpu@fd4b0000 { status = "disabled"; compatible = "arm,mali-400", "arm,mali-utgard"; reg = <0x0 0xfd4b0000 0x0 0x10000>; interrupt-parent = <&gic>; interrupts = <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>; interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPP1", "IRQPPMMU1"; clock-names = "gpu", "gpu_pp0", "gpu_pp1"; power-domains = <&zynqmp_firmware PD_GPU>; };
SPIに対しては、2つ (spi0/spi1) が搭載されています。compatible の "cdns,spi-r1p6" とあるように Cadence社のIPを使ってます。この compatible に対応するデバイスドライバを探せばいいのです。
spi0: spi@ff040000 { compatible = "cdns,spi-r1p6"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 19 4>; reg = <0x0 0xff040000 0x0 0x1000>; clock-names = "ref_clk", "pclk"; #address-cells = <1>; #size-cells = <0>; power-domains = <&zynqmp_firmware PD_SPI_0>; }; spi1: spi@ff050000 { compatible = "cdns,spi-r1p6"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 20 4>; reg = <0x0 0xff050000 0x0 0x1000>; clock-names = "ref_clk", "pclk"; #address-cells = <1>; #size-cells = <0>; power-domains = <&zynqmp_firmware PD_SPI_1>; };
Cadenceの SPI のデバイスドライバは、spi-cadence.c です。
下記のように、.compatible に、"cdns,spi-r1p6" があります。
static const struct of_device_id cdns_spi_of_match[] = { { .compatible = "xlnx,zynq-spi-r1p6" }, { .compatible = "cdns,spi-r1p6" }, { /* end of table */ } };
他のデバイスドライバも dts ファイル内の compatible を見て、デバイスドライバのディレクトリ (drivers) の下から見つければいいだけです。 見つけたら、どんなことを行っているのかを調べるだけです。
Linxuのデバイスドライバって、どうなっているの?
Linux 2.6までであれば、下記の「Linuxデバイスドライバ 第3版」を読めばよかったのですが、今のLinuxのバージョンは、6 ですから、もう 2.6 なんていつの頃?って感じですよね。
第4版(英語版)ですが、3.2 ですね。
平田豊さんの「Linuxデバイスドライバの開発 (I/O BOOKS) 」は、5.2 対応なので、こちらの方がいいですね。
こちらのサイトも参考になりそうです。
おわりに
Zynq Ultrascale+ MPSoC だけでなく、x86-64 や Apple M1 の Linux でも 各 dts を見れば、どんなデバイスが繋がっていて、そのデバイスドライバのソースコードをみることができます。
Asahi Linux の Apple M1/M2 の dts ファイルは、下記のところにあります。
是非、調べてみてください。