I tried to build an Ubuntu/Debian image from scratch (i.e. not using any of the pre-compiled images). It’s working now, and maybe someone finds it useful. This is what i did, step by step:
I’m using the kernel 4.14, from the official github repository. You have to use a PC running Ubuntu 16.04 (64 Bit). Ubuntu 18.04 will not work correctly because of the gcc version!
To download and compile the kernel:
1. Install tools required tools:
apt-get install git build-essential automake autoconf gcc-arm-linux-gnueabihf u-boot-tools libc6-armhf-cross bc libc6-dev libncurses5-dev libssl-dev bison flex pv
2. If your gcc is newer than version 5 (check with arm-linux-gnueabihf-gcc
), install gcc 5:
apt-get install gcc-5-arm-linux-gnueabihf
update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-7 50
update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-5 100
update-alternatives --config arm-linux-gnueabihf-gcc
3. Clone BSP for kernel 4.14 into a subdirectory bsp14:
git clone https://github.com/BPI-SINOVOIP/BPI-R2-bsp-4.14.git bsp14
4. Build kernel 4.14 and bootloader (select “1”):
cd bsp14
./build.sh
cd ..
Now create the image:
1. Install required tools:
apt-get install qemu-user-static debootstrap binfmt-support parted zip
2. Create image file (8GB):
dd if=/dev/zero bs=1M count=7296 | pv | dd of=bpir2.img
3. Load image as virtual drive:
losetup /dev/loop8 bpir2.img
4. Make partitions and format:
parted -s /dev/loop8 mklabel msdos
parted -s /dev/loop8 unit MiB mkpart primary fat32 -- 100MiB 356MiB
parted -s /dev/loop8 unit MiB mkpart primary ext2 -- 356MiB 7295MiB
partprobe /dev/loop8
mkfs.vfat /dev/loop8p1 -I -n BPI-BOOT
mkfs.ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 /dev/loop8p2 -L BPI-ROOT
sync
parted -s /dev/loop8 print
The last step should show 2 partitions (one FAT and one EXT). Hint: the parted software prints the start offsets and lengths in MB (1000-based) and not in MiB (1024 based), so the start offset 105MB is correct.
Now fill the linux root filesystem:
1. Mount filesystems:
mkdir /mnt/rootfs
mount /dev/loop8p2 /mnt/rootfs
mkdir /mnt/rootfs/boot
mount /dev/loop8p1 /mnt/rootfs/boot
2. Bootstrap ubuntu rootfs (part 1):
debootstrap --arch=armhf --foreign xenial /mnt/rootfs
cp /usr/bin/qemu-arm-static /mnt/rootfs/usr/bin/
3. Continue bootstrapping (part 2) in the chroot:
chroot /mnt/rootfs
export LANG=C
/debootstrap/debootstrap --second-stage
4. Set apt packages 16.04 and update/upgrade (still in chroot):
echo "" > /etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial universe">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial universe">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted">>/etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse">>/etc/apt/sources.list
echo "deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse">>/etc/apt/sources.list
apt-get update
apt-get upgrade
apt-get dist-upgrade
5. Install packages (still in chroot), add more packages as you need:
apt-get install sudo nano openssh-server locales ntpdate htop pv
6. Set hostname (still in chroot):
echo "bpi-r2" >/etc/hostname
nano /etc/hosts
-> add "bpi-r2" to line with 127.0.0.1
7. Set root password (still in chroot), if you want to enable root login:
passwd
8. Create one or more users (still in chroot):
useradd -m -G users,sudo,ssh -s /bin/bash bpi
passwd bpi
9. Configure locales (still in chroot), add the locales that you need:
locale-gen en_US
locale-gen en_US.UTF-8
dpkg-reconfigure locales
dpkg-reconfigure tzdata
update-locale LANG=en_US.UTF-8
10. Configure fstab (still in chroot):
nano /etc/fstab
->
proc /proc proc defaults 0 0
LABEL=BPI-BOOT /boot vfat errors=remount-ro 0 1
LABEL=BPI-ROOT / ext4 defaults,noatime 0 0
11. Configure network 16.04 (still in chroot), update for your requirements: nano /etc/network/interfaces
->
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
auto wan
iface wan inet dhcp
auto lan0
iface lan0 inet static
address 192.168.1.1
netmask 255.255.255.0
#gateway 192.168.0.1
auto lan1
iface lan1 inet static
address 192.168.1.2
netmask 255.255.255.0
#gateway 192.168.0.1
auto lan3
iface lan3 inet static
address 192.168.1.3
netmask 255.255.255.0
#gateway 192.168.0.1
auto lan4
iface lan4 inet static
address 192.168.1.4
netmask 255.255.255.0
#gateway 192.168.0.1
12. Configure sshd (still in chroot), i prefer using Pubkey-auth only and disable password auth:
mkdir /root/.ssh
chmod 0700 /root/.ssh
touch /root/.ssh/authorized_keys
chmod 0600 /root/.ssh/authorized_keys
nano /etc/ssh/sshd_config
->
PubkeyAuthentication yes
PasswordAuthentication no
Your public key must be appended to /root/.ssh/authorized_keys.
20. Exit and remove qemu:
exit
rm /mnt/rootfs/usr/bin/qemu-arm-static
Now write the image file:
1. Copy boot partition files:
tar -x -f bsp14/SD/BPI-BOOT-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs/boot
2. Copy kernel files to root file system:
tar -x -f bsp14/SD/4.14.34-BPI-R2-Kernel.tgz --keep-directory-symlink -C /mnt/rootfs
tar -x -f bsp14/SD/4.14.34-BPI-R2-Kernel-net.tgz --keep-directory-symlink -C /mnt/rootfs
3. Copy bootloader files to root file system:
tar -x -f bsp14/SD/BOOTLOADER-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs
4. Blacklist power button module:
echo "blacklist mtk_pmic_keys" > /mnt/rootfs/etc/modules-load.d/mtk_pmic_keys.conf
5. Unmount:
umount /mnt/rootfs/boot
umount /mnt/rootfs
6. Write header blocks (get these files from the BPI-files repository on github):
gunzip -c BPI-R2-HEAD440-0k.img.gz | dd of=/dev/loop8 bs=1024 seek=0
gunzip -c BPI-R2-HEAD1-512b.img.gz | dd of=/dev/loop8 bs=512 seek=1
7. Write preloader and u-boot bootloader:
dd if=bsp14/mt-pack/mtk/bpi-r2/bin/preloader_iotg7623Np1_sd_1600M.bin of=/dev/loop8 bs=1024 seek=2
dd if=bsp14/u-boot-mt/u-boot.bin of=/dev/loop8 bs=1024 seek=320
sync
8. Remove loop device:
losetup -d /dev/loop8
9. Zip image (optional):
zip bpir2.img.zip bpir2.img
Now it’s finished. Write the image file to a 8GB SD card (e.g. with the Etcher tool, or simply with dd), put it in your BPI-R2 and power on.
Only the debug UART is used (no HDMI), so connect a USB serial adapter to the 3-pin debug header and start a terminal like minicom.