Raspberry Pi(以下rpi)のカーネルではなくて、mainline等のカーネルを使いたい場合のメモです。
TL;DR
基本的に次のwebサイトを見れば事足ります。
概要
rpi向けのカーネルは以下なのですが、mainlineのカーネルを使いたい等の理由がある場合の環境構築方法のメモです。
uart、wifi、hdmiを使えるところまでが対象です。archはaarch64を対象とします。使っているのはRaspberry Pi 3 B+です。
必要なもの
これらが必要です。
最初の2つはそりゃそうだなって感じですね。次のrpiで〜というところはstart.elfやfixup.datといったブートに必要なバイナリファイル群です。最後のfirmwareはwifiを使うのに必要になります。
u-boot
RPi U-Boot - eLinux.orgを見てビルドしてください。
Linux Kernel
適当なaarch64環境でコンパイルするか、クロスコンパイルします。
Fedoraならgcc-aarch64-linux-gnuあたりのパッケージをインストールします。クロスコンパイル時のmakeコマンドは基本的に次の通りです。これにoldconfigだったりがオプションで付きます。
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
configオプションで設定するものがいくつかあります。defconfigでmakeしたあとに以下のスクリプトを実行し、最後にmake oldconfigを実行します。ここで設定しているのは有線LAN、wifiドライバ、HDMI出力、broadcomのドライバ、フレームバッファです。面倒なのでモジュールではなくてカーネルに組み込んでます。
#!/bin/bash configs=(USB_LAN78XX RFKILL BRCMFMAC RCMFMAC_PROTO_BCDC BRCMFMAC_PROTO_MSGBUF BRCMFMAC_SDIO BCMFMAC_USB BRCMFMAC_PCIE CFG80211 CFG80211_REQUIRE_SIGNED_REGDB CFG80211_USE_KERNEL_REGDB_KEYS CFG80211_DEFAULT_PS CFG80211_DEBUGFS CFG80211_CRDA_SUPPORT CFG80211_WEXT ARCH_BCM2835 SERIAL_8250_BCM2835AUX HW_RANDOM_BCM2835 I2C_BCM2835 SPI_BCM2835 SPI_BCM2835AUX PINCTRL_BCM2835 BCM2835_THERMAL BCM2835_WDT SND_BCM2835_SOC_I2S MMC_BCM2835 DMA_BCM2835 BCM2835_VCHIQ SND_BCM2835 VIDEO_BCM2835 BCM2835_MBOX BCM2835_POWER PWM_BCM2835 HW_RANDOM_BCM2835 ROCKCHIP_DW_HDMI ROCKCHIP_INNO_HDMI ROCKCHIP_RK3066_HDMI DRM_SUN4I_HDMI_CEC DRM_MSM_HDMI_HDCP DRM_VC4_HDMI_CEC HDMI FB_SIMPLE LOGO LOGO_LINUX_CLUT224 ) for config in ${configs[@]}; do ./scripts/config --enable $config done
HDMIで画面出力する場合はフレームバッファが必要で、mainlineのカーネルだとsimple-framebuffer(CONFIG_FB_SIMPLE)を有効にする必要があります。
.configが作れたらカーネルとdevicetreeをビルドします。
Imageのビルド
make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
DeviceTreeのビルド
make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs
カーネルのビルドはこれにて終了です。
Raspberry Piのfirmwareダウンロード
ラズパイ用のfirmwareをgitリポジトリからcloneしましょう。
Linuxのfirmwareダウンロード
wifiを動かすのに必要なfirmwareを一式gitリポジトリからcloneしましょう。
sdカードの準備
こんな感じで最初のパーティションはfat32で作ります。起動はここからです。もう一つのほうはroot filesystemです。
root@qemuarm64:~# fdisk -l Disk /dev/mmcblk0: 30 GB, 31914983424 bytes, 62333952 sectors 973968 cylinders, 4 heads, 16 sectors/track Units: cylinders of 64 * 512 = 32768 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/mmcblk0p1 4,4,1 261,4,2 2048 133119 131072 64.0M c Win95 FAT32 (LBA) Partition 1 does not end on cylinder boundary /dev/mmcblk0p2 261,5,1 1023,254,2 133120 2097151 1964032 959M 83 Linux Partition 2 does not end on cylinder boundary
bootパーティションの設定
firmwareのコピー
/mnt/rpiにマウントしているとして、cloneしてきたrpiのfirmwareディレクトリに移動しファイルをコピーします。
$ cd firmware $ cp -a boot/start* /mnt/rpi/. $ cp -a boot/fixup* /mnt/rpi/. $ cp -a boot/overlays/ /mnt/rpi/. $ cp -a boot/bootcode.bin /mnt/rpi/.
カーネルのコピー
arch/arm64/boot/Imageとarch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b-plus.dtbを/mnt/rpiにコピーします。
u-bootのコピー
ビルドしたu-boot.binを/mnt/rpiにコピーします。
config.txtの作成
つぎに/mnt/rpi/config.txtを以下の内容で作ります。
[all] boot_delay=1 kernel=u-boot.bin arm_control=0x200 upstream_kernel=1 audio_pwm_mode=0 enable_uart=1 gpu_mem=16 mask_gpu_interrupt1=0x100
u-bootの設定
以下のようなファイルを(boot.cmd)を作ります。作成する場所は任意です。
fatload mmc 0:1 ${kernel_addr_r} Image fatload mmc 0:1 ${fdt_addr} bcm2837-rpi-3-b-plus.dtb setenv bootargs dwc_otg.lpm_enable=0 earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rootwait booti ${kernel_addr_r} - ${fdt_addr}
そして以下のコマンドでboot.scrを/mnt/rpiに作成します。
$ mkimage -C none -A arm64 -T script -d ./boot.cmd /mnt/rpi/boot.scr
上記のmkimageコマンドはfedoraならuboot-toolsパッケージにあります。
uartの設定
u-bootの段階からuartでログを表示したい場合は以下のようにします。
$ sed -i -e "s/BOOT_UART=0/BOOT_UART=1/" /mnt/rpi/bootcode.bin
と、ここまででブートローダとカーネルの準備はOKです。が、これだとルートファイルシステムがないので面白くないですよね。なのでルートファイルシステムも用意しましょう。
ルートファイルシステム
ルートファイルシステムのビルド
まあなんでもいいのですが、せっかくなので自作のyoctoのレイヤーを使いましょう(´ω`)
MACHINEにはqemuarm64を指定してcore-image-minimalでビルドしてください。build/tmp-glibc/deploy/images/qemuarm64/にルートファイルシステムのtarファイルがあるのでそれをルートファイルシステムのパーティションに展開します。
/mnt/rootfsがルートファイルシステムのパーティションだとしてこうします。
$ sudo tar xvf build/tmp-glibc/deploy/images/qemuarm64/core-image-minimal-qemuarm64.tar.bz2 -C /mnt/rootfs/
firmwareのコピー
broadcomのファームウェアをルートファイルシステムにコピーしましょう。こんな感じです。
$ sudo mkdir /mnt/rootfs/lib/firmware $ sudo cp -a linux-firmware/brcm/ /mnt/rootfs/lib/firmware/.
起動
ここまででホストでの作業は完了したのであとはsdカードから起動させましょう。
TV側
起動時の🐧
ログイン
uartでもログインしてるのでttyS1もありますね。
uart側
有線LAN、wifiが認識されてます。
wlan0
root@qemuarm64:~# ip link show wlan0 2: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
eth0
root@qemuarm64:~# ip link show wlan0 2: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
まとめ
rpiのカーネルでなくてもhdmiを使ったり有線・wifi使えるようになりましたΣ(゚∀゚ノ)ノキャー tftpブートすればrpiでのカーネルハックが捗ると思います😃
カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる (ブルーバックス)
- 作者: 金丸隆志
- 出版社/メーカー: 講談社
- 発売日: 2016/07/22
- メディア: Kindle版
- この商品を含むブログを見る