找回密码
 -注册-
查看: 2523|回复: 50
打印 上一主题 下一主题

全内存播放开发笔记

[复制链接]
跳转到指定楼层
1
发表于 2024-3-3 17:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自 北京市
本帖最后由 中关村东路 于 2024-3-3 20:20 编辑

全内存播放开发笔记

内存的速度和延迟都远优于各种形式的硬盘,流行的Linux音乐发行版,如GentooPlayer,HQplayer OS,AudioLinux, Euphony都提供内存系统功能,把整个操作系统都放到内存中。本帖回顾主流内存系统的实现,讨论前三者的优劣,之后简要介绍我实现并开源的另外一种方案【1】。Euphony做的比较粗糙我不喜欢没深入用过,不过从网页介绍【2】来看和AudioLinux原理相同。

【1】https://github.com/zhjie/ramroot
【2】https://euphony-audio.com/hesk/knowledgebase.php?article=14
【3】http://erji.net/forum.php?mod=viewthread&tid=2253401&extra=
【4】http://erji.net/forum.php?mod=viewthread&tid=2272124&extra=
【5】https://github.com/arcmags/ramroot
【6】http://erji.net/forum.php?mod=viewthread&tid=2284715&extra=


来自 2楼
 楼主| 发表于 2024-3-3 17:46 | 只看该作者 来自 北京市
1. GentooPlayer的tmpfs方案

在我之前的帖子《Roon系统硬核安装笔记》【3】中,介绍了GentooPlayer方案的内存系统实现。大致原理是先挂载tmpfs的目录,从根目录把整个系统文件同步过去,之后再通过mount -o bind命令用新的内存目录覆盖掉原磁盘目录,这样读写的就都是内存中的tmpfs了。不过这种实现有两个问题,一个是尽管我在【3】中提出了让磁盘自动休眠的方案,但磁盘事实依然是无法umount的,如果这时候把盘拔下来再去访问根目录就会出问题——不够优雅。二是整个系统会load两次——依然是不够优雅,而且消耗很大。虽然我自己的电脑上长期都用这套方案,不过总想折腾出一个漂亮一些的实现。

【3】http://erji.net/forum.php?mod=vi ... =2253401&extra=

回复

使用道具 举报

来自 3楼
 楼主| 发表于 2024-3-3 17:46 | 只看该作者 来自 北京市
2. HQplayer OS的initramfs方案

Initramfs不是新鲜技术了,原理是在系统正式启动到根目录之前,先启动到一个比较小的cpio格式的initramfs.img里,同时会把这个img完全load到tmpfs中。这是内核自身提供的功能,原设计是用来维护raid啊,光盘启动啊,网络启动啊,zfs/unionfs啊,等等特殊设备的,在initramfs中折腾好这些设备之后再boot到实际系统中。HQplayer OS就用这个方案直接把整个最终系统都写入这个initramfs.img中,只不过最后并没有boot进实际硬盘,而是在initramfs里直接用hqplayerd了。这套方案逻辑上是没有问题的,但实际用起来就会比较麻烦了,因为整个系统都在生成initramfs.img的时候被固定住了无法修改,别说新增软件了,就是改个密码,改个主机名,增加个ssh公钥都麻烦。当然也都能,就是真的麻烦,感兴趣的详见我在本站的帖子【4】。

【4】http://erji.net/forum.php?mod=vi ... =2272124&extra=

回复

使用道具 举报

来自 4楼
 楼主| 发表于 2024-3-3 17:46 | 只看该作者 来自 北京市
3. AudioLinux的zram+initramfs方案

今年春节前我阅读了AudioLinux的内存系统代码,不是他自己开发的,而是用了开源的【5】。这段代码实现的很工程师很漂亮,流传度也很高,和ArchLinux高度耦合,换成其他系统是不能运行的。但这并不是让我不满意的原因。这套方案基于zram,也是把工作放在了initramfs里。大致原理是,在initramfs中先用zram生成一个大小为一半内存的块设备,之后把这个块设备当成一个普通磁盘,分区,格式化,再把实际硬盘数据同步到这个块设备的根分区上来,最后boot到这个块设备而不是硬盘。看起来是不是很优雅,但这套方案有个不漂亮的地方,那就是块设备,比如磁盘啊,tf卡啊,一般都是低速设备,在Linux下会被缓存起来,算是充分利用硬件吧。不过这套方案里的块设备实际上却是内存,也就相当于给内存再缓存一遍内存。这就不仅是不优雅了,本来读一条数据,从内存读过就可以了,现在要读了之后再写入内存缓存中一份,消耗加倍了还要多,从性能上要远低于前两种方案,可以说是非常不科学了。

【5】https://github.com/arcmags/ramroot

回复

使用道具 举报

来自 5楼
 楼主| 发表于 2024-3-3 17:47 | 只看该作者 来自 北京市
4. 我实现并开源的tmpfs+initramfs方案

读者读到这里应该已经能想到我的方案【1】了吧,那就是在initramfs中,不生成块设备zram,而是生成一个tmpfs作为最终的根目录。是不是听起来很简单?其实实现起来更简单。我的源里核心代码有三个文件,init, ramdisk.sh, gen_initramfs-ARCH.sh。

4.1. init

init文件,是initramfs.img的入口,修改或编写这个文件是本方案的核心。我的init文件修改自/usr/share/genkernel/defaults/linuxrc,是gentopo的内核编译软件genkernel提供的gentoo默认脚本。如果你用的是archlinux,应该看/usr/lib/initcpio/init。源里init文件最后几行代码是我写的,做的事情是用tmpfs生成一个占用一半系统内存的/ram_chroot,从/mnt/.ramdisk文件夹同步根目录数据。如果你的内存很大能轻松容纳整个磁盘,也可以直接从磁盘根目录同步过来。我的/mnt/.ramdisk文件夹是在ramdisk.sh中生成的,生成的时候把系统中一些没什么用的文件夹去掉了。最后一句switch_root之后,系统就boot到内存系统中了。注意下面脚本在启动之前先umount了实际硬盘,这也是从原理到性能都优于GentooPlayer方案的地方。

  1. mkdir /ram_chroot
  2. mount -t tmpfs -o rw,noatime none /ram_chroot
  3. cp -a "${CHROOT}"/mnt/.ramdisk/* /ram_chroot/

  4. mount --move /proc /ram_chroot/proc
  5. mount --move /sys /ram_chroot/sys
  6. mount --move /dev /ram_chroot/dev

  7. umount ${CHROOT}

  8. good_msg "Switching to real root: switch_root /ram_chroot ${init} ${init_opts}"
  9. exec switch_root /ram_chroot "${init}"
复制代码


4.2. ramdisk.sh

ramdisk.sh其实是可有可无的,生成一个小一些新的root_fs放在/mnt/.ramdisk/,exclude掉了一些没用又占空间的文件,比如/usr/src内核源码等等。主要是因为我的树莓派只有2g内存,虽然也足够把整个系统都同步过来,不过为了战未来还是写了这段脚本。需要指出的是,我的系统中/bin /lib /lib64 /sbin四个目录是软链接的,并没同步过去,如果你的系统原本不是软链接就全同步过去。总之让/mnt/.ramdisk看起来和/基本上一样就好了,注意不要把/mnt自己也同步过去了。

4.3. gen_initramfs-ARCH.sh

树莓派和x86我是分开写的,主要是因为树莓派用config.txt控制启动入口,x86我用了grub控制启动入口。我同时提供了如下树莓派的config.txt,意思是kernel/initramfs的文件名分别是kernel和initramfs,你如果不喜欢我的口味可以按需改脚本,注意别改followkernel这个是关键字。


  1. kernel kernel
  2. initramfs initramfs followkernel
复制代码


gen_initramfs-ARCH.sh文件一共要做三件事:先mount了/boot分区,该删除删除该备份备份,之后从服务器把交叉编译生成的内核文件同步到/boot,如果你是本地编译就不需要这步了;之后把刚刚出炉的initramfs解压缩,把init文件替换为我们刚刚改好的那个,再重新打包回initramfs.img;最后把这个文件部署到/boot分区,配置grub等等启动项。以x86/grub为例,现在boot到新生成的这个initramfs.img就是内存启动,boot到编译生成的那个就是硬盘启动。需要指出两点,一个是这段脚本中我利用了genkernel的一个配置生成了一个名为kernel的内核链接,和一个名为initramfs的initramfs.img链接;一个是我在编译内核时用的xz压缩。如果你不喜欢这种设置可能需要对应修改自己的代码。

4.4. 关于是否成功执行

启动系统之后执行df,如果你的根目录类型是none或者tmpfs就对了。更进一步还可以执行mount命令不用参数,可以看到目前mount的所有目录中没有磁盘。注意曾经mount过的磁盘是不能再次mount的,这个方案也允许用户自己执行mount /dev/sda2 /mnt; mount /dev/sda1 /mnt/boot 这种命令。

4.5. 关于日常维护

逻辑上,直接boot到刚刚生成的磁盘分区就可以日常维护了,不过实际上有更简单的办法。直接boot到内存系统中,用mount命令把磁盘挂载起来,之后用我在本站的帖子【6】中介绍的chroot方法,就可以直接进入硬盘系统使用包管理软件进行软件安装了,记得最后执行ramdisk.sh同步一下即可。

【1】https://github.com/zhjie/ramroot
【6】http://erji.net/forum.php?mod=vi ... =2284715&extra=



回复

使用道具 举报

来自 6楼
 楼主| 发表于 2024-3-3 17:48 | 只看该作者 来自 北京市
5. 小结

本帖简要回顾了目前流行的tmpfs方案,initramfs方案和zram方案三种内存系统实现,介绍了我实现并开源的tmpfs+initramfs方案。如果对你有用,欢迎回帖讨论支持。

也再次重申,我不是科学派,不是玄学派,不排斥线材,也不排斥指标,但本帖只讨论方案,不讨论听感。请不要以听不出来之类为由在本帖下攻击我或网友。另外,我并不是程序员只是一个普通理工男,代码供自己使用,方案完全开源免费分享给大家,具体如何应用到读者的机器或者产品中需要你自己斟酌。


回复

使用道具 举报

来自 28楼
 楼主| 发表于 2024-3-11 16:04 | 只看该作者 来自 北京市
lalekuku 发表于 2024-3-11 14:08
明白了。
我的是arm板子,还没想出软件层面给emmc或tf卡断电的办法,
automagic内核的arm源码能用来 ...

其实是可以切断的,

  1. echo -n mmc0:0001 > /sys/bus/mmc/drivers/mmcblk/unbind
复制代码


回复

使用道具 举报

7
 楼主| 发表于 2024-3-3 17:48 | 只看该作者 来自 北京市
打完收工
回复

使用道具 举报

8
发表于 2024-3-3 19:45 | 只看该作者 来自 四川省成都市
给大佬顶贴
回复

使用道具 举报

9
发表于 2024-3-3 19:54 来自手机 | 只看该作者 来自 广东省湛江市
大佬牛逼!
很多看不懂
回复

使用道具 举报

10
 楼主| 发表于 2024-3-3 19:54 | 只看该作者 来自 北京市

感谢支持
回复

使用道具 举报

11
 楼主| 发表于 2024-3-3 19:54 | 只看该作者 来自 北京市
sszj2010 发表于 2024-3-3 19:54
大佬牛逼!
很多看不懂


回复

使用道具 举报

12
 楼主| 发表于 2024-3-3 20:19 | 只看该作者 来自 北京市
已经有网友成功跑起来了
回复

使用道具 举报

13
发表于 2024-3-3 20:32 来自手机 | 只看该作者 来自 江苏省镇江市
你让那些能听出不同硬盘声音的骚友肿么办
回复

使用道具 举报

14
发表于 2024-3-3 20:36 | 只看该作者 来自 浙江省宁波市
技术大牛的贴一定要顶。
另外多嘴问一句,gentoo player里面设置了ramsystem后,是不是就可以把优盘拔掉了?
回复

使用道具 举报

15
发表于 2024-3-3 20:37 来自手机 | 只看该作者 来自 浙江省杭州市
厉害了又热爱,很多看不懂。
回复

使用道具 举报

16
 楼主| 发表于 2024-3-3 20:43 | 只看该作者 来自 北京市
Devastat0r 发表于 2024-3-3 20:36
技术大牛的贴一定要顶。
另外多嘴问一句,gentoo player里面设置了ramsystem后,是不是就可以把优盘拔掉了 ...

原则上是不能的,因为gp的ramroot并没有umount掉原来的root,拔了之后一般的操作都不会有问题,但不能执行和根目录有关的命令,也不能执行磁盘操作。

当然都是原则上,正常优化的系统一般是不会执行磁盘操作的,即便执行了也就是这个程序自己出错,不会影响naa/roon之类的,没强迫症可以当做不存在。
回复

使用道具 举报

17
 楼主| 发表于 2024-3-3 20:55 | 只看该作者 来自 北京市
大点 发表于 2024-3-3 20:37
厉害了又热爱,很多看不懂。

哪没看懂可以提出来,可能是我没说清楚
回复

使用道具 举报

18
发表于 2024-3-3 22:01 来自手机 | 只看该作者 来自 福建省福州市
顶一下大佬
回复

使用道具 举报

19
 楼主| 发表于 2024-3-3 22:34 | 只看该作者 来自 北京市

不老不老
回复

使用道具 举报

20
发表于 2024-3-4 07:10 | 只看该作者 来自 北京市
hqos换专辑才会读一秒优盘(优盘灯闪烁1秒),如果拔了优盘可以继续播放本专辑下一首歌,但是无法更换专辑播放。 为何这样设计,为何不设计为拔了优盘也能全部正常播放实现真正的脱盘全内存运行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | -注册-

本版积分规则

Archiver|手机版|粤icp备09046054号|耳机网-耳机大家坛

粤公网安备 44030602000598号 耳机大家坛、www.erji.net、网站LOGO图形均为注册商标

GMT+8, 2024-4-28 18:12

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表