Home  ›  All Blogs  ›  mihir  › 

Virtualizing ARM-Based Firmware Part - 1


arm logo

Introduction: ARM Trusted Firmware

Hello everyone, this blog demonstrates how to simulate/virtualize the ARM trusted firmware in your system. This blog is for the people who are interested in IoT security and love playing with firmware. This is a custom approach to simulate firmware. Using a virtual machine will make the task easy. Commands in blog pertain to Linux, to be more specific Ubuntu. The blog will be divided into 2 parts.

Part 1: Preparing ARM Machine

Let’s start preparing a machine(ARM) on which ARM based firmware will be simulated. Steps are as below:

  • Setup QEMU
  • Compile Linux kernel for ARM
  • Download and prepare the ARM file system
  • Setup network
  • Boot up ARM file system using compiled kernel

Setup QEMU

QEMU is an open-source machine emulator and virtualizer. As this blog focus on preparing/virtualizing the ARM machine, QEMU is not covered in depth. More details and documentation can be found on QEMU

Install QEMU and other utilities

sudo apt-get install qemu qemu-system qemu-user-static

Compiling Linux Kernel for ARM

Here, the kernel will be customized and compiled for ARM using the Ubuntu machine. Compiling an executable code for a platform other than the compiler is running on, is known as cross compilation. Cross Compilers of ARM like gcc, g++ will be used to fulfill task. Follow the steps mentioned below.

  • Installing cross compilation tools sudo apt-get install gcc-arm-*
  • Installing dependencies and other tools sudo apt-get install build-essential ncurses-dev flex bison
  • Download and extract kernel from The Linux Kernel Archives. For demo, linux kernel version 5.2.6 is used. Explore the folders after extraction. Different architectures can be found under <kernel path>/arch/ directory. Go into architecture directory and explore more. Check for <kernel path>/arch/arm/configs/. This directory contains many default configuration files used while compiling kernel.
  • Kernel Root Directory Kernel Root Directory
  • ”./arch” Directory kernel/arch Directory
  • ”./arch/arm” Directory kernel/arch/arm Directory
  • ”./arch/arm/config” Directory kernel/arch/arm/config Directory
  • Copy any config file (as per requirement) from <kernel path>/arch/arm/configs/ to <kernel path>/.config. For demo, let’s use vexpress_defconfig config file to compile the kernel. Copy config file
  • Customize the kernel configuration (as per requirement) using interactive GUI way: make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig
  • Alternatively, traditional console based configuration can be used: make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig
  • Being GUI, menuconfig is easier way to go ahead. Don’t forget to save the configuration before exiting. Configure kernel Configure kernel
  • Start compilation. This process may take a while depending on your CPU and threads. make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k Start Compilation
  • Compiled kernel files (Image, zImage, etc.) can be found under <kernel path>/arch/arm/boot/ direcroty. Compiled Kernel Files

The end result for this step is customized kernel files which will be used along with virtualization software to bootup the file system.

Download and prepare ARM file system

Here, file system (ARM) will be prepared using Ubuntu ARM file system which will be used to start ARM-based firmware. This will be booted along with compiled kernel using QEMU.

Terms: (Below terms are used for demo purpose. Replace it accordingly)

  • armfs - is a directory used to mount the partition
  • /dev/sdb1 - is a harddisk partition
  • TestARM - is hostname used for ARM system

Follow the steps mentioned below:

  • Download the appropriate file system from Ubuntu Base. Extract it. Here, for demo purpose ubuntu 18.04.1 ARMHF file system is used.
  • Create a formatted hard disk partition with size 5 GB or more. In case of virtual machine, add a hard disk. Hard Disk Partition
  • Create folder in base machine where newly created partition can be mounted. For e.g. mkdir ~/armfs
  • Mount the partition  sudo mount <drivepath> <foldername>. Mount Hard Disk Partition
  • Copy the extract file system to ~/armfs. The folder should look like ~/armfs/etc, ~/armfs/var, etc... Armfs folder
  • Copy qemu-arm-static to armfs sudo cp -av /usr/bin/qemu-arm-static ~/armfs/usr/bin/
  • Copy resolv.conf to armfs sudo cp -av /run/systemd/resolve/stub-resolv.conf ~/armfs/etc/resolv.conf. Copying Required Files
  • Change root to armfs sudo chroot armfs. Now root filesystem is changed to ARM file system.
  • Add user useradd -G sudo -m -s /bin/bash <username>.
  • Change password echo <username>:<password> | chpasswd.
  • Example:
    • useradd -G sudo -m -s /bin/bash test
    • echo demo:demopass | chpasswd
  • Change password of root user passwd root.
  • Setup hostname and hosts file. Follow commands as below:
echo <hostname> > /etc/hostname
echo	localhost > /etc/hosts
echo	<hostname> >> /etc/hosts

  Setting up User

  • Run apt-get update && apt-get upgrade
  • Install basic tools apt-get install locales dialog perl sudo ifupdown net-tools ethtool udev wireless-tools iputils-ping resolvconf wget apt-utils wpasupplicant nano systemd openssh-server
  • Exit from chroot exit
  • Unmount the file system sudo umount armfs

The end result of these steps will be an ARM-based Ubuntu file system which can be booted with some kernel using virtualization software.

Setup network for ARM system

Network setup is required to share a base network interface in QEMU. Follow Setting up Qemu with a tap interface · GitHub to create bridge interface in the host operating system and use it with QEMU. To make task simple create a shell script for the same. In addition to the above steps, /etc/network/interfaces file needs to be created/modified for the ARM file system. Changes can be made in both the ways, while setting up file system or after booting file system. Add the below lines in the ARM file system’s interfaces file. i.e ~/armfs/etc/network/interfaces

auto eth0
iface eth0 inet dhcp

By this step setting up the ARM machine is completed. Let’s boot up and check if things are working fine.

Boot up ARM system with compiled kernel

Let’s boot up ARM system using previously compiled kernel and file system. Below is the command to boot up the ARM system.

sudo qemu-system-arm -M virt -cpu cortex-a15 -kernel <kernel path>/arch/arm/boot/zImage -nographic -append "-noinitrd root=/dev/sda rw init=/sbin/init" -device virtio-scsi-device,id=scsi -device scsi-hd,drive=hd -drive if=none,id=hd,file=<device path. In my case /dev/sdb1> -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net-device,netdev=net0,mac=52:55:00:d1:55:01

Note: Make sure to change directory paths accordingly. Running Qemu After system is booted, system will prompt for credentials. Provide the credentials that was set while preparing ARM file system. If something fails make sure to go through all the above steps properly.

Bingo!!! ARM system is up and running. Now its time to boot up ARM-based firmware (router, IP Camera, etc.)…

Payatu is at the front line of IoT security research, with a world-renowned team, and cutting edge in house tools like expliot.io. In the last 8+ years, Payatu has performed, security assessment of 100+ IoT product ecosystems and we understand the IoT ecosystem inside out.

Get in touch with us by clicking below “Get Started Today” button.

Get to know more about our process, methodology & team!

Close the overlay

I am looking for
Please click one!