projects github about
Using Ubuntu-base arm64 rootfs for Raspberry Pi 3

Extract the Rootfs

18/10/13: [mkinitramfs -o /boot/initrd.img /lib/modules/4.x.x] Remove creating initrd.img not needed... Will boot with/without uboot
18/10/17: issue resolve.. Below procedure also works for ubuntu-base-18.04.1.
Note: While inside chroot, also install package systemd or you'll encounter error: /bin/sh: 0: can't access tty; job control turned off

To create our bare filesystem, we need:

Ubuntu Base 16.04.3 file_download Ubuntu Base 18.04.1 file_download

-C - To extract the files in a different directory
1
2
3
4
5
6
7
8
wget http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.3-base-arm64.tar.gz
mkdir rootfs
sudo tar xzvf ubuntu-base-16.04.3-base-arm64.tar.gz -C $HOME/rootfs

// OR
wget http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz
mkdir rootfs
sudo tar xzvf ubuntu-base-18.04.1-base-arm64.tar.gz -C $HOME/rootfs

Modifying the Rootfs

Going back from when we compile the Raspberry Pi 3 kernel, We are goig to install the kernel module and firmware into the rootfs folder that we just created above.

1
sudo make -C rpi-4.14.70/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=$HOME/bo_4.14/ modules_install INSTALL_MOD_PATH=$HOME/rootfs/

Verify that it was installed correctly. And remove build and source links.

1
2
3
4
5
6
7
8
9
ls $HOME/rootfs/lib/modules/4.11~

modules.builtin     modules.devname        modules.symbols.bin  build
kernel              modules.builtin.bin    modules.order        source
modules.alias       modules.dep            modules.softdep
modules.alias.bin   modules.dep.bin        modules.symbols

sudo find $HOME/rootfs/ -name build | xargs rm -rf
sudo find $HOME/rootfs/ -name source | xargs rm -rf

Well use chroot to further setup our filesystem.

1
sudo cp -av /usr/bin/qemu-aarch64-static $HOME/rootfs/usr/bin

Then we need to copy resolv.conf from our host machine for internet connection to $HOME/rootfs/etc/:

1
2
3
4
5
# If your host is Ubuntu 17.10
sudo cp -av /run/systemd/resolve/stub-resolv.conf $HOME/rootfs/etc/resolv.conf

# For Ubuntu 16.04.3 below
sudo cp -av /run/resolvconf/resolv.conf $HOME/rootfs/etc/resolv.conf

Enter chroot environment:

1
sudo chroot $HOME/rootfs/

Now that you’re in the chroot environment, we can now add an admin user with sudo permission.

1
2
useradd -G sudo -m -s /bin/bash pi3
echo pi3:pi3 | chpasswd
The format input line of chpasswd is: user_name:password.


Change root password with these command:

1
passwd root

You can setup your hostname here for your target device or in the kernel configuration making sure that the hostname is empty.

1
2
3
echo U-Base_min > /etc/hostname
echo 127.0.0.1	localhost > /etc/hosts
echo 127.0.1.1	U-Base_min >> /etc/hosts

Fetch the latest package lists from server then upgrade.

1
2
apt-get update
apt-get upgrade

Then install these first:

1
apt-get install dialog perl

We need those installed first to correct some error messages about locale: If locale-gen command is missing, apt-get install locales first.

1
2
3
4
locale-gen "en_US.UTF-8"
        Generating locales...
            en_US.UTF-8... done
        Generation complete.

Install minimal packages:

1
apt-get install sudo ifupdown net-tools ethtool udev wireless-tools iputils-ping resolvconf wget apt-utils wpasupplicant nano
To-Do: gonna use Netplan for future network management

When everything you want are done, exit chroot:

1
exit

We need to add /etc/fstab file entry below coz’ if not…it will run on read-only mode. Below are Tab not spacebar

1
echo "/dev/mmcblk0p2	/	ext4	defaults,noatime	0	1" >> $HOME/rootfs/etc/fstab

Removing unwanted files

To reduce the rootfs/ size we can remove some unwanted files. Create a file /etc/dpkg/dpkg.cfg.d/01_nodoc which specifies the desired filters. Example:

1
2
3
4
5
6
7
8
9
path-exclude /usr/share/doc/*
# we need to keep copyright files for legal reasons
path-include /usr/share/doc/*/copyright
path-exclude /usr/share/man/*
path-exclude /usr/share/groff/*
path-exclude /usr/share/info/*
# lintian stuff is small, but really unnecessary
path-exclude /usr/share/lintian/*
path-exclude /usr/share/linda/*

Then you can manually remove any documentation already installed:

1
2
3
4
sudo find rootfs/usr/share/doc -depth -type f ! -name copyright|xargs rm || true
sudo find rootfs/usr/share/doc -empty|xargs rmdir || true
sudo rm -rf rootfs/usr/share/man/* rootfs/usr/share/groff/* rootfs/usr/share/info/*
sudo rm -rf rootfs/usr/share/lintian/* rootfs/usr/share/linda/* rootfs/var/cache/man/*

Then copy the $HOME/rootfs/* content to the 2nd partition of your MicroSD card.


Creating the Image file (*Optional)

We could make an image file with several partition on it. We will create a 700M empty img file:

Modify the desired image size according to your needs. I use resize2fs after i boot this up
sudo dd if=/dev/zero of=myimage.img bs=700K count=1024

Then partition it using fdisk in my case:

1
2
3
4
5
6
sudo fdisk -l myimage.img
        Result:
        | Device     w| Boot | Start 	| End	  | Sectors |
        |:-----------|:-----|:----------|:--------|:--------|
        | myimage1   |      | 2048  	| 264191  | 1024000 | Fat32
        | myimage2   |      | 264192 	| 1433599 | 3168256 | Linux
For 32Bit - kernel bootup message sometimes do not show up. But using a usb-serial with putty you’ll know the kernel boots up…

To assign a loopback device and be able to format it.

1
2
3
4
sudo losetup -o $((512*2048)) --sizelimit $((512*264191)) /dev/loop14 myimage.img 
sudo losetup -o $((512*264192)) --sizelimit $((512*1433599)) /dev/loop15 myimage.img
sudo mkfs.vfat -F 32 -n boot /dev/loop14
sudo mkfs.ext4 -L root /dev/loop15
mkfs.vfat -n partition name /dev/loop1.

Mount and Copy those necessary files that we need to their respected partition. Install dosfstools if cannot mount vfat

1
2
3
4
5
6
7
8
9
10
11
sudo mount /dev/loop14 /mnt/boot
sudo mount /dev/loop15 /mnt/rootfs

// run sync before umounting and after copying files are done
sync

    # Then umount and detach:
sudo umount /dev/loop14
sudo umount /dev/loop15
sudo losetup --detach /dev/loop14
sudo losetup --detach /dev/loop15

You can now burn that myimage.img to yor MicoSD card. Now boot it up and you should now be able to login.


Reference :

http://docs.khadas.com/social/BuildUbuntuRootfsViaUbuntuBase/
https://gnu-linux.org/building-ubuntu-rootfs-for-arm.html
http://manpages.ubuntu.com/manpages/xenial/man8/losetup.8.html