How to Build Ubuntu

This procedure describes how to create Ubuntu image with SD Card for I-Pi SMARC IMX8M Plus with 2G/4G Memory. The version of Ubuntu used is 20.04 (Focal Fossa).

Recommended Hardware

To setup the build environment for Ubuntu image creation, a Linux host with the following configuration is recommended.

  • Intel Core-i7 processor (>= 4 cores)

  • 8 GB RAM

  • 1 TB disk space

  • High speed network connectivity

  • OS: Ubuntu 18.04 LTS/Ubuntu 16.04 LTS


Update apt repositories list on your host machine and install required packages.

$ sudo apt update
$ sudo apt install build-essential

Install kernel and u-boot dependencies.

$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip device-tree-compiler liblz4-tool libssl-dev

Install buildroot dependencies.

$ sudo apt-get install libfile-which-perl sed make binutils gcc g++ bash patch gzip bzip2 perl tar cpio python unzip rsync file bc libmpc3 git repo texinfo pkg-config cmake tree texinfo

Getting Started

The following are the steps required to generate Ubuntu image for I-Pi SMARC IMX8M Plus.

Step 1: Create a Ubuntu root file system.
Step 2: Downloading Yocto IMX8MP image.
Step 3: Replacing IMX8MP yocto image rootfs with Ubuntu 20.04 rootfs.

Note: Remember to download yocto image respective to memory. For example, Download 2G image, if you are building Ubuntu image for 2G memory and vice versa.


Step 1: Create a Ubuntu root file system

  1. Create a new working directory and change directory into it.
$ mkdir $HOME/imx8mp
$ cd $HOME/imx8mp
  1. Create a rootfs directory.
$ mkdir rootfs
  1. Install deboot strap and its dependencies.
$ sudo apt install debootstrap binfmt-support qemu-user-static
$ sudo debootstrap --arch=arm64 --include=sudo,net-tools,isc-dhcp-client --foreign focal rootfs
  1. Add required apt repositories to sources.list
$ sudo bash -c "printf 'deb http://ports.ubuntu.com/ubuntu-ports focal main restricted\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal main restricted\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal universe\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal universe\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-updates universe\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-updates universe\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal multiverse\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal multiverse\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-updates multiverse\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-updates multiverse\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-backports main restricted universe multiverse \n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-backports main restricted universe multiverse\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-security main restricted \n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-security main restricted\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-security universe\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-security universe\n\ndeb http://ports.ubuntu.com/ubuntu-ports focal-security multiverse\n# deb-src http://ports.ubuntu.com/ubuntu-ports focal-security multiverse' > rootfs/etc/apt/sources.list"
  1. Configure the Rootfs, Add host name to /etc/hostname. Here is an example,
$ sudo bash -c"echo 'adlink' > rootfs/etc/hostname"
  1. Add host entry in /etc/hosts
$ sudo bash -c"printf'127.0.0.1\tlocalhost\n127.0.1.1\tadlink\n\n'>rootfs/etc/hosts"
$ sudo bash -c "echo'root::0:0:root:/root:/bin/bash'>rootfs/etc/passwd"
  1. Prepare QEMU
$ sudo wget https://github.com/multiarch/qemu-user-static/releases/download/v4.2.0-6/qemu-aarch64-static -O rootfs/usr/bin/qemu-aarch64-static
$ sudo chmod +x rootfs/usr/bin/qemu-aarch64-static
  1. Get your network ready
$ sudo cp /etc/resolv.conf rootfs/etc/
  1. Mount the proc sys dev file systems
$ for f in proc sys dev dev/pts; do sudo mount --bind /$f rootfs/$f; done
  1. Change root
$ sudo chroot rootfs /bin/bash
  1. Add user name
$ /debootstrap/debootstrap --second-stage
$ apt install sudo net-tools isc-dhcp-client
$ adduser imx8mp (provide new password and name for the user in the prompt)
$ usermod -a -G sudo imx8mp
  1. Install the required tools or utilities
$ apt update
$ apt install vim git sudo net-tools ifupdown kmod iputils-ping man wget bash-completion alsa-utils apt-utils usbutils locales i2c-tools netplan.io tightvncserver lm-sensors usbmount build-essential mesa-utils cmake can-utils sox v4l-utils glmark2
  1. Configure locales

You will be prompted through GUI menu to make certain selections such as date/time/region. Please make the appropriate selections and proceed.

$ dpkg-reconfigure locales
  1. Install ubuntu-desktop and necessary packages
$ apt install ubuntu-desktop
  1. Clean up and exit from chroot
$ rm -rf /var/cache/apt/archives/*.deb
$ sync
$ exit
  1. Unmount the mounted files
$ for f in proc sys dev/pts dev; do sudo umount rootfs/$f; done
  1. Remove emulator and resolv.conf file
$ sudo rm rootfs/usr/bin/qemu-aarch64-static rootfs/etc/resolv.conf
  1. Use netplan to enable configurations in networking on the system

Create a01-network-manager-all.yaml file under /etc/neplan

$ sudo vim $HOME/imx8mp/rootfs/etc/neplan/01-network-manager-all.yaml
  1. Add the following content, then save it.

Let network manager manage all devices on this system

network:

version: 2

render: NetworkManager

  1. Make the Root File System

Execute the commands below to make the rootfs.img

Notice that you need change the “count” value according to the size of the “rootfs” folder

Below command will create new rootfs.img file of size 4 GB (3 GB)

$ cd
$ dd if=/dev/zero of=rootfs.img count=4096 status=progress && sync
$ sudo mkfs.ext4 rootfs.img
$ mkdir rootfs
$ sudo mount rootfs.img rootfs/
$ sudo cp -rfp $HOME/imx8mp/rootfs/* rootfs/
$ sudo umount rootfs/

Step 2: Downloading Yocto imx8mp image

Click Here to download the Yocto IMX8MP image

Unzip the file and flash the Image into SD card

$ sudo bunzip2 -dk -f filename
$ sudo dd if=filename of=/dev/sdX bs=64M status=progress

(where X will give mounted device id)

Step 3: Replacing IMX8MP Yocto image rootfs with Ubuntu rootfs

  1. Unmount the mounted partitions.
$ sudo umount /dev/sdc*

Note: In our case, /dev/sdb is SD card device name.

  1. Run GParted in the command line.
$ sudo gparted

Note: GParted is a free partition editor for graphically managing your disk partitions.

  1. Select SD card as highlighted in above corner in below picture.
img
  1. Select the rootfs partition and select resize option above. Partition 2 (/dev/sdc2) is the rootfs partition in below picture.

    img
  2. Size of rootfs before resize as shown below.

img
  1. Increase the rootfs size i.e /dev/sdb2 here and click on resize button.
img
  1. Save changes and select apply.
img
  1. Close the GParted and eject SD card. Also connect your SD Card to the development Linux Host PC.
img
  1. Run lsblk command to get the path for mounted rootfs partition.
img
  1. Remove the existing contents as this filesystem is the default build root file system.
$ sudo rm -rf <mount_path>/*
$ sync
  1. Run the following commands to copy the contents of the Debian rootfs.img to the SD card.
$ sudo cp -rvfp $HOME/imx8mp/rootfs/* <mount_path>/
$ sync
  1. Eject the SD card. You can directly insert SD card and power on the system to boot using the SD card.

After boot, login to imx8mp user using password set in adduser command.

Note:

Use below command to create a Debian image from SD card.

sudo dd if=/dev/sdX of=<image_name>.img bs=<size> count=<size> , sync status=progress

Use the below command to compress the image from SD card.

sudo dd if=/dev/sdX bs=<size> count=<size> status=progress | gzip -c > </home/directory_name/file_name.img.gz>