盗梦空间:在X86平台上构建ARM模拟器-程序员宅基地

技术标签: ubuntu  Linux系统开发  arm  

需求来源于如何构建arm平台的Ubuntu文件系统。

我们希望在ARM开发板上使用Ubuntu系统,那么就需要构建一个Ubuntu的根文件系统,然后可基于该基础文件系统,进一步扩展开发。比如,可以使用不同的桌面版本,安装需要的arm源安装包等。

当然,也可能是,大部分的需求更多来源于如何在host系统上构建arm环境,编译arm程序。

殊途同归,问题都归结为一点,即如何在host系统上构建arm模拟环境

从上述构建文件系统需求出发,查找资料。发现,搜索到的资料无一例外的都提到了chroot命令和qemu-arm-static安装包。

具体思路是,先安装qemu-arm-static安装包,然后构建一个目标平台的根文件系统(其实是根文件系统目录,包含有常规的一些可执行程序)。我们将该根文件系统作为基础裸根文件系统。这一基础根文件系统可从Ubuntu官网上下载。注意,这个基础根文件系统里面自带的arm平台程序,是在ubuntu官网上打包好的,我们只需要根据硬件平台特点,下载对应的包解压即可。比如是32位还是64位,是否支持硬件浮点计算等。如果你有自己待验证的程序,也可以放进去,只要保证是基于对应硬件平台的交叉工具链编译的。

https://ubuntu.com/

有了上述基础文件系统目录后,还需要将主机的proc  sys  dev  pts等目录挂载到目标文件系统对应的路径下,最终实际切换到目标系统硬件上时,proc  sys等是所在目标硬件上运行的内核生成的,设备目录也是目标硬件内核动态监测生成或者极少的是通过应用层udev工具生成。这些东西并不天然的包含在镜像文件中。

也就是到时候,这些目录下的系统信息和设备信息还是基于主机系统的,这样便于我们做一些操作,毕竟是模拟的。后面了解模拟器工作原理后,你就可以更深刻的理解这一点。

之后,将安装qemu-arm-static后下载的usr bin目录下的qemu-arm-static 或者qemu-aarch-static程序拷贝到目标文件系统对应目录下。

至此,我们在host上构建了一个目标平台的根目录,这个根目录包含三部分:

1 原始的ubuntu系统的基于arm平台的基础程序

2 主机host系统挂载过去的proc 和 sys等目录

3 下载的qemu-arm-static或aarch(64位)对应目录下的程序

上述工作准备好后,执行chroot切换到目标平台根目录。如此,即切换到arm环境,也就是qemu构建的模拟器环境

按照上述流程执行,确实进入了arm模拟器环境。但是疑问来了,chroot是怎么就切换到arm模拟器环境了,这中间到底发生了什么?

chroot本身是一个命令,可以完成根文件目录的切换,也就是将新的目录作为根目录,挂载到系统中。

这样做,就构建了一个比较弱的隔离环境。说是比较弱的,是因为此时只是根目录相关的路径变换了,而系统的很多内部资源仍然是全局可见的。

当然,需求本身就是多样的,如果用户只是想在独立的目录下进行编译安装更新等操作,chroot的功能则很好的契合了这种需求,再多一些隔离操作,反而显得多余了。

但是,仅从切换根目录路径这一点来看,chroot似乎还不至于完成平台的切换。再多一点细节,chroot切换根目录后,会默认执行bash程序,构建新的交互环境。当然,调用者也可以指定要执行的程序。

那从这个逻辑思路来走的话,chroot只能完成将根目录切换到为arm环境准备的根目录,并执行arm环境根目录下的bash程序。且这个bash程序应该是基于arm指令的,不能够成功执行才对。

但是我们看到实际结果是成功切换到arm模拟器环境了。

这中间的中间发生了什么?一定是有一个纽带,完成了关联

再回到原始流程上,除了chroot外,我们发现,需要安装qemu-arm-static并拷贝这个程序到目标平台的usr bin 目录下,即跟其安装目录一致。为什么会有这个要求

再继续搜索资料。

https://blog.csdn.net/weixin_35511255/article/details/117550321中提到了binfmt_misc,

https://hblok.net/blog/posts/2014/02/06/chroot-to-arm/ 外部的一些资料也提到了,之前看资料时,对这些忽略了。

查看binfmt_misc的说明,大意是一个二进制格式的适配系统。类似windows平台上,根据后缀选择或者说匹配执行程序这样一个功能。

而linux下的这个系统,也具有这个功能,而且不仅可以通过后缀匹配,还可以根据文件魔术字段匹配。

查看系统下该目录下的相关信息

root@ubuntu:/proc/sys/fs/binfmt_misc# ls -l

total 0

-rw-r--r-- 1 root root 0 Nov 23 19:47 python2.7

-rw-r--r-- 1 root root 0 Nov 23 19:47 python3.6

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-aarch64

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-alpha

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-arm

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-armeb

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-cris

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-m68k

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-microblaze

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-mips

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-mips64

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-mips64el

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-mipsel

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-ppc

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-ppc64

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-ppc64abi32

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-ppc64le

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-s390x

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-sh4

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-sh4eb

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-sparc

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-sparc32plus

-rw-r--r-- 1 root root 0 Nov 23 19:47 qemu-sparc64

--w------- 1 root root 0 Nov 23 19:47 register

-rw-r--r-- 1 root root 0 Nov 23 19:47 status

root@ubuntu:/proc/sys/fs/binfmt_misc#

可以看到qemu注册到里面,所以qemu是使用了该系统。

那么现在可以猜测,qemu安装时应该是注册了对arm架构程序的支持。也就是,如果目标文件是arm架构的(通过可执行文件里的magic字段匹配),则使用其对应的程序来解释执行。

这里的register文件只能写,不能读,但是其他文件提供了注册的信息。我们来看看

root@ubuntu:/proc/sys/fs/binfmt_misc# cat qemu-arm

enabled

interpreter /usr/bin/qemu-arm-static

flags: OC

offset 0

magic 7f454c4601010100000000000000000002002800

mask ffffffffffffff00fffffffffffffffffeffffff

root@ubuntu:/proc/sys/fs/binfmt_misc# cat qemu-aarch64 

enabled

interpreter /usr/bin/qemu-aarch64-static

flags: OC

offset 0

magic 7f454c460201010000000000000000000200b700

mask ffffffffffffff00fffffffffffffffffeffffff

root@ubuntu:/proc/sys/fs/binfmt_misc#

可以看到,这两个应该都是通过magic过滤的,并且enable了。我们记下这里的magic头几个字节内容,后面会用到。7f 45 4c 46

我们执行以下arm架构的程序看看

root@ubuntu:/proc/sys/fs/binfmt_misc# /home/work/Ubuntu/bin/bash 

/lib/ld-linux-aarch64.so.1: No such file or directory

提示的是动态链接库找不到。

status文件提供了全局的使能功能,我们关闭所有匹配,再来看看

root@ubuntu:/proc/sys/fs/binfmt_misc# echo 0 > status 

root@ubuntu:/proc/sys/fs/binfmt_misc# 

root@ubuntu:/proc/sys/fs/binfmt_misc# cat status 

disabled

root@ubuntu:/proc/sys/fs/binfmt_misc# /home/work/Ubuntu/bin/bash 

bash: /home/work/Ubuntu/bin/bash: cannot execute binary file: Exec format error

root@ubuntu:/proc/sys/fs/binfmt_misc#

此时执行提示的是格式不对,不是库找不到了。到此,我们可以总结出,enable时,虽提示库找不到,但那是程序运行过程的错误,说明程序的格式匹配是成功了,只是在当前文件系统路径下,无法找到对应的动态库。而disable后,一开始就是可执行文件是无法运行的。

这就说明,chroot本身的功能并没有差异,当切换路径后,执行默认bash程序时,系统判断到是arm文件(通过qemu注册的匹配检测),就调用usr  bin目录(上述注册信息中使用的,这也是为啥要拷贝到对应目录的原因)下的qemu模拟器程序来执行

最终,模拟器程序将arm指令翻译为host系统的x86指令,进行执行,从而完成模拟执行。

bash执行时及之后所有调用链上的程序都是由上述模拟器程序模拟后在主机系统中执行的。

如此,就完成了一种弱的平台环境暂时切换的功能。

为了进一步的验证,我们看看arm平台下bash程序的开头几十个字节

root@ubuntu:/proc/sys/fs/binfmt_misc# hexdump -n 64 /home/work/Ubuntu/bin/bash

0000000 457f 464c 0102 0001 0000 0000 0000 0000

0000010 0003 00b7 0001 0000 2610 0003 0000 0000

0000020 0040 0000 0000 0000 83a0 0012 0000 0000

0000030 0000 0000 0040 0038 0009 0040 001b 001a

0000040

可以看到 45 7f 46 4c等几个字节,跟前面注册里的magic可以匹配上,问题得到验证。

chroot应该只是切换当前的shell,甚至跟用户都非强绑定,当前shell切换到arm模拟器环境后,我们还可以继续登录原始host,在原始host的正常目录下进行正常的操作。

在当前shell中执行exit就退出chroot切换的环境,回到host系统。至此,进出模拟器的过程就通过chroot命令完成了。

有了上面的基础,我们就可以在arm模拟器中安装arm包,然后做出属于自己的定制跟文件系统,将其刷机到自己的开发板,实现自己的专属系统。

ENJOY......

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wwwyue1985/article/details/123975969

智能推荐

Oracle 史上最详细的分区表详解_oracle 将现有表改成分区表 并将索引调整为全局索引-程序员宅基地

文章浏览阅读1.8w次,点赞30次,收藏238次。一、分区表的概念分区表:当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个“表空间”(物理文件上),这样查询数据时,不至于每次都扫描整张表而只是从当前的分区查到所要的数据大大提高了数据查询的速度。"""分区表的具体作用"""Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外_oracle 将现有表改成分区表 并将索引调整为全局索引

hihoCoder-第115周-网络流一·Ford-Fulkerson算法_ford–fulkerson算法例题-程序员宅基地

文章浏览阅读854次。题目链接点这里题目1 : 网络流一·Ford-Fulkerson算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述小Hi和小Ho住在P市,P市是一个很大很大的城市,所以也面临着一个大城市都会遇到的问题:交通拥挤。小Ho:每到周末回家感觉堵车都是一种煎熬啊。小Hi:平时交通也还好,只是一到上下班的高峰期就会比较拥挤。小Ho:要是能够限制一下车的数量就好了,不知道_ford–fulkerson算法例题

Qt基础 QT QTextEdit自动滑动_pyqt5中,qtextedit的消息实现滑条,能上滑定位历史消息-程序员宅基地

文章浏览阅读521次,点赞3次,收藏3次。获取QTextEdit的QScrollBar,然后再构造函数算出QScrollBar歩长pageStep(这里不知道为什么在其他地方算的步长很大),然后就定时器QScrollBar++或者--啦。最近公司在做一个提词项目,本来对这里功能难易感觉属于一般的,谁知道碰到一个很简单问题,搞了半天,先喷一下百度浏览器 不知道是算法越来越垃圾,还是我检索的有问题,还是说这个问题很难。那个End不用看意思就知道光标移动到文章尾部,还自动滚动,滚尼ma呢。严重标题与内容不符,别用猪脑写文章好不好!_pyqt5中,qtextedit的消息实现滑条,能上滑定位历史消息

掌控安全 暖冬杯 CTF Writeup By AheadSec-程序员宅基地

文章浏览阅读752次,点赞9次,收藏29次。本来结束时发到了学校AheadSec的群里面了的,觉得这比赛没啥好外发WP的,但是有些师傅来问了,所以还是发一下吧。

如何让vscode中的cmakelist高亮显示_linux vscode 代码高亮-程序员宅基地

文章浏览阅读4.5k次。因为甚少有人正确回答,其实很简单,安装插件cmake,居然被少有的几篇博客带偏,最后bing了国际版得到国际友人的指点https://github.com/microsoft/vscode-cmake-tools/issues/534没啥就是安装插件cmake_linux vscode 代码高亮

java 换行符 常量_6.java常量-程序员宅基地

文章浏览阅读1.1k次。Java中常量的分类:整数常量 : 所有整数小数常量 : 所有小数布尔常量 : 只有true和false字符常量 :使用’’引起来的单个字符字符串常量 :使用“”引起来的字符序列,“” 、“a” 、” ”null常量 : 只有一个值nullchar类型char类型表示的是单个字符类型,任何数据使用单引号括起来的都是表示字符。字符只能有一个字符,比如:普通的老百姓穿上军装就是军人。注意:特殊字符的..._java换行符用単引吗

随便推点

【笔记】行测——常识判断之地理常识总结与归纳(二)_重庆四川行测笔记汇总-程序员宅基地

文章浏览阅读759次。第二章 世界地理一、海陆概况(一)七大洲(二)七大洲大小(三)大洲分界线(四)四大洋(五)海峡和运河二、山川湖泊(一)高原、平原、山脉(二)河流、城市与文明(三)世界之最第三章 中国地理一、中国地理概况1.位置半球维度海陆2.疆域面积四至临海3.邻国二、山形地貌(一)四大高原(二)四大盆地(三)三大平原(四)三大丘陵(五)名山大川1.五岳2.三山(六)宗教名山1.四大佛教名山2.四大道教名山(七)著名地貌1.喀斯特地貌2.丹霞地貌3.雅_重庆四川行测笔记汇总

Unity-URP RenderFeature CommandBuffer.DrawMesh始终是蓝色的?_unity urp偏蓝-程序员宅基地

文章浏览阅读186次。URP CommandBuffer.DrawMesh 渲染不正确的?_unity urp偏蓝

虚幻4中的程序化生成【1】程序化生成河流。_虚幻4河流demo-程序员宅基地

文章浏览阅读7.5k次,点赞7次,收藏34次。给自己立了很多flag,由于时间原因很多系列都还在写,算是循序渐进的总结。在程序化生成系列里,将会有如下记述:【1】程序化生成河流主要内容有@1 shader的自动调整(如河流的深浅,河水的波涛程度) @2 河流形状的调整,我们只需要编辑一条样条线,河流根据这条样条线自适应形状。【2】程序化生成森林主要内容有:@1用随机种子随机生成森林。减少美_虚幻4河流demo

Windows系统目录及常用快捷键_目录后的............快捷键-程序员宅基地

文章浏览阅读6.2k次。1.系统目录用户目录存放用户登录后的配置文件Windows目录为系统安装目录 system32存放系统配置文件 config目录内的SAM文件存放用户的账户和密码,备份后删除该文件登录用户无需密码(需要使用第三方PE才能操作该文件) drives目录下 etc目录内的hosts文件存放用于解析域名的地址 program file(x86):64位操作系统才有的目录。32位应用程序安装于该目录 program file:应用程_目录后的............快捷键

simplexml_load_string-程序员宅基地

文章浏览阅读590次。2019独角兽企业重金招聘Python工程师标准>>> ...

Pygame 外星人入侵(5)发射子弹-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏9次。Pygame 外星人入侵(5)发射子弹目录Pygame 外星人入侵(5)发射子弹引言一、定义子弹类1、增加子弹相关的设置参数2、新增子弹模块3、定义子弹类二、发射子弹1、实现发射逻辑2、优化1:删除出界的子弹3、优化2:限制子弹数量三、代码封装四、小结引言在之前的博文中,我们实现了游戏屏幕的绘制、飞船的绘制以及玩家通过按键来操控飞船移动的功能。在这篇博文中,将会完成让玩家飞船发射子弹的功能。一、定义子弹类我们既然要 “发射”“子弹”,那么首先就必须要有可发射的“子弹”。所以我们需要自己定义一个

推荐文章

热门文章

相关标签