In this guide we will create a minimal Debian 9.0 (Stretch) system update image from scratch. I will cover everything from cloning the repositories, to compiling the kernel, creating a rootfs.img, ramdisk.img, logo.img, and finally packing the update.img.
This will probably look daunting at first. Just follow my directions step-by-step and you’ll be ok.
Requirements
- Khadas VIM w/USB C cable
- Windows PC (to flash the update.img)
- Reasonably powerful machine for building/compiling
Short on time?
Download a prebuilt version of this ‘ROM’ from Mediafire
http://www.mediafire.com/file/wrj0toot2f37fbk/debian-stretch-2017-06-25-update.7z
1. Setting up your build machine
-
Install Ubuntu 16.04 Server edition. Debian 8 (Jessie) should also work, possibly with a few minor tweaks. Anything with GCC 6 will cause u-boot to not compile, so unfortunately Ubuntu 17.04 and Debian 9 are out (ironically).
-
Login and run the following:
sudo apt install build-essential git-core gcc-arm-none-eabi gcc-aarch64-linux-gnu bc python qemu qemu-user-static binfmt-support debootstrap libc6:i386 libstdc++6:i386
2. Clone the repositories
mkdir ~/project && cd ~/project
git clone https://github.com/khadas/u-boot --depth 1 -b ubuntu
git clone https://github.com/khadas/linux --depth 1 -b ubuntu-4.9
git clone https://github.com/khadas/utils.git
git clone https://github.com/khadas/images_upgrade.git
3. Compile u-boot
cd ~/project/u-boot
make kvim_defconfig
make -j8 CROSS_COMPILE=aarch64-linux-gnu-
4. Compile the kernel
cd ~/project/linux
make ARCH=arm64 kvim_defconfig
make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image kvim.dtb modules
5. Build the rootfs
First we must to create a “virtual disk” to hold the operating system:
cd ~/project
truncate --size 500M rootfs.img
mkfs.ext4 -F -L ROOTFS rootfs.img
sudo mkdir /mnt/kvimrootfs
sudo mount -o loop rootfs.img /mnt/kvimrootfs
Next, let’s install a minimal version of debian stretch (this will take a while):
sudo debootstrap --arch=arm64 --foreign stretch /mnt/kvimrootfs
sudo cp -a /usr/bin/qemu-aarch64-static /mnt/kvimrootfs/usr/bin/
sudo chroot /mnt/kvimrootfs /debootstrap/debootstrap --second-stage
Some basic tweaks to make the operating system usable:
# User account
USERNAME=khadas
PASSWORD=khadas
sudo chroot /mnt/kvimrootfs adduser --disabled-password --gecos "" $USERNAME
sudo chroot /mnt/kvimrootfs usermod -aG sudo $USERNAME
echo "$USERNAME:$PASSWORD" | sudo chroot /mnt/kvimrootfs chpasswd
# Serial console
sudo chroot /mnt/kvimrootfs ln -s /lib/systemd/system/serial-getty\@.service /etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service
# Packages
sudo chroot /mnt/kvimrootfs bash -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
sudo chroot /mnt/kvimrootfs apt update
sudo chroot /mnt/kvimrootfs apt install --yes --no-install-recommends sudo fbset htop network-manager initramfs-tools openssh-server
# Hostname
sudo chroot /mnt/kvimrootfs bash -c "echo KhadasVIM > /etc/hostname"
# Display initialization script (taken from the khadas ubuntu mate image)
sudo tee /mnt/kvimrootfs/etc/initramfs-tools/scripts/local-top/khadas_init.sh <<EOF >/dev/null
#!/bin/sh
fbset -fb /dev/fb0 -g 1920 1080 1920 2160 32
echo 1080p60hz > /sys/class/display/mode
echo 0 > /sys/class/graphics/fb0/free_scale
echo 1 > /sys/class/graphics/fb0/freescale_mode
echo 0 0 1919 1079 > /sys/class/graphics/fb0/free_scale_axis
echo 0 0 1919 1079 > /sys/class/graphics/fb0/window_axis
echo 0 > /sys/class/graphics/fb1/free_scale
echo 1 > /sys/class/graphics/fb1/freescale_mode
echo 0 > /sys/class/graphics/fb0/blank
echo 0 > /sys/class/graphics/fb1/blank
echo heartbeat > /sys/class/leds/red/trigger
EOF
sudo chmod +x /mnt/kvimrootfs/etc/initramfs-tools/scripts/local-top/khadas_init.sh
Don’t unmount the rootfs just yet – we need to make the initrd first!
6. Build the initrd
cd ~/project/linux
sudo make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/mnt/kvimrootfs modules_install
sudo chroot /mnt/kvimrootfs mkinitramfs -o /boot/initrd.img $(cat ~/project/linux/include/config/kernel.release)
sudo mv /mnt/kvimrootfs/boot/initrd.img ~/project
You will see a few errors about the khadas_init.sh script in your console. Don’t worry, they are expected.
7. Clean up the rootfs
sudo chroot /mnt/kvimrootfs apt clean
sudo rm -f /mnt/kvimrootfs/usr/bin/qemu-aarch64-static
sudo sync && sudo umount /mnt/kvimrootfs
sudo rm -rf /mnt/kvimrootfs
8. Pack the ramdisk.img
cd ~/project
./utils/mkbootimg --kernel linux/arch/arm64/boot/Image --ramdisk initrd.img -o ramdisk.img
rm -f initrd.img
9. Pack the logo.img
cd ~/project
wget https://meyer.io/dl/khadasvim/debian-bootup.bmp
./utils/logo_img_packer debian-bootup.bmp logo.img
rm -f debian-bootup.bmp
Mirror: http://www.mediafire.com/view/spf59pp7q9ui82t/debian-bootup.bmp
10. Fix the symlinks in image_upgrade
cd ~/project/images_upgrade
ln -f -s ../u-boot/fip/u-boot.bin u-boot.bin
ln -f -s ../u-boot/fip/u-boot.bin.sd.bin u-boot.bin.sd.bin
ln -f -s ../u-boot/fip/u-boot.bin.usb.bl2 u-boot.bin.usb.bl2
ln -f -s ../u-boot/fip/u-boot.bin.usb.tpl u-boot.bin.usb.tpl
ln -f -s ../linux/arch/arm64/boot/dts/amlogic/kvim.dtb kvim.dtb
ln -f -s ../rootfs.img rootfs.img
ln -f -s ../ramdisk.img ramdisk.img
ln -f -s ../logo.img logo.img
11. Pack the system update image
cd ~/project
./utils/aml_image_v2_packer -r images_upgrade/package.conf images_upgrade update.img
Now you can transfer this image over to a Windows PC and flash it using Amlogic’s USB Burning Tool.
Quick tip: you can easily put the Khadas VIM in upgrade mode by following these steps,
-
Press and hold the first button (closest to the GPIO pins).
-
Quickly press the third/reset button (closest to the I/O ports).
-
Continue holding down the first button for at least 10 seconds.
Notes
- The filesystem will be limited to 500MB until you run
sudo resize2fs /dev/rootfs
- Khadas (or Amlogic): if you’re reading this, we really need proper EDID & KMS support. This “khadas_init.sh” script is a garbage fire.