先发两个感慨,一个是感概是学如逆水行舟不进则退,最近几年太关注与上层应用、微服务、大数据等前沿技术,而没有再在底层基础技术上下功夫,今天重新去做系统级底层的事情恍然若失。一个感慨是技术变化真的太快,几年前arm上跑的程序都需要自己编译,系统需要自己订制,现在随便下载就可以在很多硬件上跑起来。

回归正题,Qemu原来只是一个虚拟化工具,现在它支持用户模式的进程虚拟化。这是什么意思呢?就是说你可以把一个可执行程序放到你的宿主机上,Qemu就可以根据ELF二进制的格式的机器码转换成对应的cpu的格式直接运行。

运行静态编译应用

举个简单的例子,用gcc交叉静态编译一个在arm上运行的helloworld。

arm-linux-gnueabi-gcc -static hello.c -o hello

这时直接运行 ./hello 会出现下面的错误。
在这里插入图片描述
这是我们有三个方法将程序运行起来,一将程序放到arm开发板上,一是启动qemu的arm虚拟机,一个就是采用qmeu的user mode运行。

qemu-user-static 是qemu用户空间运行工具,直接安装 yum install qemu-user-static 即可。

测试运行一下:

qemu-aarch64 hello

正常运行。

运行动态编译应用

如果是动态编译的程序可能会依赖相关的host的库,将相应的库复制到某个目录下,这里我放到了当前文件夹的./lib 目录, 尝试运行。

LD_LIBRARY_PATH=./lib /usr/bin/qemu-aarch64 hello

或者

/usr/bin/qemu-aarch64 ld-linux-aarch64.so.1 hello --library-path ./lib 

内核自动判断运行不通平台应用

前面的操作稍显麻烦,你必须要知道这个应用的平台。使用内核自动判断ELF文件的平台运行通过binfmt_misc内核模块来实现。安装yum install qemu-user-binfmt 后直接运行就可以

ld-linux-aarch64.so.1 hello --library-path ./lib 

总结

qemu这种运行模式与docker有什么区别?docker有独立的user namespace,而qemu user mode只是一个进程。qemu 可以运行不通cpu架构的应用,而docker却不可以。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐