用Qemu模拟ARM

本文详细介绍了如何使用Qemu模拟ARM,包括Qemu-arm和qemu-system-arm的区别,如何运行Linux内核,Bootloader的类型,以及裸机编程的概念。通过示例展示了从编写代码到启动内核的过程,涉及编译链、链接脚本和启动代码的编写,并解释了在Qemu中运行u-boot的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Qemu模拟ARM(1)

前面已经安装并配置了编译链和qemu,现在可以用qemu来模拟arm平台了。

1. Hello, Qemu!

输入下面的代码:

hello.c - hello.c

#include<stdio.h>
int main()
{
         
         
    printf("Hello, Qemu!\n");
    return 0;
}

编译并运行:

$ arm-none-linux-gnueabi-gcc -o hello hello.c -static
$ qemu-arm ./hello
$ file hello
hello: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), \
 statically linked, for GNU/Linux 2.6.16, not stripped

不加-static变量的话,运行时则需要使用-L选项链接到相应的运行库

$ qemu-arm -L /home/dash/CodeSourcery/\
Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/\
arm-none-linux-gnueabi/libc/  ./hello_1 
Hello, Qemu!
$ file hello_1
hello_1: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV),\
 dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped

动态编译和静态编译生成的文件大小差别:

$ ls -l -h
total 656K
-rwxr-xr-x 1 dash root 640K Jul  7 18:46 hello
-rwxr-xr-x 1 dash root 6.6K Jul  7 18:48 hello_1

小插曲1:

系统里安装了两套编译链arm-none-eabi-和arm-none-linux-eabi-,很容易让人混淆,可参考编译链的命名规则:

arch(架构)-vendor(厂商名)–(os(操作系统名)–)abi(Application Binary Interface,应用程序二进制接口)

举例说明:

  • x86_64-w64-mingw32 = x86_64 “arch”字段 (=AMD64), w64 (=mingw-w64 是”vendor”字段), mingw32 (=GCC所见的win32 API)
  • i686-unknown-linux-gnu = 32位 GNU/linux编译链
  • arm-none-linux-gnueabi = ARM 架构, 无vendor字段, linux 系统, gnueabi ABI.
  • arm-none-eabi = ARM架构, 无厂商, eabi ABI(embedded abi)

两种编译链的主要区别在于库的差别,前者没有后者的库多,后者主要用于在有操作系统的时候编译APP用的。前者不包括标准输入输出库在内的很多C标准库,适合于做面向硬件的类似单片机那样的开发。因而如果采用arm-none-eabi-gcc来编译hello.c会出现链接错误。

小插曲2:

qemu-arm和qemu-system-arm的区别:

  • qemu-arm是用户模式的模拟器(更精确的表述应该是系统调用模拟器),而qemu-system-arm则是系统模拟器,它可以模拟出整个机器并运行操作系统
  • qemu-arm仅可用来运行二进制文件,因此你可以交叉编译完例如hello world之类的程序然后交给qemu-arm来运行,简单而高效。而qemu-system-arm则需要你把hello world程序下载到客户机操作系统能访问到的硬盘里才能运行。

2. 使用qemu-system-arm运行Linux内核

从www.kernel.org下载最新内核,而后解压

$ tar xJf linux-3.10.tar.xz
$ cd linux-3.10
$ make ARCH=arm versatile_defconfig
$ make menuconfig ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

上面的命令指定内核架构为arm,交叉编译链为arm-none-linux-gnueabi, 需要在make menucon

### 关于Linux设备驱动开发中使用QEMU模拟ARM的相关资料 #### QEMU简介及其在ARM环境下的应用 QEMU是一个开源的仿真器和虚拟机监视器,支持多种架构。对于ARM平台而言,QEMU能够提供一个完整的硬件抽象层来运行未经修改的操作系统镜像[^1]。 #### 安装与配置QEMU用于ARM Linux平台 为了利用QEMU进行ARM Linux平台上的工作,在本地环境中需先完成QEMU软件包的获取与设置: - 下载并安装适合操作系统的QEMU版本; - 验证安装是否成功通过命令`qemu-system-arm --version`查看版本号; 上述过程确保了后续实验的基础环境搭建完毕。 #### 编译适用于QEMUARM内核 针对特定需求定制化的Linux内核编译是必要的步骤之一。这涉及到几个方面的工作: - 获取目标平台对应的内核源码树; - 对其进行适当配置以适应所选的机器类型(如Versatile Express等); - 执行实际构建流程得到可用于加载执行的目标文件uImage或zImage形式; 此阶段完成后即可准备启动测试实例。 ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- ``` #### 构建最小化根文件系统 创建精简版rootfs有助于减少不必要的复杂度,并加快迭代速度。BusyBox项目提供了便捷的方式实现这一点: - 解压官方发布的预构建tarball至指定位置作为初始模板; - 修改其中的关键路径指向以便匹配预期布局; - 将调整后的结构打包成img格式供下一步骤调用; 最终产物应当包含基本shell工具集以及任何额外依赖项。 #### 启动QEMU会话连接到新建立的ARM环境 借助之前准备工作积累下来的资源,现在可以尝试开启一次交互式的session来进行初步验证: ```bash qemu-initrd rootfs.img -append "console=ttyAMA0,38400 kgdboc=ttyAMA0,38400" -serial stdio ``` 这条指令指定了要使用的machine model、kernel image还有ramdisk archive的同时也设置了串口重定向方便观察输出日志流。 #### 加入外设驱动的支持 当基础框架已经稳固下来以后,则可进一步探索如何集成自定义硬件组件的能力。具体做法如下所示: - 移步至对应driver source code所在的位置; - 应用交叉编译链生成适配当前体系结构的对象库; - 把产出物安置进先前预备好的filesystem内部相应地方去; 如此这般便实现了功能扩展的目的[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值