Raspberry Pi 3/3+でarm64なOSイメージ生成

## 背景
https://qiita.com/abtc/items/862e2999d7c136201a44 さんの記事とほとんど同じです．
ROS2がリリースされ，Twitter上でちらほら見かけるようになったので，1年ほど前に取り組んだ成果をシェアします．もちろん，単純にDocker使いたいならHypriotOSをおすすめしますし，Raspiの公式サポートしているカーネルはarm32hfなので，安定動作を希望の方はそちらを使いください．

> **CAUTION**
> 本記事は途中経過の内容です．
> 生成されるイメージではコマンドライン表示のみしか確認できていません．
> またdebootstrap初心者のため，使用は自己責任でお願いします．

github: https://github.com/realteck-ky/raspi-arm64-debootstrap

## 準備するもの
Ubuntuからクロスコンパイル環境を想定しています．

* 環境

クロスコンパイルするため，g++-aarch64を入れます．
またdebootstrapを利用しますので，それらも入れます．

```sh 
sudo apt-get install -y make git bc libncurses5-dev g++-aarch64-linux-gnu
sudo apt-get install -y kpartx qemu-user-static binfmt-support debootstrap
```

* ソース

取得が遅いので`--depth 1`としてますが，なくても結構です．

``` sh
midir temp && cd ./temp
git clone https://github.com/raspberrypi/firmware.git firmware --depth 1
git clone https://github.com/raspberrypi/linux.git rpi-linux --depth 1

```

####
debootstrapで生成するRaspiイメージの準備をします．ここでイメージをubuntuのarm64ブランチから引っ張ってきます．またopensshが使いたかったので入れてます．

``` sh
cd .. && midir raspi-dir && cd raspi-dir
sudo debootstrap --include=sudo,apt,openssh-server,wget --foreign --arch=arm64 bionic . http://ports.ubuntu.com/ubuntu-ports/
sudo cp $(which qemu-aarch64-static) ./usr/bin/
sudo chroot . debootstrap/debootstrap --second-stage --verbose
```

仮想ルートを設定したので，raspiの設定をしていきます．まずはマウントするディレクトリから．

``` sh
sudo mount -t sysfs sysfs sys/ 
sudo mount -t proc  proc  proc/
sudo mount -o bind /dev  dev/
sudo mount -o bind /dev/pts dev/pts
```

続いてネットワークのhostnameの設定です.

``` sh
sudo echo 'raspberry' | sudo tee $PWD/etc/hostname
sudo echo '127.0.0.1 raspberry' | sudo tee $PWD/etc/host
```

ソースリスト（日本サーバにしました）

``` sh
cat << EOF | sudo tee -a ./etc/apt/sources.list
deb http://jp.archive.ubuntu.com/ports/ bionic main restricted universe multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu/ bionic main restricted universe multiverse
    
deb http://jp.archive.ubuntu.com/ports/ bionic-security main restricted universe multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse
    
deb http://jp.archive.ubuntu.com/ports/ bionic-updates restricted main multiverse universe
deb-src http://jp.archive.ubuntu.com/ubuntu/ bionic-updates restricted main multiverse universe
    
deb http://jp.archive.ubuntu.com/ports/ bionic-backports restricted main multiverse universe
deb-src http://jp.archive.ubuntu.com/ubuntu/ bionic-backports restricted main multiverse universe
EOF
```

イーサネットの設定

```
cat << EOF | sudo tee ./etc/fstab
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
```

パーティションの設定

```
cat << EOF | sudo tee ./etc/fstab
proc           /proc    proc  defaults         0 0
/dev/mmcblk0p1 /boot    vfat  defaults,noatime 0 0
/dev/mmcblk0p2 /        ext4  defaults,noatime 0 0
tmpfs          /tmp     tmpfs defaults         0 0
tmpfs          /var/tmp tmpfs defaults         0 0
EOF
```

raspi-configが使いたい人はこちらも．

``` sh
sudo -E chroot . wget http://archive.raspbian.org/raspbian.public.key -O - | sudo chroot . apt-key add -
sudo -E chroot . wget http://archive.raspberrypi.org/debian/raspberrypi.gpg.key -O - | sudo chroot . apt-key add -
```

ロケールの設定です．英語設定なので，日本語の方は変更してください．ただし言語パッケージ入れるまで文字化けしますのでご注意を．

``` sh
export LANG=en_US.UTF-8 # or 'export LANG=ja_JP.UTF-8'
sudo -E chroot . locale-gen en_US.UTF-8
echo "LANG=en_US.UTF-8" | sudo tee $RASPI_ROOT/etc/default/locale
sudo -E chroot . dpkg-reconfigure -f noninteractive locales
echo "Asia/Tokyo" | sudo tee $RASPI_ROOT/etc/timezone
sudo -E chroot . dpkg-reconfigure -f noninteractive tzdata
```

いろいろソフトをセットアップします．
ここでlxdeやopenbox等入れてみたけど，うまく行ってないです．（誰か教えて）

``` sh
sudo -E chroot . apt-get update
sudo -E chroot . apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
sudo -E chroot . add-apt-repository ppa:ubuntu-raspi2/ppa-rpi3 -y
sudo -E chroot . dpkg-divert \
  --divert /lib/firmware/brcm/brcmfmac43430-sdio-2.bin \
  --package linux-firmware-raspi2 \
  --rename --add /lib/firmware/brcm/brcmfmac43430-sdio.bin
```

い　つ　も　の　（親の顔より叩いたログイン）
ここのラストはユーザーpiのパスワード設定なので，raspberryとかしておくといいゾ（適当）

``` sh
sudo chroot . useradd -m -s /bin/bash pi
sudo chroot . usermod -a -G sudo,staff,kmem,plugdev,audio pi
sudo chroot . passwd pi
```

## クロスコンパイル
いったん，gitで取得したfirmwareと
コンパイラの設定は，https://gist.github.com/doevelopper/46f78eb2c635835c04867da4cdd13904 を参考にしました．カーネルコンフィグいじりたい方は，途中のmake menuconfigでいじってください．ニチアサスーパービルドタイムなので，人によっては朝になるのを待ったほうがいいです．（このまま〜，歩き続け〜てる〜，こーんやーも

```
cd .. && cp -r raspi-temp/* . && cd rpi-linux

export CFLAGS="-pipe -mcpu=cortex-a53  -march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations"
export CFLAGS="${CFLAGS} -O3 -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations"
export LDFLAGS="${LDFLAGS} -O3 -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations"

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export KERNEL=kernel8
make mrproper
make bcmrpi3_defconfig
#make menuconfig
make -j5 Image modules dtbs
```

余談ですが，ここでxenomaiを当ててみたんですけど，USBが認識しなくなって死にました．おそらくコンフィグレーションですはい．ちなみにリアルタイム化したところで，raspiのEthernetはUSBのIC経由なので，あまり保証できないです．

```
cd .. && mkdir raspi-boot
sudo mount --bind ./raspi-boot ./raspi-dir/boot
sudo mkdir ./raspi-dir/lib/modules/
```

moduleとdtbsのコピー

``` sh
sudo cp -r ./firmware/boot/* ./raspi-boot/boot/
cd ./raspi-linux
sudo make INSTALL_MOD_PATH=../raspi-dir modules_install dtbs_install ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE
sudo cp ./arch/arm64/boot/Image ../raspi-dir/boot/kernel8.img
sudo cp ./arch/arm64/boot/dts/broadcom/*.dtb ../raspi-dir/boot/
sudo cp ./arch/arm64/boot/dts/overlays/*.dtb* ../raspi-dir/boot/overlays/
sudo cp ./arch/arm64/boot/dts/overlays/README ../raspi-dir/boot/overlays/
```

デバイスコンフィグのスクリプトです，いじってどうぞ

``` sh
cd ..
sudo cat << EOF | sudo tee -a ./raspi-dir/boot/config.txt
kernel=kernel8.img
dev_tree=bcm2837-rpi-3-b+.dtb
arm_control=0x200
kernel_address=0x80000
dtparam=audio=on
arm_64bit=1
cmdline=cmdline.txt
gpu_mem_256=1
dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt
force_turbo=1
smsc95xx.turbo_mode=N
EOF

sudo cat << EOF | sudo tee -a ./raspi-dir/boot/cmdline.txt
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
EOF
```

ssh使う方は，`touch ./raspi-dir/boot/ssh.txt`とか必要だった気がします．

#### Docker 入れたい人

``` sh
cd ./raspi-dir
sudo -E chroot . apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
sudo -E chroot . curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo -E chroot . apt-key add -
sudo -E chroot . apt-key fingerprint 0EBFCD88
sudo -E chroot . add-apt-repository \
   "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo -E chroot . apt-get update
sudo -E chroot . apt-get install -y docker-ce
```

## イメージファイル生成
イメージファイルを焼きます．

``` sh
cd ./raspi-dir
## create img file
sudo -E chroot . apt-get clean
sudo -E chroot . apt-get autoclean
sudo -E chroot . apt-get autoremove -y
#sudo -E chroot . rpi-update
sudo umount -l ./dev/pts
sudo umount -l ./dev
sudo umount -l ./proc
sudo umount -l ./sys
sudo umount -l ./boot

## create sd image
dd if=/dev/zero bs=1k count=1000000  > ../raspi-ubuntu-arm64.img
sudo losetup -f ../raspi-ubuntu-arm64.img
sudo losetup -a
sudo parted -s /dev/loop0 mklabel msdos
sudo parted -s /dev/loop0 unit MB mkpart primary fat32 -- 4MB 128MB
sudo parted -s /dev/loop0 set 1 boot on
sudo parted -s /dev/loop0 unit MB mkpart primary ext4 -- 128MB -1MB
sudo losetup -d /dev/loop0
sudo losetup -f -P ../raspi-ubuntu-arm64.img
sudo mkfs.vfat -n System /dev/loop0p1
sudo mkfs.ext4 -L Storage /dev/loop0p2
sudo mount /dev/loop0p1 -o rw /mnt
sudo cp -R ../raspi-boot/* /mnt/
sudo umount /mnt
sudo mount /dev/loop0p2 -o rw /mnt
sudo cp -R ../raspi-dir/* /mnt/
sudo umount /mnt
sudo losetup -d /dev/loop0
```

あとはsdカードに焼くなり，杏花のオトメドメインのネットラジオ聞くなりしてください．
http://www.onsen.ag/program/otomain/
今気づいたけど，緑で見分けつかないｗ

と，ここまでの話を試行錯誤したデータたちとともに，githubへ上げておきます．
https://github.com/realteck-ky/raspi-arm64-debootstrap

今出張中なので，帰って時間ができたら修正します（修正するとは言ってない
それではよいraspiライフを〜