やまちゃんのオーディオブログ

真空管アンプ、最近は資金調達のためのFX,MetaTrader4ネタもやっています。

FPGA ラズベリーパイB

ラズベリーパイのi2s外部クロック、その後3-3(2018年度版)

投稿日:2018年3月25日 更新日:

(以下、コンパイルの説明をする。コンパイルをしてしまうと後で戻ることは難しくなる。
 ここで、パソコンにSDカードのデータをセーブする必要がある。セーブするにはsdformatterを使う(後の回に説明)。)

12 カーネルソースのコンパイル

(過去記事「ラズベリーパイDAC、I2S完全外部クロック、スレーブ入力のめどが立ちました!」の「7 カーネルソースをコンパイルする。」も参照。)

<2018.5.11 追記>
ラズベリーパイのi2s外部クロック、その後3-1(2018年度版)」で述べたように、rpi-sourceというコマンドで実行可能なカーネルのソースをインストールするのですが、
rpi-sourceでインストールされるカーネルのバージョンが、4.14!?とまったくもって古いバージョンがインストールされ、後でinsmodをしても、invalid module formatとなって、モジュールを組み込むことができません。また、kernel-headersをインストールするだけでは足りなかったので、説明を加えます。実はもう一度、一からこのサイトの内容を追試してみて、invalid module formatで悩み、沈み込んでしまったので、再検討していました。

以下の治療は荒治療ではないかと思います。カーネルのバージョンを無理やり合わせます。本来はどうして4.14がインストールされるのかの原因を究明すべきですが、動くからまあいいや、というレベルです。「Atelier Orchard」さんの「Invalid module formatと格闘」という記事を参考にしました。私も文字通り、格闘しました。このサイトのとおり行い、荒治療を行い、何とか切り抜けている状態です。方法は、makeをするときに参照するMakefileにつき、そのファイルで表示されるカーネルのバージョンを、無理やり合わせます。これはこの荒治療では必須です。これをしないで、カーネルヘッダーをインストールすると、上記古い4.14のカーネルヘッダーがダウンロードされ組み込まれ、話になりません。

まず、以下のコマンドでカーネルのバージョンを調べます。

cat /proc/version

前述したカーネルソースのダウンロード先のフォルダの先頭へ移動します。

cd /root
root@raspberrypi:~# dir
linux
linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130
linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130.tar.gz
root@raspberrypi:~# cd linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130
root@raspberrypi:~/linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130# dir
arch Documentation ipc Makefile samples virt
block drivers Kbuild mm scripts
certs firmware Kconfig Module.symvers security
COPYING fs kernel Module.symvers.backup sound
CREDITS include lib net tools
crypto init MAINTAINERS README usr
root@raspberrypi:~/linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130# nano Makefile

rootディレクトリ(「~」でも表記される)の下のダウンロードしたパッケージのフォルダ「linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130」があるフォルダに移動します。そのMakefileの先頭につき、VERSION = 4、PATCHLEVEL = 14・・・となっているのを無理やり以下のように修正します。cat /proc/versionと合致していれば(現在では、4.9・・・となっていれば)問題ないです。

# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 80
EXTRAVERSION = -v7+
NAME = Petit Gorille

このようにすると、そこのフォルダ全部につき、カーネルが4.9.80-v7+でコンパイルされることになります。そこでコンパイルされるカーネルのバージョンは以下で調べます。

root@raspberrypi:~/linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130# make kernelversion
4.9.80-v7+

kernel-headersをここでインストールします。

sudo apt-get install raspberrypi-kernel-headers
・・・The following NEW packages will be installed:
raspberrypi-kernel-headers
0 upgraded, 1 newly installed, 0 to remove and 5 not upgraded.
Need to get 15.4 MB of archives.
After this operation, 99.0 MB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian stretch/main armhf raspberrypi-kernel-headers armhf 1.20180313-1 [15.4 MB]
Fetched 15.4 MB in 47s (324 kB/s)
Selecting previously unselected package raspberrypi-kernel-headers.
(Reading database … 37476 files and directories currently installed.)
Preparing to unpack …/raspberrypi-kernel-headers_1.20180313-1_armhf.deb …
Unpacking raspberrypi-kernel-headers (1.20180313-1) …
Setting up raspberrypi-kernel-headers (1.20180313-1) …

上記の日付が、カーネルが発行されたバージョンの日付と一致することを確認したほうがいいです。

そうすると、後述のkernel-headersをインストールしたとき、以下のように、きちんとしたカーネルのバージョンのフォルダにリンクされ、適正なバージョンでコンパイルされます。

root@raspberrypi:~/linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130/sound/soc/bcm# make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make: Entering directory ‘/usr/src/linux-headers-4.9.80-v7+

この赤字で書いた部分ですが、kernel-headersxxがcat /proc/versionと合致して初めて、コンパイル後にエラーが出ないモジュールが完成されます。

上記の環境変数$bcmを登録したことを前提として、以下のコマンド。

cd $bcm
make -C /lib/modules/$(uname -r)/build M=$(pwd) clean
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install

これにより、bcm2835-i2s.cがsnd-soc-bcm2835-i2s.koへ、rpi-dac.cがsnd-soc-rpi-dac.koへそれぞれコンパイルされ、モジュールが生成される。
ここで、エラーが出る場合には、全角のエラーが出る場合が多い。ダブルクオーテーション、スペースが全角になっていないかをチェック。
ここで、pcm1794a.cは直さなくてもよいが、ほかのモジュールとの依存関係(後述)があるので、組み直す時にこれを削除する必要があり、さらにもう一度組み入れる場合に、snd-soc-pcm1794a.koがないと困るので、コンパイルせざるを得ない。上記の環境変数$codecを登録したことを前提として、以下のコマンド。

cd $codec
make -C /lib/modules/$(uname -r)/build M=$(pwd) clean
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install

なお、上記のコマンドでは、フォルダ内の全部のファイルをコンパイルしようとする。そこで、後ろにファイル名を付けても、特定のファイルのみコンパイルすることはできないようである。

13 コンパイルしたモジュールのインストール
コンパイルが通った場合、コンパイルが通ってモジュールを生成しても、登録しなければ動かない。そこで、以下のコマンド。

insmod $bcm/snd-soc-bcm2835-i2s.ko
insmod $codecs/snd-soc-pcm1794a.ko
insmod $bcm/snd-soc-rpi-dac.ko

・なお、いったんモジュールを組み込んだ場合には、更新するには、モジュールを除去する必要があり、モジュールを除去するコマンドはrmmodである。もっとも、モジュールには依存関係があるので、除去するには、snd-soc-rpi-dac.ko、snd-soc-pcm1794.ko、snd-soc-bcm2835-i2s.koの順に除去する必要がある。
更新コマンドは以下の通り。一括コピーして、teraterm上で、右クリックすると一括ペーストできます。

rmmod $bcm/snd-soc-rpi-dac.ko
rmmod $codec/snd-soc-pcm1794a.ko
rmmod $bcm/snd-soc-bcm2835-i2s.ko
insmod $bcm/snd-soc-bcm2835-i2s.ko
insmod $codec/snd-soc-pcm1794a.ko
insmod $bcm/snd-soc-rpi-dac.ko
cp $bcm/snd-soc-bcm2835-i2s.ko /lib/modules/(uname -r)/kernel/sound/soc/bcm/snd-soc-bcm2835-i2s.ko
cp $bcm/snd-soc-bcm2835-i2s.ko /lib/modules/(uname -r)/extra/snd-soc-bcm2835-i2s.ko
cp $bcm/snd-soc-rpi-dac.ko /lib/modules/$(uname -r)/kernel/sound/soc/bcm/snd-soc-rpi-dac.ko
cp $bcm/snd-soc-rpi-dac.ko /lib/modules/$(uname -r)/extra/snd-soc-rpi-dac.ko
depmod

これによりモジュールが登録され、使えるようになります。

<2018.4.29 訂正>
insmodコマンドを実行して、invalid formatというエラーが出た場合には、ラズパイの本家サイトに記載の以下のコマンドを実行してから、コンパイルをやり直してください。

sudo apt-get install raspberrypi-kernel-headers

<2018.5.5 訂正>
insmodだけではメモリー上にロードされるだけで、電源を切るとドライバーをインストールしたことを忘れてしまいます。そこで、cpコマンドにより直接本来のドライバーの位置にコピーして、古いドライバーを上書きして、更新します。

<以下、invalid formatの試行錯誤顛末記>
以下長くなるので、飛ばしてください。

従前と同様にinsmodを使おうとすると、invalid formatと言って、カーネルのバージョンが合わないというエラー。
私の技量では手に負えず、2日余り、責任を感じながら唸っていました。modules_installを使えば、あっさり動いたように思ったが、やっぱり、invalid formatのエラーが出た場合には、エラーが出ないのにモジュールが組み込まれない。
エラーの訂正にさらに四苦八苦。rpisourceは、そもそもカーネルのコンパイルをしなくても、現在のバージョンに合致した情報を組み込んでくれるのが売りだったはずなのにバージョン違いでコンパイルしたものが組み込めないとはおかしい。そこで、ネット検索をいろいろ。。。上記rpisourceの本家サイトであるHome · notro/rpi-source Wiki · GitHubでリンクがされている、ラズパイの本家サイトの「documentation > linux > kernel > headers」では、新しいカーネルが登場したとき、カーネルに対応したヘッダーファイル(コンパイルの情報、バージョン等を格納したもののようだ)が必要になるが、最新のカーネルが発表されてから反映されるまで5~6週間かかる(いまいち訳に自信がない)。そういえば、私がカーネルをダウンロードしたのは、最新のカーネルが3月に発行されてから、1か月ぐらいしかたっていなかった。
insmodコマンドを実行して、invalid formatが出た場合には、ラズパイの本家サイトに記載の以下のコマンド。

sudo apt-get install raspberrypi-kernel-headers

これによりどうなるかですが、上記コンパイル済みで組み込む予定の「xx.ko」というファイルにつき、カーネルのバージョンを調べます。

modinfo $bcm/snd-soc-rpi-dac.ko

で調べたカーネルのバージョンが、4.14.24-v7+だったのが、4.9.80-v7+へ訂正されました。 

<2018.5.11追記:このようにバージョンが変更されるのは、上記のMakefileにつき、荒治療を行ったときだけです。>

また、コンパイルしたときにコンパイラが処理に入るディレクトリが、以下の通り変わりました。

# make -C /lib/modules/`uname -r`/build M=$(pwd) clean
make: Entering directory ‘/root/linux-80a14a56dacb7cc2b40d5f37d00bedb0ceace130’
→make: Entering directory ‘/usr/src/linux-headers-4.9.80-v7+’

<invalid formatの試行錯誤の顛末記ここまで。>

-FPGA, ラズベリーパイB

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

no image

ラズベリーパイ カーネル3 I2Sドライバのコンパイルをあきらめず続ける

以前の記事に引き続き、I2Sドライバのコンパイルをあきらめず続ける。 「三日坊主な私がいつまでブログやれるか...( ̄~ ̄;) 」のラズベリーパイの記事を参考にさせていただいています。 volumio …

no image

ラズベリーパイDAC、I2S完全外部クロック、スレーブ入力のめどが立ちました!

ラズベリーパイ、I2S、完全外部クロック、スレーブ入力のめどが立ちました! 現在、I2Sという形式でデジタル音声データをラズベリーパイからDACへ送ることが流行っています。 I2Sは、従来のUSB経由 …

no image

ラズベリーパイ LANクロスケーブル接続を外部ネットへ ネットワークブリッジ 接続トラブル

ラズベリーパイとPCとを直接つないで、かつ、ラズベリーパイを外部ネットワークにつなぐ方法 トラブル対策 ラズベリーパイには、私はvolumioを入れたが、基本はリナックスなので、リナックスベースのプロ …

no image

コマンドラインで動く、汎用i2sハイレゾモジュールの作り方(これまでのまとめ)。 (How to make a general i2s hi-resolution play-module with external bck clock using command-line on raspberry pi. And you can use gpio for operation)

これまでののうち、コマンドをまとめました。 <2018.4.28 追記 以下は、24ピンのラズパイBノーマルバージョンかつ当時のカーネルを使うことが前提になります。 今のカーネルには、bcm2708- …

no image

ラズベリーパイのi2s外部クロック、その後1(2018年度版)

ラズベリーパイの24ピンの初代Bは、市場からほとんど消えている状況なので、今までの記事は独りよがりになっている可能性が高く、そこで、入手性の高いラズベリーパイ2を購入し、誰でも、外部クロックを追試でき …

[最近の記事]
2018年3月
 123
45678910
11121314151617
18192021222324
25262728293031