Skip to content

Instantly share code, notes, and snippets.

@olegslavkin
Last active August 13, 2020 10:27
Show Gist options
  • Save olegslavkin/f25bff4ebf7a10c22f5c1327a911086a to your computer and use it in GitHub Desktop.
Save olegslavkin/f25bff4ebf7a10c22f5c1327a911086a to your computer and use it in GitHub Desktop.
Setup ARM Development Environment with QEMU

docker

mkdir ~/Downloads/arm/
cd ~/Downloads/arm/
docker run -it --rm -v $(pwd):/mnt --privileged -w /mnt --name arm ubuntu

prepare container

apt update
apt install gcc-arm-linux-gnueabi python gcc pkg-config libglib2.0-dev libpixman-1-dev libncurses-dev bison flex wget git bc -y

Download and compile qemu

cd /mnt
wget https://download.qemu.org/qemu-3.1.0.tar.xz
tar xvf qemu-3.1.0.tar.xz
cd qemu-3.1.0/
./configure --prefix=$(pwd)/../ \
--target-list=arm-softmmu,arm-linux-user \
--enable-debug \
--extra-cflags="-g3" \
--extra-ldflags="-g3" \
--disable-strip --disable-pie
make -j $(nproc) && make install

Download and compile u-boot

Machine: vexpress_ca9x4

cd /mnt
git clone git://git.denx.de/u-boot.git
cd u-boot
(optional) git pull
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_ca9x4_defconfig O=../u-boot-build
make -j $(nproc) O=../u-boot-build

Machine: virt

make mrproper O=../u-boot-build
make qemu_arm_defconfig O=../u-boot-build
(optional) make menuconfig O=../u-boot-build
make -j $(nproc) O=../u-boot-build

Download and compile Xilinx U-Boot

apt install -y libssl-dev
cd /mnt
git clone https://github.com/Xilinx/u-boot-xlnx.git
cd u-boot-xlnx
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
(optional) make mrproper O=../u-boot-build-xlnx
make zynq_zc702_defconfig O=../u-boot-build-xlnx
make -j $(nproc) O=../u-boot-build-xlnx

change PATH

cd /mnt
export PATH=$(pwd)/bin:$PATH

Download and compile Linux Kernel

apt install wget bc -y
cd /mnt
mkdir -p linux-build
wget https://mirror.yandex.ru/pub/linux/kernel/v4.x/linux-4.20.8.tar.xz
tar xf linux-4.20.8.tar.xz
rm linux-4.20.8.tar.xz
cd linux-4.20.8
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_defconfig O=../linux-build
make menuconfig O=../linux-build
make -j $(nproc) O=../linux-build

Download and compile Busybox

cd /mnt
mkdir busybox-build
wget https://busybox.net/downloads/busybox-1.30.1.tar.bz2
tar xvf busybox-1.30.1.tar.bz2
rm *.tar.*
cd busybox-1.30.1/
CROSS_COMPILE=arm-linux-gnueabi- make defconfig O=../busybox-build/
CROSS_COMPILE=arm-linux-gnueabi- make menuconfig O=../busybox-build/

Busybox Settings —> Build Options —> [*] Build BusyBox as a static binary (no shared libs)

CROSS_COMPILE=arm-linux-gnueabi- make -j $(nproc) O=../busybox-build/
CROSS_COMPILE=arm-linux-gnueabi- make install O=../busybox-build/

Prepare rootfs

cd /mnt
mkdir rootfs
mkdir rootfs/lib

Create

cd /mnt/busybox-build
mkdir -p _install/proc/
mkdir -p _install/sys/
mkdir -p _install/tmp/
mkdir -p _install/root/
mkdir -p _install/var/
mkdir -p _install/mnt/
mkdir -p _install/dev/
mkdir -p _install/home/
mkdir -p _install/etc/init.d/
cp busybox-build/_install/* -r rootfs/

Create dev

cd /mnt
mkdir -p rootfs/dev
mknod rootfs/dev/tty1 c 4 1  
mknod rootfs/dev/tty2 c 4 2  
mknod rootfs/dev/tty3 c 4 3  
mknod rootfs/dev/tty4 c 4 4

Create image

cd /mnt
dd if=/dev/zero of=arm.img bs=1M count=32  
mkfs.ext3 arm.img  

Create image Xilinx (ref.3)

# TODO: add url to empty image
apt install -y dosfstools
cd /mnt
fdisk sd-2G.raw
Command (m for help): p
Disk sd-2G.raw: 2 GiB, 2097152000 bytes, 4096000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot   Start     End Sectors  Size Id Type
sd-2G.raw1 *       2048 2099199 2097152    1G 83 Linux
sd-2G.raw2      2099200 4095999 1996800  975M 83 Linux

Command (m for help): w
The partition table has been altered.
Syncing disks.

losetup /dev/loopX sd-2G.raw -o 512
mkfs.vfat /dev/loopX
losetup /dev/loopX sd-2G.raw -o 67072
mkfs.ext4 -L root /dev/loopX
mkdir u-boot-build-xlnx/1
mkdir u-boot-build-xlnx/2
mount /dev/loopX u-boot-build-xlnx/1
cp u-boot-build-xlnx/u-boot.img u-boot-build-xlnx/1

Copy busybox to img

cd /mnt
mkdir tmpfs
mount -t ext3 -o loop arm.img tmpfs  
cp -r rootfs/*  tmpfs/  
umount tmpfs

Start qemu

Linux kernel

cd /mnt
qemu-system-arm -M vexpress-a9 -m 256 -dtb linux-build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
-kernel linux-build/arch/arm/boot/zImage -nographic \
-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
-sd arm.img

u-boot (as kernel)

cd /mnt
qemu-system-arm -M vexpress-a9 -m 256 -kernel u-boot-build/u-boot -nographic

u-boot (as bios)

cd /mnt
qemu-system-arm -M virt -m 256 -bios u-boot-build/u-boot.bin -nographic

Exit from qemu

For terminate qemu press: ctrl+a x

Debug

Start qemu with debug options

qemu-system-arm -s -S -M vexpress-a9 -m 256 -dtb linux-build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
-kernel linux-build/arch/arm/boot/zImage -nographic \
-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
-sd arm.img

From host OS

https://www.kernel.org/doc/html/v4.20/dev-tools/gdb-kernel-debugging.html

docker exec -it -w /mnt arm bash -c 'apt install -y gdb-multiarch && gdb-multiarch linux-build/vmlinux'  // where xxxxxxxxxxxx Container ID
add-auto-load-safe-path linux-build/
target extended-remote :1234
b start_kernel
c

Reference

  1. http://140.120.7.21/LinuxRef/DIYBigData/ARMUbootQemu.html
  2. https://github.com/u-boot/u-boot/blob/master/doc/README.qemu-arm
  3. https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842385/How+to+format+SD+card+for+SD+boot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment