ZYBO (Zynq) 初心者ガイド (9) Linuxカーネルを少しカスタマイズする

- [1回目: 開発環境の準備](https://qiita.com/take-iwiw/items/966f252f6ca954aff08b)
- [2回目: Hello Worldプロジェクト](https://qiita.com/take-iwiw/items/24a8a94741fdbb80f62a)
- [3回目: PSのGPIOでLチカ](https://qiita.com/take-iwiw/items/39d2ed00fa88a1204fce)
- [4回目: PLのAXI GPIOでPSからLチカ](https://qiita.com/take-iwiw/items/a3b935a4e4dbd41593e1)
- [5回目: PLだけでLチカ](https://qiita.com/take-iwiw/items/efcdfca1866b9941fd2a)
- [6回目: 自作IPでLチカ](https://qiita.com/take-iwiw/items/b0f2ce7b4653bc6f32b9)
- [7回目: ブートイメージを作る](https://qiita.com/take-iwiw/items/ece0cdf83e6e1908fad8)
- [8回目: Linux起動する](https://qiita.com/take-iwiw/items/6e6915f7318689818368)
- __[9回目: Linuxカーネルを少しカスタマイズする](https://qiita.com/take-iwiw/items/6f2644d16cbfdb021d07) <--- 今回の内容__
- [10回目: LinuxのRootFSをカスタマイズする / PythonでHello World](https://qiita.com/take-iwiw/items/94a90047978664159681)
- [11回目: LinuxユーザアプリケーションでLチカ](https://qiita.com/take-iwiw/items/5e4ab9a106acfda2c866)
- [12回目: LinuxカーネルモジュールでLチカ](https://qiita.com/take-iwiw/items/e7efc48d92d7b979efdc)
- [13回目: LAN(Ethernet 0)を使う](https://qiita.com/take-iwiw/items/ac489acaca1ab54d7ce8)
- [14回目: Linuxユーザアプリをデバッグする / RootFSに取り込む](https://qiita.com/take-iwiw/items/8134ca7098622219b177)
- [15回目: Linux起動時にアプリケーションを自動実行させる](https://qiita.com/take-iwiw/items/50065df6cdd1ba8bcbd6)
- [16回目: Linuxから自作IPをUIOで制御する](https://qiita.com/take-iwiw/items/da91ce4dc2a8a8df3c0a)
- [17回目: Linuxで自作IPのデバイスドライバを作る](https://qiita.com/take-iwiw/items/05eb1204cb51ce0a5c03)
- [18回目: IoT化してスマホからLチカ](https://qiita.com/take-iwiw/items/e9311292c5078d785699)

この記事の内容を3分で見る ( https://youtu.be/swrcNY7KO8Q )

# 環境
- 開発用PC: Windows 10 64-bit 
	- Vivado 2017.4 WebPACKライセンス
	- Xilinx SDK 2017.4  <- 今回は使わない
- 開発用PC (Linux): Ubuntu 16.04 本家 (日本語版じゃない) (on VirtualBox 5.2.4)
	- PetaLinux 2017.4
- ターゲットボード: ZYBO (Z7-20) 

Windows環境は[1回目](https://qiita.com/take-iwiw/items/966f252f6ca954aff08b)、Linux環境は[8回目](https://qiita.com/take-iwiw/items/6e6915f7318689818368)を参照。
使用するハードウェア(hdf)は[8回目](https://qiita.com/take-iwiw/items/6e6915f7318689818368)を参照。

# Linuxカーネルを少しカスタマイズする
前回はLinuxイメージを作成して、起動させました。この時作成したLinuxイメージは、PetaLinuxツールが設定してくれたものをそのまま使用してビルドしたものです。今回は、カーネルを少しだけカスタマイズしてみようと思います。Linuxカーネルの設定は、それだけでご飯が食べていけるくらい奥が深い分野になりますが、今回は簡単な触りだけをやります。

## 変更する内容
今回は、試しに以下の2点をカスタマイズしてみようと思います。

- ルートファイルシステム(rootfs)をSDカードにする
	- デフォルト設定だと、Linuxファイルシステムのルートは、DDR上にマウントされるようです(initramfs)。そのため、ファイルを作成しても、再起動したら消えてしまいます。SDカードを使用するようにします。
- 自動ログインにする
	- 起動後、rootとして自動ログインします。(これは、趣味レベルならいいですが、実プロダクトではやるべきではありません。)


# コンフィグ / ビルドする
新規PetaLinuxプロジェクトの作成からやります。ハードウェアは前回と同じく、PSのみを配置したhdfを使用します。既存のプロジェクトに対してやる場合は、`petalinux-config --get-hw-description=../project_1.sdk`を`petalinux-config`に置き換えてください。)

下記コマンドを実行すると、menuconfigの画面が表示されるので、以下の設定を変更します。

```sh
cd ~/work/peta
petalinux-create --type project --template zynq --name SimplePS
cd SimplePS/
petalinux-config --get-hw-description=../project_1.sdk
```

![01.png](https://qiita-image-store.s3.amazonaws.com/0/214268/7c92a25a-40ae-040e-0c54-1f84c6a07744.png)

- Image Packaging Configuration ->  Root filesystem type -> SDカードを選択する
- Yocto Settings -> Enable Debug Tweaks を有効にする (Spaceキーを押す)

設定完了したら、SaveしてExitします。その後、ビルドし、BOOT.binを作ります。

```sh
petalinux-build
petalinux-package --boot --force --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/design_1_wrapper.bit --u-boot
```

## 成果物
最終的に必要となる成果物は、以下の3つです。

- images/linux/BOOT.bin
	- FSBL (First Stage Boot Loader)、ビットストリーム、U-Boot (Second Stage Boot Loader)
- images/linux/image.ub
	- Linuxシステムイメージ (カーネルなど)
- images/linux/rootfs.ext4
	- SDカードに書き込まれるrootfs

![02.png](https://qiita-image-store.s3.amazonaws.com/0/214268/d1d0f859-c06c-5052-854d-7c9bfa2a8813.png)

## メモ
ここ(https://github.com/Digilent/Petalinux-Zybo-Z7-20/blob/master/README.md )には、config後に、meta-user/recipes-bsp/device-tree/files/system-user.dtsiを編集してbootargsを変更しろみたいなことが書いてあったのですが、不要でした。ug1144-petalinux-tools-reference-guide.pdfによると、自動生成される　components/plnx_workspace/device-tree-generation/system-conf.dtsiで設定されているらしいです。

# SDカードを作成する
ラズパイなどでおなじみですが、SDカードを2つのパーティションに分けて使用します。

- 起動用パーティション (FAT32)
	- BOOT.binとimage.ubを保存
- Linuxのルートファイルシステム (ext4)
	- rootfs.ext4を保存

## パーティションを分ける
Windowsだとext4を扱えないので、Ubuntu上でパーティションを作成します。VirtualBoxを使用している場合は、SDカードリーダ(USB)をVirtualBoxに接続します。(VirtualBox上のメニューバー -> デバイス -> USB -> General Mass Storage Device(このデバイス名は環境によって異なる))

コマンドでやってもいいのですが、Disks (gnome-disk-utility) でGUIから設定します。僕は、8GByteのSDカードを使用しているのですが、以下のように、先頭100MByteをFAT32として、残り全部(7.6GByte)をExt4としてパーティションを分けてフォーマットしました。また、この画面で、Ext4のデバイス名を確認しておいてください。ここだと、`/dev/sdb2`になっています。

![03.jpg](https://qiita-image-store.s3.amazonaws.com/0/214268/d31f68c2-9957-1308-e641-a5c56e42187e.jpeg)

### メモ
ug1144-petalinux-tools-reference-guide.pdfを見ると、起動用パーティション (FAT32)の前に、「4MB の未割り当て領域が必要」とのことでしたが、特に何の設定もしないでも大丈夫でした。

## イメージファイルのコピー
起動用パーティション (FAT32)にimages/linux/BOOT.binとimages/linux/image.ubをコピーします。これは、前回と同様です。

Linuxのルートファイルシステム (ext4)には、images/linux/rootfs.ext4を書き込むのですが、これはファイルのコピーではなく、バイナリレベルでイメージをそのまま書き込みます。ddで書き込むとファイルサイズもrootfs.ext4に合わせて60MByteくらいに小さくなってしまうので、最後にリサイズして戻しておきます。

```
sudo umount /dev/sdb2
cd ~/work/peta/SimplePS/
sudo dd if=images/linux/rootfs.ext4 of=/dev/sdb2
sync
sudo resize2fs /dev/sdb2 
sync
```

# 起動確認する
前回と同様に、SDカードを挿入して、ジャンパ(JP5)をSDに設定して、電源ONします。

すると、起動完了時に自動的にrootとしてログインしていることが分かると思います。また、試しに、以下のように/home/root/にファイルを作成して再起動してみると、再起動後もファイルがあることが分かると思います。(前回だと、再起動後にファイルは消えていた)

```sh
touch newFile
ls
reboot
```

# 修正
記事を書いた後に気付いたのですが、これまでの内容は、Linuxカーネルのコンフィグではありません。プロジェクトのコンフィグになります。そのため、U-Bootの設定などはここでやりました。

Linuxカーネルそのもののコンフィグ(カーネルツリーでの`make menuconfig`相当)をやるには、以下コマンドを実行します。

```sh
petalinux-config -c kernel 
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214268/038b69c4-cd0c-cec9-99b4-27d5989acb0a.png)

## メモ
自分で変更したkernel configは、`project-spec/meta-user/recipes-kernel/linux/linux-xlnx/user_2018-01-14-15-33-00.cfg`といった感じに、変更した差分だけが保存されているっぽい。ベースとなるコンフィグはたぶんこれ。`project-spec/meta-plnx-generated/recipes-kernel/linux/configs/plnx_kernel.cfg`。一番最初にpetalinux-configしたときに作られているっぽい。
最終的には、これらをマージしたものが使われるのかな??