Creating Ubuntu 16.04 boot image for Zybo Z7-20 (Xilinx 2018.3 tools)

# Work Flow
This article is about the second step and later below. Note that the first step should be completed before reading this article.

1. Prepare boot files with ramdisk based rootfs distributed by Xilinx according to the [previous article][1].
2. Setup SD card
    1. Modify device tree
    2. Create `uEnv.txt`
    3. Create partitions on SD card
    4. Copy files to SD card
3. Setting up Ubuntu 16.04 on Linux running with ramdisk [(See also Ref.)][4]
4. My configuration

Ref. [Petalinux 2017.2 Ubuntu RFS on zynq timed out waiting for device][4]

# Setup SD card
## Modify device tree
Modify `bootargs` in `system-top.dts` as follows,

```system-top.dts
bootargs = "earlycon root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait";
```
Here, we assume `/dev/mmcblk0p2` is the drive of rootfs formatted as ext4. 
 Note that the `devicetree.dtb` created in the [previous step][1] is used in the later steps. It may be better that the device tree blob is created with different name, e.g. `devicetree_ubuntu.dtb`. 

```
$ dtc -I dts -O dtb -o devicetree_ubuntu.dtb system-top.dts
```

## Create uEnv.txt
`u-boot`, which built in the [previous article][1], loads Linux kernel basically according to the command list embedded in the binary. (The command sequence is found in `include/configs/zynq-common.h`) But if `uEnv.txt` was found in the boot disk, the command listed in the file is preemptively executed.

```uEnv.txt
uenvcmd=fatload mmc 0 0x2080000 uImage && fatload mmc 0 0x2000000 devicetree_ubuntu.dtb && bootm 0x02080000 - 0x2000000
```
The commands load kernel image and devicetree_ubuntu.dtb to 0x2080000 and 0x2000000 respectively, and boot them without specifying the ramdisk address. (See `-` is in the `bootm` argument instead of the ramdisk address) By the way, the addresses are from the hard coded boot commands found in `zynq-common.h`.

  
## Create partitions on SD card
In my Ubuntu 16.04 installed on x64 PC, SD card is found  as `/dev/sdk`.

```
$ fdisk /dev/sdk
```
Following two partitions are to be created on a SD card. 
1 First partition (1024MB FAT32) 
2. Second partition (all remained, EXT4)

The first one is for boot drive, and the second one is for the Ubuntu rootfs. Of course, the capacity of the SD card should be large enough to enjoy Ubuntu 16.04.
 Then, two partitions, `/dev/sdk1` and `/dev/sdk2`, are to be formatted as:

```
$ sudo mkfs.vfat -F 32 /dev/sdk1
$ sudo mkfs.ext4 /dev/sdk2
```

## Copy files to SD card 
Now, make mount points, and mount two partitions onto them. 

```
$ mkdir sd_fat32
$ mkdir sd_ext4
$ sudo mount /dev/sdk1 sd_fat32
$ sudo mount /dev/sdk2 sd_ext4
```
Here `sd_fat32` is the first one, `sd_ext4` is the second one.
 Download and copy Ubuntu rootfs to sd_ext4.

```
$ wget http://cdimage.ubuntu.com/ubuntu-base/releases/16.04.2/release/ubuntu-base-16.04.3-base-armhf.tar.gz
$ sudo tar zxvf ubuntu-base-16.04.3-base-armhf.tar.gz -C sd_ext4
```

Copy followings, created [previously][1],  to `sd_fat32`
- boot.bin
- devicetree.dtb
- uramdisk.image.gz
- uImage

At this time, `uEnv.txt` and `devicetree_ubuntu.dtb` should not be copied, because rootfs of Ubuntu does not work properly; it stalls during boot. 

Unmount partitions.

```
$ sudo umount sd_fat32
$ sudo umount sd_ext4
```
Remove SD card and insert it to ZYBO Z7-20.

# Setting up Ubuntu 16.04 on Linux running with ramdisk
This section is almost the same as in the [article][4]. Here, the detailed setup steps are presented that the article does not show.
 Boot ZYBO Z7-20 with the SD card created above. The Linux kernel boots with ramdisk rootfs. 
 First, setup the network interface.

```
$ ifconfig lo up
$ ifconfig eth0 up
$ ifconfig eth0 192.168.100.10
```
The network address is for my private network, replace it to yours.
 Create mount point `rootfs`, and mount `/dev/mmcblk0p2` the partition of the Ubuntu rootfs.

```
$ mkdir rootfs
$ mount /dev/mmcblk0p2 /rootfs
```
On `chroot` session, create a user `zynq` and change the password for `root`. 

```
$ chroot /rootfs adduser zynq
$ chroot /rootfs passwd root
```

To retrieve required apps using `apt`, nameserver should be specified in `resolv.conf`. 

```
$ route add default gw 192.168.100.1
$ echo "nameserver 192.168.100.1" >> /rootfs/etc/resolv.conf
```
Note that `/rootfs/etc/resolv.conf` is not `/etc/resolv.conf`.
 Install required packages.

```
$ chroot /rootfs apt update
$ chroot /rootfs apt upgrade
$chroot /rootfs apt install sudo vim nano net-tools iproute2 iputils-ping ifupdown openssh-client openssh-server -y
```

Make getty aware of `ttyPS0`, our serial console.

```
$ chroot /rootfs ln -s /lib/systemd/system/getty@.service /etc/sys
$ temd/system/getty.target.wants/getty@ttyPS0.service
$ echo "ttyPS0" >> /rootfs/etc/securetty
```

To make final modification on boot drive, mount it onto `/mnt`.

```
$ mount /dev/mmcblk0p1 /mnt
```

From PCs in the network, copy `uEnv.txt` and `devicetree_ubuntu.dtb` to the boot drive of the ZYBO Z7-20.

```
$ scp uEnv.txt 192.168.100.10:/mnt/uEnv.txt
$ scp devicetree_ubuntu.dtb 192.168.100.10:/mnt/devicetree_ubuntu.dtb
```

Reboot ZYBO Z7-20. Then Ubuntu starts. 

# My configuration
## Network
Login as root, and modify `/etc/network/interfaces`  as follows.

```/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
```

Insert followings to `/etc/hosts`

```/etc/hosts
127.0.0.1 localhost
127.0.1.1 localhost.localdomain
```

## Add zynq to sudoser

```
usermod -G sudo zynq
```

## Install Apps
- gcc
- g++
- kmod
- software-properties-common
- git

## Device Drivers
Before building Linux kernel, 

```
$ make menuconfig
```

Enabled drivers.
- Device Drivers -> Character devices -> Serial Drivers -> Xilinx uartlite serial port support (using uartlite core in PL)

Disabled drivers.
- Device Drivers -> GPIO Support -> Memory mapped GPIO drivers -> Xilinx GPIO support (using my original gpio driver)

## Auto-mount Description
Modify fstab as,

```/etc/fstab
/dev/mmcblk0p1 /mnt auto defaults 0 0 
```


## GLIBCXX_3.4.22-25
```
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt upgrade
```

[1]:https://qiita.com/yhmtmt/items/cba5330ad7ded151882d
[4]:https://forums.xilinx.com/t5/Embedded-Linux/Petalinux-2017-2-Ubuntu-RFS-on-Zynq-timed-out-waiting-for-device/td-p/800863