【ITニュース解説】Cross-Compiling Linux Kernel Module: A Hands-On Guide
2025年09月07日に「Dev.to」が公開したITニュース「Cross-Compiling Linux Kernel Module: A Hands-On Guide」について初心者にもわかりやすいように丁寧に解説しています。
ITニュース概要
PC上でスマホ等の組み込み機器向けプログラムを作る「クロスコンパイル」技術を解説。Linuxカーネルのビルドから機能拡張モジュールの作成、エミュレータでの動作確認まで、ARMアーキテクチャを対象とした開発手順を実践的に紹介する。
ITニュース解説
ソフトウェア開発におけるコンパイルとは、プログラマが記述した人間が読めるソースコードを、コンピュータが直接実行できる機械語のバイナリファイルに変換する工程である。特に、Raspberry Piに代表される組み込みシステムやIoTデバイスの開発では、開発に使用する高性能なパソコンと、実際にプログラムを動かすデバイスとで、搭載されているCPUの種類、すなわちアーキテクチャが異なることが一般的である。例えば、多くのパソコンがx86-64アーキテクチャのCPUを搭載しているのに対し、組み込みデバイスではARMアーキテクチャが広く採用されている。このような異なるアーキテクチャのデバイスで動作するプログラムを開発用パソコン上で作成する技術が「クロスコンパイル」であり、組み込み開発において極めて重要なスキルとなる。
プログラムのコンパイルは、ソースコードを機械語に変換するだけでなく、プリプロセス、アセンブル、リンクといった複数の段階を経て実行ファイルが生成される。このコンパイル方式には、大きく分けて二つの種類が存在する。一つは「ネイティブコンパイル」で、これはプログラムをコンパイルする環境と、そのプログラムを実行する環境のアーキテクチャが同じ場合に行われる。つまり、x86-64のパソコンで、同じx86-64のパソコンで動くソフトウェアを開発する場合がこれにあたる。もう一つが「クロスコンパイル」であり、コンパイル環境と実行環境のアーキテクチャが異なる場合の手法である。クロスコンパイルが必要とされる主な理由は、ターゲットとなる組み込みデバイスが、コンパイルという重い処理を実行するにはCPU性能やメモリ容量といったリソースが著しく不足しているためである。そのため、開発用のパワフルなパソコン上で、ターゲットデバイス向けの実行ファイルを効率的に生成する必要がある。
クロスコンパイルを実現するためには、「クロスコンパイルツールチェイン」と呼ばれる特別な開発ツール群が必要となる。ツールチェインには、特定のターゲットアーキテクチャ向けのコードを生成するコンパイラやリンカ、ライブラリなどが含まれている。例えば、x86-64アーキテクチャのLinuxマシン上でARM64アーキテクチャ向けのプログラムを開発する場合、aarch64-linux-gnu-gccといった名前のコンパイラを使用する。このツールはx86-64マシン上で動作するが、出力するバイナリはARM64マシンで実行可能な形式となる。
Linuxシステムをゼロから構築する場合、OSの中核をなす「Linuxカーネル」だけでは不十分である。カーネルが起動した後にユーザーが操作するためのコマンド群や、システム設定ファイルなどを格納する「ルートファイルシステム」が必要不可欠となる。まず、ターゲットデバイスであるARM64向けにLinuxカーネルを準備する。Linuxカーネルの公式サイトからソースコードをダウンロードし、ターゲットのアーキテクチャをARCH=arm64、使用するクロスコンパイラをCROSS_COMPILE=aarch64-linux-gnu-のように環境変数で指定する。make defconfigコマンドでターゲットアーキテクチャ向けの標準的な設定ファイルを生成し、makeコマンドを実行することで、ARM64で動作するカーネルイメージがビルドされる。次に、ルートファイルシステムを構築する。組み込みシステムではリソースを節約するため、最小限の構成が求められる。そこで、「BusyBox」というツールが役立つ。BusyBoxは、lsやmountといった多数の基本的なUNIXコマンドを、単一の小さな実行ファイルにまとめたものである。これをクロスコンパイルし、binやetcといったLinuxの標準的なディレクトリ構造を作成したrootfsという作業ディレクトリに配置する。さらに、システム起動の仕組みを整える。Linuxカーネルは起動後、最初にinitという名前のプログラムを実行しようとする。このinitプロセスの役割を担う簡単なシェルスクリプトを作成し、ファイルシステムのマウントなど、最低限の初期化処理を記述する。このスクリプトに実行権限を与え、rootfs内に配置する。最後に、このrootfs全体を「initramfs」という形式の圧縮アーカイブファイルに変換する。initramfsは、システム起動時にメモリ上に展開される一時的なルートファイルシステムとして機能する。
Linuxカーネルモジュールは、OSの中核であるカーネルの機能を、システムを再起動することなく動的に追加または削除するための仕組みである。デバイスドライバの多くはこの形式で実装されており、システムの柔軟性を高めている。このカーネルモジュールも、ターゲットアーキテクチャに合わせてクロスコンパイルする必要がある。先ほどビルドしたLinuxカーネルのソースコードディレクトリを指定し、クロスコンパイラを使ってコンパイルを実行すると、.koという拡張子を持つARM64向けのカーネルモジュールファイルが生成される。この生成されたモジュールファイルを、先ほど作成したrootfsディレクトリ内にコピーし、initramfsアーカイブを再作成することで、起動するシステムにカスタムモジュールを組み込む準備が整う。
開発したカーネルやモジュールを実機に書き込む前に、その動作をPC上で確認できると開発効率が大幅に向上する。これを可能にするのが「QEMU」というエミュレータである。QEMUを使うことで、ARM64などの異なるアーキテクチャを持つマシンを仮想的にPC上で再現できる。QEMUの起動コマンドで、先ほどビルドしたARM64向けカーネルイメージとinitramfsファイルを指定し、CPUタイプやメモリサイズなどを設定して仮想マシンを起動する。起動が成功すると、ターミナル上に仮想マシンのコンソールが表示され、作成したinitスクリプトが実行される。この仮想Linux環境上でinsmodコマンドを使って作成したカーネルモジュールをロードすると、カーネルのログにモジュールが正常に読み込まれたことを示すメッセージが出力される。このログはdmesgコマンドで確認できる。同様にrmmodコマンドでモジュールをアンロードできることも確認する。
このように、クロスコンパイルの技術を用いることで、開発用PC上で異なるアーキテクチャ向けのLinuxカーネル、ルートファイルシステム、そしてカーネルモジュールを構築することが可能となる。さらにQEMUのようなエミュレータを活用すれば、実機なしでシステムの起動からモジュールの動作テストまでを完結させることができる。これらの知識と手順は、組み込みLinuxシステムの開発、特にデバイスドライバの開発やカーネルのカスタマイズを行う上で、システムエンジニアにとって基礎的かつ不可欠なスキルである。