目次: Linux
独自のカーネルモジュールをビルドしたかったのですがスマートな方法が良く分からず、力ずくでやってしまいました。
まずaptでLinuxのソースコードを持ってきました。apt-get installだけだと /usr/srcにtarballが置かれるだけなので、手で展開します。
# apt-get install linux-source-3.16 Reading package lists... Done Building dependency tree Reading state information... Done Suggested packages: libqt4-dev pkg-config The following NEW packages will be installed: linux-source-3.16 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/83.6 MB of archives. After this operation, 83.7 MB of additional disk space will be used. Selecting previously unselected package linux-source-3.16. (Reading database ... 54876 files and directories currently installed.) Preparing to unpack .../linux-source-3.16_3.16.7-ckt25-2_all.deb ... Unpacking linux-source-3.16 (3.16.7-ckt25-2) ... Setting up linux-source-3.16 (3.16.7-ckt25-2) ... # cd /usr/src # ls linux-config-3.16 linux-source-3.16.tar.xz # tar xf linux-source-3.16.tar.xz # ln -s linux-source-3.16 linux
カーネルバージョンを見るか、Debianのカーネルパッケージのバージョンを確認して、適切なカーネルのconfigファイルを展開します。
# cd /usr/src # uname -a Linux vbox-blackbird 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux # cp linux-config-3.16/config.amd64_none_amd64.xz linux/ # cd /usr/src/linux # xz -d config.amd64_none_amd64.xz # mv config.amd64_none_amd64 .config
ビルドします。Debianのカーネルコンフィグはやたらめったらドライバをビルドするので、かなりビルドに時間が掛かります…。
# cd /usr/src/linux # make -j 4 bzImage modules ...
ビルドが終わったら、独自カーネルモジュールをビルドします。
# cd /home/username/hoge_module # make ...
生成された*.koをinsmodして文句言われなければ成功です。
# insmod hoge.ko insmod: ERROR: could not insert module hoge.ko: Invalid module format
こんな風に怒られる時は、昔のバージョンのtarballを展開したときのコードが残っているなど、カーネルのソースコードが古いか、コンフィグを選び間違っていますので、確認しましょう…。
目次: Linux
昨日(2016年4月15日の日記参照)のやり方は、やはり一般的では無かった(1時間以上掛かるし…)らしく、スマートなやり方を教えていただきました。
# apt-get install linux-headers-3.16 パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 Note, selecting 'linux-headers-3.16.0-4-all' for regex 'linux-headers-3.16' Note, selecting 'linux-headers-3.16.0-4-amd64' for regex 'linux-headers-3.16' Note, selecting 'linux-headers-3.16.0-4-common' for regex 'linux-headers-3.16' Note, selecting 'linux-headers-3.16.0-4-all-amd64' for regex 'linux-headers-3.16 ' linux-headers-3.16.0-4-commonはすでに最新版です。 以下の追加パッケージがインストールされます: cpp-4.8 gcc-4.8 libasan0 libgcc-4.8-dev linux-compiler-gcc-4.8-x86 linux-kbuild-3.16 提案パッケージ: gcc-4.8-locales gcc-4.8-multilib gcc-4.8-doc libgomp1-dbg libitm1-dbg libatomic1-dbg libasan0-dbg libtsan0-dbg libquadmath0-dbg 以下のパッケージが新たにインストールされます: cpp-4.8 gcc-4.8 libasan0 libgcc-4.8-dev linux-compiler-gcc-4.8-x86 linux-headers-3.16.0-4-all linux-headers-3.16.0-4-all-amd64 linux-headers-3.16.0-4-amd64 linux-kbuild-3.16 アップグレード: 0個、新規インストール: 9個、削除: 0個、保留: 0個。 12.7 MBのアーカイブを取得する必要があります。 この操作後に追加で39.9 MBのディスク容量が消費されます。 (以下略)
カーネルモジュールをビルドしますが、もし /usr/src/linuxを見に行ってしまうようなモジュールであれば、ちょっと書き換えが必要です。
$ make -C /usr/src/linux M=`pwd` ↓ $ make -C /lib/modules/`uname -r`/build M=`pwd`
昨日の方法と比べると、Linuxのソースコードもビルドも要らないし、格段にスマートです。素敵。
でも、カーネルモジュールがヘボくて、カーネル内でクラッシュし、結局Linuxのソースコードにデバッグprintkを埋め埋めしてビルドする羽目になったのはご愛敬です…。
目次: ALSA
以前(2016年2月28日の日記参照)にALSA SoC Layerについて調べましたが、詳細な解説が出来るほど良く分かってないので、現時点で分かっていることのメモ書きを貼っておこうと思います。
まず、openとcloseができるだけの、何もしないドライバを作るだけであれば、呼び出すべきAPIは4つです。
各APIに渡す構造体と、APIの関連は下記のようになっていました。これで全て網羅できているわけではありません。奥が深いです…。
実際にコードをどう書いたら良いかについては GitHub にサンプルを置いています。このコードをコンパイルしていただければ動きます(音は鳴りませんけど)。
Linux 4.4系がLongtermの仲間入りをしたので、自作ARMエミュレータememuでLinux 4.4.8を動かしてみたのですが、未定義の領域にアクセスしてクラッシュしてしまい動かず…。
他のLongterm(Linux 4.1.23)は元気に動くんだけどな。何かドライバが変わったんだろうなあ。