机顶盒并在LXC容器中使用Android进行实验

在Linux容器中运行Android的奇怪需求是什么,以及它的来龙去脉

背景知识


我认为在LXC容器中运行Android是一个合理的决定,如果您想拥有Bare Linux的透明性和可靠性,并利用好的(而不是那么好的)第三方Android应用程序的巨大潜力。 此外,此配置作为在尽可能接近战斗条件下调试自己的AOSP映像的平台也很受关注。
对于实验,选择了基于Amlogic S905x的64位ARMv8的渐进且廉价的中文机顶盒(CPU-4核,RAM-2GB,MMC-8GB)。 此外,一个很好的论据(与其他供应商相比)是OpenSource中的代码库以及Mali-450的源内核内核驱动程序的存在。 今天在ARM Limited官方网站上的公共领域中的用户空间图书馆Mali。 适用于Linux-FB,Linux-Wayland和Android的二进制访问库。

实验的主要目的是在线电影院的应用程序以及用于网络媒体托管的应用程序。 例如,在Linux上的Youtube上,麻烦立即开始。 首先,由于Google通过广告抓取方法的无情斗争,黑客通过解析JS脚本并生成签名(以前在Tordini的minitube和youtube-dl中实现)来获取内容链接的黑客方法开始定期崩溃。 其次:内容的最大分辨率为720p-没有发布更多的Google-API。 第三:WebKit失去了常规支持,最近仅受到一小部分爱好者的支持。 同样的命运落在他的Qt端口上。 结果,有一天,YouTube /电视页面由于网络引擎的年代久远而拒绝工作。 好吧,最后,他提出了一个令人惊讶的WebEngine(Qt-Chromium)。 事实证明,这种美不支持硬件加速。 仅对其Android端口和Linux中的边缘VAAPI分支例外。 死胡同。 通常,我找不到在Linux上为Chromium启用硬件加速视频解码的简单方法。 对我来说,为Amlogic实施VAAPI似乎是艰巨而无用的工作。 我也觉得佩珀尔插件-不幸的是,PPAPI不​​允许播放屏幕外视频。

安卓系统


为什么不在容器中运行Android? Anbox项目激发了这一壮举。 对Anbox的深入研究表明,它不适合我们。 但是这个想法很明确。 其他作者的文章声称,在容器中运行Android是一项愚蠢的任务。 但是实际上,一切都变得更加复杂。 通过简单地配置配置文件,我们无法完成。

因此,我收集了LXC并将其安装在系统中。 内核配置测试揭示了问题:您需要启用名称空间支持。 由于平台是内置的,因此禁用了所有不必要的东西。 我不得不找出这些必要的不必要的东西。

第一个测试是检查容器中的Busybox。 确保一切正常后,我开始进行实验。

初始视图是/var/lib/lxc/abox.conf:

lxc.rootfs = /var/lib/lxc/abox/rootfs lxc.rootfs.backend = dir lxc.utsname = abox lxc.pts = 1024 lxc.cap.drop = mac_admin mac_override 

下载中文战利品AOSP 6.0.19。 它与普通版本的区别在于它具有一个普通的启动器,并通过杂散和硬修补的Surfacelinger增强了对Amlogic硬件平台的某些功能的支持。 香草AOSP随后也进行了测试。

与主题略有不同的是:中文,软件的改编,遵循了社区制定的所有规则。 例如,内核3.14.29。 此静默内核发行版号已在Amlogic S8xx和S9xx处理器上的几乎所有硬件上使用。 但是,几乎总是一样,它们之间的区别非常严重,直到旧模块与新映像完全不兼容为止,反之亦然。 核心似乎已按照以下原则进行了修正:“尽快将产品投放市场”。 该代码不仅肮脏,而且质量令人作呕。 更改配置通常会导致编译或链接映像或模块时出错。 已修补的Android具有相同的质量,并且适应的原理相似。 AOSP团队的几乎所有建议都被忽略了。

好无处可去! 我们收集。

尝试1。将图像安装在容器中,运行。 不起作用。 分析表明没有内核对象:binder和ashmem。 我们添加内核模块。

尝试2号我们再次开始。 已安装的崩溃。 原来,原始活页夹不知道名称空间。 从Anbox中拉出活页夹。

尝试编号3开始,然后立即重新启动。 事实证明,init想要SELinux并拒绝没有它的工作。

尝试4。打开SELinux。 主机系统遇到很多问题。 至少直到现在,我必须关闭它-直到弄清该过程的本质和理论为止。 加载内核时,也可以在命令行上禁用SELinux,但是我仍然不了解如何将参数传递给容器。 我必须进入初始化源并大致纠正其行为。 这是后来的第一次也是最后一次外科手术。

尝试5号引导过程到达合子。 在日志中,在UID init上从内核起誓。 在活页夹(和来自Anbox的活页夹)中,可以轻松地将所有者进程的UID与统一进行比较。 唯一的方法是禁用该检查,尤其是因为此检查在容器中没有意义。

尝试6与共享对设备管理的访问权相关的冲突浮出水面。 我评论了初始化脚本中的USB和蓝牙控件。 我从fstab中删除了所有条目,并禁止安装和验证脚本中的所有媒体。 现在,将安装卡添加到容器配置中。 它仅包含一行。 /mnt/lxc.data目录安装在真实MMC分区中的主机上。

 lxc.mount.entry = /mnt/lxc.data data auto rw,bind 0 0 

尝试7号弹跳球出现在屏幕上,下载需要很长时间,因为Android映像已安装在NFS上,并且/ xx目录中也正在生成dexx。 重新加载速度快了很多倍。 最后,启动器出现了。
我们将认为这是最后一次尝试,因为一般而言,一切正常,您需要完成细节。

网络无法正常工作,但网络工作更精确,但是某些应用程序通过网络接口的状态评估其性能。 一句话,歪的手。 为了消除主机上的此缺陷,我们提出了网桥(bridge)和虚拟接口(veth)。

 lxc.network.type = veth lxc.network.flags = up lxc.network.name = eth1 lxc.network.link = br0 lxc.network.veth.pair = veth-01 lxc.network.ipv4 = 10.0.0.10/24 lxc.network.ipv4.gateway = 10.0.0.1 lxc.network.hwaddr = 00:FE:CD:BA:09:87 

您还需要提高DHCP服务器,否则DNS会出现问题。 不幸的是,Android无法分析resolv.conf,并且它在文件系统中的位置不起作用。 您可以手动配置网络连接,但是如果您从数据部分删除数据,所有设置将被重置。

总结


所有库存申请工作。 从市场上安装有问题。 例如:Youtube.tv版本3要求更新Google服务框架,此后系统崩溃。 密钥库问题浮出水面(尚未解决)。 TEE也暂时被禁用,因此Widevine不起作用。 玩具和应用程序无需特殊的硬件即可正常运行。 Chrome使用软件解码器扭曲HTML5视频,拒绝连接硬件解码器。 在这种情况下,有人对中国人歪曲的AOSP抱有看法。 但是香草AOSP发射带有触摸屏的发射器-无法控制弹射。

后记


在不久的将来-制作一个用于直接从Linux启动Android应用程序的启动器。 wpa-supplicant源中提供了一个示例。 您还可以在Anbox中窥视此操作。

感谢您的关注!

加法1


前几天,我检查了Qt应用程序的可伸缩性。 最初,IPTV客户端应用程序是使用QML for Linux编写的。 播放器通过QtMultimedia插件工作。 在编译期间,有问题的依赖关系浮出水面。 幸运的是,所有内容都仅限于QtDbus,而它不在Android中。 我仍然不明白为什么Android需要重新发明轮子-活页夹。 DBus开发人员不喜欢什么? 它在用户空间中工作吗? 还是许可方面的考虑?
断开DBus。 这很轻松,因为需要通道来实现与操作系统相关的一些功能。 收集了apk。 组装没有困难,因为我使用QtCreator(并且向您推荐)。
在AOSP中,我必须绘制一个Mediaplayer桥-android :: MediaPlayerInterface的继承者。 setDataSource()和stop()方法已在其中实现。 其余的插头。 setDataSource具有三个接口。 仅要求实现:
 setDataSource(const sp<IMediaHTTPService> &httpService, const char *uri, const KeyedVector<String8, String8> *headers) 


如果要扭曲媒体中的文件,则必须进行修补
 setDataSource(int fd, int64_t offset, int64_t length) 

文件名将需要通过“ / proc / self / fd /” + fd获得;

安装后,该应用程序赢得了收入,并且广播开始了。 太好了! 我预计会有很多问题,但几乎没有。 感谢Qt和QtCreator的开发人员所做的出色而有用的工作!
结果,我得到了一大堆:主机守护程序播放器。 在容器中,有一个客户端程序和一个将android :: Mediaplayer的调用广播到主机的地带。 该捆绑包通过UDP套接字工作。

Source: https://habr.com/ru/post/zh-CN413809/


All Articles