Select Your Language

免責事項

  • 本サイトの情報の利用、内容、サービスによって、利用者にいかなる損害、被害が生じても、著者は一切の責任を負いません。ユーザーご自身の責任においてご利用いただきますようお願いいたします。

    本サイトで頒布している基板およびキットは、技術者、またはそれに準ずる電気的知識をお持ちの電子工作ファンの方のためのものです。一般のオーディオファンの方のためのものではありません。
    また、頒布基板およびキットは、いかなる条件でも動作を保証するものではございませんので、あらかじめご了承ください。

    電子工作では、火傷、感電、火災などの可能性があります。十分に注意をして作業して下さい。

    営利目的のご使用は認めておりません。 記事の転載や、基板・キットの商用利用の方は、ご連絡ください。学生やサークルの学習目的でまとめてご購入する場合は特別価格でご提供させていただきます。

スポンサー

無料ブログはココログ

« ついに64bit版 Moode Audio R6.4.1用のSabreberry32ドライバリリース | トップページ | RaspberryPiのCPU比較 どれが64bitで動くの? »

2020年2月 2日 (日)

RaspberryPi kernelとDriverのクロスコンパイル方法

ARMv8 32bit/64bitのクロスコンパイルの方法についてまとめました。

https://www.raspberrypi.org/documentation/linux/kernel/building.md

基本的にはRaspberryPi公式の方法に則ってやっていきます。(公式では32bit版しか載っていません。)クロスコンパイルに使ったのはVirtualBoxとubuntu 18.4LTSの組み合わせです。

Vbox_build

見た目はこんな感じで、普段のWindowsと変わらない操作感です。ホストOS-ゲストOS間のコピペも自在ですし、USBメモリやSDカードをゲストOSに直接マウントすることもできて便利です。ただし、ホストのストレージは喰うので256GB以下の小容量SSDなパソコンにはあまりお薦めできません。

 

 

ubuntu 18.4LTS(PC-Linux)上での作業

ツールチェーン用にディレクトリを作成してその中に入れていきます。

mkdir raspi-dev

cd raspi-dev

sudo apt-get update

sudo apt-get -y install git build-essential libncurses5-dev bc bison flex libssl-dev

 

続いてツールチェーンのダウンロード

git clone https://github.com/raspberrypi/tools.git

準備完了です。※ここで導入できるのはARMv7(32bit)用のクロスコンパイラ一式です。

 

この後、公式サイト通りに進めると最新版のカーネルソースを取得していきますが、現在、起動しているラズパイがあるのでしたら、そのカーネルと同じソースを取得した方がドライバ作成には好都合です。カーネルバージョンが完全一致しないとドライバモジュールを取り込まないセキュリティになっているからです。

という訳で、ラズパイ側でも作業します。
64bitモードで起動しているのか、32bitモードで起動しているのか把握しておく必要があります。普通にRaspbianを起動すると32bitモードです。(2020年2月時点)

 

 

ラズパイでの作業

sshでラズパイにリモートログインします。
Raspbianなら、ユーザー名:pi    パスワード:raspberry

sudo apt-get update

apt-get install bc bison flex libssl-dev libncurses5-dev

sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source

sudo chmod +x /usr/bin/rpi-source

sudo /usr/bin/rpi-source -q --tag-update

sudo rpi-source --skip-gcc -d /home/pi/

*** SoC: BCM2711

*** Using: /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz

*** Latest firmware revision: 01508e81ec1e918448227ca864616d56c430b46d

*** Linux source commit: 6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720

*** Download kernel source
--2020-01-27 12:33:16-- https://github.com/raspberrypi/linux/archive/6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720.tar.gz
Resolving github.com (github.com)... 52.192.72.89
Connecting to github.com (github.com)|52.192.72.89|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/raspberrypi/linux/tar.gz/6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720 [following]
--2020-01-27 12:33:17-- https://codeload.github.com/raspberrypi/linux/tar.gz/6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720
Resolving codeload.github.com (codeload.github.com)... 52.193.111.178
Connecting to codeload.github.com (codeload.github.com)|52.193.111.178|:443... connected.
HTTP request sent, awaiting response... 200 OK

・・・・・・・・・・・・・・・・・・

このあとも続いていますが、必要な情報としては、Download kernel source
と出たところのhttps://github.com/raspberrypi/*********.tar.gzがソースコード一式です。(上ではブラウザによって見切れているかも)

このURLのソース一式をPC-linux側でも使うのでダウンロードします。ここではURLだけ覚えておいてください。

 

続けて、実行中のconfigを取得します。ファイルとして存在するディストリビューションもあるのですが、Raspbianでは以下のようにして取り出します。

cd ./linux

sudo modprobe configs

sudo zcat /proc/config.gz > .config

sudo cp .config /boot/config.pi4.txt

/boot はSDカードをPCに挿したときに見えるディレクトリですので、分かりやすい名称にして保存しておきます。

ラズパイでの作業はここまで。

 

 

ubuntu 18.4LTS(PC-Linux)に戻って作業

先ほどのURLのカーネルソース一式のファイルを落としてきます。

wget https://github.com/raspberrypi/linux/archive/6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720.tar.gz

(ブラウザによって見切れているかも ******.tar.gz まであります。)

解凍します。

tar -xvf 6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720.tar.gz

cd linux-6d8bf28fa4b1ca0a35c0cd1dcb267fb216daf720

ここに、先ほどラズパイで取得したconfig.pi4.txtを .configとしてコピーしてきます。

virtualBoxではホスト-ゲスト間でドラッグ&ドロップでファイルをコピーできますし、Raspberryのストレージからscpで直接持ってきても良いです。

下はssh://moode.local としてネットワーク接続した例です。

Vbox_scp

< winSCPのようにLinux-PCもラズパイのストレージに接続できる >

 

さて、ラズパイを32bitモードで起動しているなら

32bitOS Raspberry Pi 2, Pi 3用

CCPREFIX=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

KERNEL=kernel7

make ARCH=arm CROSS_COMPILE=$CCPREFIX oldconfig

make -j10 ARCH=arm CROSS_COMPILE=$CCPREFIX zImage modules dtbs

 

32bitOS Raspberry Pi 4用

CCPREFIX=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

KERNEL=kernel7l

make ARCH=arm CROSS_COMPILE=$CCPREFIX oldconfig

make -j10 ARCH=arm CROSS_COMPILE=$CCPREFIX zImage modules dtbs

 

ラズパイを64bitモードで起動しているなら

64bitOS Raspberry Pi 3, Pi 4用

sudo apt-get install binutils-aarch64-linux-gnu

とaarch64用のクロスコンパイラをインストールしてから

KERNEL=kernel8

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- oldconfig

make -j10 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

です。

これで、カーネルをビルドできました。-j10 のところは、cpu数の1.5倍くらいにしておくと高速にビルドできると言われています。
modules dtbsは、外部ドライバをコンパイルするという目的なら必要ありません。ビルドしたカーネルを起動するなら必要です。SDカードに転送したりする部分は公式サイトをご覧ください。

 

昨年組んだ新しいPCを使っているので、非常に高速にkernelをビルドすることができました。一番上の画像に載っている通り1分48秒でzImageが出来てます。Pi4のセルフビルドで約1時間と速くなったな~なんて思っていたのですが、さすがx86系CPUの上位モデルは違いますね。仮想環境でもこの速度。

ようやくカーネルソース外のドライバをコンパイルする環境が整いました。

 

 

■ 外部ドライバをコンパイル

引き続きPC-linux上での作業です。

Dev_folder

 

という具合にドライバソースを入れたディレクトリを配置してそのディレクトリに移動します。

Makefileの中でカーネルソースやDTCを指定しているときは変更します。

KERNEL_SRC = ../linux-*********/
DTC_DIR = $(KERNEL_SRC)/scripts/dtc/


ラズパイが32bitモードなら

CCPREFIX=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

make ARCH=arm CROSS_COMPILE=$CCPREFIX

ラズパイが64bitモードなら

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

 

以上でドライバのコンパイルが出来ました。

あとは、ラズパイ本体に入れて動作をみてみるだけです。

 

64bit版moodeAudio用のSabreberry32ドライバはこうやって作りました。

 

参考になれば幸いです。

 

そもそもの話

そもそも、なぜドライバをコンパイルするために先にカーネル本体をビルドしなければいけないのか?疑問に思う人もいると思います。

 

カーネルとドライバモジュールとのバージョン整合性を持たせる仕組みに Module.symvers というファイルが使われています。

カーネルソースとビルドの設定(.config)の組み合わせでシンボルのプロトタイプをCRCハッシュ計算したものをModule.symvers に保存しています。カーネルソースが同じでも.configが違うとModule.symversの内容が違ってくることに注意が必要です。

Module.symversはカーネルをビルドすると生成されます。

ドライバは、そのModule.symversを参照して、組み込み先のカーネルに拒絶されないようにコンパイルされます。

 

Module.symversの中身はめっちゃ長いのですが、おそらく

0xb1adfa60 module_layout vmlinux EXPORT_SYMBOL

というシンボルが外部ドライバでは共通で使われます。この例だと0xb1adfa60という数値がハッシュ値です。

modprobe --dump-modversions *****.ko 

でコンパイルしたドライバのmodule_layout のハッシュ値を確認することができます。完全一致していないとカーネルに取り込めません。変な仕組みですが、セキュリティのため。未検証で外部ドライバをカーネルに取り込むと、そこからデータを抜かれてしまう、というのを防ぐのだと思います。

 

 

話は戻って、

rpi-source スクリプトは、Raspbian公式のgithubからカーネルソースとModule.symversもダウンロードしてくるため、カーネル本体をビルドすることなくドライバをコンパイルすることが出来るようになります。正式にリリースされたRaspbianのModule.symversがgithubにUPされているようなので、独自に.configをいじったりすると使えなくなります。

https://raw.githubusercontent.com/raspberrypi/firmware/${FIRMWARE_REV}/extra/Module.symvers

からダウンロードできます。

 

FIRMWARE_REV は、rpi-sourceで最初の方に表示される(上の例だと)

*** Latest firmware revision: 01508e81ec1e918448227ca864616d56c430b46d

の長い数字の部分です。
firmware revisionは /boot/.firmware_revision に保存されている場合もあるようです。(apt-get upgradeしたときなど)

 

まあ、現時点ではARM64bit版のgcc、glibが提供されていないので、64bit版のドライバを作るにはクロスコンパイルするしか手段はありません。(64bit版のgcc、glibをコンパイルして作ればよいという話もありますが。。。)

 

 

 

にほんブログ村 PC家電ブログ PCオーディオへ にほんブログ村

ブログランキングに参加中です。 めざせ1位! 

もしよろしければ「ぽちっと」お願いします。 

 

« ついに64bit版 Moode Audio R6.4.1用のSabreberry32ドライバリリース | トップページ | RaspberryPiのCPU比較 どれが64bitで動くの? »

Raspberry Pi」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« ついに64bit版 Moode Audio R6.4.1用のSabreberry32ドライバリリース | トップページ | RaspberryPiのCPU比較 どれが64bitで動くの? »

サイト内検索

Sponsors link

2020年8月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31