这次换一种写作风格,尝试一下轻松的行文方式。
很久以前看见有群友讨论关于docker部署Redroid,拿来挂机玩游戏一类的。当时听了感觉很有意思,后面粗浅地在zero2上部署了一下,容器虽然是跑起来了,但是scrcpy连接总是黑屏,后来我试着帮助一个群友部署,也部署失败了。最近又想起来这回事,所以决定再试一试。下面就说说我的尝试过程。
我使用的系统是官方的5.16内核的系统。4.9内核的系统是跑不起来的,这点需要注意一下。
这里我把编译好的内核和模块放上来,链接和使用方法如下:
123盘链接
下载之后:
unzip opi_zero2_kernel_redroid.zip
sudo mv 5.16.17+ /lib/modules
sudo mv uInitrd-5.16.17+ vmlinuz-5.16.17+ /boot
cd boot
sudo rm -rf Image uInitrd
sudo ln -s vmlinuz-5.16.17+ Image
sudo ln -s uInitrd-5.16.17+ uInitrd
reboot
重启完成后:
sudo apt install docker.io
sudo docker pull redroid/redroid:11.0.0-arm64
sudo docker run -itd --privileged -v ~/data11:/data -p 5555:5555 --name redroid11 redroid/redroid:11.0.0-arm64 androidboot.use_memfd=1 androidboot.redroid_gpu_mode=guest
这样就部署好了。连接方法见文末。
Redroid(remote android)是一种AIC(Android in Cloud),能够便捷的部署很多个Android容器,非常适合于云游戏等应用…(以上废话,一个词总结:云手机)。
项目地址:GitHub
通过仔细研读这篇readme发现,这个小玩意,需要两个内核模块支持:ashmem(注:主线内核在5.18 drop了这个模块,官方的替代方案是memfd,而且redroid也提供了androidboot.use_memfd=1来启用memfd支持,所以理论上可以不编译这个模块,不过这里稳妥起见,还是编译进去了)和binder。虽然作者也提供了redroid_modules库来进行树外模块的安装,但是我的内核版本太高了(5.16.17),编译过不了,于是只能通过自定义内核的方式了。
先去香橙派官方搞内核源码:GitHub
打开看了看,我选择了orange-pi-5.16-sunxi64分支。
这个时候,我才想起来,手上没有服务器给我编译,只能在本机上进行编译,又想了想4颗a53孱弱的性能…只能忍忍了。
git clone -b orange-pi-5.16-sunxi64 https://github.com/orangepi-xunlong/linux-orangepi
由于众所周知的原因,克隆过程又花了几十分钟,心里一万只羊驼奔腾而过…
随后,把系统本来就带的config搞过去:
cd linux-orangepi
cp /boot/config-5.16.17-sun50iw9 ./.config
搞好之后,打开内核配置界面:
make menuconfig
打开之后,Device Drivers -> Android -> Android Drivers勾上,弹出来binder ipc driver勾上,binderfs filesystem也勾上,这样binder模块就编译进去了。然后回到上一级,去Staging Drivers里面,进入Android,把Enable the Anonymous Shared Memory Subsystem也勾上,这样ashmem也搞定了。随后开始编译:
make -j8
随后开始漫长的等待…
大概5个小时之后,编译结束了,先把模块安装下,然后搓个initrd镜像出来:
sudo make modules_install -j8
sudo mkinitramfs 5.16.17+ -o initrd.img
mkimage -A arm64 -T ramdisk -C none -n uInitrd -d initrd.img uInitrd
然后把内核和initrd镜像搞到/boot目录下面:
cd /boot
sudo cp ~/linux-orangepi/uInitrd ./uInitrd-5.16.17+
sudo cp ~/linux-orangepi/arch/arm64/boot/Image ./vmlinuz-5.16.17+
搞好之后,ln一下,让系统重启时使用新编译的内核:
sudo rm -rf Image uInitrd
sudo ln -s vmlinuz-5.16.17+ Image
sudo ln -s uInitrd-5.16.17+ uInitrd
然后重启就行了。
答案是装一个:
sudo apt install docker.io
随后,搞个Android13的镜像试试水:
sudo docker pull redroid/redroid:13.0.0-arm64
接下来进入下一个环节:Debug(笑)。
对照官方文档,跑个容器试下水:
sudo docker run -itd --privileged -v ~/data13:/data -p 5555:5555 --name redroid13 redroid/redroid:13.0.0-arm64 androidboot.use_memfd=1
docker ps -a
OK,容器确实run起来了,但是adb连接提示offline。没辙,只能启动logcat看看What’s happening:
sudo docker exec redroid13 logcat
不看不知道,一看吓一跳啊:
#假装这里有log,但是当时的log我怎么可能还留着嘛!
#反正就是/vendor下面一个什么什么dri的so,报了segmentation fault。
#dri是什么,是drm的东西,那就和GPU有关系了。
#既然知道是GPU的毛病,那看文档就OK了。
根据以上log,可以知道,是GPU的问题(雾)。那怎么办呢,只能启用软件渲染咯:
sudo docker stop redroid13
sudo docker rm redroid13
sudo docker run -itd --pull always -v ~/data13:/data -p 5555:5555 --name redroid13 redroid/redroid:13.0.0-arm64 androidboot.use_memfd=1 androidboot.redroid_gpu_mode=guest
OK,重新搞起容器,连接还是报offline。麻麻的,还得看log:
sudo docker exec redroid13 dmesg
#再次假装有log,大体就是lmkd的问题,可以看见
#lmkd以每分钟30次的速度不断重启(大概每2秒一次)。
根据以上log(逃),可以得出是lmkd问题,去仓库issue搜一下,#293

tnnd,原来还要PSI支持,为什么不早说!(抓狂)
这里怎么不写上PSI支持…麻了
General Setup -> CPU/Task time and stats accounting -> Pressure stall information tracking,勾上。然后又开始一次漫长的编译过程…
编译好之后,还是一样的步骤安装好内核。
搞定之后,还是一样启动容器,照样offline…掏出log仔细研读,也没研究出来个所以然,只能试试换个版本:
sudo docker pull redroid/redroid:11.0.0-arm64
sudo docker run -itd --privileged -v ~/data11:/data -p 5555:5555 --name redroid11 redroid/redroid:11.0.0-arm64 androidboot.use_memfd=1 androidboot.redroid_gpu_mode=guest
run起来之后,adb连上,提示连接成功。哦豁,有搞头。
装个scrcpy:
sudo apt install scrcpy
adb connect localhost:5555
scrcpy

Windows下scrcpy参考官方GitHub即可。
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
-if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
我已经开始学习Ruby,我已经阅读了一些教程,甚至还买了一本书(“ProgrammingRuby1.9-ThePragmaticProgrammers'Guide”),我遇到了一些以前从未见过的新东西使用我知道的任何其他语言(我是一名PHP网络开发人员)。block和过程。我想我明白它们是什么,但我不明白的是为什么它们如此伟大,以及我应该在何时何地使用它们。我到处都看到他们说block和过程是Ruby中的一个很棒的特性,但我不理解它们。这里有人能给像我这样的Ruby新手一些解释吗? 最佳答案 block有很多好处。电梯演讲:bloc
我写了一个脚本,其中包含一些方法定义,没有类和一些公共(public)代码。其中一些方法执行一些非常耗时的shell程序。然而,这些shell程序只需要在第一次调用该方法时执行。现在在C中,我会在每个方法中声明一个静态变量,以确保这些程序只执行一次。我怎么能在Ruby中做到这一点? 最佳答案 ruby中有一个成语:x||=y。defsomething@something||=calculate_somethingendprivatedefcalculate_something#somelongprocessend但是如果您的“长时间
我想在格式化数字时每隔三个字符放置一个空格。根据这个规范:it"shouldformatanamount"dospaces_on(1202003).should=="1202003"end我想出了这段代码来完成这项工作defspaces_onamountthousands=amount/1000remainder=amount%1000ifthousands==0"#{remainder}"elsezero_padded_remainder='%03.f'%remainder"#{spaces_onthousands}#{zero_padded_remainder}"endend所以我
rails中View的解析过程是怎样的?我对View中erb标记中原始html与ruby代码的解析顺序部分感兴趣。我认为这是View代码被解析并最终发送给请求者的顺序:Controller调用ViewView代码从上到下解析当Rails在解析过程中遇到erb标记时:rails解析它并将结果附加到解析的html(这包括erb标签引用助手)一旦整个View被解析,整体结果将发送给请求者这似乎并非如此。看来View代码会扫描任何erb片段并首先解析那些片段(包括对助手的引用)。之后,rails然后从上到下解析所有View代码并将结果发送给请求者。以这个View为例:#_form.html