Debootstrap

On debian based systems, you can manually initialize an installation using debootstrap.

This whole process takes half an hour or so (depending on network bandwidth and disk setup, direct to sd-card will be slower), and will result in a 250MB root filesystem, or a 80MB tarball,

= Pre-requisites =


 * A debian based distribution.
 * package debootstrap
 * package qemu-user-static if you are doing this from a different architecture

It is assumed that your target filesystem is mounted in /mnt

Also, figure out which distribution version you wish to use. Current debian stable is called buster (debian 10.6, dated 20200926), and a current ubuntu is called focal (Ubuntu 20.04 LTS aka "focal fossa", dated 20200623).

= First stage =

This step can be run from any host architecture.

armhf debootstrap --arch=armhf --foreign /mnt/ arm64 debootstrap --arch=arm64 --foreign /mnt/

Replace with your preferred distribution, probably buster or focal.

= Second stage =

From a different host architecture
Copy qemu to the target filesystem and chroot to target:

armhf cp /usr/bin/qemu-arm-static /mnt/usr/bin/ chroot /mnt /usr/bin/qemu-arm-static /bin/sh -i arm64 cp /usr/bin/qemu-aarch64-static /mnt/usr/bin/ chroot /mnt /usr/bin/qemu-aarch64-static /bin/sh -i

From the same architecture
Chroot to target: chroot /mnt /bin/sh -i

Debootstrap second stage
/debootstrap/debootstrap --second-stage

It's also possible to use qemu-debootstrap instead of manual two-stage bootstrap.

= Mandatory setup =

Add root passwd
While in the chroot, run: passwd

Hostname
You do not wish to have your rootfs have the same hostname as your host machine, so it is wise to change this now, as this will surreptitiously influence things like your ssh keys.

Simply edit /etc/hostname, this can be done from both inside and outside of the chroot.

Fstab
This can be done from both inside and outside of the chroot.

Add tmpfs
none		/tmp	tmpfs	defaults,noatime,mode=1777	0	0

Add root filesystem
/dev/mmcblk0p2	/	ext4	defaults	0	1

Rename this to /dev/mmcblk0p1 if you use a single partition.

Add boot partition (if present)
/dev/mmcblk0p1	/boot	vfat	defaults	0	2

Adjust filesystemtype accordingly.

With systemd

 * From within the chroot: systemctl enable serial-getty@ttyS0.service


 * Outside of chroot: ln -s /lib/systemd/system/serial-getty@.service /mnt/etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service

With upstart
Please follow this ubuntu howto, which can be done from outside the chroot.

With sysvinit
Add the following line to /etc/inittab, independent of chroot (apart from the path): T0:2345:respawn:/sbin/getty -L ttyS0 115200 vt100

= Optional/deferrable setup =

Most of these things can be done from within the chroot or on the actual machine. They are really nice to have, but not totally necessary before the first boot of the target machine.

If debians servers are not resolving, you might need to copy the hosts' resolv.conf to the target filesystem before chrooting back in.

Locales
Run: apt-get install locales dpkg-reconfigure locales

It might make sense to choose en_US.UTF-8

Configure ethernet with dhcp
Add the following to /etc/network/interfaces

auto lo eth0 allow-hotplug eth0 iface lo inet loopback iface eth0 inet dhcp

This method is preferred over catting, as that will overwrite any inclusion of interfaces.d/

More complete apt sources.list
Here are some expanded sources.lists, which are bound to be out of date. Edit /etc/apt/sources.list and add.

Debian
Replace buster with your chosen debian distribution name. deb http://deb.debian.org/debian/ buster main contrib non-free deb-src http://deb.debian.org/debian/ buster main contrib non-free deb http://deb.debian.org/debian/ buster-updates main contrib non-free deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free deb http://deb.debian.org/debian-security/ buster/updates main contrib non-free deb-src http://deb.debian.org/debian-security/ buster/updates main contrib non-free

Ubuntu
Replace focal with your chosen ubuntu version. deb http://ports.ubuntu.com/ focal main universe deb-src http://ports.ubuntu.com/ focal main universe deb http://ports.ubuntu.com/ focal-security main universe deb-src http://ports.ubuntu.com/ focal-security main universe deb http://ports.ubuntu.com/ focal-updates main universe deb-src http://ports.ubuntu.com/ focal-updates main universe

Openssh-server
Run: apt-get install openssh-server

Root login over SSH
If you want access as root, you will need to edit /etc/ssh/sshd_config.

Key based authentication
Uncomment the following line:
 * 1) PermitRootLogin prohibit-password

And add your key to /root/.ssh/authorized_keys.

Password based authentication
Uncomment the PermitRootLogin line, and set it to yes.

PermitRootLogin yes

PRNG entropy seeding speedups (debian buster!)
In case you notice long startup times for ssh server (or any other software calling getrandom, see debian bug #912087) on your device, it can be alleviated by installing `haveged` package:

apt install haveged

This issue is not seen on Debian 9 (Stretch), but does occur on Debian 10 (Buster).

= Cleanup =

From within the chroot, run apt-get clean to remove cached packages.

If you were using a qemu chroot, then you need to remove /mnt/usr/bin/qemu-arm-static or /usr/bin/qemu-aarch64-static.

If you needed the hosts' resolv.conf, then you need to remove /mnt/etc/resolv.conf

= Tarring up the result =

You spent some time setting this up, and you might not want to retrace the above steps every few days, so you might as well throw this into a 100ish MB tarball:

From the host, from within /mnt/, run: tar -cjpf /home/user/sunxi_rootfs.tar.bz2.

Be careful when you unpack that, as rootfses are pretty much the only time tarballs should be untarred in the local directory.