<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Walkman on ntzyz&#39;s space</title>
        <link>/zh-cn/categories/walkman/</link>
        <description>Recent content in Walkman on ntzyz&#39;s space</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Wed, 11 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="/zh-cn/categories/walkman/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Walkman 上手玩：给十年前的老玩意做个新 UI Part 1</title>
            <link>/zh-cn/post/walkman-and-musicos-chapter-1/</link>
            <pubDate>Wed, 11 Nov 2026 00:00:00 +0000</pubDate>
            <guid>/zh-cn/post/walkman-and-musicos-chapter-1/</guid>
            <description>&lt;img src=&#34;/post/walkman-and-musicos-chapter-1/cover.webp&#34; alt=&#34;Featured image of post Walkman 上手玩：给十年前的老玩意做个新 UI Part 1&#34; /&gt;&lt;p&gt;前一阵子突然脑抽，想整一个 Walkman 回来玩玩，&lt;del&gt;毕竟曾经也是 NW 系列 walkman 的忠实用户&lt;/del&gt;。拿到手之后，稍微搜索了一下发现社区对这个播放器已经有很多折腾的记录了，例如 Walkman One 固件，或者是一些 UI&#xA;tweak。我自己呢其实一开始也没想到这玩意有啥可折腾的，到手之后装了个 Walkman One 固件之后就吃灰了，主要是非要拿个有线耳机确实不方便，而且 Walkman 的固件和 AirPods Pro 2 已经开始有兼容性问题：&#xA;连接上设备之后播放没有任何声音，无奈最后还是束之高阁。&lt;/p&gt;&#xA;&lt;p&gt;中秋放假期间，我突然想起来自己还有这么个玩意，感觉放着心里痒痒用也派不上用场，掏出来看看我能拿来干些啥，突然发现这些自制固件是悄咪咪的把索尼留着的 adbd 激活了，这一下突然感觉就有意思了：当我拿到了 root&#xA;shell，岂不是来去自如，想干嘛就干嘛！&lt;/p&gt;&#xA;&lt;p&gt;先简单看看这个机器的基础信息吧：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ adb devices&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;List of devices attached&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;10453485000783&#x9;device&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ adb shell&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/meminfo | head -n 3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MemTotal:         &lt;span class=&#34;m&#34;&gt;467984&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MemFree:           &lt;span class=&#34;m&#34;&gt;44644&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Buffers:           &lt;span class=&#34;m&#34;&gt;21532&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/cmdline&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/null &lt;span class=&#34;nv&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/ram &lt;span class=&#34;nv&#34;&gt;vmalloc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;496M &lt;span class=&#34;nv&#34;&gt;slub_max_order&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;slub_debug&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;O  &lt;span class=&#34;nv&#34;&gt;lcm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1-otm8018b_vdo_cmd &lt;span class=&#34;nv&#34;&gt;fps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6023&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;vram&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6291456&lt;/span&gt; androidboot.selinux&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;disabled bootprof.pl_t&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1145&lt;/span&gt; bootprof.lk_t&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2137&lt;/span&gt; printk.disable_uart&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;boot_reason&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; icx_pm_helper.icx_sysinfo&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x00000000 icx_pm_helper.icx_modelid&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x20000007 mmc_core.emmc_boot_serial&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x96615529 icx_pm_helper.icx_boot_option&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; leds_drv.brightness&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;255&lt;/span&gt; androidboot.serialno&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10453485000783&lt;/span&gt; androidboot.bootreason&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;wdt_by_pass_pwk icx_pm_helper.icx_boot_reason&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x1 androidboot.hardware&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;icx androidboot.console&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ttyMT1 androidboot.printk&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; androidboot.bid3&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/cpuinfo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Processor&#x9;: ARMv7 Processor rev &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;v7l&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Processor&#x9;: ARMv7 Processor rev &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;v7l&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hardware&#x9;: MT8590&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Revision&#x9;: &lt;span class=&#34;m&#34;&gt;0000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serial&#x9;&#x9;: &lt;span class=&#34;m&#34;&gt;0000000000000000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ls | tr &amp;#39;\n&amp;#39; &amp;#39; &amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bin boot boot.sh bootshow bootui build.prop cache contents contents_ext contents_ext1 data db default.prop dev emmc@android emmc@bootimg emmc@cache emmc@cm4 emmc@contents emmc@db emmc@dkb emmc@ebr1 emmc@expdb emmc@kb emmc@logo emmc@misc emmc@nvp emmc@nvram emmc@option1 emmc@option2 emmc@option3 emmc@pro_info emmc@protect_f emmc@protect_s emmc@recovery emmc@sec_ro emmc@seccfg emmc@tee1 emmc@tee2 emmc@uboot emmc@usrdata emmc@var emmc@xhrome etc factory file_contexts home init init.hagoromo.rc init.project.rc init.rc init.real init.usbcfg.rc init.usbcfgdmp.rc install_update_script lib newroot oem_cast_shlib opt1 opt2 opt3 proc res root sbin sys system tmp ueventd.audiodefault-b1.rc ueventd.audiodefault-b2.rc ueventd.audiodefault-b3.rc ueventd.icx.rc ueventd.rc usr var xbin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;看起来是一个很常规的 Linux，但是带了一个非常 Android 风味的 rootfs。那么问题来了，如果我想在这个设备的屏幕上跑点什么，有什么办法可以做？&lt;/p&gt;&#xA;&lt;p&gt;简单的搜索了一下发现其实社区已经有人做好了，就是 &lt;a class=&#34;link&#34; href=&#34;https://github.com/unknown321/wampy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;wampy&lt;/a&gt;：简单来说，索尼的播放器主程序 &lt;code&gt;HgrmMediaPlayerApp&lt;/code&gt; 是个 Qt 应用，作者很讨巧的用上了 Qt eglfs 平台插件把自己的代码塞进这个进程，再通过 &lt;code&gt;QWindow::hide()&lt;/code&gt; 把原窗口藏起来，屏幕就可以从索尼的进程中释放出来了。作者为了方便其他人用上他的成果，还准备了个 &lt;code&gt;/tmp/wampy.sock&lt;/code&gt; 和 wampyctl 命令，给我们更容易的控制入口。&lt;/p&gt;&#xA;&lt;p&gt;怎么跑的问题解决了，那么接下来需要想的就是跑点什么了。其实最开始我想到的是 DOOM，但是这玩意的小触摸屏玩 FPS 还是比较难以操作的（笑）。随后想到的就是另一个一次编写到处移植的经典老游戏：SDLPAL。&lt;/p&gt;&#xA;&lt;p&gt;要让 SDLPAL 跑起来，首先要做的事让 SDL 在这个平台上能用。如果想正儿八经的让 SDL 移植过来，需要走的路线是 SDL video driver,对于这个折腾来说其实就有点划不来了。但是根据 wampy 画磁带的方案我们能看到，实际上想让内容到屏幕上出来，可以直接在内存里弄一个 bitmap 当作纹理，也就是说，我们完全可以直接走纯 CPU 的 SDL 运行模式，把所有的画面都塞进一个 480x800 的 SDL_Surface，最后用 eglSwapBuffers 把纹理画到屏幕上即可。为了验证这条思路，我直接让 DSH 开始上手编码啊（老实写代码，很枯燥吧），很顺利的就完成了基础图形的验证：&lt;/p&gt;&#xA;&lt;figure class=&#34;video-figure&#34;&gt;&#xA;    &lt;video&#xA;        controls&#xA;        playsinline&#xA;        preload=&#34;metadata&#34;&#xA;        src=&#34;/post/walkman-and-musicos-chapter-1/sdl-port.mp4&#34;&#xA;        &#xA;        &#xA;        &#xA;    &gt;&#xA;        &lt;p&gt;你的浏览器不支持 HTML5 视频，可以&lt;a href=&#34;/post/walkman-and-musicos-chapter-1/sdl-port.mp4&#34;&gt;直接下载&lt;/a&gt;。&lt;/p&gt;&#xA;    &lt;/video&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;显示问题解决了接下来要做的就不多了，接着让 AI 来做触屏和按键的支持，编译方面 SDL2 静态交叉编译用 zig：&lt;code&gt;-target arm-linux-gnueabihf.2.23&lt;/code&gt;，再把自己库存的游戏资源放到机器里，游戏就水灵灵的跑起来了～&lt;/p&gt;&#xA;&lt;figure class=&#34;video-figure&#34;&gt;&#xA;    &lt;video&#xA;        controls&#xA;        playsinline&#xA;        preload=&#34;metadata&#34;&#xA;        src=&#34;/post/walkman-and-musicos-chapter-1/sdlpal-run.mp4&#34;&#xA;        &#xA;        &#xA;        &#xA;    &gt;&#xA;        &lt;p&gt;你的浏览器不支持 HTML5 视频，可以&lt;a href=&#34;/post/walkman-and-musicos-chapter-1/sdlpal-run.mp4&#34;&gt;直接下载&lt;/a&gt;。&lt;/p&gt;&#xA;    &lt;/video&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;群友：好hifi的敲脑袋&lt;/p&gt;&#xA;&lt;p&gt;群友：好听才是好头&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;当然整个过程其实并没有这么顺利，还是踩了很多坑的，这里简单的列举一下遇到的问题和解决方案，具体的细节已经记不太清了，我直接让 AI 归纳了一下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;事件没用&lt;/strong&gt;：往 SDL 队列里塞 &lt;code&gt;SDL_KEYDOWN&lt;/code&gt; 没反应，SDLPAL 判断输入走的是 &lt;code&gt;SDL_GetKeyboardState()&lt;/code&gt; 轮询，得直接改键盘状态。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;按键穿透&lt;/strong&gt;：hide 只是不画索尼窗口，&lt;code&gt;KeyService&lt;/code&gt; 还在读同一个 evdev，按播放键游戏没动、MP3 倒是开始放了 → &lt;code&gt;EVIOCGRAB&lt;/code&gt; 独占 &lt;code&gt;event0/1/4&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;红蓝对调&lt;/strong&gt;：&lt;code&gt;SDL_PIXELFORMAT_ARGB8888&lt;/code&gt; 在小端内存里是 BGRA，按 &lt;code&gt;GL_RGBA&lt;/code&gt; 上传就反了 → 换 &lt;code&gt;RGBA32&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;触摸不准&lt;/strong&gt;：上报范围是 0..959 × 0..1599，不是 480×800，所以帮助面板上的红点跟手指完全无关。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;声卡归谁&lt;/strong&gt;：SDL 的 ALSA 后端在交叉编译时没真编进去，走内核 OSS 兼容层 &lt;code&gt;AUDIODEV=/dev/snd/dsp&lt;/code&gt;；索尼在放歌时先让它 pause，抢不到就静音继续。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;做到这里我突然有了一个很大胆甚至点狂妄的想法：其实我觉得索尼的系统并没有那么好用，既然现在有 AI 神力加持，同时我自己对 Linux 和音频 codec 相关不说精通，至少方方面面都有点了解，那么我是不是可以带着 LLM，做出一个更满足我个人偏好的用户态播放器呢？&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
