LoginSignup
20
25

More than 5 years have passed since last update.

Raspberry Pi Zero用のカーネルをクロスコンパイルし、ドライバモジュールを作成する

Last updated at Posted at 2016-01-09

Raspberry Pi Zeroを5GHzの無線LANに参加させたいのですが、2015/11/21にリリースされたJessieだと、手持ちのWifiアダプタGW-450Sは使用できませんでした。githubにあるドライバ (https://github.com/gnab/rtl8812au) をカーネルモジュールとしてコンパイルする必要があるようです。

本稿では、他のマシンでRaspberry Pi Zero用のカーネルをクロスコンパイルする手順と、今回のGW-450Sを例に外部ドライバをカーネルモジュールとして導入する手順を紹介したいと思います。

※カーネルのコンパイルをRaspberry Pi Zeroでも行えますが、Raspberry Pi Zeroのカーネルイメージにデフォルトで使われている.configを用いたところ、14時間かかりました。。。作成モジュールが相当多いため、時間がかかるようです。


2017/2追記
Raspberry Pi Zero上で同一バージョンのカーネルソースを取得し、モジュールのみコンパイル、という方法で短時間で達成できます。

参考
https://www.max2play.com/en/forums/topic/howto-raspberry-pi-3-realtek-802-11ac-rtl8812au/

こちらの方がオススメです。


環境はUbuntu 14.04 LTSです。以下、64bitマシンで作業する前提で記述します。

カーネルのクロスコンパイル

「石を売る」さんの「Raspberry Pi2のカーネルの再構築とGW-450Dを使えるようにする。」を参考にさせていただきました。

作業フォルダの作成

$ mkdir -p $HOME/src/Raspberry_Pi_Zero
$ cd $HOME/src/Raspberry_Pi_Zero

必要なパッケージのインストール

たまたまIntel Edisonのカーネルビルドも行っていたので、インストールが必要なパッケージはありませんでしたが、以下のパッケージが必要になります。

$ sudo aptitude install build-essential git openssh-server ncurses-dev

toolchainとkernel sourceのダウンロード

クロスコンパイルに必要なツールと、Raspberry Piのカーネルソースをダウンロードします。

$ git clone --depth=1 git://github.com/raspberrypi/tools.git
$ git clone --depth=1 git://github.com/raspberrypi/linux.git

環境変数の設定

$ ls tools/arm-bcm2708
$ export PATH=`pwd`/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-

クロスコンパイラが使えるか確認します。

$ arm-linux-gnueabihf-gcc -v

Raspberry Pi Zeroより.config取得

Raspberry Pi Zeroから取得します。

$ cd linux
$ ssh pi@(Raspberry Pi Zeroのアドレス) 'sudo modprobe configs'
$ ssh pi@(Raspberry Pi Zeroのアドレス) 'zcat /proc/config.gz' > config-pizero
$ mv config-pizero .config

カーネルに命名

Makefile内の EXTRAVERSION を指定すると、カーネル名の後ろに名前がつけられます。今回は mod としました。カーネルのバージョンが4.1.15だったので、4.1.15-modになります。(後でカーネル名やフォルダ名としてまた出てきます)

$ vim Makefile
EXTRAVERSION = -mod

menuconfigの実行

別途、使用したいデバイス等があれば設定します。menuconfigのお作法に倣って設定、保存をしてください。

$ make menuconfig

カーネルのビルド

$ make -j 4

-jの後の数字はCPUコア数に応じて変えます。2倍程度が一般的です。
Core2 Duo T7600(2.33GHz)のデュアルコアなマシンで30分弱で終わりました。

モジュールとカーネルをまとめる

$ cat include/config/kernel.release
4.1.15-mod+
$ export KERNEL_RELEASE=`cat include/config/kernel.release`
$ export INSTALL_MOD_PATH=../$KERNEL_RELEASE
$ mkdir -p $INSTALL_MOD_PATH
$ mkdir -p ../$KERNEL_RELEASE/boot
$ make modules
$ make modules_install
$ cp arch/arm/boot/Image ../$KERNEL_RELEASE/boot/kernel-$KERNEL_RELEASE.img
$ cd ..

Raspberry Pi Zeroで一度動作確認

出来上がったカーネルが動作するか確認します。

$ cd $KERNEL_RELEASE
$ tar zcvf $KERNEL_RELEASE.tar.gz boot lib
$ scp $KERNEL_RELEASE.tar.gz pi@(Raspberry Pi ZeroのIPアドレス):/home/pi/
$ ssh pi@(Raspberry Pi ZeroのIPアドレス)

ログイン後

$ sudo tar zxC / -f 4.1.15-mod+.tar.gz
$ ls /boot
(今回作成したkernel-4.1.15-mod+.imgがあることを確認)

$ sudo vim /boot/config.txt
末尾に以下を追加
kernel=kernel-4.1.15-mod+.img

Raspberry Pi Zeroを再起動します。uname -aで今回設定したカーネル名が表示されるか確認してください。
起動に失敗した場合、SDカードを取り出して、先ほどのconfig.txtを元に戻せば修正前の状態で起動できます。

rtl8812モジュールのビルド

前項の「カーネルのクロスコンパイル」を実施済みが前提になります。このパートのみ再度行う場合は、前項中にある「環境変数の設定」を実施して、クロスコンパイラが使用できる状態にしてください。

githubにあるドライバのページ(https://github.com/gnab/rtl8812au) にある手順に従います。

ドライバソースのダウンロード

$ cd $HOME/src/Raspberry_Pi_Zero
$ git clone https://github.com/gnab/rtl8812au

設定の変更

$ vim Makefile

ターゲットをI386_PCからARM_RPIに変更します。

(変更前)
CONFIG_PLATFORM_I386_PC = y
...
CONFIG_PLATFORM_ARM_RPI = n

(変更後)
CONFIG_PLATFORM_I386_PC = n
...
CONFIG_PLATFORM_ARM_RPI = y

続いて、クロスコンパイラ(CROSS_COMPILE)、カーネルバージョン(KVER)とこれに付随して指定されるディレクトリ(KSRC, MODDESTDIR)を変更します。ディレクトリは絶対参照から相対参照に切り替えています。

カーネルバージョンは「4.1.15-mod+」を決め打ちしていますので、適宜変更してください。(以後も登場します)

(変更前)
ifeq ($(CONFIG_PLATFORM_ARM_RPI), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE :=
KVER  := $(shell uname -r)
KSRC ?= /lib/modules/$(KVER)/build
MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/
endif

(変更後)
ifeq ($(CONFIG_PLATFORM_ARM_RPI), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-linux-gnueabihf-
KVER  := 4.1.15-mod+
KSRC := ../$(KVER)/lib/modules/$(KVER)/build
MODDESTDIR := ../$(KVER)/lib/modules/$(KVER)/kernel/drivers/net/wireless/
endif

ドライバモジュールのビルド

$ make

ドライバのコピー

$ cp 8812au.ko ../4.1.15-mod+/lib/modules/4.1.15-mod+/kernel/drivers/net/wireless

Raspberry Pi Zeroへの転送

前項「Raspberry Pi Zero側で一度動作確認」を実施して、カーネルイメージを再送、再起動してください。

再起動後

$ sudo depmod

このあと、GW-450SをUSBポートに刺すと無事使えるようになるはずです。

おまけ

カーネルコンパイルをRaspberry Pi Zero上で行いたい場合

いばらの道です。

$ cd $HOME
$ bash -c "$(curl -fsSSL https://raw.githubusercontent.com/moutend/raspi-kernel/master/raspi-kernel)"
$ cd /usr/src/linux-...
$ sudo modprobe configs
$ zcat /proc/config.gz > .config
$ time make

real    742m7.551s
user    700m51.830s
sys     29m42.700s

$ make modules
$ make modules_install

現在使用中のカーネルからconfigを取得

configを取得できるカーネルコンフィグがあることを初めて知りました。

CONFIG_IKCONFIG=m
CONFIG_IKCONFIG_PROC=y

このオプションが組み込まれたカーネルで、以下を実行します。

$ sudo modprobe configs
$ zcat /proc/config.gz > .config

Todo

最初のインストールイメージに対して更新したい。
PiTFTの変更を反映したい(本稿で作成するGW-450S等のモジュールと一緒に用いたい)

20
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
25