QEMU starts the ARM64 Linux kernel

foreword

This article introduces the use of qemu to simulate the ARM-64bit development board ( there is another article for ARM-32bit ), and starts the ARM64 Linux kernel. The general idea is:

  • Install the qemu-system-aarch64 (ARM-64bit) simulator;
  • Install aarch64-linux-gnu (ARM-64bit) cross compiler;
  • Cross-compile the linux source code to get the ARM64 Linux kernel image;
  • Cross-compile busybox source code, use busybox to make initramfs;
  • Finally, use qemu-system-aarch64 to enable the ARM64 Linux kernel;

My environment:

  • Host hardware platform: x86_64
  • Host operating system: Ubuntu 20.04 (Linux 5.4.0-139-generic)
  • QEMU version: qemu-4.2.1
  • Experimental kernel: linux-5.19
  • busybox version: busybox-1.35.0

Pre-knowledge

virt development board

As of the time of this manuscript, QEMU has simulated more than 70 hardware development boards, please refer to Arm System emulator . But there are so few QEMU emulators for ARM-64bit that virt is the only choice. Virt supports PCI, virtio, newer ARM CPU, and large-capacity memory. Unfortunately, it does not support graphical interfaces. If you don't know what hardware development board to choose, choose virt.

For more detailed content, please refer to:

Why the “virt”board?
Installing Debian on QEMU’s 32-bit ARM “virt”board
Installing Debian on QEMU’s 64-bit ARM “virt”board

Introduction to ARM Processor Family

ARM processor and architecture correspondence table
There are many families of ARM processors, which are 32bit and which are 64bit, please refer to:
List_of_ARM_processors

Many manufacturers use ARM cores to design SOC chips. There are many listed here. You can refer to:
List_of_products_using_ARM_processors

Install qemu-system-aarch64

Install:

$ sudo apt install qemu-system-arm

The qemu-system-arm version of ARM-32bit and the qemu-system-aarch64 version of ARM-64bit will be installed at the same time, check the version number:

$ qemu-system-aarch64 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.24)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

Check the ARM kernel development board supported by qemu. This article chooses the virt development board:

$ qemu-system-aarch64 -M help
Supported machines are:
akita                Sharp SL-C1000 (Akita) PDA (PXA270)
ast2500-evb          Aspeed AST2500 EVB (ARM1176)
ast2600-evb          Aspeed AST2600 EVB (Cortex A7)
borzoi               Sharp SL-C3100 (Borzoi) PDA (PXA270)
canon-a1100          Canon PowerShot A1100 IS
cheetah              Palm Tungsten|E aka. Cheetah PDA (OMAP310)
collie               Sharp SL-5500 (Collie) PDA (SA-1110)
connex               Gumstix Connex (PXA255)
cubieboard           cubietech cubieboard (Cortex-A8)
emcraft-sf2          SmartFusion2 SOM kit from Emcraft (M2S010)
highbank             Calxeda Highbank (ECX-1000)
imx25-pdk            ARM i.MX25 PDK board (ARM926)
integratorcp         ARM Integrator/CP (ARM926EJ-S)
kzm                  ARM KZM Emulation Baseboard (ARM1136)
lm3s6965evb          Stellaris LM3S6965EVB
lm3s811evb           Stellaris LM3S811EVB
mainstone            Mainstone II (PXA27x)
mcimx6ul-evk         Freescale i.MX6UL Evaluation Kit (Cortex A7)
mcimx7d-sabre        Freescale i.MX7 DUAL SABRE (Cortex A7)
microbit             BBC micro:bit
midway               Calxeda Midway (ECX-2000)
mps2-an385           ARM MPS2 with AN385 FPGA image for Cortex-M3
mps2-an505           ARM MPS2 with AN505 FPGA image for Cortex-M33
mps2-an511           ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3
mps2-an521           ARM MPS2 with AN521 FPGA image for dual Cortex-M33
musca-a              ARM Musca-A board (dual Cortex-M33)
musca-b1             ARM Musca-B1 board (dual Cortex-M33)
musicpal             Marvell 88w8618 / MusicPal (ARM926EJ-S)
n800                 Nokia N800 tablet aka. RX-34 (OMAP2420)
n810                 Nokia N810 tablet aka. RX-44 (OMAP2420)
netduino2            Netduino 2 Machine
none                 empty machine
nuri                 Samsung NURI board (Exynos4210)
palmetto-bmc         OpenPOWER Palmetto BMC (ARM926EJ-S)
raspi2               Raspberry Pi 2
raspi3               Raspberry Pi 3
realview-eb          ARM RealView Emulation Baseboard (ARM926EJ-S)
realview-eb-mpcore   ARM RealView Emulation Baseboard (ARM11MPCore)
realview-pb-a8       ARM RealView Platform Baseboard for Cortex-A8
realview-pbx-a9      ARM RealView Platform Baseboard Explore for Cortex-A9
romulus-bmc          OpenPOWER Romulus BMC (ARM1176)
sabrelite            Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)
sbsa-ref             QEMU 'SBSA Reference' ARM Virtual Machine
smdkc210             Samsung SMDKC210 board (Exynos4210)
spitz                Sharp SL-C3000 (Spitz) PDA (PXA270)
swift-bmc            OpenPOWER Swift BMC (ARM1176)
sx1                  Siemens SX1 (OMAP310) V2
sx1-v1               Siemens SX1 (OMAP310) V1
terrier              Sharp SL-C3200 (Terrier) PDA (PXA270)
tosa                 Sharp SL-6000 (Tosa) PDA (PXA255)
verdex               Gumstix Verdex (PXA270)
versatileab          ARM Versatile/AB (ARM926EJ-S)
versatilepb          ARM Versatile/PB (ARM926EJ-S)
vexpress-a15         ARM Versatile Express for Cortex-A15
vexpress-a9          ARM Versatile Express for Cortex-A9
virt-2.10            QEMU 2.10 ARM Virtual Machine
virt-2.11            QEMU 2.11 ARM Virtual Machine
virt-2.12            QEMU 2.12 ARM Virtual Machine
virt-2.6             QEMU 2.6 ARM Virtual Machine
virt-2.7             QEMU 2.7 ARM Virtual Machine
virt-2.8             QEMU 2.8 ARM Virtual Machine
virt-2.9             QEMU 2.9 ARM Virtual Machine
virt-3.0             QEMU 3.0 ARM Virtual Machine
virt-3.1             QEMU 3.1 ARM Virtual Machine
virt-4.0             QEMU 4.0 ARM Virtual Machine
virt-4.1             QEMU 4.1 ARM Virtual Machine
virt                 QEMU 4.2 ARM Virtual Machine (alias of virt-4.2)
virt-4.2             QEMU 4.2 ARM Virtual Machine
witherspoon-bmc      OpenPOWER Witherspoon BMC (ARM1176)
xilinx-zynq-a9       Xilinx Zynq Platform Baseboard for Cortex-A9
xlnx-versal-virt     Xilinx Versal Virtual development board
xlnx-zcu102          Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5Fs based on the value of smp
z2                   Zipit Z2 (PXA27x)

Look at the list of CPUs supported by the virt development board. This article takes the 64-bit cortex-a57 as an example:

$ qemu-system-aarch64 -M virt --cpu help
Available CPUs:
  arm1026
  arm1136
  arm1136-r2
  arm1176
  arm11mpcore
  arm926
  arm946
  cortex-a15
  cortex-a53
  cortex-a57
  cortex-a7
  cortex-a72
  cortex-a8
  cortex-a9
  cortex-m0
  cortex-m3
  cortex-m33
  cortex-m4
  cortex-r5
  cortex-r5f
  max
  pxa250
  pxa255
  pxa260
  pxa261
  pxa262
  pxa270-a0
  pxa270-a1
  pxa270
  pxa270-b0
  pxa270-b1
  pxa270-c0
  pxa270-c5
  sa1100
  sa1110
  ti925t

Install cross-compilation tools

We are developing under the X86 platform, the target platform is the arm architecture, and the cross-compilation tool chain needs to be installed. The cross compilers for arm-linux mainly include:

  • arm-linux-gnueabi and arm-linux-gnueabihf for ARM-32bit.
  • aarch64-linux-gnu for ARM-64bit.

For the differences between the versions of the cross compiler, please refer to " The Differences Between the Versions of the Arm Series Cross Compilers ".

Install the aarch64-linux-gnu version of ARM-64bit:

$ sudo apt install gcc-aarch64-linux-gnu

View version:

$ aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Cross compile ARM64 Linux kernel

Download the source code:

$ mkdir ~/kvm-arm
$ cd ~/kvm-arm/
$ wget https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-5.19.tar.gz
$ tar -xf linux-5.19.tar.gz
$ cd linux-5.19/
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=build defconfig
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=build -j8

illustrate:

  • ARCH: Specify the target CPU architecture;
  • CROSS_COMPILE: Specify a cross compiler;
  • O=build: O is the abbreviation of Out, which means that the compiled output files are placed in the build directory, not mixed with the source code, and the source code is kept clean.
  • Only defconfig configuration is optional during make, because there is one and only defconfig in the linux-5.19/arch/arm64/configs/ directory.

Check the original kernel file vmlinux compiled by the kernel, which is the ARM 64-bit version.

$ file build/vmlinux
build/vmlinux: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=f2a5fd51bd2d59f90b7b26b8926f5afdeab60f36, not stripped

vmlinux cannot directly boot the Linux system. It can boot the Linux system from the Image file (uncompressed version) or Image.gz (compressed version). The kernel image used below is Image:

$ file build/arch/arm64/boot/Image
build/arch/arm64/boot/Image: MS-DOS executable PE32+ executable (EFI application) Aarch64 (stripped to external PDB), for MS Windows

$ file build/arch/arm64/boot/Image.gz 
build/arch/arm64/boot/Image.gz: gzip compressed data, max compression, from Unix, original size modulo 2^32 36112896

Cross compile ARM64 Busybox

$ mkdir ~/kvm-arm
$ cd ~/kvm-arm/
$ wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
$ tar -xf busybox-1.35.0.tar.bz2
$ cd busybox-1.35.0/

$ export ARCH=arm64
$ export CROSS_COMPILE=aarch64-linux-gnu-
$ make menuconfig

# 修改配置,选中如下项目,静态编译
# Settings –> Build Options –> [*] Build static binary(no share libs)

# 反选如下项目,否则后续qemu执行会提示 /bin/sh:can't access tty;job control turned off
# Shells  --->  [ ]   Job control

$ make -j `nproc`
$ make install

After installation, it will be installed to the _install/ directory of the source code directory by default:

$ ls _install/
bin  linuxrc  sbin  usr

The most important thing is _install/bin/busybox, the others are link files.

$ file _install/bin/busybox 
_install/bin/busybox: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=3768162c347859f16ab4f0b01a48fb8c0502774d, for GNU/Linux 3.7.0, stripped

If the following prompts appear during compilation, ignore them:

Trying libraries: m resolv rt
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
 Library rt is not needed, excluding it
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
Final link with: m resolv

Use busybox to make initramfs

Use busybox to quickly make initramfs.

Create the inti startup script in the virtual rootfs and give it executable permissions:

$ cd ~/kvm-arm/busybox-1.35.0/_install/
$ mkdir proc sys dev tmp
$ touch init
$ chmod +x init

Script content:

#!/bin/sh

# 挂载一些必要的文件系统
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
mount -t devtmpfs none /dev

echo
echo "Hello 64-bit ARM Linux"

# 显示开机消耗时间
echo "This boot took $(cut -d' ' -f1 /proc/uptime) seconds"
echo

# 停留在控制台
exec /bin/sh

Make the initramfs file, which is a file packaged by cpio and compressed by gzip. It is a memory file system in cpio format.

$ find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz

Boot ARM64 Linux Kernel Using QEMU

ARM Linux kernel image and initramfs are ready, you can use QEMU to start the linux kernel.

Start QEMU in the character interface mode, and log output to the console at the same time:

$  qemu-system-aarch64 \
		-M virt \
		-cpu cortex-a57 \
		-smp 8 \
		-m 8G \
		-kernel ./linux-5.19/build/arch/arm64/boot/Image \
		-initrd ./busybox-1.35.0/initramfs.cpio.gz \
		-nographic \
		-append "init=/init console=ttyAMA0"

QEMU parameter description (for more, please refer to: Standard options ):

  • -M: Specifies the simulated development board, which can be viewed through qemu-system-aarch64 M help. As of the time of writing, only virt supports 64-bit ARM.
  • -cpu: Specify the simulated cpu, which can be viewed through qemu-system-aarch64 -M virt --cpu help, here select cortex-a57.
  • -smp: Specify the number of cpu cores, you can use the nproc command to check after startup.
  • -m: Specify the memory size, virt can support large memory, you can use the free -h command to check after startup.
  • -kernel: Specifies the kernel image to start;
  • -initrd: Specify the memory file system to start;
  • -append: The startup parameters passed to the kernel; you can use the cat /proc/cmdline command to check after startup.
  • -nographic: start the character interface (do not start the graphical interface), redirect the output to the host command line, and use it in combination with the parameter console=ttyAMA0;

9 Reference

Supongo que te gusta

Origin blog.csdn.net/benkaoya/article/details/129509269
Recomendado
Clasificación