ILD

build & run aarch64 tiny kernel on qemu
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2024-12-18 站点:Inside Linux Development

使用qemu来学习linux内核是一个很好的方法,效率很高,不需要开发板。可以快速编译运行。

本文编译一个最新的longterm内核6.12,arch为arm64。qemu系统为:qemu-system-aarch64。


1 安装qemu程序

$ sudo dnf install qemu-system-aarch64


2 准备交叉工具链

我自己使用crosstool-ng 1.26编译了一个arm64的工具链。网上也有很多编译好的工具链,比如buildroot有,可以直接使用。


3 编译内核

编译内核需要指定两个环境变量:下面我的编译指令,我省略了这两个环境变量的定义:

ARCH=arm64 CROSS_COMPILE=/home/yuan/toolchain/crosstool-mt7981/bin/aarch64-linux-gnu-


第一种,使用默认配置,然后合并arch/arm64/configs/virt.config,virt.config会删除很多其它的配置,加快编译时间。

$ make defconfig

$ make virt.config


第二种,使用tinyconfig,这个是最小的内核。

$ make tinyconfig


编译:

$ make Image -j12


4 Qemu运行

运行命令如下:

$ qemu-system-aarch64 -machine virt -cpu cortex-a53 -kernel arch/arm64/boot/Image -nographic


-machine 指定模拟的设备类型。


使用help可以查看所有的设备类型。

$ qemu-system-aarch64 -machine help


这里我们使用virt,这个虚拟设备类型,virt是qemu自己标准的虚拟设备,而且指向最新版本的virt设备:

virt-9.0             QEMU 9.0 ARM Virtual Machine

virt                 QEMU 9.1 ARM Virtual Machine (alias of virt-9.1)

virt-9.1             QEMU 9.1 ARM Virtual Machine


-cpu 指定cpu的类型,


使用help可以查看所有的cpu。

$ qemu-system-aarch64 -machine virt -cpu help


cpu默认为32位的cortex-a15,这里我们指定64位架构的cortex-a53


-kernel 指定内核的路径,这里我们使用Image。

-nographic,指定不使用图形界面,这样qemu会使用当前终端作为输入输出。


5 tinyconfig无输出问题

tinyconfig编译非常快,几十秒就可以完成内核的编译,编译后的内核也非常小,

没压缩的Image为2.4M,压缩后的Image.lzma仅有655KB


$ ls arch/arm64/boot/ -l

-rwxr-xr-x. 1 yuan yuan 2539528 Dec 17 18:06 Image

-rw-r--r--. 1 yuan yuan  670951 Dec 17 18:06 Image.lzma


但是运行会没有输出,我们需要开启一些virt的配置,因为tinyconfig没有开启驱动和printk等支持。


qemu在启动kernel的时候,会自动加载它内置的dtb。可以使用dumpdtb指令存储dtb到本地文件,如:

$ qemu-system-aarch64 -machine virt,dumpdtb=virt.dtb -cpu cortex-a53


然后我们可以转成dts看看:

$ dtc -i dtb virt.dtb > virt.dts


可以得到串口设备的dts,virt使用的是PL011串口。


        pl011@9000000 {

                clock-names = "uartclk", "apb_pclk";

                clocks = <0x8000 0x8000>;

                interrupts = <0x00 0x01 0x04>;

                reg = <0x00 0x9000000 0x00 0x1000>;

                compatible = "arm,pl011", "arm,primecell";

        };


        aliases {

                serial0 = "/pl011@9000000";

        };


因此我们开启下面几个配置项即可:

CONFIG_PRINTK

CONFIG_TTY

CONFIG_SERIAL_AMBA_PL011

CONFIG_SERIAL_AMBA_PL011_CONSOLE


编译后启动,可以看到内核输出了启动信息:


$ qemu-system-aarch64 -machine virt -cpu cortex-a53 -kernel arch/arm64/boot/Image -nographic

Booting Linux on physical CPU 0x0000000000 [0x410fd034]

Linux version 6.12.1+ (yuan@fedora) (aarch64-linux-gnu-gcc (crosstool-NG 1.26.0) 13.2.0, GNU ld (crosstool-NG 1.26.0) 2.40) #5 SMP Tue Dec 17 18:0

6:05 CST 2024

random: crng init done

Machine model: linux,dummy-virt

Zone ranges:

  Normal   [mem 0x0000000040000000-0x0000000047ffffff]

Movable zone start for each node

Early memory node ranges

  node   0: [mem 0x0000000040000000-0x0000000047ffffff]

Initmem setup node 0 [mem 0x0000000040000000-0x0000000047ffffff]

psci: probing for conduit method from DT.

psci: PSCIv1.1 detected in firmware.

psci: Using standard PSCI v0.2 function IDs

psci: Trusted OS migration not required

psci: SMC Calling Convention v1.0

percpu: Embedded 16 pages/cpu s35488 r0 d30048 u65536

Detected VIPT I-cache on CPU0

CPU features: kernel page table isolation disabled by kernel configuration

alternatives: applying boot alternatives

Kernel command line:

Dentry cache hash table entries: 16384 (order: 5, 131072 bytes, linear)

Inode-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)


由于没有rootfs,所以内核启动后会panic。后续移植一个initramfs,这样就可以快速的调试和学习内核了。按CTRL+a,然后再按x,可以退出qemu。


参考:

generic virtual platform (virt). https://www.qemu.org/docs/master/system/arm/virt.html


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.