NAS用のカーネルモジュールをビルドする:CH341 USBシリアルドライバー
CH340またはCH341チップを搭載したUSBシリアル変換アダプターの多くは、カーネルのch341ドライバーを必要とします。ここで使用するQTS 6.1搭載NASには、このドライバーが付属していません。Bucket & Code Server IDEのカーネルワークショップは、NASで動作中のカーネルに合わせてモジュールをビルドし、そのカーネルとの互換性を確認してロードします。
- プロファイルカーネルの情報
- ワークスペース情報に合わせて設定したツリー
- ビルドdrivers/usb/serial
- 確認vermagic、レイアウト、シンボル
- ロード管理者が自己責任で実行
画像はQTS 6.1とカーネル6.6.129-qnapを搭載したNASのものです。各フィールドは、このガイドの説明に従って入力しています。
01ワークショップの役割
QNAPの公開GPLアーカイブに掲載されているカーネルソースはQTS 5.2.3までで、このQTS 6.1搭載NASで動作中のカーネルは含まれていません。そのため、ワークショップは動作中のカーネルが公開する情報を読み取り、kernel.orgのカーネルツリーをそれに合わせて設定します。Kernelsページには、リリース、QNAPが使用したコンパイラー、QNAP製モジュールのvermagicとstruct moduleのレイアウト、モジュールの署名が必須かどうかを含むプロファイルが表示されます。
- Examplesギャラリー(Apps → Examples)のKernel builder環境が必要です。Ubuntu 24.04にGCC 13とカーネルのビルドツールを備えています。ワークショップでは、動作中のカーネルをビルドしたものと同じGCCメジャーバージョンが必要で、ワークスペースの準備前に確認します。
- 準備、ビルド、ロードには管理者ロール、確認には開発者ロールが必要です。rootで動作するエディターのターミナルでは、同じ手順を
bvs kernelコマンドで実行できます。
02ワークスペースを準備する
ワークスペースは動作中のカーネルに正確に対応するカーネルツリーで、データフォルダーのkernels/<release>に置かれます。KernelsページでPrepare the workspaceを押します。
- Source:推奨されるソースのままにします。QNAP自身のツリーには古いカーネルしかないため、6.6.129ではkernel.orgのツリーが選ばれます。

- Environment:
kernel-builder。Extra settingsには、USBシリアルのコアとCH341ドライバーを指定するUSB_SERIAL=mとUSB_SERIAL_CH341=mを1行ずつ入力します。Build the whole kernelはオフのままにして、Prepareを押します。
- ジョブがソースを展開し、プロファイルと指定した設定に従って構成し、モジュールをビルドできる状態にします。続いて、ツリーのビルド対象が動作中のリリースと完全に一致することを確認します。Workspaceカードにreadyと表示されます。準備に失敗した場合、以前のツリーは保持されます。

03プロジェクト
New projectのKernelには、自作のHelloモジュールとch341ドライバーの2つのテンプレートがあります。USB serial driver ch341を選びます。
プロジェクトには、ワークショップのコマンドを各ターゲットで実行するMakefileと、NASのランナー用ワークフローが含まれます。
# プロジェクトのMakefile。エディターのターミナルでrootとして実行 make prepare # bvs kernel prepare --option USB_SERIAL=m --option USB_SERIAL_CH341=m make # bvs kernel make --dir drivers/usb/serial make check # bvs kernel check ch341 make load # bvs kernel load ch341 make unload # bvs kernel unload ch341
ワークフローはpushのたびに--build-onlyでドライバーをビルドし、確認します。そのビルドのch341.koは実行結果のアーティファクトmodulesに保存され、ワークスペースのmodules/フォルダーには入りません。そのため、make loadは自分でビルドしたモジュールを引き続きロードします。
04ドライバーをビルドする
KernelsページのBuild modulesは、プロジェクトのフォルダーまたはカーネルツリー内のディレクトリをビルドします。ch341ドライバーはツリーの一部なので、A directory of the kernel treeを選び、drivers/usb/serialと入力します。プロジェクト内でのmakeも同じ処理を行います。
ビルドによってch341.koとusbserial.koが生成されます。ワークスペースはch341.koをmodules/に保持します。usbserial.koはQNAPが提供しており、ロードにはQNAPのコピーを使用するため、保持しません。
05動作中のカーネルとの互換性を確認する
Checkはモジュールを動作中のカーネルと比較します。対象はvermagic、struct moduleのサイズとinitおよびexitの位置、署名の必要性、依存するモジュール、必要なすべてのシンボルです。各検出結果には、不一致の内容と対処方法が示されます。
QNAPのカーネルはデータシンボルを列挙しないため、確認ではjiffiesなどのシンボルを警告として表示します。コマンドラインのbvs kernel check ch341は、モジュールをロードしてはいけない場合、終了ステータス3で終了します。
06ロードとその影響
モジュールはカーネル内部で、カーネルと同じすべての権限を持って動作します。不具合のあるモジュールはNASを停止させるおそれがあります。明確な目的で自分がビルドしたものだけを、再起動できるNASでロードしてください。
- Load(管理者)または
make loadは再度確認を実行し、依存するモジュールから順にロードします。この例ではQNAPのusbserialが先です。確認でエラーが出たモジュールはロードされません。Unloadはモジュールを取り除きますが、使用中のモジュールはロードされたままです。ロードとアンロードはすべてlog/kernel-modules.logに記録されます。 - 手動でロードしたモジュールは再起動後にはなくなります。毎回の起動時にロードするには、App Builderアプリのカーネルモジュールにその名前を指定します。アプリの有効化時にロードされ、その後もパッケージの起動ごとに再ロードされます。
- パッケージがモジュールをロードした起動中に、パッケージの正常な停止を経ずにNASが停止した場合(クラッシュ、停電、ハードリセット)、次の起動ではそのモジュール群を読み込みません。いずれかのモジュールがクラッシュの原因だった可能性があるためで、通知に名前が表示されます。モジュールを手動でロードするか、そのアプリを再度有効にすると、起動時に再びロードできるようになります。
- QTSの更新でカーネルが変わったら、新しいカーネルのワークスペースを準備してモジュールを再ビルドします。バックアップには
kernels/は含まれません。