はじめに
今回は、以下の基板をJetson Orin Nanoに接続して画像を取得できるように、Linuxカーネルの
カスタマイズを行ってみたいと思います。
この基板、2020年7月頃にJetson Nanoに接続して試用していたものを引っ張り出して来ました。
Mzyy94さんの以下のページでも紹介されているものです。
搭載されているのは、TOSHIBAさんのTC358743という、HDMI to MIPI-CSI2 ブリッジチップです。
HDMI入力をRaspberry Piで駆使する | 犬アイコンのみっきー
まず、物理的に接続するには、別記事「Jetson Orin Nanoの使い始め(カメラ導入編)」でも紹介しました、15-pin to 22-pin conversion cable(15ピン-22ピン変換ケーブル)が必要となります。
これで、Jetson Orin NanoとTC358743基板とは物理的には接続できました。また、TC358743基板のHDMIのコネクタで、Windows PCとHDMIケーブルで接続しています。
少し前に、R35.4.1でも動作確認していたのですが、紹介するのが遅れているうちに、JetPack 5.1.3 (L4T R35.5.0)が2/23にリリースされていました。なので、どうせなら、ということで、その新しいバージョンで動作確認をしました。
JetPack 5.1.3のセットアップについて
別記事「Jetson Orin Nanoの使い始め(初期セットアップ編)」に書きましたが、R35.5.0以前の環境から、R35.5.0にアップデートに、SD Card Methodにてセットアップすると、中途半端な状態になるようなので、最初は、SDK Manager Methodでセットアップして下さい。
そして、NVIDIA Developer Forumの以下のスレッドにて、TC358743を用いたキャプチャについて議論がされておりましたので、そこにアップされているソースファイルを使用します。
カーネルのビルド環境構築
Jetson Nanoにて色々検討していた時代は、NVIDIAやJetsonHacksのページに沿って、自分なりにアレンジした形で手動でmakeしていましたが、今回、@kitazakiさんなどが使っておられたbuildKernelAndModulesというツールが気に入って私も使うようになりましたので、それベースで説明してみます。
まず、デフォルトの状態を確認しておきましょう。
$ uname -a
Linux orin-nano-dev-02 5.10.192-tegra #1 SMP PREEMPT Mon Feb 19 20:19:53 PST 2024 aarch64 aarch64 aarch64 GNU/Linux
$ cat /etc/nv_tegra_release
# R35 (release), REVISION: 5.0, GCID: 35550185, BOARD: t186ref, EABI: aarch64, DATE: Tue Feb 20 04:46:31 UTC 2024
R35.5.0であることがわかります。
$ sudo dmesg |grep imx
[ 15.639801] imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
[ 15.651393] imx219 9-0010: imx219_board_setup: error during i2c read probe (-121)
[ 15.667298] imx219 9-0010: board setup failed
[ 15.673491] imx219: probe of 9-0010 failed with error -121
[ 15.680012] imx219 10-0010: tegracam sensor driver:imx219_v2.0.6
[ 15.694740] imx219 10-0010: imx219_board_setup: error during i2c read probe (-121)
[ 15.719616] imx219 10-0010: board setup failed
[ 15.736129] imx219: probe of 10-0010 failed with error -121
ブート時のログを確認すると、上記のように、2つのカメラコネクタ(J20:CAM0, J21:CAM1)のどちらに対しても、imx219の検知処理が動作する状態になっています。
ここから、Linuxカーネルのカスタマイズするために、そのビルド環境を用意します。
ツールの取得
buildKernelAndModulesツールをgitにて取得します。(~/work/gitの下でgit cloneしたとします)
$ git clone https://github.com/JetsonHacksNano/buildKernelAndModules
Cloning into 'buildKernelAndModules'...
remote: Enumerating objects: 149, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 149 (delta 30), reused 26 (delta 26), pack-reused 114
Receiving objects: 100% (149/149), 41.24 KiB | 2.42 MiB/s, done.
Resolving deltas: 100% (91/91), done.$ cd buildKernelAndModules/
スクリプトファイルの若干の変更
L4T R35.1.0までしか対応していないようなので、最新の環境に対応するため、若干、スクリプトファイルを変更します。変更するファイルは以下の2つです。
- scripts/jetson_variables
- scripts/getKernelSources.sh
$ cd buildKernelAndModules/
$ cp -p scripts/jetson_variables scripts/jetson_variables.org
$ vi scripts/jetson_variables
$ diff scripts/jetson_variables scripts/jetson_variables.org
33,34d32
< "35.5.0") JETSON_JETPACK="5.1.3" ;;
< "35.4.1") JETSON_JETPACK="5.1.2" ;;
$ cp -p scripts/getKernelSources.sh scripts/getKernelSources.sh.org
$ vi scripts/getKernelSources.sh
$ diff scripts/getKernel
Sources.sh scripts/getKernelSources.sh.org
23,24d22
< ["35.5.0"]="https://developer.nvidia.com/embedded/l4t/r35_release_v5.0/sources/public_sources.tbz2"
< ["35.4.1"]="https://developer.nvidia.com/embedded/l4t/r35_release_v4.1/sources/public_sources.tbz2"
ここでは、一応、R35.4.1とR35.5.0の2つのバージョンに対する記述を追加していますが、/etc/nv_tegra_releaseが参照されて、それに対応されるソースファイルがダウンロードされるようになっていますので、現在使用しているJetson Orin Nanoにて使用しているバージョンのR35.5.0に対応する行だけ追加しても大丈夫です。
あと、ソースファイル一式が置かれている場所をURLで記述している形ですが、今までも置き場所がちょこちょこと変わっていますので、今後、また新しいバージョンで使うときには、その変更に合わせてURLを追加していく必要があるかもしれません。(例えば、今、JetPack 6.0 DPというバージョンがありますが、このバージョンでは、カーネルモジュールなどが別ファイルに分かれていたりするので、そのままではだめ、など。)
ソースファイル一式の取得
実際にスクリプトを実行してソースファイル一式をダウンロードします。
$ ./getKernelSources.sh
Jetpack 5.1.3 [L4T 35.5.0]
Kernel Release: 5.10
Placing kernel source into /usr/src/
...略...
nvcommon_build.sh
nvbuild.sh
/usr/src/kernel/kernel-5.10
また、「はじめに」で予告した通り、ソースコードは、Forumにアップされていたもの(tc358743-orin.zip)を使います。~/work/の下に置いたとして、
$ cd ~/work/
$ unzip tc358743-orin.zip
$ sudo cp -p tc358743-orin/tc358743.c /usr/src/kernel/kernel-5.10/drivers/media/i2c/
$ sudo cp -p tc358743-orin/tc358743_regs.h /usr/src/kernel/kernel-5.10/drivers/media/i2c/
$ sudo cp -p tc358743-orin/tc358743.h /usr/src/kernel/kernel-5.10/include/media/i2c/
$ cd ~/work/git/buildKernelAndModules/
などと、getKernelSources.shによって配置されたソースツリー内にて、それぞれのファイルの存在する場所にコピーします。
カーネルのカスタマイズ
次に、カーネルのカスタマイズに進みます。通常のカスタマイズでは、以下のようにeditConfig.shを使用してメニューから必要なカスタマイズを選択することになります。スクリプトの内部ではmake menuconfig
が実行されます。
$ ./editConfig.sh
ただし、今回は、TC358743のドライバを有効にしようとしていますが、上記の方法で表示されるメニューにはTC358743向けの項目は(多分)現れないようなので、その代わりに、次のように、手動で.configを編集する方法を採ります。
$ cd /usr/src/kernel/kernel-5.10/
$ sudo cp -p .config .config.org
$ sudo vi .config
$ diff .config .config.org
4625c4625
< CONFIG_VIDEO_TC358743=m
---
> # CONFIG_VIDEO_TC358743 is not set
$ cd ~/work/git/buildKernelAndModules/
上記のdiffの結果のように、CONFIG_VIDEO_TC358743=m
とすることで、TC358743用のドライバを有効にしています。=y
はスタティックにカーネルに組み込むのに対して、=m
は動的にロード/アンロードできるようにカーネルモジュールとしての形態とすることを意味します。
カーネルのビルド
次に、カーネルのビルドに進みます。
ここで、デフォルト状態でそのままカーネルのビルドに進むと、途中で、
scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: そのようなファイルやディレクトリはありません
21 | #include <openssl/bio.h>
| ^~~~~~~~~~~~~~~
compilation terminated.
などとエラーになりますので、先に、以下のように、libssl-devをインストールします。
$ sudo apt install libssl-dev
ようやく、makeKernel.shスクリプトを用いてカーネルのビルドを実行します。途中で、コンフィグを変更したことにより、いくつか質問されますが、ENTERキーを押しておけば大丈夫です。
$ ./makeKernels.sh
Proposed source path: /usr/src/kernel/kernel-5.10
Source Target: /usr/src/
SYNC include/config/auto.conf.cmd
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTLD scripts/kconfig/conf
*
* Restart config...
*
*
* Video decoders
*
Analog Devices ADV7180 decoder (VIDEO_ADV7180) [N/m/y/?] n
Analog Devices ADV7183 decoder (VIDEO_ADV7183) [N/m/y/?] n
Analog Devices ADV748x decoder (VIDEO_ADV748X) [N/m/y/?] n
Analog Devices ADV7604 decoder (VIDEO_ADV7604) [N/m/y/?] n
Analog Devices ADV7842 decoder (VIDEO_ADV7842) [N/m/y/?] n
BT819A VideoStream decoder (VIDEO_BT819) [N/m/y/?] n
BT856 VideoStream decoder (VIDEO_BT856) [N/m/y/?] n
BT866 VideoStream decoder (VIDEO_BT866) [N/m/y/?] n
KS0127 video decoder (VIDEO_KS0127) [N/m/y/?] n
OKI ML86V7667 video decoder (VIDEO_ML86V7667) [N/m/y/?] n
Philips SAA7110 video decoder (VIDEO_SAA7110) [N/m/y/?] n
Philips SAA7111/3/4/5 video decoders (VIDEO_SAA711X) [N/m/y/?] n
Toshiba TC358743 decoder (VIDEO_TC358743) [M/n/y/?] m
Enable Toshiba TC358743 CEC support (VIDEO_TC358743_CEC) [N/y/?] (NEW)
Texas Instruments TVP514x video decoder (VIDEO_TVP514X) [N/m/y/?] n
Texas Instruments TVP5150 video decoder (VIDEO_TVP5150) [N/m/y/?] n
Texas Instruments TVP7002 video decoder (VIDEO_TVP7002) [N/m/y/?] n
Techwell TW2804 multiple video decoder (VIDEO_TW2804) [N/m/y/?] n
Techwell TW9903 video decoder (VIDEO_TW9903) [N/m/y/?] n
Techwell TW9906 video decoder (VIDEO_TW9906) [N/m/y/?] n
Techwell TW9910 video decoder (VIDEO_TW9910) [N/m/y/?] n
vpx3220a, vpx3216b & vpx3214c video decoders (VIDEO_VPX3220) [N/m/y/?] n
Maxim MAX9286 GMSL deserializer support (VIDEO_MAX9286) [N/m/y/?] n
*
* Video and audio decoders
*
Philips SAA7171/3/4 audio/video decoders (VIDEO_SAA717X) [N/m/y/?] n
Conexant CX2584x audio/video decoders (VIDEO_CX25840) [N/m/y/?] n
WRAP arch/arm64/include/generated/uapi/asm/kvm_para.h
WRAP arch/arm64/include/generated/uapi/asm/errno.h
WRAP arch/arm64/include/generated/uapi/asm/ioctl.h
WRAP arch/arm64/include/generated/uapi/asm/ioctls.h
WRAP arch/arm64/include/generated/uapi/asm/ipcbuf.h
WRAP arch/arm64/include/generated/uapi/asm/msgbuf.h
WRAP arch/arm64/include/generated/uapi/asm/poll.h
WRAP arch/arm64/include/generated/uapi/asm/resource.h
WRAP arch/arm64/include/generated/uapi/asm/sembuf.h
WRAP arch/arm64/include/generated/uapi/asm/shmbuf.h
WRAP arch/arm64/include/generated/uapi/asm/siginfo.h
WRAP arch/arm64/include/generated/uapi/asm/socket.h
WRAP arch/arm64/include/generated/uapi/asm/sockios.h
WRAP arch/arm64/include/generated/uapi/asm/stat.h
WRAP arch/arm64/include/generated/uapi/asm/swab.h
WRAP arch/arm64/include/generated/uapi/asm/termbits.h
WRAP arch/arm64/include/generated/uapi/asm/termios.h
WRAP arch/arm64/include/generated/uapi/asm/types.h
WRAP arch/arm64/include/generated/asm/early_ioremap.h
WRAP arch/arm64/include/generated/asm/mcs_spinlock.h
WRAP arch/arm64/include/generated/asm/qrwlock.h
WRAP arch/arm64/include/generated/asm/qspinlock.h
WRAP arch/arm64/include/generated/asm/set_memory.h
WRAP arch/arm64/include/generated/asm/user.h
WRAP arch/arm64/include/generated/asm/bugs.h
WRAP arch/arm64/include/generated/asm/delay.h
WRAP arch/arm64/include/generated/asm/div64.h
WRAP arch/arm64/include/generated/asm/dma-mapping.h
WRAP arch/arm64/include/generated/asm/dma.h
WRAP arch/arm64/include/generated/asm/emergency-restart.h
WRAP arch/arm64/include/generated/asm/hw_irq.h
WRAP arch/arm64/include/generated/asm/irq_regs.h
UPD include/config/kernel.release
WRAP arch/arm64/include/generated/asm/kdebug.h
WRAP arch/arm64/include/generated/asm/kmap_types.h
UPD include/generated/uapi/linux/version.h
WRAP arch/arm64/include/generated/asm/local.h
WRAP arch/arm64/include/generated/asm/local64.h
WRAP arch/arm64/include/generated/asm/mm-arch-hooks.h
WRAP arch/arm64/include/generated/asm/mmiowb.h
WRAP arch/arm64/include/generated/asm/msi.h
WRAP arch/arm64/include/generated/asm/rwonce.h
WRAP arch/arm64/include/generated/asm/switch_to.h
WRAP arch/arm64/include/generated/asm/serial.h
WRAP arch/arm64/include/generated/asm/unaligned.h
WRAP arch/arm64/include/generated/asm/vga.h
UPD include/generated/utsrelease.h
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
LEX scripts/dtc/dtc-lexer.lex.c
YACC scripts/dtc/dtc-parser.tab.[ch]
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/kallsyms
HOSTCC scripts/sorttable
HOSTCC scripts/asn1_compiler
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/selinux/genheaders/genheaders
HOSTCC scripts/selinux/mdp/mdp
YACC scripts/genksyms/parse.tab.[ch]
LEX scripts/genksyms/lex.lex.c
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTCC scripts/sign-file
HOSTCC scripts/extract-cert
...(中略)...
CC drivers/platform/tegra/clocks-config.o
CC drivers/platform/tegra/tegra-fsicom.o
CC drivers/platform/tegra/tegra-epl.o
CC drivers/platform/tegra/tegra-uss-io-proxy.o
AR drivers/platform/tegra/built-in.a
AR drivers/platform/built-in.a
AR drivers/built-in.a
GEN .version
CHK include/generated/compile.h
LD vmlinux.o
MODPOST vmlinux.symvers
MODINFO modules.builtin.modinfo
GEN modules.builtin
LD .tmp_vmlinux.kallsyms1
KSYMS .tmp_vmlinux.kallsyms1.S
AS .tmp_vmlinux.kallsyms1.S
LD .tmp_vmlinux.kallsyms2
KSYMS .tmp_vmlinux.kallsyms2.S
AS .tmp_vmlinux.kallsyms2.S
LD vmlinux
SORTTAB vmlinux
SYSMAP System.map
OBJCOPY arch/arm64/boot/Image
real 22m37.174s
user 90m29.109s
sys 11m33.879s
Image make successful
Image file is here:
/usr/src/kernel/kernel-5.10/arch/arm64/boot/Image
しばらく時間はかかりますが、カーネルイメージのファイルがどこに出力されたかのメッセージが表示されてビルドは完了します。
カーネルイメージのインストール
次に、元のカーネルイメージをバックアップしつつ、copyImage.shを用いて、ビルドしたイメージをシステム領域にコピーします。
$ sudo cp -p /boot/Image /boot/Image.org
$ ./copyImage.sh
カーネルモジュールのビルド及びインストール
次に、カーネルモジュールのビルドに進みます。makeModules.shを使用しますが、このスクリプトは、makeKernel.shとは異なり、いきなりシステム領域にコピーしてしまうので、ここでは、カーネルモジュールもディレクトリごとバックアップした上で、makeModules.shを実行しておきます。
$ sudo cp -rp /lib/modules/5.10.192-tegra /lib/modules/5.10.192-tegra.org
$ ./makeModules.sh
Proposed source path: /usr/src/kernel/kernel-5.10
Source Target: /usr/src/
CALL scripts/atomic/check-atomics.sh
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CC [M] fs/quota/quota_v2.o
CC [M] arch/arm64/crypto/sha1-ce-glue.o
AS [M] arch/arm64/crypto/sha1-ce-core.o
CC [M] fs/quota/quota_tree.o
...(中略)...
LD [M] sound/soc/tegra/snd-soc-tegra210-ope.ko
LD [M] sound/soc/tegra/snd-soc-tegra210-sfc.ko
LD [M] sound/tegra-safety-audio/safety-i2s.ko
real 34m20.617s
user 132m3.403s
sys 17m47.919s
Modules make successful
INSTALL arch/arm64/crypto/aes-arm64.ko
INSTALL arch/arm64/crypto/aes-ce-blk.ko
INSTALL arch/arm64/crypto/aes-ce-ccm.ko
...(中略)...
INSTALL sound/soc/tegra/snd-soc-tegra210-ope.ko
INSTALL sound/soc/tegra/snd-soc-tegra210-sfc.ko
INSTALL sound/tegra-safety-audio/safety-i2s.ko
DEPMOD 5.10.192-tegra
ここで一旦リブートしておきます。
$ sudo reboot
unameで確認すると、以下のように、今、ビルドしたものでブートしていることがわかります。
$ uname -a
Linux orin-nano-dev-02 5.10.192-tegra #1 SMP PREEMPT Mon Mar 4 10:23:39 JST 2024 aarch64 aarch64 aarch64 GNU/Linux
今回、TC358743のカーネルモジュールを追加しましたので、以下のように、tc358743.koが生成され、システム領域に配置されています。(makeModules.shにて)
$ ls -las /lib/modules/5.10.192-tegra/kernel/drivers/media/i2c/tc358743.ko
804 -rw-r--r-- 1 root root 822689 3月 4 11:56 /lib/modules/5.10.192-tegra/kernel/drivers/media/i2c/tc358743.ko
カーネルモジュールtc358743.koをインストールしたわけですが、この時点ではまだ、dmesgなどで確認しても、上で最初に確認したデフォルトの状態と同じく、imx219の検知処理が動いている状態のままです。
$ sudo dmesg |grep imx
[ 17.483366] imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
[ 17.505398] imx219 9-0010: imx219_board_setup: error during i2c read probe (-121)
[ 17.519361] imx219 9-0010: board setup failed
[ 17.523958] imx219: probe of 9-0010 failed with error -121
[ 17.529991] imx219 10-0010: tegracam sensor driver:imx219_v2.0.6
[ 17.546893] imx219 10-0010: imx219_board_setup: error during i2c read probe (-121)
[ 17.559813] imx219 10-0010: board setup failed
[ 17.564448] imx219: probe of 10-0010 failed with error -121
この後、tc358743に対する検知処理が動作するように環境をセットアップする必要があります。
デバイスツリー環境について
次に、TC358743に対する検知処理が動作するように、デバイスツリーの環境を作成及び更新します。
私が以前にJetson NanoにてTC358743を試用したときには、以下のGithubでの情報に助けられました。
TC358743 Jetson Nano driver and device tree | GitHub
その当時、そのREADME.mdのセクション"Update-device-tree"に書かれている方法にそのまま従って、なんとかデバイスツリーのファイルを生成し、それをなんとか書き込んで、TC358743を認識させることに成功したという経緯がありました。
このときは、上記方法の通り、デフォルトのimx219のデバイスツリー環境を消してしまって、TC358743の環境で上書きしてしまう、というやり方でした。
今回は、uzunaさんの以下のページを参考にさせてもらい、デフォルトのIMX219やIMX477の設定環境は残しつつ、Device Tree OverlayでTC358743を認識させる、という形でやってみましたので、その方法をここでは紹介します。
Jetsonのカメラドライバを書く[I2C編] - Qiita
デバイスツリーの作成
上記uzunaさんの記事で、IMX708に関するデバイスツリーのファイルの作成の仕方をほぼ真似して、IMX477のファイルをベースに、
- tegra234-camera-toshiba-tc358743.dtsi
- tegra234-p3768-camera-toshiba-tc358743.dtsi
を作成し、/usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/に置きます。
ここで、ポイントのリストアップだけしておきます。(説明が荒くてすみません)
- compatibleを"toshiba,tc358743"に変更
- i2cのアドレスを0x0fに変更
- TC358743には関係のないmode0やmode1の記述削除
- i2c@1にrefclk_hzの設定を追加
- i2c@1に、クロック関連の設定を追加
また、tegra234-p3768-0000-a0.dtsiにtegra234-p3768-camera-toshiba-tc358743.dtsiのinclude行を入れることで、キャリアボード全体のデバイスツリーに追加したことになります。
$ diff /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-p3768-0000-a0.dtsi /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-p3768-0000-a0.dtsi.org
19d18
< #include "tegra234-p3768-camera-toshiba-tc358743.dtsi"
また、これも、IMX708に関するデバイスツリーオーバレイの作成の仕方を真似して、IMX477のファイルをベースに、TC358743用Device Tree Overlayファイルの、
- tegra234-p3767-camera-p3768-tc358743.dts
を作成し、/usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/に配置して、かつ、そのエントリをMakefileに追加します。
$ sudo cp -p /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/Makefile /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/Makefile.org
$ sudo vi /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/Makefile
$ diff /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/Makefile /usr/src/hardware/nvidia/platform/t23x/p3768/kernel-dts/Makefile.org
42d41
< dtbo-$(BUILD_ENABLE) += tegra234-p3767-camera-p3768-tc358743.dtbo
なお、ここで使用したデバイスツリーファイルなどは、とりあえず、GitHubのJetsonOrinNanoに置いています。
デバイスツリーのビルド
makeKernel.shを参考にmakeDtbs.shを作成して、それを実行します。(スクリプト内の実体はmake dtbs
です。
$ ./makeDtbs.sh
Proposed source path: /usr/src/kernel/kernel-5.10
Source Target: /usr/src/
...(中略)...
real 0m16.999s
user 0m29.649s
sys 0m9.149s
DTBs make successful
DTB files are here:
/usr/src/kernel/kernel-5.10/arch/arm64/boot/dts/nvidia/
デバイスツリーファイルのインストール
copyDtbs.shにて、ベースのdtbファイル(tegra234-p3767-0003-p3768-0000-a0.dtb)と、Device Tree Overlayのファイル(tegra234-p3767-camera-p3768-tc358743.dtbo)とをシステム領域にコピーします。
$ sudo cp -p /boot/dtb/kernel_tegra234-p3767-0003-p3768-0000-a0.dtb /boot/dtb/kernel_tegra234-p3767-0003-p3768-0000-a0.dtb.org
$ ./copyDtbs.sh
Jetson-IOを用いて
最後に、Jetson-IOツールを使用して、デフォルトの環境とは別に、用意したDevice Tree Overlayにより、デバイスツリー環境をTC358743を使えるように上書きする方法を説明します。
$ sudo /opt/nvidia/jetson-io/jetson-io.py
と、jetson-io.pyを実行して、[Configure Jetson 24pin CSI Connector]→[Configure for compatible hardware]と選択すると、
と、"Camera TC358743-C"という項目が現れますので、それを選択し、[Save pin changes]→[Save and reboot to reconfigure pins]と選択すると、
という最終画面になります。ENTERキーなど、適当にキーを叩くとリブートして、次の起動からは、TC358743基板が使えるようになっているはずです。
ちなみに、ここで、"Camera TC358743-C"という項目が現れるようになったのは、上述のcopyDtbs.shにて、/boot/にtegra234-p3767-camera-p3768-tc358743.dtboをコピーしたことによる効果です。そして、"Camera TC358743-C"という文字列は、デバイスツリーのソースファイルtegra234-p3767-camera-p3768-tc358743.dtsの中の、
overlay-name = "Camera TC358743-C";
jetson-header-name = "Jetson 24pin CSI Connector";
という記述の効果、ということになります。
動作確認例
$ gst-launch-1.0 v4l2src device=/dev/video0 ! 'video/x-raw,format=UYVY,width=1920,height=1080,framerate=30/1' ! nvvidconv ! video/x-raw ! xvimagesink sync=0
などと実行すると、以下のスクリーンショットのように、Windows PCの外部モニタとして動作する状態になります。
(今、丁度、この記事を編集しているウィンドウを「Jetson Orin NanoとTC358743基板とで実現している外部モニタもどき」に表示してみているところです。)
書き忘れていましたが、Windows PC側でのディスプレイの詳細設定で、リフレッシュレートを60Hzではなく30Hzに落とさないと正常に動作しませんでした。あまりちゃんと考察できていませんが。
おわりに
この記事では、Jetson Orin Nanoで、TC358743(HDMI To MIPI-CSI2ブリッジチップ)搭載基板を用いて、PCの外部モニタ動作をさせてみることをテーマに、Linuxカーネル環境のビルド環境の構築及びその動作確認例を紹介してみました。
後で、もう少し補足説明を追加するかもしれません。とりあえず、ここで使用したデバイスファイルやスクリプトファイルなどは、GitHubのJetsonOrinNanoに置いています。とりあえずな置き方ですみません。