Milk-V Duo,但是光驱模拟器

大家好,我又来了。这次来折腾点不一样的。

起因是收到了一台来自群友的 ThinkPad,尝试通过恢复介质为其重装系统(四张 CD)。

然后很不幸我手头的光盘质量不太行,刻了好几张都是 CRC 校验错误。

于是想起了群友 driver1998 利用 Linux Gadget File CD 功能搓了一个光驱模拟器,并且还是用 Milk-V Duo 实现的,RISC-V + Retro Computing 这一波确实是我没想到的。

介绍视频见 史前大坑,USB光驱模拟器终于做完了[藏狐]。虽然主要工作就是这个UI[辣眼睛]_哔哩哔哩_bilibili


本次登场嘉宾:

  • Milk-V Duo (CV1800B, 64M)
  • EC11 旋转编码器(某宝售价 ~¥3.6)
  • 128*96 OLED 屏幕一块(SSD1306 驱动,SPI/I²C 双接口,本次使用 SPI,某宝售价 ~¥10)
  • 杜邦线、XH2.54 排针若干(或者面包板,我只有杜邦线,就这样吧 xD)
  • 存储卡一张
  • USB Type-C 数据线一条

使用到的系统镜像:duo-buildroot-sdk-v2

测试报告见:https://matrix.ruyisdk.org/reports/Duo-BuildRoot-README_v2/

使用到的开源项目 DiscEmu:https://github.com/driver1998/DiscEmu

Fork 版,添加了 I2C 屏幕和 Duo 256M / Duo S 支持: https://github.com/slzKud/DiscEmu

(两个版本主要区别是 Duo 256M/Duo S 支持,按需取用即可,这里用的是 fork 版。注意 pinmux 可能不一样。)


步骤比较简单:

  • 烧好系统镜像
  • 连好外设
  • 上电开机,给分区扩个容。
  • (可选)编译并配置 uMTP-REsponder 以支持 MTP 文件传输
  • 将所有需要的二进制和配置文件等传输到开发板
  • 把需要的光盘镜像放进去
  • Enjoy

准备工作

烧镜像比较简单,直接 dd 进存储卡即可,当然也可以考虑使用 ruyi device provison

外设连接因为 pin 比较多,还请慢慢来。

可以对着 Duo 的文档看看 Duo Pinmux: https://milkv.io/zh/docs/duo/application-development/pinmux

OLED 屏幕一共六条线:

(建议对照供应商的 datasheet,比如我手上这个是双模的,靠电阻切换,SCK 的丝印就是 I²C 的 SCL,而数据管脚 MOSI 则写的是 SDA,另有一些模块这个地方会标记 D0/D1,以实际情况为准)

Duo OLED
GP7/PIN#10 MOSI/数据
GP6/PIN#9 SCK/时钟
GP22/PIN#29 RES
GP21/PIN#27 DC
任一 GND,如 PIN#28 GND
3V3(OUT)/PIN#36 VCC

EC11 旋转编码器五条线:

Duo EC11
GP20 S1
GP19 S2
GP18 KEY
VBUS/PIN#40 5V/VCC
任一 GND,如 PIN#38 GND

软件准备

下载 DiscEmu 的 release 二进制并解压。

disc-emu二进制和 run_usb.sh放在 /mnt/data目录下。

/mnt/data新建一个脚本auto.sh

OLD_PWD=$PWD
cd /mnt/data
nohup ./disc-emu
cd $OLD_PWD

移除/mnt/system/usb.sh以免冲突。

因为我打算在 Duo 上用 MTP,所以还需要手动编译 uMTP-REsponder。

这一步因为需要用到 Duo 的交叉编译工具链,使用了 ruyi 包管理器来简化配置过程。

#安装 ruyi 包管理器
wget https://mirror.iscas.ac.cn/ruyisdk/ruyi/tags/0.41.0/ruyi-0.41.0.amd64
chmod +x ruyi-0.41.0.amd64
sudo cp ruyi-0.41.0.amd64 /usr/local/bin/ruyi
#更新元数据,安装工具链并创建虚拟环境
ruyi update
ruyi install gnu-milkv-milkv-duo-musl-bin
ruyi venv -t gnu-milkv-milkv-duo-musl-bin milkv-duo venv-duo
source venv-duo/bin/ruyi-activate
#检查工具链版本
riscv64-unknown-linux-musl-gcc -v
#拉取源码并编译
git clone https://github.com/viveris/uMTP-Responder
cd uMTP-Responder
CC=riscv64-unknown-linux-musl-gcc make -j$(nproc)

然后就可以在当前目录下找到编译好的 umtprd二进制了。

umtprd二进制放在 /usr/bin下,并在/etc/umtprd/umtprd.conf写入如下内容:

loop_on_disconnect 1

storage "/mnt/data/isos"  "isos" "rw"

# Set the USB manufacturer string

manufacturer "Cvitek"

# Set the USB Product string

product "DiscEmu"

# Set the USB Serial number string

serial "0123456789"

# Set the MTP firmware version

firmware_version "Rev A"

# Set the USB interface string. Should be always "MTP"

interface "MTP"

# Set the USB Vendor ID, Product ID and class

usb_vendor_id  0x1D6B # Linux Foundation
usb_product_id 0x0100 # PTP Gadget
usb_class 0x6         # Image
usb_subclass 0x1      # Still Imaging device
usb_protocol 0x1      #

# Device version

usb_dev_version 0x3008

#
# USB gadget device driver path
#

########################################################################
#
# -- Generic FunctionFS Mode --
#
########################################################################

usb_functionfs_mode 0x1

usb_dev_path   "/dev/usb-ffs/mtp/ep0"
usb_epin_path  "/dev/usb-ffs/mtp/ep1"
usb_epout_path "/dev/usb-ffs/mtp/ep2"
usb_epint_path "/dev/usb-ffs/mtp/ep3"

usb_max_packet_size 0x200

然后就可以把需要的 ISO 镜像放进 /mnt/data/isos了。放好后会在 Image Browser 里看到它们。


成品效果:

(前后两张图的线重新连过,请勿直接参考)

(手头没几条线了只好用相同颜色的了,勿喷 xD)

(MTP 不清楚为什么没有工作,可能和我用了 v2 的镜像有关系;各位如果想复刻的话可以试试用 v1 镜像。)

(对 ISO 镜像有 2.2GB 的限制,有内核补丁可以绕过,如遇到此问题,可以考虑用 driver1998 的 fork 版 duo-buildroot-sdk 镜像:https://github.com/driver1998/duo-buildroot-sdk/releases)

(虽然非常好用,但还是有个坏消息:兼容性确实可能有点问题,在部分老设备上真的会认不出来 xD)


欢迎各位复现/吐槽丁丑小队的所有测试结果。
如果有对我们的测试方法/结果有任何建议/问题,欢迎直接在 GitHub 开 issue,或者在论坛 @ 我们、回帖询问。

6 个赞