How to create Ubuntu 18.04/16.04 SD card image for iMX8/iMX6

From ESS-WIKI
Jump to: navigation, search


Host Prerequisites

required packages

sudo apt install binfmt-support qemu-user-static wget gddrescue
sudo modprobe binfmt_misc

pre-built yocto image

SDIMAGE=5620A1AIM20LIV90140_iMX8X_2020-07-29.img # i.MX8 ROM-5620
SDIMAGE=3430A1AIM20LIV90107_DualQuad_2020-08-26.img # i.MX6 RSB-3430

duplicate the new image

read _ PSTART _ PSECTORS _ <<< `fdisk -lu $SDIMAGE | grep "${SDIMAGE}2"`
UIMAGE=${SDIMAGE/LIV/UIV}
cp $SDIMAGE $UIMAGE
mkfs.ext4 -F -E offset=$((PSTART*512)) -L ubuntu ${UIMAGE} ${PSECTORS}s

backup preserved data

BACKUPDIR=~/${SDIMAGE%%_*}
MNT=~/mnt
mkdir -p $BACKUPDIR $MNT
sudo mount -o ro,offset=$((PSTART*512)) $SDIMAGE $MNT
sudo tar zcvf $BACKUPDIR/preserved.tgz -C $MNT lib/{modules,firmware} etc/{modprobe.d,modules-load.d,udev}
sudo umount $MNT

Root Filesystem Building

set ARM architecture

ARCH=arm64 # for i.MX8
ARCH=armhf # for i.MX6

set Ubuntu version code name

UBUNTU_CODENAME=bionic # for Ubuntu 18.04
UBUNTU_CODENAME=xenial # for Ubuntu 16.04

get the basic rootfs

ROOTFS=~/ubuntu_${UBUNTU_CODENAME}_${ARCH}

sudo qemu-debootstrap --arch=${ARCH} \
--variant=buildd \
--exclude=debfoster ${UBUNTU_CODENAME} ${ROOTFS}

cat << EOT | sudo tee ${ROOTFS}/etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports/ ${UBUNTU_CODENAME} main universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ ${UBUNTU_CODENAME}-updates main universe multiverse
EOT

go on in chroot

enter the chroot

sudo mount -t proc proc $ROOTFS/proc
sudo mount -t sysfs sysfs $ROOTFS/sys
sudo mount --bind /dev $ROOTFS/dev
sudo mount --bind /dev/pts $ROOTFS/dev/pts

HOME=/root sudo chroot $ROOTFS /bin/bash --login -i


install & configure (base)

cd ~
apt clean
apt update

ln -sf bash /bin/sh
ln -sf bash.1.gz /usr/share/man/man1/sh.1.gz

export DEBIAN_FRONTEND=noninteractive

apt -y install locales tzdata dialog lsb-release vim

locale-gen "en_US.UTF-8"
update-locale LANG=en_US.UTF-8 LANGUAGE
#// or run 'dpkg-reconfigure locales' to set locale

echo "Aisa/Taipei" > /etc/timezone
ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
#// or run 'dpkg-reconfigure tzdata' to set time zone

apt -y install console-setup whois kmod sudo \
network-manager iputils-ping iproute2 ifupdown ethtool openssh-client net-tools \
systemd systemd-sysv parted bsdmainutils mtd-utils pciutils usbutils lshw \
haveged busybox

NUSER=adv; NID=1000; NPSWD=adv
groupadd -g $NID $NUSER
useradd -u $NID -d /home/$NUSER -m -g $NUSER -G adm,sudo,audio,video,plugdev $NUSER
CRYPT=$(echo $NPSWD | mkpasswd -m sha-512 -s)
sed -i "s@^$NUSER:[^:]\+:@$NUSER:$CRYPT:@" /etc/shadow
sed -i "s/^root:[^:]\+:/root::/" /etc/shadow

cat << "EOT" > /etc/udev/rules.d/50-firmware.rules
SUBSYSTEM=="firmware", ACTION=="add", RUN{program}="firmware"
EOT

cat << "EOT" > /lib/udev/firmware
#!/bin/bash
echo 1 > /sys/$DEVPATH/loading
cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data
if [ $? = 0 ]; then
    echo 0 > /sys/$DEVPATH/loading
fi
EOT

chmod +x /lib/udev/firmware

mkdir -p /etc/systemd/system/systemd-udevd.service.d

cat << EOT > /etc/systemd/system/systemd-udevd.service.d/override.conf
[Service]
MountFlags=shared
EOT

sed -i '/ExecStart.*/i Environment="TERM=xterm-color"' /lib/systemd/system/serial-getty@.service
sed -i 's/"$/ --data=16"/' /etc/default/haveged
chmod -x /sbin/hwclock && mv /sbin/hwclock{,.util-linux} && ln -s /bin/busybox /sbin/hwclock
touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf

cp -a /etc/skel/.bashrc ~/
cp -a /etc/skel/.profile ~/

install & configure (xfce4)

apt -y install xfce4 xfce4-goodies lightdm xterm

rm /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf

cat << EOT > /usr/share/lightdm/lightdm.conf.d/50-xfce-greeter.conf
[SeatDefaults]
greeter-session=unity-greeter
user-session=xfce
EOT

cat << EOT > /etc/lightdm/lightdm.conf
[Seat:*]
autologin-guest=false
autologin-user=adv
autologin-user-timeout=0
EOT

leave the chroot

history -c
logout

sudo umount -lf $ROOTFS/dev/pts
sudo umount -lf $ROOTFS/dev
sudo umount $ROOTFS/sys
sudo umount $ROOTFS/proc

backup the rootfs

#// use pre-defined ARCH as hostname
echo $ARCH | sudo tee $ROOTFS/etc/hostname
echo -e "127.0.0.1\tlocalhost\n127.0.1.1\t$ARCH" | sudo tee $ROOTFS/etc/hosts

sudo tar zcvf ${BACKUPDIR}/${UBUNTU_CODENAME}_rootfs.tgz -C ${ROOTFS} .

Processing the new image

restore rootfs & preserved data

sudo mount -o offset=$((PSTART*512)) $UIMAGE $MNT
sudo tar zxvf ${BACKUPDIR}/${UBUNTU_CODENAME}_rootfs.tgz -C $MNT
sudo tar zxvf ${BACKUPDIR}/preserved.tgz -C $MNT

#//set hostname
HOST=rsb-3430 # specify the actual hostname
echo $HOST | sudo tee $MNT/etc/hostname
echo -e "127.0.0.1\tlocalhost\n127.0.1.1\t$HOST" | sudo tee $MNT/etc/hosts

sudo umount $MNT

flash image to SD device

SD_DEVICE=/dev/sdh #// specify the actual SD device
sudo umount ${SD_DEVICE}*
sudo ddrescue -D -f ${UIMAGE} ${SD_DEVICE}