やりたいこと
RaspberryPi3 Model Bを64bitで動かしたくなりました。
せっかく64bit CPU (Cortex-A53)が載っているのに、標準イメージ(32bit)で動かすなんてもったいない!ですよね?
カーネルだけではなく、rootfsも含めて64bitで動作させます。
おおまかな流れ
基本的にgentoo linux wikiのRaspberry_Pi_3_64_bit_Installに沿っています。
さすがgentooだけあって細かく手順を書いてくれてます。
ただし、gentoo linux PCが手元になかったので、Ubuntu16.04 PC上で作業しました。
また、wikiではSDカードに直接書き込んでますが、SDカードがない環境でも作業できるよう、イメージを作成してから流し込むようにしています。
環境
- PC: Ubuntu 16.04
- RaspberryPi 3 model B
ツールのインストール
$ sudo apt install gcc-5-aarch64-linux-gnu
$ sudo apt install kpartx
Linux Kernelビルド
$ git clone --depth 1 --branch rpi-4.10.y https://github.com/raspberrypi/linux
$ cd linux
$ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make bcmrpi3_defconfig
$ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j9
$ cd ..
空のディスクイメージ作成
$ fallocate -l 2GiB GentooAarch64_`date +%Y%m%d`.img
Partitionの作成
$ fdisk GentooAarch64_20171114.img
Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x1218c51a.
コマンド (m でヘルプ): o
Created a new DOS disklabel with disk identifier 0x8c0219cc.
コマンド (m でヘルプ): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
パーティション番号 (1-4, default 1):
First sector (2048-4194303, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-4194303, default 4194303): +128M
Created a new partition 1 of type 'Linux' and of size 128 MiB.
コマンド (m でヘルプ): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
パーティション番号 (2-4, default 2):
First sector (264192-4194303, default 264192):
Last sector, +sectors or +size{K,M,G,T,P} (264192-4194303, default 4194303):
Created a new partition 2 of type 'Linux' and of size 1.9 GiB.
コマンド (m でヘルプ): t
パーティション番号 (1,2, default 2): 1
Partition type (type L to list all types): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
コマンド (m でヘルプ): t
パーティション番号 (1,2, default 2): 2
Partition type (type L to list all types): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
コマンド (m でヘルプ): p
Disk GentooAarch64_20171114.img: 2 GiB, 2147483648 bytes, 4194304 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x8c0219cc
デバイス 起動 Start 最後から セクタ Size Id タイプ
GentooAarch64_20171114.img1 2048 264191 262144 128M c W95 FA
GentooAarch64_20171114.img2 264192 4194303 3930112 1.9G 82 Linux
コマンド (m でヘルプ): w
The partition table has been altered.
Syncing disks.
ファイルシステムの作成
$ sudo kpartx -av GentooAarch64_20171114.img
add map loop0p1 (253:0): 0 262144 linear 7:0 2048
add map loop0p2 (253:1): 0 3930112 linear 7:0 264192
$ lsblk /dev/loop0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 2G 0 loop
├─loop0p2 253:1 0 1.9G 0 part
└─loop0p1 253:0 0 128M 0 part
$ sudo mkfs -t vfat -F 32 /dev/mapper/loop0p1
mkfs.fat 3.0.28 (2015-05-16)
unable to get drive geometry, using default 255/63
$ sudo mkfs -i 8192 -t ext4 /dev/mapper/loop0p2
mke2fs 1.42.13 (17-May-2015)
Discarding device blocks: done
Creating filesystem with 491264 4k blocks and 245760 inodes
Filesystem UUID: 0391b4da-c88d-4cb4-9da8-2a51b7f7f2fa
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
Root file system
$ mkdir mnt
$ sudo mount /dev/mapper/loop0p2 mnt/
$ curl -L -O http://ftp.jaist.ac.jp/pub/Linux/Gentoo/experimental/arm64/stage3-arm64-arm64-20170223.tar.bz2
$ sudo tar xvf stage3-arm64-arm64-20170223.tar.bz2 -C mnt/
$ sudo rm -rf mnt/tmp/ mnt/boot
$ sudo mkdir mnt/tmp/ mnt/boot
Boot partition
$ sudo mount /dev/mapper/loop0p1 mnt/boot
$ git clone --depth=1 https://github.com/raspberrypi/firmware.git
# 確認時のSHA1は008700b83121b92
$ sudo cp -r firmware/boot/* mnt/boot/
$ sudo cp linux/arch/arm64/boot/Image mnt/boot/kernel8.img
$ sudo mv mnt/boot/bcm2710-rpi-3-b.dtb mnt/boot/bcm2710-rpi-3-b.dtb_32
$ sudo cp linux/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb mnt/boot
$ cd linux/
$ sudo ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make modules_install INSTALL_MOD_PATH=../mnt
$ cd ..
configuration
rootのパスワード設定(raspberry
)
$ sudo emacs mnt/etc/shadow
root:$6$xxPVR/Td5iP$/7Asdgq0ux2sgNkklnndcG4g3493kUYfrrdenBXjxBxEsoLneJpDAwOyX/kkpFB4pU5dlhHEyN0SK4eh/WpmO0::0:99999:7:::
ファイルシステムのマウント設定
$ sudo emacs mnt/etc/fstab
/dev/mmcblk0p1 /boot vfat noauto,noatime 1 2
/dev/mmcblk0p2 / ext4 noatime 0 1
Unmount image
$ sudo umount mnt/boot
$ sudo umount mnt
$ sudo kpartx -d GentooAarch64_20171114.img
イメージの書き込み
書き込み先SDカードのデバイスは、差し込み前後のdf -h
やdmesg
で確認できます。
ただし、df -h
の出力が/dev/sdc1
の場合、最後の1
はパーティションを表すので、/dev/sdc
を書き込み先とします。
$ sudo umount /dev/sdX1
$ sudo dd bs=4M if=GentooAarch64_20171114.img of=/dev/sdX status=progress conv=fsync
$ sync && sync && sync
64bitであるかどうか確認
上記SDカードでラズパイを起動したら、下記コマンドで64bitで動いているかどうかを確認してみます。
(全く同じ手順であれば、root
/raspberry
でログインできるはずです)
# Kernel
$ uname -m
aarch64
# rootfs
$ getconf LONG_BIT
64
# rootfs(念押し)
$ readelf -h `which readelf`
Machine: AARCH64
成功!
まとめ
せっかくのaarch64なのだから、公式で64bit版サポートして欲しいなと思いつつ、とても勉強になったので結果オーライです。
それにしてもまさか初めてのgentoo linuxがラズパイになるとは思いませんでした汗
参考
- Raspberry_Pi_3_64_bit_Install
- Arch Linux ARMのディスクイメージを作成する(losetup、kpartx)
- 【Linux】kpartxでループバックデバイスを簡単にマウントする
- BUILD A 64-BIT KERNEL FOR YOUR RASPBERRY PI 3
- [メモ] Raspberry Pi 3向けの 64bitカーネルをビルドして、使用する
- Raspberry Pi 3を64-bitモードで扱うための現状について調べてみた
- RASPBERRY PI 3用64BIT DOCKER ENGINEを含むイメージを公開しました
- イメージ
- Linuxでrawディスクのimageファイルを扱うあれこれ(空ファイル作成、パーティション作成、マウントなど)
- Booting 64-bit kernel on Raspberry Pi 3
- ディスクイメージのサイズを大きくする