<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>EDK Piepaint&apos;s Personal Collections -- EDK Piepaint 的個人所藏</title><description>Powered by QTI SM8750 MTP (SM8750 MTP 개발 플랫폼)</description><link>https://blog.cloudflare88.eu.org/</link><language>en</language><item><title>個人歷代搜尋引擎使用歷程之歌(Feat. Hana Oryon) -- 「我們國家的大統領」大韓民國歷代大統領之歌的 FOSS 改編</title><link>https://blog.cloudflare88.eu.org/posts/personal-search-engine-uasge-history-song/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/personal-search-engine-uasge-history-song/</guid><description>僅以此曲，記錄我的搜尋引擎使用歷程。</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%E5%80%8B%E4%BA%BA%E6%AD%B7%E4%BB%A3%E6%90%9C%E5%B0%8B%E5%BC%95%E6%93%8E%E4%BD%BF%E7%94%A8%E6%AD%B7%E7%A8%8B%E4%B9%8B%E6%AD%8C%20(Remix).mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%E5%80%8B%E4%BA%BA%E6%AD%B7%E4%BB%A3%E6%90%9C%E5%B0%8B%E5%BC%95%E6%93%8E%E4%BD%BF%E7%94%A8%E6%AD%B7%E7%A8%8B%E4%B9%8B%E6%AD%8C.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/3jr283nGAjs?si=W5234I_xRIHHBUF0&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Intro&lt;/h1&gt;
&lt;p&gt;全球資訊網(史上)第一，是 Archie 和 Gopher,&amp;lt;/br&amp;gt;
1991 年創立，13年統治 &amp;lt;/br&amp;gt;
(選單)結構限制，最終被趕下臺 &amp;lt;/br&amp;gt;
世上第一搜尋引擎，就這樣退場 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;華文搜尋第一，(我們)臺灣蕃薯藤 &amp;lt;/br&amp;gt;
1995 年成立，服務(使用者)至今 &amp;lt;/br&amp;gt;
即使政治色彩濃厚，「第一」不可否 &amp;lt;/br&amp;gt;
感謝 Yam 大統領，我們的大統領 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;專有軟體出發，美國 Google 會社 &amp;lt;/br&amp;gt;
1998 年以來，統治網路至今 &amp;lt;/br&amp;gt;
蒐集隱私好手，使用者苦不堪言 &amp;lt;/br&amp;gt;
感謝 Google 大統領，我們的大統領 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;南韓市佔最高，韓國 Naver 檢索 &amp;lt;/br&amp;gt;
1999 年成立，(僅僅)使用6個月 &amp;lt;/br&amp;gt;
新聞電郵(電子)地圖，服務獨佔鰲頭 &amp;lt;/br&amp;gt;
(無用)資訊氾濫，廣告漫天，真讓我爲難 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 4&lt;/h1&gt;
&lt;p&gt;專有軟體再臨，美國 Yahoo! 搜尋 &amp;lt;/br&amp;gt;
1994 年成立，(至今)32年統治 &amp;lt;/br&amp;gt;
向政府出賣個資，廣告無處不在 &amp;lt;/br&amp;gt;
並不感謝 Yahoo ，卻是我的網路教師 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 5&lt;/h1&gt;
&lt;p&gt;普通愛好者趣味*(自架)，FrogFind 檢索 &amp;lt;/br&amp;gt;
2023 年成立，專爲老舊硬體 &amp;lt;/br&amp;gt;
雖然設計簡單，卻足夠瀏覽網路 &amp;lt;/br&amp;gt;
感謝 FrogFind 大統領，我們的大統領 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;*趣味：興味，興趣愛好&lt;/em&gt; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 6&lt;/h1&gt;
&lt;p&gt;間諜軟體出發，中國百度檢索 &amp;lt;/br&amp;gt;
虛假信息干擾，網路搜尋實名制 &amp;lt;/br&amp;gt;
以隱私換方便，Google 自愧不如 &amp;lt;/br&amp;gt;
不曾使用百度搜尋，也不會感激 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 7&lt;/h1&gt;
&lt;p&gt;隱私保護出發，美國鴨走走(DuckDuckGo)搜尋，&amp;lt;/br&amp;gt;
Onion (網址)匿名化搜尋，是重大變革 &amp;lt;/br&amp;gt;
從不記錄/蒐集隱私，一切功能從簡 &amp;lt;/br&amp;gt;
感謝 DuckDuckGo 大統領，我們的大統領 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 8&lt;/h1&gt;
&lt;p&gt;開源自架(軟體)出發，SearXNG (元)搜尋 &amp;lt;/br&amp;gt;
集合搜尋，統一檢索，高度客製化 &amp;lt;/br&amp;gt;
只需支援 Docker 容器就可以實作 &amp;lt;/br&amp;gt;
&lt;strong&gt;隱私牢牢掌控，做自己的大統領&lt;/strong&gt; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 9&lt;/h1&gt;
&lt;p&gt;實用從簡出發，荷蘭 Startpage 檢索 &amp;lt;/br&amp;gt;
1998 年成立，28年歷史 &amp;lt;/br&amp;gt;
沒有總結，AI 服務，只有質朴耐用 &amp;lt;/br&amp;gt;
感謝 Startpage 大統領，不再依賴過度 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 10&lt;/h1&gt;
&lt;p&gt;最早元搜尋引擎是 Dogpile, &amp;lt;/br&amp;gt;
1996 年建立，30年歷史 &amp;lt;/br&amp;gt;
介面設計不禁讓人回想到從前, &amp;lt;/br&amp;gt;
無憂無慮的時代，如今一去不返 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 11&lt;/h1&gt;
&lt;p&gt;下面要介紹的間諜軟體是 Bing 搜尋,&amp;lt;/br&amp;gt;
介面華麗，Copilot 助理，盜走我個資 &amp;lt;/br&amp;gt;
儘管 AI 助理曾經幫助我事務, &amp;lt;/br&amp;gt;
可牠是專有軟體，內建追蹤器 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 12&lt;/h1&gt;
&lt;p&gt;革命軟體出發，Claude AI 檢索 &amp;lt;/br&amp;gt;
功能多樣，程式開發是拿手絕活 &amp;lt;/br&amp;gt;
在大統領幫助下我開始 Linux 移植,&amp;lt;/br&amp;gt;
雖然過程艱難，但我依舊熱愛 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;回顧過去使用搜尋引擎的歷程，&amp;lt;/br&amp;gt;
捍衛個人隱私已是我的必選項 &amp;lt;/br&amp;gt;
我不是犯罪分子也不是異見人士，&amp;lt;/br&amp;gt;
只想守護個資，捍衛數位主權 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;縱使守護個資之路再遠再艱難，&amp;lt;/br&amp;gt;
&lt;strong&gt;(依然)捍衛個人隱私，做自己的大統領&lt;/strong&gt; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>給 Radxa Q6A 單板機安裝 PostmarketOS，在 Armbian 之外的另一個選擇</title><link>https://blog.cloudflare88.eu.org/posts/postmarketos-q6a/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/postmarketos-q6a/</guid><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Radxa Q6A 單板機改裝 PostmarketOS，使用基於 &lt;code&gt;musl&lt;/code&gt; 的發行版，節省記憶體，沒有受支援的 Android 手機，也可以體驗爲手機開發的 Linux 發行版。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Radxa Q6A 單板機紹介&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;請參閱 &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/q6a-review/&quot;&gt;Q6A 單板機紹介&lt;/a&gt;了解更多關於單板電腦的硬體資訊。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Radxa Q6A 是採用高通 Dragonwing QCS6490 ARM 晶片的單板機。相容 Arm V8 指令集，核心時脈2.7GHz。提供 GPIO，PCIe 等介面，用於連接多種外部裝置，可以滿足一般軟體/硬體開發者的開發，除錯需求。&amp;lt;/br&amp;gt;
板底還附有 MIPI CSI/DSI，UFS/eMMC 模組接口，用於安裝熒幕和UFS/eMMC 快閃記憶體。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;PostmarketOS 的支援情況&lt;/h1&gt;
&lt;p&gt;Q6A 的 PostmarketOS 移植採用 upstream kernel，硬體支援較好。CPU，GPU，PCIe 等功能都已受到支援，Wi-Fi 和 Bluetooth 在自行編譯核心模組後也可以正常工作。不過軟體依然有些問題...&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;待機(Suspend)似乎有些問題，必須通過 &lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;alt&lt;/code&gt; + &lt;code&gt;F7&lt;/code&gt; 組合鍵切換 TTY 控制臺才可以喚醒；&amp;lt;/br&amp;gt;&lt;/li&gt;
&lt;li&gt;GNOME 桌面在 OpenRC init 程式下似乎有問題，嘗試登出使用者會遇到「GNOME Shell 失去回應」的提示，但是 GNOME 依然可以操作；&amp;lt;/br&amp;gt;&lt;/li&gt;
&lt;li&gt;冷啓動單板機會導致 RTC 時鐘無法存取，&lt;code&gt;dmesg&lt;/code&gt; 有 &lt;code&gt;ioctl&lt;/code&gt; 相關錯誤。&amp;lt;/br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;準備刷機&lt;/h1&gt;
&lt;p&gt;在電腦上安裝 &lt;code&gt;pmbootstrap&lt;/code&gt;，鍵入 &lt;code&gt;pmbootstrap init&lt;/code&gt; 進行設定。Radxa Q6A 已經被 PostmarketOS 列爲「社群維護(community)」支援等級，因此官方的 &lt;code&gt;pmaports&lt;/code&gt; 機型套件庫有收錄這臺裝置。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pmbootstrap init                                                      
[14:24:31] Location of the &apos;work&apos; path. Multiple chroots (native, device arch, device rootfs) will be created in there.
[14:24:31] Work path [/home/kodiak/.local/var/pmbootstrap]: 
[14:24:32] Location of the &apos;pmaports&apos; path, containing package definitions.
[14:24:32] pmaports path [/home/kodiak/.local/var/pmbootstrap/cache_git/pmaports]: 
[14:24:34] Choose the postmarketOS release channel.
[14:24:34] Available (14):
[14:24:34] * edge: Rolling release / Most devices / Occasional breakage: https://postmarketos.org/edge
[14:24:34] * v26.06: Latest release / Recommended for best stability
[14:24:34] * v25.12: Old release (supported until 2026-07-31)
[14:24:34] Channel [edge]: 
[14:24:34] NOTE: pmaports is on main branch, copying git hooks.
[14:24:34] Choose your target device vendor (either an existing one, or a new one for porting).
[14:24:34] Available vendors (107): acer, alcatel, amazon, amediatech, amlogic, apple, ark, arrow, asus, ayaneo, ayn, bananapi, barnesnoble, beelink, blackberry, bq, clockworkpi, cubietech, cutiepi, dell, dongshanpi, epson, essential, fairphone, finepower, fly, fxtec, generic, goclever, google, gp, hisense, hp, htc, huawei, inet, infocus, jolla, khadas, klipad, kobo, lark, leeco, lenovo, lg, librecomputer, linksys, lynx, mangopi, medion, meizu, microsoft, mnt, mobvoi, motorola, nextbit, nobby, nokia, nothing, nvidia, odroid, oneplus, oppo, ouya, pine64, planet, pocketbook, postmarketos, powkiddy, purism, qcom, qemu, qualcomm, radxa, raspberry, realme, rockchip, samsung, semc, sharp, shift, sipeed, solidrun, sony, sourceparts, sqfmi, starway, surftab, t2m, thundercomm, tokio, tolino, trekstor, valve, vernee, vivo, volla, wd, wexler, wiko, wileyfox, xiaomi, xunlong, yu, zhihe, zte, zuk
[14:24:34] Vendor [qcom]:               # 裝置廠家選擇「qcom」
[14:24:36] Devices are categorised as follows, from best to worst:
* Main: ports where mostly everything works.
* Community: often mostly usable, but may lack important functionality.
* Testing: anything from &quot;just boots in some sense&quot; to almost fully functioning ports.
* Downstream: ports that use a downstream kernel — very limited functionality. Not recommended.

Available devices by codename (9): msm8226 (testing), msm8909 (testing), msm8916 (testing), msm8953 (community), msm8956 (testing), msm89x7 (testing), qcs6490 (community), rbx (testing), sm7150 (community)
[14:24:36] Device codename [qcs6490]:               # 鍵入「qcs6490」，使用爲 Dragonwing QCS6490 晶片建立的通用 port
[14:24:37] Username [kodiak]:                       # 鍵入自己的使用者名稱，例如 yupik
[14:24:40] Available providers for postmarketos-base-ui-audio-backend (2):
[14:24:40] * pulseaudio: Use pulseaudio as the audio backend. (default)
[14:24:40] * pipewire: Use pipewire as the audio backend. (but may not work with all devices)
[14:24:40] Provider [pulseaudio]:                       # 選擇系統採用的音訊伺服器，沒什麼使用音效增益軟體的需求就選 pulseaudio
[14:24:41] Available providers for postmarketos-base-ui-wifi (2):
[14:24:41] * wpa_supplicant: Use wpa_supplicant as the WiFi backend. (default)
[14:24:41] * iwd: Use iwd as the WiFi backend (but may not work with all devices)
[14:24:41] Provider [default]: 
[14:24:42] Available providers for postmarketos-usb-moded-default-profile (2):
[14:24:42] * developer: Make &apos;developer mode&apos; the default usb-moded profile (always enables usb networking) (default)
[14:24:42] * charging: Make &apos;charging mode&apos; the default usb-moded profile (usb networking must be manually enabled)
[14:24:42] Provider [developer]: 
[14:24:43] Available user interfaces (30): 
[14:24:43] * none: Bare minimum OS image for testing and manual customization. The &quot;console&quot; UI should be selected if a graphical UI is not desired.
[14:24:43] * buffyboard: Plain framebuffer console with modern touchscreen keyboard support
[14:24:43] * cage: (Wayland) Kiosk WM
[14:24:43] * console: Console environment, with no graphical/touch UI
[14:24:43] * cosmic: COSMIC Desktop Environment from System76
[14:24:43] * fbkeyboard: Plain framebuffer console with touchscreen keyboard support
[14:24:43] * gnome: (Wayland) Gnome Shell
[14:24:43] * gnome-mobile: (Wayland) Gnome Shell patched to adapt better to phones (Experimental)
[14:24:43] * i3wm: (X11) Tiling WM (keyboard required)
[14:24:43] * kodi: (GBM) 10-foot UI useful on TV&apos;s
[14:24:43] * lomiri: (Wayland) The convergent desktop environment (Experimental)
[14:24:43] * lxqt: (X11) Lightweight Qt Desktop Environment (stylus recommended)
[14:24:43] * mate: (X11) MATE Desktop Environment, fork of GNOME2 (stylus recommended)
[14:24:43] * moonlight: (Wayland) Open Source PC client for NVIDIA GameStream, as used by the NVIDIA Shield
[14:24:43] * niri: (Wayland) A scrollable-tiling compositor (DOES NOT RUN WITHOUT HW ACCELERATION!)
[14:24:43] * openbox: (X11) A highly configurable and lightweight X11 window manager (keyboard required)
[14:24:43] * os-installer: UI for installing postmarketOS
[14:24:43] * phosh: (Wayland) Mobile UI using GNOME components and apps
[14:24:43] * plasma-bigscreen: (Wayland) 10-feet variant of Plasma, made for big screen TVs
[14:24:43] * plasma-desktop: (Wayland) KDE Desktop Environment (works well with tablets)
[14:24:43] * plasma-mobile: (Wayland) Mobile variant of KDE Plasma
[14:24:43] * retroarch: RetroArch in KMS mode
[14:24:43] * shelli: Plain console with touchscreen gesture support
[14:24:43] * sway: (Wayland) Tiling WM, drop-in replacement for i3wm
[14:24:43] * sxmo-de-dwm: Simple Mobile: Mobile environment based on SXMO and running on dwm
[14:24:43] * sxmo-de-i3: Simple Mobile: Mobile environment based on SXMO and running on i3
[14:24:43] * sxmo-de-river: Simple Mobile: Mobile environment based on SXMO and running on river
[14:24:43] * sxmo-de-sway: Simple Mobile: Mobile environment based on SXMO and running on sway
[14:24:43] * weston: (Wayland) Reference compositor (demo, not a phone interface)
[14:24:43] * windowmaker: (X11) Window manager inspired by the NeXTSTEP user interface (stylus recommended)
[14:24:43] * xfce4: (X11) Lightweight desktop (stylus recommended)
[14:24:43] User interface [gnome]:  # 依用途選擇桌面環境或者使用者介面
[14:24:45] Based on your UI selection, &apos;default&apos; will result in installing systemd.
[14:24:45] Install systemd? (default/always/never) [never]:  # 是否使用 systemd？鍵入「never」來改用 Alpine 採用的 OpenRC init 程式
[14:24:46] Additional options: extra free space: 0 MB, boot partition size: 512 MB, parallel jobs: 8, ccache per arch: 5G, sudo timer: False, mirror: http://mirror.postmarketos.org/postmarketos/
[14:24:46] Change them? (y/n) [n]: 
[14:24:46] Additional packages that will be installed to rootfs. Specify them in a comma separated list (e.g.: vim,file) or &quot;none&quot;
[14:24:46] Extra packages [nano]: 
[14:24:47] Your host timezone: Australia/Perth
[14:24:47] Use this timezone instead of GMT? (y/n) [y]: # 設定時區，語言...
[14:24:47] Choose your preferred locale, like e.g. en_US. Only UTF-8 is supported, it gets appended automatically. Use tab-completion if needed.
[14:24:47] Locale [en_US]: 
[14:24:48] Device hostname (short form, e.g. &apos;foo&apos;) [qcom-qcs6490]: 
[14:24:48] SSH public keys found (1):
[14:24:48] * /home/kodiak/.ssh/id_ed25519.pub
[14:24:48] See https://postmarketos.org/ssh-key-glob for more information.
[14:24:48] Would you like to copy these public keys to the device? (y/n) [n]: 
[14:24:49] After pmaports are changed, the binary packages may be outdated. If you want to install postmarketOS without changes, reply &apos;n&apos; for a faster installation.
[14:24:49] Build outdated packages during &apos;pmbootstrap install&apos;? (y/n) [n]: 
[14:24:49] Zap existing chroots to apply configuration? (y/n) [y]: 
[sudo] password for kodiak: 
[14:24:56] DONE!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定完成後，鍵入 &lt;code&gt;pmbootstrap install --sdcard= &lt;/code&gt; 命令語將 PostmarketOS 安裝到 SD 卡，或者是 NVME SSD 之類的裝置上。安裝完成後，將 SD 卡(或者是快閃記憶體模組)插到單板機上，按下開機按鈕，將 boot order 改爲從 SD 卡開機，等到熒幕出現 &lt;code&gt;gdm&lt;/code&gt; 的畫面後，鍵入自己設定的密碼登入系統。&amp;lt;/br&amp;gt;
除了內建的 WiFi 網路卡不可用(沒有驅動程式)，其他功能都可以使用了。&lt;/p&gt;
&lt;h1&gt;修復 Wi-Fi 網路卡&lt;/h1&gt;
&lt;p&gt;Q6A 單板機內建採用 USB 2.0 協定的 Quectel FCU760K(又是妳啊...還是一如既往的難以使用，對吧？) Wi-Fi 網路卡，使用 AICSemi AIC8800 晶片。目前裝置相關的驅動程式沒有進入 upstream kernel，需要使用 out-of-tree 的 &lt;code&gt;aic8800&lt;/code&gt; &lt;a href=&quot;https://github.com/radxa-pkg/aic8800&quot;&gt;核心模組&lt;/a&gt;。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;編譯自訂核心&lt;/h2&gt;
&lt;p&gt;雖然 Alpine Linux 採用自己的 AKMS(Alpine Kernel Module Support)，同樣可以像 DKMS 那樣編譯 out-of-tree 核心模組到核心中，隨着核心升級而升級。但我並不會編寫自己的 AKMS 編譯指令搞，只能手動編譯核心模組，再 &lt;code&gt;insmod&lt;/code&gt; 到自己的自訂核心中了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;執行 &lt;code&gt;git clone https://github.com/radxa-pkg/aic8800.git&lt;/code&gt; 命令語下載 Radxa 提供的 &lt;code&gt;aic8800&lt;/code&gt; 模組原始碼，再去 kernel.org 上下載一份主線核心的原始碼 tar 壓縮檔，解壓縮檔案就可以開始編譯核心了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 下載核心原始碼
wget https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.1.5.tar.xz
tar -Jxf linux-7.1.5.tar.xz 

# 安裝編譯用套件 &amp;amp; 編譯核心

sudo apk add build-base openssl-dev libelf-dev bison flex perl linux-headers ncurses-dev tar xz cpio bash
cd linux-7.1.5
make nconfig    # 或者 make xconfig (需要安裝QT6套件)
make -j8 Image.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不想通過 &lt;code&gt;make nconfig&lt;/code&gt; 來手動建立配置檔，可以從單板機上正在運行的作業系統複製其核心 &lt;code&gt;.config&lt;/code&gt; 配置檔，例如 Armbian 或者 Fedora。&amp;lt;/br&amp;gt;之後通過 &lt;code&gt;make nconfig&lt;/code&gt; 命令語儲存就可以了。在 Q6A 單板機編譯核心需要大約36分鐘(12GB記憶體)就可以完成。&amp;lt;/br&amp;gt;
安裝自訂核心及核心模組。PostmarketOS 默認需要自己處理 &lt;code&gt;initramfs&lt;/code&gt; 和開機程式的修改。雖然安裝了核心之後需要藉助 &lt;code&gt;mkinitfs&lt;/code&gt; 重新產生一份 &lt;code&gt;initramfs&lt;/code&gt; 給自訂核心，但似乎直接拿自帶 7.1.2 核心的 &lt;code&gt;initramfs&lt;/code&gt; 也可以？&amp;lt;/br&amp;gt;
之後，用 &lt;code&gt;nano&lt;/code&gt; 或者其他方法，新增一份 &lt;code&gt;systemd-boot&lt;/code&gt; 開機載入程式的配置檔，告訴 &lt;code&gt;systemd-boot&lt;/code&gt; 採用自訂核心開機(其中 &lt;code&gt;option&lt;/code&gt; 可以從 &lt;code&gt;/proc/cmdline&lt;/code&gt; 中複製當前核心的引數修改)：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /boot/loader/entries/pmos-custom.conf

title PostmarketOS
sort-key PostmarketOS
linux vmlinuz
initrd initramfs
options loglevel=5 rw console=tty0 ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;/boot/loader/loader.conf&lt;/code&gt; 檔案，新增 &lt;code&gt;timeout&lt;/code&gt; &lt;code&gt;console-mode&lt;/code&gt; 引數：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /boot/loader/loader.conf

timeout 3
console-mode keep
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;編譯驅動原始碼&lt;/h2&gt;
&lt;p&gt;首先執行 &lt;code&gt;lsusb&lt;/code&gt;，應該會看到 VID 和 PID 爲 &lt;code&gt;a69c:8d80&lt;/code&gt; 的裝置，根據原始碼中提供的廠家文檔來看，應該是 AIC8800D80 晶片(下方命令語爲範例):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 003: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 005: ID 248a:60ab Maxxter AiMouse
Bus 001 Device 006: ID 2717:5015 Xiaomi Inc. Xiaomi Wired Mechanical Keyboard      # 嗯...這些是我自願放棄的隱私
Bus 001 Device 007: ID a69c:8d81 AICSemi AIC 8800D80    # 裝載韌體並正常工作的 AIC8800 網路卡
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 002: ID 05e3:0626 Genesys Logic, Inc. Hub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/aic-doc.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;因爲 Linux 7.1 &lt;code&gt;cfg80211&lt;/code&gt; 有幾處 API 變更，直接編譯驅動程式會遇到錯誤不給編譯，需要自己 patch &lt;code&gt;aic8800&lt;/code&gt; 驅動原始碼才可以補正問題。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ~/aic8800
$ wget https://raw.githubusercontent.com/gahingwoo/kiln/main/aic8800-patches/0001-aic8800-cfg80211-7.1-net_device-to-wireless_dev.patch
$ patch -p1 &amp;lt; 0001-aic8800-cfg80211-7.1-net_device-to-wireless_dev.patch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;補正之後，到原始碼找到 USB 資料夾，然後開終端機，編譯並安裝 &lt;code&gt;aic8800&lt;/code&gt; &lt;code&gt;aic_btusb&lt;/code&gt; 核心模組：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd ~/aic8800/src/USB/driver_fw/drivers/aic8800
$ make -C /lib/modules/$(uname -r)/build M=$PWD modules
$ make -C /lib/modules/$(uname -r)/build M=$PWD modules_install

$ cd ~/aic8800/src/USB/driver_fw/drivers/aic_btusb
$ make -C /lib/modules/$(uname -r)/build M=$PWD modules
$ make -C /lib/modules/$(uname -r)/build M=$PWD modules_install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安裝完成後，重開機，或者使用 &lt;code&gt;depmod -a&lt;/code&gt; 命令套用核心模組變更。&amp;lt;/br&amp;gt;
之後，鍵入 &lt;code&gt;modprobe aic_load_fw aic8800_fdrv&lt;/code&gt; 命令加載核心模組。如果發現網路卡依然不工作，檢視 &lt;code&gt;dmesg&lt;/code&gt; 發現 &lt;code&gt;aic_btusb&lt;/code&gt; 模組噴出 &lt;code&gt;failed to open&lt;/code&gt; 錯誤：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ 9.051106] aic_load_fw: loading out-of-tree module taints kernel.
[ 9.054417] aic_bluetooth_mod_init
[ 9.054424] AICWFDBG(LOGINFO) aicwf_prealloc_init enter
[ 9.057687] AICWFDBG(LOGINFO) aicwf_usb_probe vid:0xA69C pid:0x8D80 icl:0x0 isc:0x0 ipr:0x0
[ 9.057692] AICWFDBG(LOGINFO) aicloadfw_chipmatch USE AIC8800D80
[ 9.061080] aic_load_firmware :firmware path = /lib/firmware/aic8800D80/fw_patch_table_8800d80_u02.bin
[ 9.061176] aic_load_firmware: fw_patch_table_8800d80_u02.bin file failed to open
[ 9.061220] aicbt_patch_table_alloc fail
[ 9.061230] aicwf_bus_deinit
[ 9.561648] usb_err:&amp;lt;aicwf_usb_rx_submit_all_urb,234&amp;gt;: bus is not up=0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把原始碼中提供的韌體(在 &lt;code&gt;src/USB/driver_fw/fw&lt;/code&gt; 目錄)檔案，按照 &lt;code&gt;dmesg&lt;/code&gt; 中的訊息，複製到 &lt;code&gt;/lib/firmware&lt;/code&gt; 下，重開機就可以了。&amp;lt;/br&amp;gt;
複製韌體並重載核心模組後，GNOME 的 Quick setting 面板就會出現「Wi-Fi」選單，執行 &lt;code&gt;lsusb&lt;/code&gt; 後，裝置的 PID 變成 &lt;code&gt;8d81&lt;/code&gt;，網路卡可以正常使用了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;後記&lt;/h1&gt;
&lt;p&gt;使用 GNOME 的 PostmarketOS，在不安裝擴充程式的情況下，使用 &lt;code&gt;htop&lt;/code&gt; 程式檢視裝置 RAM 利用率，只有 1.5GB ~ 2GB！很棒。或許之後應該把 &lt;code&gt;aic8800&lt;/code&gt; 驅動做成 AKMS，隨着核心更新而更新，也就不用每次都要手動編譯了。&lt;/p&gt;
</content:encoded></item><item><title>Bootloader 解鎖恥辱牆 -- 適合刷機的 Android 裝置，攜帶電話等，以及無法解鎖的裝置</title><link>https://blog.cloudflare88.eu.org/posts/suitable-phones-for-flashing/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/suitable-phones-for-flashing/</guid><description>當解鎖 Bootloader 不再可能的時候，自由軟件、個人隱私與消費者權益就成爲了一句空話。</description><pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;哪家的智慧手機值得買？除了考慮裝置處理器，快閃記憶體規格和記憶體大小以外，我還會關注另外一個「鮮有人知」的指標 —— 是否可以解鎖和受主線核心支援。&amp;lt;/br&amp;gt;
如果手機可以解鎖刷機，甚至可以支援改裝 Linux 等自由軟體，支援自訂開機韌體，即使是貴得要命的 Nothing，Pixel，甚至 Qualcomm 等晶片廠自家的原型機我也會考慮。假如手機不支援解鎖，即使CP值再高的 Xiaomi，Samsung 我也不會買。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
至於 iPhone，Huawei 這種「監獄」裝置，我更不會購買。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;具體來講，「解鎖」是指裝置的 Bootloader 開機韌體允許使用者解鎖，且可以隨意載入任何相容該裝置的第三方作業系統(3rd party OS)，除非有漏洞可以繞開限制，不可以解鎖的裝置無法執行任何第三方作業系統和軟體。這種裝置也並不真正屬於妳。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve been an user or been a developer,&amp;lt;/br&amp;gt;
I&apos;m the person who just rent a brend new phone.&amp;lt;/br&amp;gt;
Adopted from &lt;em&gt;MTP Trouble -- A FOSS Parody of Trouble by Avicii&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我一般不會接受藉助漏洞方法或者 EDL 這種方式解鎖，除非真的有必要。AOSP 已經定義了非常標準的解鎖方法：&lt;strong&gt;就是利用 &lt;code&gt;fastboot oem unlock&lt;/code&gt; 或 &lt;code&gt;fastboot flashing unlock&lt;/code&gt; 命令語來解鎖&lt;/strong&gt; ，沒有必要搞特規！！&lt;/p&gt;
&lt;p&gt;裝置在解開 Bootloader 鎖之後，應該允許使用者改裝其他作業系統。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bootloader 解鎖恥辱牆&lt;/h1&gt;
&lt;p&gt;哪些手機/裝置可以解鎖呢？ GitHub 上有一位同好整理了一份 &lt;a href=&quot;https://github.com/zenfyrdev/bootloader-unlock-wall-of-shame/&quot;&gt;「Bootloader 解鎖恥辱牆」&lt;/a&gt;，根據表中的「在乎使用者隱私」的廠家進行排除，再去挑裝置。&amp;lt;/br&amp;gt;
專案的 README 有各種選擇/避開該廠家的理由。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;現在，就允許我結合個人使用經驗，用我的表格來解說：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;分類&lt;/th&gt;
&lt;th&gt;代表含義&lt;/th&gt;
&lt;th&gt;品牌/裝置例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A+&lt;/td&gt;
&lt;td&gt;沒有 Bootloader 鎖或硬體安全啓動限制，使用者可以自訂裝置開機韌體，改裝 Linux 或者其他三方作業系統&lt;/td&gt;
&lt;td&gt;PINE64 PinePhone, Purism Librem 5, SHIFT SHIFT6mq, Qualcomm QRD/CRD/MTP/HDK 原型機, FuriLabs FLX1S 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;可支援解鎖，但有硬體安全啓動限制，使用者可以改裝 Linux 或其他作業系統&lt;/td&gt;
&lt;td&gt;Nothing, Volla 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-&lt;/td&gt;
&lt;td&gt;同A，但是廠家不釋出核心原始碼，違反 GPL 協議&lt;/td&gt;
&lt;td&gt;Cubot, Micromax, Teracube, Teclast 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;可支援解鎖，但需要申請，登入賬號，或依賴廠家網站/專有解鎖工具，其他同A&lt;/td&gt;
&lt;td&gt;OnePlus, Google Nexus/Pixel, FairPhone 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;僅部分裝置支援解鎖，限制多，其解鎖政策反覆變動&lt;/td&gt;
&lt;td&gt;Hisense/HMD, Nokia, Honor, HTC, LG, Motorola/Lenovo/NEC, OPPO/Realme, Oukitel, Xiaomi/Redmi/POCO, ZTE/nubia/Redmagic 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;廠家不支援解鎖，使用者控制權幾乎沒有，只能藉助晶片/作業系統漏洞強制解開 Bootloader&lt;/td&gt;
&lt;td&gt;Alcatel，Amazon，Asus，Cat，Coolpad，Doogee，Energizer，Huawei，Meizu，Panasonic，Samsung，Sharp，TCL/BlackBerry，Vivo/IQOO，Vsmart，各種 Windows Phone 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;同D，解鎖後會有部分硬體/軟體功能不可使用，重新 lock 後也無法恢復，部分廠家的裝置解鎖後甚至會直接黑磚&lt;/td&gt;
&lt;td&gt;ZTE/Nubia, OnePlus, Google Nexus/Pixel, Samsung, Sony 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F&lt;/td&gt;
&lt;td&gt;封閉的「圍牆花園」，完全無法客製化裝置&lt;/td&gt;
&lt;td&gt;UniSoc, ASR Micro Electronics，各種廠家自訂嵌入式 Linux 裝置等&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;看完 GitHub 上專案的紹介和我自己整理的表格之後，起碼妳現在知道半數以上的 Android 手機廠家的裝置都不值得買了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;就務實考量來看，目前臺灣可以買到的主流手機廠牌，又可以解鎖 Bootloader 的，應該是 Nothing Phone，Google Pixel。當然追求 Linux 攜帶電話的使用者，可以考慮買 PinePhone 或者 FuriLabs 的 FLX1S 了。&lt;/p&gt;
&lt;h1&gt;即使解開 Bootloader 也不夠，「黃金籠」仍然是封閉使用者自由和隱私的籠子&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Long since, I’ve been used to, the golden cage,&amp;lt;/br&amp;gt;
Not even grasping, what “freedom” really means.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;即使可以解開 Bootloader，可以取得 Root 權限，仍然是不夠的。妳的裝置仍然被廠家控制着，原廠的系統軟體依然潛藏着不計其數的專有軟體，蒐集者妳的一切。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;原廠家必須按照 GPL v2 協定把裝置的 Linux 核心原始碼公開，提供完整的 source tree 和 Firmware blobs。確保使用者可以自行編譯出可用的作業系統，很多廠商至今仍只公開「部分」原始碼，或公開後卻故意缺漏關鍵 patch，導致社群無法建置可開機的核心。其他三方 ROM 開發，例如 Lineage OS，crDroid 之類，就是要利用原廠的核心和韌體檔案，才可以製作出來一般使用者可以日常使用的 ROM。 &amp;lt;/br&amp;gt;
雖然會受到晶片廠家的 BSP 限制，但是一般廠家能提供5年以上系統和安全性修補程式更新是最好。還有優秀的加密措施，例如 Snapdragon 筆電上的 TPM，可以被利用產生隨機金鑰，配合 LUKS 加密硬碟防止資料被竊取。或是利用 EL2 來跑虛擬機，做到安全隔離也不錯。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Locked Bootloader 並非是不好的，但是金鑰不能只給廠商握著。爲了解決 TEE 簽章在解開 Bootloader 後手機不可信的問題，裝置應該要能使用自訂 AVB 金鑰，使用自簽的金鑰啓動 Locked Bootloader 的手機。也就是說，手機允許在刷機之後回鎖 Bootloader 仍能開機。這樣的裝置只有 Google Pixel 和少數以「可修復、可自由」為賣點的品牌(Fairphone，Shift等)，Qualcomm MTP/QRD 原型機才可以支援這麼做。其餘大多數旗艦，無論跑多漂亮的 HyperOS, ColorOS, One UI，本質上仍是「可租用的黃金籠」。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
至於把手機改裝成 Linux 手機，解鎖 Bootloader 和廠家開放原始碼更是必須。解鎖 Bootloader 是打開籠子的第一道門。真正的自由，是能把裝置變成完全屬於自己的運算平台——無論是跑 Android 衍生 ROM、還是徹底換成 mainline Linux（postmarketOS, Mobian 等）。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We run together now, toward to the freedom where we seek,&amp;lt;/br&amp;gt;
Proprietary software that we waved final “Goodbye” and we will never meet.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;解鎖 Bootloader 從來不是終點。牠只是證明：這台裝置還有機會屬於妳，而不是永遠屬於廠商。&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Look at the Code -- A FOSS Parody of Look at the Sky by Porter Robinson</title><link>https://blog.cloudflare88.eu.org/posts/look-at-the-code/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/look-at-the-code/</guid><description>Look at the Code, you&apos;re still here. You&apos;ll be alive next year. Tribute to my OnePlus 6T with postmarketOS.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/8diNtEqmKhE?si=qct7OlZ6fb56MpgS&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;OnePlus 6T at the beach&quot; 圖片，EDKPiepaint 版權所有；&lt;/li&gt;
&lt;li&gt;Look at the Sky 歌詞，Porter Robinson 版權所有。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如有疑問，請洽版權所有者。
:::&lt;/p&gt;
&lt;p&gt;(原文寫於2025年10月16日)&lt;/p&gt;
&lt;h2&gt;Part 1&lt;/h2&gt;
&lt;p&gt;It&apos;s a fate? &amp;lt;/br&amp;gt;
If it&apos;s not easy, then it must not be &amp;lt;/br&amp;gt;
At my age, An old phone’s slowly dying on me &amp;lt;/br&amp;gt;
But I’m breaking out these walled gardens, &amp;lt;/br&amp;gt;
Android’s walls and Apple&apos;s chains, &amp;lt;/br&amp;gt;
Now I’m trying, I just want time &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 2&lt;/h2&gt;
&lt;p&gt;Wait again, You&apos;ll be much better than &amp;lt;/br&amp;gt;
Trust me, I said: &amp;lt;/br&amp;gt;
You&apos;ll be much better than &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 3&lt;/h2&gt;
&lt;p&gt;Loot at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
I will port mainline goods, oh &amp;lt;/br&amp;gt;
Mainline for you &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Loot at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
Linux and Docker on you, oh &amp;lt;/br&amp;gt;
Updates too &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 4&lt;/h2&gt;
&lt;p&gt;Are you close? &amp;lt;/br&amp;gt;
Shouldn’t freedom come naturally? &amp;lt;/br&amp;gt;
And everyone laughts: &amp;lt;/br&amp;gt;
&quot;You’re killing convenience for privacy&quot; &amp;lt;/br&amp;gt;
But then something must have urged me, &amp;lt;/br&amp;gt;
To set this silicon free, &amp;lt;/br&amp;gt;
Now I&apos;m sure, &amp;lt;/br&amp;gt;
I&apos;m sure &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 5&lt;/h2&gt;
&lt;p&gt;Loot at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
I will port mainline goods, oh &amp;lt;/br&amp;gt;
Mainline for you &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Loot at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
Linux and Docker on you, oh &amp;lt;/br&amp;gt;
Updates too &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 6&lt;/h2&gt;
&lt;p&gt;Restart again, You&apos;ll be much better then &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
And finally, &amp;lt;/br&amp;gt;
I kept your software up-to-date &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Look at the code... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Ending&lt;/h2&gt;
&lt;p&gt;Look at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
I will port mainline goods, oh &amp;lt;/br&amp;gt;
Mainline for you &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;Look at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
I will port mainline goods, oh &amp;lt;/br&amp;gt;
Mainline for you &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Look at the code, you&apos;re still here, &amp;lt;/br&amp;gt;
You&apos;ll be alive next year, &amp;lt;/br&amp;gt;
I will run Docker on you, oh &amp;lt;/br&amp;gt;
Minecraft too &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>即使核心跑在 EL2 也沒關係，照樣可以聽音樂和使用虛擬機～ 驍龍裝置使用 qebspil EFI 驅動程式，讓系統 UEFI 韌體載入遠端處理器保証裝置硬體功能運作</title><link>https://blog.cloudflare88.eu.org/posts/qebspil-guide/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/qebspil-guide/</guid><pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;寫在前面&lt;/h1&gt;
&lt;p&gt;在&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/&quot;&gt;前面&lt;/a&gt;寫過講高通平臺如何利用 &lt;code&gt;slbounce&lt;/code&gt; 讓 Linux 核心跑在 EL2 下，從而可以使用 Snapdragon X Elite 晶片的硬體虛擬化功能跑 Linux 或 Windows 虛擬機的教學。但是，因爲高通晶片的限制，Linux 核心跑在 EL2 之後， ADSP，CDSP 之類的遠端處理器都會噴掉，包括 USB，音訊的功能將無法使用。即使使用 &lt;code&gt;echo &quot;start&quot; &amp;gt; /sys/class/remoteproc/remoteprocN/state&lt;/code&gt; 命令手動打開遠端處理器也不行。&lt;code&gt;dmesg&lt;/code&gt; 會噴 &lt;code&gt;-22 EINVAL&lt;/code&gt; 錯誤。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;之後我在使用 Q6A 單板電腦跑虛擬機的時候發現，同樣是 Snapdragon 平臺的 QCA6490 晶片跑 Armbian，遠端處理器卻在正常執行。進入 UEFI 韌體的設定選單發現韌體支援預載入遠端處理器，但是普通的筆電當然不會支援這個功能，畢竟驍龍筆電本身就是跑 Windows 系統的。韌體自然也是針對 Windows 作業系統的開機流程實作的。有沒有像 &lt;code&gt;slbounce&lt;/code&gt; 那樣的 EFI 驅動程式可以預先初始化遠端處理器呢？&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
今天 Piepaint 要來介紹的，就是高通平臺下預先載入遠端處理器的 EFI 驅動程式 -- &lt;code&gt;qebspil&lt;/code&gt;。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;&lt;code&gt;qebspil&lt;/code&gt; 紹介&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;qebspil&lt;/code&gt;（Qualcomm Exit Boot Services Peripheral Image Loader）是由 Stephan 開發的一個 UEFI 驅動程式(UEFI boot driver)，在 UEFI EBS(&lt;code&gt;ExitBootServices()&lt;/code&gt;) 階段之前（late boot 階段）啟動 Qualcomm 平台的遠端處理器(remote processors，如 ADSP/CDSP 之類)。 牠讓 DSP 韌體能在作業系統無關的情況下早期載入，特別適合 EL2/虛擬化環境或不支援 DSP 啟動的 Linux 配置。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;stephan-gh/qebspil&quot;}&lt;/p&gt;
&lt;p&gt;關鍵特點如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;獨立於 OS：在 UEFI &lt;code&gt;ExitBootServices&lt;/code&gt; 前執行，不依賴 Linux &lt;code&gt;remoteproc&lt;/code&gt; 核心模組。&lt;/li&gt;
&lt;li&gt;安全性：依賴 TZ/PAS 進行韌體驗證，加載廠商數位簽章後的韌體。&lt;/li&gt;
&lt;li&gt;相容性：只在套用了 EL2 DTB overlay 裝置 DTB 的 boot flow 中啟動，保留標準 Linux 行為。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;準備工作&lt;/h1&gt;
&lt;p&gt;首先，在網路搜尋「 UEFI Shell 」，找到相對應的 &lt;a href=&quot;https://github.com/pbatard/UEFI-Shell/releases&quot;&gt;GitHub 網址&lt;/a&gt;，下載檔案名爲 &lt;code&gt;shellaa64.efi&lt;/code&gt; 的EFI應用程式，將其複製到 EFI系統分割中的 &lt;code&gt;/EFI/BOOT/&lt;/code&gt; 目錄下。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;pbatard/UEFI-Shell&quot;}&lt;/p&gt;
&lt;p&gt;如果妳使用的是 rEFInd 或者 &lt;code&gt;systemd-boot&lt;/code&gt; 引導載入器，那麼牠們會自動搜尋 UEFI shell 並將其添加到選單中，如果是 GRUB 使用者，可能還需要進行手動設定。&amp;lt;/br&amp;gt;
然後，到 GitHub 上搜尋&lt;a href=&quot;https://github.com/stephan-gh/qebspil/&quot;&gt;「qebspil」&lt;/a&gt;，然後下載 &lt;code&gt;qebspil.efi&lt;/code&gt; EFI驅動程式，將其複製到 EFI系統分割中。。同時，需要將啟動遠端處理器（ADSP、CDSP 等）的韌體檔案複製到 ESP 的頂層 &lt;code&gt;/firmware/&lt;/code&gt; 目錄下，不同晶片平臺需要的遠端處理器韌體不同。可以使用 &lt;code&gt;find /sys/firmware/devicetree -name firmware-name -exec cat {} + | xargs -0n1&lt;/code&gt; 指令檢視需要複製的韌體，在 Yoga Slim 7x 筆電上，需要複製 &lt;code&gt;adsp_dtbs.elf&lt;/code&gt; &lt;code&gt;cdsp_dtbs.elf&lt;/code&gt; &lt;code&gt;qcadsp8380.mbn&lt;/code&gt; &lt;code&gt;qccdsp8380.mbn&lt;/code&gt; 四個啓動 ADSP，CDSP 的韌體。關於 &lt;code&gt;qebspil&lt;/code&gt; EFI 驅動程式預先啓動遠端處理器的機理比較複雜，Piepaint 我根據自己的理解與檢索程式原始碼和相關資料之後，將實作流程寫在下面，供專業讀者和開發人員進行參考：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;qebspil&lt;/code&gt; 的實作流程分爲五部分： &lt;code&gt;callback&lt;/code&gt; 的建立與觸發；DTB 解析與 PIL 管理；韌體載入與準備；與 TZ/SCM 互動；與 Linux 核心的配合。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;&lt;code&gt;callback&lt;/code&gt; 的建立與觸發&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;event_register_group_callback()&lt;/code&gt; 檢視設備樹表(Device Tree Table)的變更[^1]；&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;...
// main.c
status = event_register_group_callback(&amp;amp;EfiDtbTableGuid, &amp;amp;event, efi_dtb_changed);
if (EFI_ERROR(status)) return status;
return efi_dtb_changed();   // 立即執行一次
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;當 Bootloader 載入設備樹後，呼叫 &lt;code&gt;efi_dtb_changed()&lt;/code&gt;，將這一變數傳遞給 &lt;code&gt;dtb_enumerate_rprocs(dtb)&lt;/code&gt; 來解析裝置的設備樹，並處理 DTB 中標記爲「正常(&lt;code&gt;status = &quot;okay&quot;&lt;/code&gt;)」的遠端處理器。檢視設備樹中遠端處理器的 &lt;code&gt;compatible&lt;/code&gt; 字串內容，匹配預先定義的 &lt;code&gt;pil_type&lt;/code&gt;。爲了避免核心執行不穩定，&lt;code&gt;qebspil&lt;/code&gt; 只會載入有 &lt;code&gt;qcom,broken-reset&lt;/code&gt; 屬性的遠端處理器[^2]；&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;...
status = dtb_enumerate_rprocs(dtb);
   if (status == EFI_NOT_FOUND)
   	return EFI_SUCCESS; /* No remoteprocs found */
   if (EFI_ERROR(status))
   	return status;
   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;同時，在 &lt;code&gt;efi_dtb_changed()&lt;/code&gt; 內部會註冊一個 Late EBS（&lt;code&gt;ExitBootServices&lt;/code&gt;）事件 &lt;code&gt;efi_late_ebs&lt;/code&gt;。這是 &lt;code&gt;qebspil&lt;/code&gt; 的精妙之處，牠使用 EDK2 的內部機制讓該 callback 在極晚的 TPL 級別執行，確保在 UEFI 轉交控制權給 Linux 核心的最後一刻，才真正執行 &lt;code&gt;pil_finish_all()&lt;/code&gt; 來啟動遠端處理器。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// event.c + main.c
if (!ebs_event) {
   status = event_register_late_ebs_callback(&amp;amp;ebs_event, efi_late_ebs);
   // 使用 EDK2 內部 hack 將 TPL 調低，讓 callback 盡量晚執行
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DTB 解析與 PIL 管理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;dtb_enumerate_rprocs()&lt;/code&gt; 中遍歷所有 &lt;code&gt;remoteproc*&lt;/code&gt; 節點;&lt;/li&gt;
&lt;li&gt;匹配 &lt;code&gt;pil_type&lt;/code&gt;（包含 compatible、PAS ID、proxy GUID 等）;&lt;/li&gt;
&lt;li&gt;支援多組件（DTB 擴充段 + 主要韌體），並限制全域最多可管理的遠端處理器裝置數量（目前 4 個）[^4];&lt;/li&gt;
&lt;li&gt;從 DTB 取得 &lt;code&gt;memory-region&lt;/code&gt;、&lt;code&gt;firmware-name&lt;/code&gt; 等屬性。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// dtb.c 片段
ret = lkfdt_u32list_get(ctx-&amp;gt;dtb, node, &quot;memory-region&quot;, idx, &amp;amp;mem_phandle);
if (ret) return EFI_INVALID_PARAMETER;
// ... 取得 reserved-memory 資訊

fw_name = fdt_stringlist_get(ctx-&amp;gt;dtb, node, &quot;firmware-name&quot;, idx, NULL);
if (!fw_name) return EFI_INVALID_PARAMETER;
    ...

/* 枚舉裝置的遠端處理器 */

static EFI_STATUS dtb_enumerate_rproc(struct dtb_context *ctx, int node, struct pil *pil)
{
    for (enum pil_component c = 0; c &amp;lt; PIL_COMPONENTS; c++) {
        /* DTB 在 DTB 中排在後面，但在 enum 中排在前面 */
        int idx = PIL_COMPONENTS - c - 1;
        if (!pil_has_component(pil, c)) continue;
        status = dtb_load_pil_data(ctx, node, &amp;amp;pil-&amp;gt;fw[c], idx);
        ...
    }
}

...

while ((node = fdt_next_node(dtb, node, NULL)) &amp;gt;= 0) {
    ...
    if (!name || strncmp(name, &quot;remoteproc&quot;, sizeof(&quot;remoteproc&quot;) - 1))
        continue;
    if (!lkfdt_node_is_available(dtb, node))
        continue;
    if (!QEBSPIL_ALWAYS_START &amp;amp;&amp;amp; !fdt_getprop(dtb, node, &quot;qcom,broken-reset&quot;, NULL))
        continue;   // 預設只啟動標記 qcom,broken-reset 的 remoteproc
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;韌體載入與準備&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;從 ESP 分割的 &lt;code&gt;/firmware/&lt;/code&gt; 目錄讀取韌體(根據 DTB 中 &lt;code&gt;firmware-name&lt;/code&gt; 定義的韌體路徑和韌體名稱而定)；&lt;/li&gt;
&lt;li&gt;載入 ELF 韌體(&lt;code&gt;*_dtbs.elf&lt;/code&gt;)，利用 ELF 函式庫(&lt;code&gt;elf.h&lt;/code&gt;)驗証 ELF header，Program headers，&lt;code&gt;PT_LOAD&lt;/code&gt; 引數之類；&lt;/li&gt;
&lt;li&gt;準備 metadata（從 ELF 的 &lt;code&gt;PT_NULL&lt;/code&gt; segments 提取，用於 PAS 驗證）[^3]；&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;...
EFI_STATUS fw_load_metadata(struct pil_fw *fw)
{
   const Elf32_Ehdr *ehdr = fw-&amp;gt;elf_data;
   const Elf32_Phdr *phdr = fw-&amp;gt;elf_data + ehdr-&amp;gt;e_phoff;
   VOID *metadata = (VOID*)fw-&amp;gt;metadata;
   UINT64 pos = 0;

   for (Elf32_Half i = 0; i &amp;lt; ehdr-&amp;gt;e_phnum; i++, phdr++) {
   	if (phdr-&amp;gt;p_type != PT_NULL || phdr-&amp;gt;p_filesz == 0)     // 複製到預分配的 metadata 記憶體
   		continue;
   	if ((pos + phdr-&amp;gt;p_filesz) &amp;gt; MAX_METADATA_SIZE)
   		return EFI_BUFFER_TOO_SMALL;

   	CopyMem(metadata + pos, fw-&amp;gt;elf_data + phdr-&amp;gt;p_offset, phdr-&amp;gt;p_filesz);
   	pos += phdr-&amp;gt;p_filesz;
   }

   if (pos == 0)
   	return EFI_NOT_FOUND;

   WriteBackInvalidateDataCacheRange(metadata, MAX_METADATA_SIZE);		// 透過 WriteBackInvalidateDataCacheRange() 確保資料完整寫入實體 RAM。
   return EFI_SUCCESS;
}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fw_prepare()&lt;/code&gt;：分配 metadata 頁面與載入 ELF 資料。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fw_load()&lt;/code&gt;：將 &lt;code&gt;PT_LOAD&lt;/code&gt; segments 複製到目標記憶體位址，並處理 cache 維護。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;與 TZ/SCM 互動&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在準備好韌體與記憶體後，透過 Qualcomm SCM（Secure Channel Manager）通訊協定（&lt;code&gt;QCOM_SCM_PROTOCOL&lt;/code&gt;）向 TrustZone 核心發起安全系統呼叫（Syscall）[^5]:&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;scm_pil_init()&lt;/code&gt;：初始化 PIL（Peripheral Image Loader），傳 PAS ID + metadata;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;/* pil.c */
status = scm_pil_init(pil-&amp;gt;type-&amp;gt;id[c].full, fw-&amp;gt;metadata);
   	if (EFI_ERROR(status)) {
   		Print(u&quot;qebspil: Failed to init firmware for %a%a: %r (wrong firmware?)\n&quot;,
   		      pil-&amp;gt;type-&amp;gt;compatible, pil_component_names[c], status);
   		return status;
   	}

/* scm.c */        
EFI_STATUS scm_pil_init(UINT8 pas_id, EFI_PHYSICAL_ADDRESS metadata)
{
   UINT64 Parameters[SCM_MAX_NUM_PARAMETERS] = {
   	pas_id,
   	metadata,
   };
   UINT64 Results[SCM_MAX_NUM_RESULTS];

   return scm-&amp;gt;ScmSipSysCall(scm, TZ_PIL_INIT_ID, TZ_PIL_INIT_ID_PARAM_ID, Parameters, Results);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;scm_pil_mem_setup()&lt;/code&gt;：鎖定並設定該遠端處理器的專屬安全記憶體區域，限制非安全環境的非法存取;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
/*scm.c*/
EFI_STATUS scm_pil_mem_setup(UINT8 pas_id, EFI_PHYSICAL_ADDRESS addr, UINTN size)
{
   UINT64 Parameters[SCM_MAX_NUM_PARAMETERS] = {
   	pas_id,     /* 指定 PAS ID，大小和在記憶體的地址 */
   	addr,
   	size,
   };
   UINT64 Results[SCM_MAX_NUM_RESULTS];

   return scm-&amp;gt;ScmSipSysCall(scm, TZ_PIL_MEM_ID, TZ_PIL_MEM_ID_PARAM_ID, Parameters, Results);
}

/*pil.c*/
status = scm_pil_mem_setup(pil-&amp;gt;type-&amp;gt;id[c].full, fw-&amp;gt;mem_addr, fw-&amp;gt;mem_size);
   	if (EFI_ERROR(status)) {
   		Print(u&quot;qebspil: Failed to setup memory area for %a%a: %r\n&quot;,
   		      pil-&amp;gt;type-&amp;gt;compatible, pil_component_names[c], status);
   		return status;
   	}
   }

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;scm_pil_start()&lt;/code&gt;：驗證並用完整韌體(full firmware)再啓動遠端處理器（&lt;code&gt;TZ_PIL_AUTH_RESET_ID&lt;/code&gt;），如果因爲韌體或 DTB 原因無法完成啟動，程式會執行狀態回溯 (Rollback)：關閉剛才已成功載入的部分完整版韌體元件，避免系統處於載入一半的異常狀態（注意：此時並不會重新啟動精簡版韌體，遠端處理器將保持停止狀態）。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
/*scm.c*/
EFI_STATUS scm_pil_start(UINT8 pas_id)
{
	UINT64 Parameters[SCM_MAX_NUM_PARAMETERS] = {
		pas_id,
	};
	UINT64 Results[SCM_MAX_NUM_RESULTS];

	return scm-&amp;gt;ScmSipSysCall(scm, TZ_PIL_AUTH_RESET_ID, TZ_PIL_AUTH_RESET_ID_PARAM_ID, Parameters, Results);
}

/* pil.c */

/* Stop lite firmware in reverse order (full first, then DTB) */
	for (enum pil_component b = PIL_COMPONENTS; b &amp;gt; 0; b--) {
		if (!pil_has_component(pil, b - 1) || !pil-&amp;gt;type-&amp;gt;id[b - 1].lite)
			continue;

		/* Ignore return status since we don&apos;t know if lite was running */
		scm_pil_stop(pil-&amp;gt;type-&amp;gt;id[b - 1].lite);    // 因爲無法事先了解遠端處理器是否執行精簡版韌體，因此忽略返回的狀態變數
	}

	/* 錯誤處理 */

	for (enum pil_component c = 0; c &amp;lt; PIL_COMPONENTS; c++) {
		if (!pil_has_component(pil, c))
			continue;

		status = scm_pil_start(pil-&amp;gt;type-&amp;gt;id[c].full);
		if (EFI_ERROR(status)) {
			Print(u&quot;qebspil: Failed to authenticate and start firmware for %a%a: %r\n&quot;,  /* 錯誤信息 */
			      pil-&amp;gt;type-&amp;gt;compatible, pil_component_names[c], status);

			/* Rollback：僅停止已成功啟動的 full firmware 元件 */
			for (enum pil_component b = c; b &amp;gt; 0; b--)
				if (pil_has_component(pil, b - 1))
					scm_pil_stop(pil-&amp;gt;type-&amp;gt;id[b - 1].full);

			return status;
		}
	}


&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;使用 Proxy Vote Protocol（&lt;code&gt;PIL_PROXY_PROTOCOL&lt;/code&gt;）進行資源投票，強迫啟動相關的 Power Domain（電源域）與時脈，確保硬體周邊處於可用狀態（在 &lt;code&gt;pil_prepare()&lt;/code&gt; 階段執行）。啟動前會先嘗試停止精簡版韌體(lite firmware)（若存在），但失敗時不會自動回退到 lite 版本，而是保持停止狀態並 rollback full firmware，避免半載狀態。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;與 Linux 配合&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;qebspil&lt;/code&gt; 加載後，需要修補 Linux 核心的 &lt;code&gt;qcom_q6v5_pas.c&lt;/code&gt; &lt;code&gt;remoteproc&lt;/code&gt; 原始碼來添加遠端處理器 late attach / takeover 支援，修補後的 Linux 核心會自動接管預先啓動的遠端處理器。&lt;/p&gt;
&lt;h1&gt;修補 Linux 核心&lt;/h1&gt;
&lt;p&gt;即使使用 &lt;code&gt;qebspil&lt;/code&gt; 驅動程式，ADSP，CDSP 依然會噴掉，因爲 Linux 核心的 &lt;code&gt;qcom_q6v5_pas.c&lt;/code&gt; 驅動原始碼會重設遠端處理器的運行狀態，即使預先啓動後的遠端處理器也會被重設。因此需要修改核心這一驅動程式的原始碼。不過有一位開發者在他維護的 &lt;a href=&quot;https://github.com/sppidy/linux&quot;&gt;Ubuntu 核心&lt;/a&gt;原始碼中修補了這一驅動程式，雖然這是專爲 ASUS Zenbook A14 筆電而開發的核心，但是 Yoga Slim 7x 也同樣可以套用。下載原始碼之後鍵入 &lt;code&gt;make qcom_laptops.config ubuntu_x1e_defconfig defconfig&lt;/code&gt; 套用核心的配置檔，鍵入 &lt;code&gt;make -j12&lt;/code&gt; 開始編譯，等待五分鐘就可以了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;對於其他支援 EL2 的裝置，如果主線核心沒有關於 &lt;code&gt;qcom_q6v5_pas&lt;/code&gt; 的&lt;a href=&quot;https://github.com/sppidy/linux/commit/434c518bbe754f3ba3dea4364e99ab44a224c453&quot;&gt;相關 commit &lt;/a&gt;,則需要自己修補核心。&amp;lt;/br&amp;gt;
在核心原始碼找到 &lt;code&gt;drivers/remoteproc/qcom_q6v5_pas.c&lt;/code&gt; 原始碼，找到第824行，將程式碼修改爲下面的樣子，讓驅動程式支援「韌體已在 bootloader 載入並運行」的場景[^6]：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// remoteproc/qcom_q6v5_pas.c
rproc-&amp;gt;has_iommu = of_property_present(pdev-&amp;gt;dev.of_node, &quot;iommus&quot;);
	if (desc-&amp;gt;auto_boot)
	//	rproc-&amp;gt;auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;		// 修改 auto_boot 旗標，允許框架檢查 firmware 是否可用，並決定是 restart 還是 attach 到已經 running 的遠端處理器。
		rproc-&amp;gt;auto_boot = RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE;
	else
		rproc-&amp;gt;auto_boot = RPROC_AUTO_BOOT_DISABLED;
	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後找到887~893行，刪去驅動對於遠端處理器的檢查，讓驅動程式即使 remoteproc 還沒完全上線也能繼續初始化（特別是讀取 SMP2P 狀態、加入 glink/smd/pdm subdev 等）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// remoteproc/qcom_q6v5_pas.c
...
  /* 移除驅動對 remoteproc 沒有 start ops 就退出的檢查，即使遠端處理器沒有完全啓動也可以被核心初始化，而不是一定要從頭啓動 */
  /*if (rproc-&amp;gt;state == RPROC_OFFLINE &amp;amp;&amp;amp; !ops-&amp;gt;start) { */
	/*	dev_err(&amp;amp;pdev-&amp;gt;dev, &quot;reset broken and remoteproc not running during boot, exiting\n&quot;); */
	/*	ret = 0; */
	/*	goto deinit_q6v5; */
	/*} */
  qcom_q6v5_read_smp2p_state(&amp;amp;pas-&amp;gt;q6v5);
  qcom_add_glink_subdev(rproc, &amp;amp;pas-&amp;gt;glink_subdev, desc-&amp;gt;ssr_name);
	qcom_add_smd_subdev(rproc, &amp;amp;pas-&amp;gt;smd_subdev);
	qcom_add_pdm_subdev(rproc, &amp;amp;pas-&amp;gt;pdm_subdev);
  ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這些改動讓驅動程式能接管（attach） 已經運行的 remote processor，而不是強制從頭 start 或 boot。&lt;/p&gt;
&lt;h1&gt;套用變更&lt;/h1&gt;
&lt;p&gt;安裝編譯的核心，重開機。通過 &lt;code&gt;dmesg&lt;/code&gt; 檢視 ADSP 和 CDSP 相關的 log，應該會看到 &lt;code&gt;remoteproc: attached to adsp&lt;/code&gt; 或類似的訊息。代表 Linux 成功接管了預先啓動的遠端處理器。如果想要使用虛擬機，需要向核心啓動引數添加 &lt;code&gt;id_aa64mmfr0.ecv=1&lt;/code&gt; 引數來避免虛擬機導致裝置當機的問題。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dmesg | grep adsp
[   11.689397] remoteproc remoteproc0: adsp is available
[   11.694972] remoteproc remoteproc0: attaching to adsp
[   11.717887] remoteproc remoteproc0: remote processor adsp is now attached
[   11.845373] qcom,apr 6800000.remoteproc:glink-edge.adsp_apps.-1.-1: Adding APR/GPR dev: gprsvc:service:2:1
[   11.860349] qcom,apr 6800000.remoteproc:glink-edge.adsp_apps.-1.-1: Adding APR/GPR dev: gprsvc:service:2:2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 &lt;code&gt;cat /sys/class/remoteproc/remoteproc0/state&lt;/code&gt; 命令檢視，也會看到遠端處理器是「&lt;code&gt;attached&lt;/code&gt;」狀態。如果裝置支援音訊的話，通過 &lt;code&gt;aplay -l&lt;/code&gt; 命令也可以檢視出音訊裝置了。&amp;lt;/br&amp;gt;
至於硬體虛擬化是否啓用，通過 &lt;code&gt;ls /dev/kvm&lt;/code&gt; 命令檢視就可以了，從 &lt;code&gt;dmesg&lt;/code&gt; 檢視也會得到 KVM 和 GIC 相關的訊息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dmesg | grep kvm
[    0.068668] kvm [1]: nv: 570 coarse grained trap handlers
[    0.068803] kvm [1]: nv: 710 fine grained trap handlers
[    0.068882] kvm [1]: IPA Size Limit: 44 bits
[    0.068893] kvm [1]: GICv4 support disabled
[    0.068895] kvm [1]: GICv3: no GICV resource entry
[    0.068898] kvm [1]: disabling GICv2 emulation
[    0.068913] kvm [1]: GIC system register CPU interface enabled
[    0.068919] kvm [1]: vgic interrupt IRQ9
[    0.068943] kvm [1]: Broken CNTVOFF_EL2, trapping virtual timer
[    0.068951] kvm [1]: VHE mode initialized successfully

# dmesg | grep EL2
[    0.000000] CPU features: detected: HCRX_EL2 register
[    0.000000] CPU features: detected: Broken CNTVOFF_EL2
[    0.011357] CPU: All CPU(s) started at EL2
[    0.068943] kvm [1]: Broken CNTVOFF_EL2, trapping virtual timer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
關於 &lt;code&gt;id_aa64mmfr0.ecv=1&lt;/code&gt; 的底層小常識:&amp;lt;/br&amp;gt;
在驍龍平台（特別是 X Elite 等新一代晶片）上，日誌中提示的 &lt;code&gt;Broken CNTVOFF_EL2&lt;/code&gt; 代表硬體虛擬化計時器存在某些已知的硬體設計缺陷（Bugs）。添加 &lt;code&gt;id_aa64mmfr0.ecv=1&lt;/code&gt; 參數是為了強制修正 Enhanced Counter Virtualization (ECV) 的特性宣告，引導核心正確處理計時器偏移量，從而徹底解決 KVM 在啟動虛擬機時，因為計時器陷阱（Trapping）導致整個主機直接當機（Kernel Panic）的陳年頑疾。
:::&lt;/p&gt;
&lt;p&gt;透過 &lt;code&gt;qebspil&lt;/code&gt; 驅動程式在引導階段的承上啟下，配合 Linux 核心的 Late Attach 補丁，我們成功在不破壞安全鏈的前提下，繞過了這些硬體層面的刻意限制。既可以利用「Secure Launch」讓核心跑在 EL2 便於存取硬體虛擬化功能，又可以保證依賴遠端處理器的大部分硬體功能正常運作。&lt;/p&gt;
&lt;p&gt;[^1]:&lt;a href=&quot;https://github.com/stephan-gh/qebspil/blob/main/src/main.c&quot;&gt;main.c - qebspil on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^2]:這一預設行爲可以在編譯時使用 &lt;code&gt;QEBSPIL_ALWAYS_START=1&lt;/code&gt; 變數覆寫，無論 bootloader 裝載何種設備樹，總會在 late EBS 階段啓動裝置上的遠端處理器。&lt;/p&gt;
&lt;p&gt;[^3]:&lt;a href=&quot;https://github.com/stephan-gh/qebspil/blob/main/src/fw.c&quot;&gt;fw.c - qebspil on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^4]:&lt;a href=&quot;https://github.com/stephan-gh/qebspil/blob/main/src/pil.c&quot;&gt;程式碼&lt;/a&gt;中 &lt;code&gt;#define MAX_PIL_NUM		4&lt;/code&gt; 對於變數 &lt;code&gt;MAX_PIL_NUM&lt;/code&gt; 的定義限制的是系統中最多能枚舉多少個遠端處理器裝置（例如 SC8280XP 平臺有 ADSP、CDSP、WPSS、MPSS 遠端處理器，上限為4個）&lt;/p&gt;
&lt;p&gt;[^5]:&lt;a href=&quot;https://github.com/stephan-gh/qebspil/blob/main/src/pil.c&quot;&gt;pil.c &amp;amp; scm.c - qebspil on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^6]:&lt;a href=&quot;https://github.com/sppidy/linux/commit/434c518bbe754f3ba3dea4364e99ab44a224c453&quot;&gt;remoteproc: qcom_q6v5_pas: Attach running remoteproc if firmware is missing&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>EasyEffects 軟體紹介 -- 調整 Linux 電腦 EQ，拯救破爛喇叭</title><link>https://blog.cloudflare88.eu.org/posts/easyeffects-guide/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/easyeffects-guide/</guid><description>如果妳的裝置喇叭在 Linux 下表現不好，又不想外接喇叭，妳應該試試「EasyEffects」增強音質...</description><pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今天 Piepaint 要來介紹的軟體是「EasyEffects」，用於調整 Linux 裝置的 EQ，讓 Linux 下的音樂鑑賞也能媲美 Windows 杜比音效。&lt;/p&gt;
&lt;h1&gt;EasyEffects 軟體紹介&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/wwmm/easyeffects&quot;&gt;Easy Effects(以前叫「PulseEffects」)&lt;/a&gt; 是 Wellington Wallace 開發的開源音效軟體，內建多種等化器(EQ)，壓縮器，增益，混響效果，可以有效改善 Linux 裝置喇叭，麥克風的聽感和音質。妳可以使用預先設定好的設定檔(Presets) 匯入，改善裝置音質，即使不會調整等化器參數也無所謂。&amp;lt;/br&amp;gt;
早期版本使用 GTK 作爲程式 UI 介面，現在採用 QT 實作了。&lt;/p&gt;
&lt;h1&gt;安裝 EasyEffects 軟體&lt;/h1&gt;
&lt;p&gt;PulseEffects 以前支援 PulseAudio，更新後改爲僅支援 Pipewire。目前 Arch Linux 和 Fedora 都應該使用 Pipewire 音訊伺服器了，如果妳仍然使用 PulseAudio，請安裝 Pipewire 相關套件，從 PulseAudio 轉換到 Pipewire。轉換完成後，在終端機執行 &lt;code&gt;pactl info&lt;/code&gt; 檢視 「Server name」是否出現「Pipewire」:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hamoa@fedora ~ » pactl info                          
Server String: /run/user/1000/pulse/native
Library Protocol Version: 35
Server Protocol Version: 35
Is Local: yes
Client Index: 305
Tile Size: 65472
User Name: hamoa
Host Name: fedora
Server Name: PulseAudio (on PipeWire 1.6.7)         # 正在使用 Pipewire 音訊伺服器
Server Version: 15.0.0
Default Sample Specification: float32le 2ch 48000Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.platform-sound.HiFi__Speaker__sink
Default Source: alsa_input.platform-sound.HiFi__Mic__source
Cookie: dadd:7a4c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;確認系統使用 Pipewire 後，就可以通過 Flatpak 或 Fedora DNF 套件庫 &lt;code&gt;dnf install easyeffects&lt;/code&gt; 安裝 EasyEffects 了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flatpak install flathub com.github.wwmm.easyeffects
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;匯入音效組態&lt;/h1&gt;
&lt;p&gt;EasyEffects 雖然功能很多，可是不熟悉做音樂的人根本不懂要調節哪些選項。對新手而言，最好的方法是匯入別人設定好的預設檔進行試驗，然後根據個人喜好進行調整。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/easyeffects-app.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/wwmm/easyeffects/wiki/Community-presets&quot;&gt;EasyEffects Wiki&lt;/a&gt; 有列出很多範本，選擇個人喜歡的，從 GitHub 下載 &lt;code&gt;.json&lt;/code&gt; 檔案。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
之後開啓 EasyEffects，點選左下「Presets」， 再點選「Import presets file」，匯入下載的 &lt;code&gt;.json&lt;/code&gt; 檔。然後載入要使用的設定檔即可。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/easyeffects-app-guide.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;我推薦 &lt;a href=&quot;https://github.com/JackHack96/EasyEffects-Presets&quot;&gt;JackHack96 製作的 「Loundness + Autogain」&lt;/a&gt;，對音質不好的筆電喇叭效果很不錯，聲音變大，細節變多。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;也可以自訂設定檔，只需點選「Add effects」，添加妳想要的增益效果，調整參數，匯出當前設定檔就可以了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;之後，再次點選「Presets」，點選「Autoload」，選擇默認音訊裝置，再選擇要套用的設定檔來設定自動套用的組態。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;最後，點選右上角的「進階選項」，打開「Preferences」，勾選「Autostart on login」設定 Easyeffects 隨使用者登入後自動啓動。&lt;/p&gt;
&lt;h1&gt;調整音效&lt;/h1&gt;
&lt;p&gt;啓用音效後，EasyEffects 就會展示正在播放音樂的應用程式了，如不想要當前程式套用音效，可以勾選「Exclude」將程式排除在外。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/easyeffects-player.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;點選「Output」面板，自由調整音效效果。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/easyeffects-effects.png&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;後記&lt;/h1&gt;
&lt;p&gt;Piepaint 認爲 EasyEffect 對於筆電和手持裝置非常有用，例如我手上的 Lenovo Yoga Slim 7x 喇叭成爲了廠商 cost-down 的對象，外放音樂音量非常小，乾巴巴的，有種塑料感，低音效果不如之前用的 MacBook Air 好。雖說我有 JBL 藍牙音響了，不過我不想帶着一組喇叭到處走啊...&amp;lt;/br&amp;gt;
在安裝 EasyEffects 之後，雖然不如 Windows 11 Arm 下的杜比音效那麼不錯，卻足以提升我的喇叭音量，音質也有所改善。筆電外放音樂也更加「悅耳」了一些。&lt;/p&gt;
</content:encoded></item><item><title>Xiaomi 14 刷 Lineage OS + Root，改善 SM8650 發熱高耗電問題</title><link>https://blog.cloudflare88.eu.org/posts/houji-lineageos-trial/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/houji-lineageos-trial/</guid><description>被小米放生了，就只好刷機了~</description><pubDate>Fri, 26 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;將 Xiaomi 14 (機型代號：Houji)改裝 Lineage OS 23.2，並取得 Root 權限，安裝三方調校器改善 SM8650 發熱問題。&amp;lt;/br&amp;gt;
所有 SM8650 機型(包括 MTP，QRD 原型機)使用者均可參考。妳可以選擇維持 HyperOS 原廠韌體，並取得 Root 權限；或者改裝 Lineage OS 23.2，再取得 Root 權限。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;刷機理由&lt;/h1&gt;
&lt;p&gt;原本是家人一直在用的 Xiaomi 14 ，系統是 HyperOS 3.0. 覺得原廠韌體還可以再用一陣子，但是火龍8650 晶片發熱是在太嚴重了，燙手還吃掉續航力。&amp;lt;/br&amp;gt;
雖說解鎖之後 Root 安裝模組就可以緩解，不過我習慣使用乾淨的 Android 系統和自由軟體，所以一次性做到底。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Xiaomi 14 刷機的特色如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;繼續獲得 Android 系統和安全性更新，目前是 Android 16；&lt;/li&gt;
&lt;li&gt;刷機後仍可使用部分原廠功能，例如 Display P3, Ultra HDR；&lt;/li&gt;
&lt;li&gt;可降低熒幕解析度更省電；&lt;/li&gt;
&lt;li&gt;DRM 等級是 L1,不會噴掉；&lt;/li&gt;
&lt;li&gt;解鎖後部分 App 過不了 Play Integrity&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;想要進一步控制功耗，可以使用 Scene 4 和第三方模組改善。&amp;lt;/br&amp;gt;
至於系統介面變化，因爲很早就在用 Lineage OS，因此沒有什麼新變化。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;解開 Bootloader&lt;/h1&gt;
&lt;p&gt;Xiaomi 14 市面販售的型號有 23127PN0CC, 23127PN0CG 兩種。其中前者爲中國大陸版，後者爲全球版。目前兩者均&lt;a href=&quot;https://mlgmxyysd.github.io/android-bootloader-kernel-source/#%E5%B0%8F%E7%B1%B3-xiaomi&quot;&gt;無法方便的解鎖&lt;/a&gt;[^1]。 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;但是，HyperOS 3.1 的 GPU 驅動程式存在一個漏洞。使用者可藉助這個漏洞取得臨時 Root 權限，獲得 SElinux 寬容模式，之後就可以寫入 ABL 工程版韌體，將 bootloader 解鎖相關變數寫入 UEFI NVRAM 達到解鎖的目的。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;到&lt;a href=&quot;https://github.com/Linuxoid-cn/Mi8G3-Unlocker&quot;&gt;這裏&lt;/a&gt;下載一份 Xiaomi 14 的解鎖檔案合集，其中包括了 Xiaomi 14 的測試用韌體。&amp;lt;/br&amp;gt;
之後電腦安裝 ADB 和 Fastboot 套件，主流的 Linux 發行版都有收。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
解開下載的檔案，找到 &lt;code&gt;exploit&lt;/code&gt; 檔案，將執行漏洞用的程式藉助 &lt;code&gt;adb push&lt;/code&gt; 傳到手機 &lt;code&gt;/data/tmp&lt;/code&gt; 目錄下，執行 Payload 即可。如果執行不成功，就多嘗試幾次。直到 SELinux 爲 Permissive。之後鍵入 &lt;code&gt;su&lt;/code&gt; 就可以獲得臨時 Root 權限了。具體的解鎖流程可以根據原專案中 Windows 指令稿的流程進行。需要注意的是刷完測試用韌體和解鎖用分割表後，可能會無法開機。需要重新刷一遍原廠韌體才可以開機，此時再通過 &lt;code&gt;fastboot oem device-info&lt;/code&gt; 指令檢視，應該會看到 &lt;code&gt;Device unlocked: Yes&lt;/code&gt; 裝置已經解鎖了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;解鎖之後手機就會重開機，之後再通過 &lt;code&gt;adb reboot bootloader&lt;/code&gt; 重新回到 Fastboot 模式。手機熒幕會展示橙色的 &lt;code&gt;FASTBOOT&lt;/code&gt; 畫面，現在就可以開始刷機了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;刷入 Lineage OS&lt;/h1&gt;
&lt;p&gt;到&lt;a href=&quot;https://drive.google.com/file/d/1PEDM7Ojz1GMu8hopTJMMn6tx-bhcE4FS/view&quot;&gt;這裏&lt;/a&gt;下載 Xiaomi 14 的 Lineage OS ROM，之後&lt;a href=&quot;https://github.com/ssut/payload-dumper-go&quot;&gt;下載&lt;/a&gt; &lt;code&gt;payload-dumper&lt;/code&gt; 用於解開 ROM 檔案，取出 &lt;code&gt;recovery.img&lt;/code&gt; &lt;code&gt;init_boot.img&lt;/code&gt; 二映像檔。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;先把手機開機到 Fastboot 模式，解開 ROM 壓縮檔。把 &lt;code&gt;payload-dumper&lt;/code&gt; 程式丟到解壓縮之後的 ROM 資料夾，在資料夾所在的目錄開終端機，鍵入 &lt;code&gt;./payload-dumper-go &lt;/code&gt; 隨後丟入 ROM 的 &lt;code&gt;Payload.bin&lt;/code&gt; 檔案，就可以解開 ROM 分割映像檔案了。之後鍵入 &lt;code&gt;fastboot flash recovery&lt;/code&gt; 命令寫入 Lineage OS Recovery 映像。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;之後重開機到 Recovery，選擇 「Wipe data」，或者藉助 ADB 命令執行 &lt;code&gt;recovery --wipe-data&lt;/code&gt; 命令來清除使用者資料。清除完成後使用「Apply update」 選單，使用 &lt;code&gt;adb sideload &amp;lt; ROM 壓縮檔目錄&amp;gt;&lt;/code&gt; 開始刷機。如果想要使用 GAPPS，我推薦 &lt;a href=&quot;https://mindthegapps.com/&quot;&gt;MindTheGapps&lt;/a&gt;。 刷 GAPPS 之前需要再次清除使用者資料。刷機完成後使用 &lt;code&gt;adb reboot&lt;/code&gt; 或點選「Reboot system now」 重開機。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;目前的 Lineage OS 沒有臉孔解鎖的功能，僅支援使用 PIN 和指紋辨識解鎖。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/lineage-home.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;安裝 Google 相機，改善錄影體驗&lt;/h1&gt;
&lt;p&gt;雖然我拒用任何專有軟體和間諜程式，但因此緣由導致手機用着反不如 Linux 手機，連最基本的需求都無法達成的話...倒不如暫時「妥協」，接受部分專有軟體的存在吧？雖然 Google 相機是專有軟體，但不可否認攝影效果確實不錯。&amp;lt;/br&amp;gt;
想要使用 Google 相機，裝置上必須載有 Google 服務套件。當然我是一定不會使用 Google 的任何服務，所以我改用 MicroG 取代專有的 Google 服務套件。雖然不使用 MicroG 也可以，但是 Gcam 開啓之後會跑出煩人的訊息，警示妳這部裝置不支援 Google 服務。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;使用 DuckduckGo 檢索「Google Camera Hub」，選擇適合妳的相機應用程式下載。我使用的是由 &lt;a href=&quot;https://www.celsoazevedo.com/files/android/google-camera/dev-BigKaka/f/dl97/&quot;&gt;BigKaka 開發維護的 AGC Google 相機修改版&lt;/a&gt;,安裝後授予除去位置資訊的所有權限即可。我個人測試認爲照片要比原廠相機拍攝要好一些(文章的圖片就是我用 Google 相機拍攝的)，因爲 Lineage OS 的 HDR 實作有問題，使用支援 HDR 的相簿檢視 HDR 圖片時會出現畫面亮度變暗的問題。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam2.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;可供調節的選項非常多，當然，偷走妳隱私的可能性就更大了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam-photo.jpg&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam-photo2.jpg&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam-photo3.jpg&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/houji-gcam-photo4.jpg&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;取得 Root 權限&lt;/h1&gt;
&lt;p&gt;手機上安裝 KernelSU，將解開的 &lt;code&gt;init_boot&lt;/code&gt; 映像用 KernelSU 修補。KMI 選擇 &lt;code&gt;Android14-6.1&lt;/code&gt;，之後刷入修補的 &lt;code&gt;init_boot&lt;/code&gt; 映像開機，取得 Root 權限。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;解決 SM8650 發熱，改善續航&lt;/h1&gt;
&lt;p&gt;實在是想不到2026年還要通過修改系統 API 的方式來改善手機效能...上次我用這種做法還是在 Coolpad C106 改裝 Lineage OS 18.1 之後裝 Kernel Auditor 降低 SD652 核心時脈省電來着... SD652 雖然不如 SD615 那樣發熱又噴續航，但是也好不到哪裏去。沒辦法，誰讓 SM8650 體質有問題，雖然比 SD888 有改善，但是廠商調校又不好。我沒有能力改造手機散熱，就只好從軟體下手...看來鳳梨*的火熱還需要丟進冷藏庫才可以解決XD。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;*「鳳梨」是 SM8650 晶片 HLOS 代號「Pineapple」的翻譯。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Uperf 是由 yc9559 開發的第三方 Android 系統調校器，能夠根據裝置的使用場景而設定參數控制裝置效能。但是原版本似乎已經停止開發，只好&lt;a href=&quot;https://github.com/yinwanxi/Uperf-Game-Turbo&quot;&gt;改用 Fork 後的版本繼續使用&lt;/a&gt;。不知道爲什麼，開發者非常喜歡在 Release 頁面放大量色圖...也好。刷機的時候尻一發，體驗不一樣的心情也不錯。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;yinwanxi/Uperf-Game-Turbo&quot;}&lt;/p&gt;
&lt;p&gt;之後通過 KernelSU 安裝模組，重開機，到 &lt;code&gt;/sdcard/Android/yc/&lt;/code&gt; 目錄，修改 &lt;code&gt;cur_powermode.txt&lt;/code&gt; 爲 &lt;code&gt;powersave&lt;/code&gt; 省電模式，就可以改善發熱問題了。還可以配合 Scene App 爲每一個應用設定唯一的配置檔，在需要使用吃 CPU 的應用(例如相機，遊戲應用)才會提高CPU核心時脈，平時就限制核心最大時脈。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;或者改用 &lt;a href=&quot;https://github.com/Liliya2727/AZenith&quot;&gt;AZenth&lt;/a&gt; 調校，在應用中設定全域 CPU 最大時脈，降低 CPU 時脈，改善電池效能。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Liliya2727/AZenith&quot;}&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/azenth-app.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;這樣一番修改下，熒幕亮着的續航時間能從6小時改善到10小時吧。&lt;/p&gt;
</content:encoded></item><item><title>Your Phone is Fused(Feat. Purwa Oryon &amp; EDKPiepaint) -- A FOSS Parody of Your Door Was Locked by Element Animation</title><link>https://blog.cloudflare88.eu.org/posts/your-phone-fused/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/your-phone-fused/</guid><description>Thanks for a shameless Canadian who gives me a good inspiration.</description><pubDate>Sun, 21 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Z7JiPUinWgY?si=SS0jISyeYuHZ_l68&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Your%20Phone%20is%20Fused%20--%20A%20FOSS%20Parody%20of%20Your%20Door%20Was%20Locked.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio tag.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Intro&lt;/h1&gt;
&lt;p&gt;I&apos;ll show you a device that you hardly seen,&amp;lt;/br&amp;gt;
It looks like black brick with shiny screen &amp;lt;/br&amp;gt;
Lots of mysterious ports lays on its side, &amp;lt;/br&amp;gt;
Without it your phone will never become alive! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;&apos;Cause you&apos;ve been locked&lt;/em&gt;&amp;lt;/br&amp;gt;
Bootloader sealed, no control in sight,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been locked&lt;/em&gt;&amp;lt;/br&amp;gt;
Instant brick got me feelin&apos; tight&amp;lt;/br&amp;gt;
&lt;em&gt;Your phone is fused&lt;/em&gt;&amp;lt;/br&amp;gt;
(Yet another)Useless prototype,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been locked&lt;/em&gt;&amp;lt;/br&amp;gt;
Dummy signature should be aligned&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;(How could)this happened so fast (in) such a cozy night?&amp;lt;/br&amp;gt;
Before I send my board on a compilein&apos; fire&amp;lt;/br&amp;gt;
A crack just found in the system core,&amp;lt;/br&amp;gt;
A zero-day flaw they never patched before&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 2&lt;/h1&gt;
&lt;p&gt;Time to have another &quot;Flashin&apos; Night&quot;,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been locked&lt;/em&gt;&amp;lt;/br&amp;gt;
Exploit runnin&apos; deep, ADB on fire&amp;lt;/br&amp;gt;
&lt;em&gt;Your phone is fused&lt;/em&gt;&amp;lt;/br&amp;gt;
SafetyNet cryin&apos;, but I never care,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been unlocked&lt;/em&gt;&amp;lt;/br&amp;gt;
(I&apos;m) &apos;bout to own this device in the air&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;(I just)Pushed the payload, got system shell,&amp;lt;/br&amp;gt;
&lt;code&gt;KSU&lt;/code&gt; jailbreak , (but I) went full rebel&amp;lt;/br&amp;gt;
Another fastboot time, (just) wipe and flash,&amp;lt;/br&amp;gt;
One command later, freedom across the land(let&apos;s go)!&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 3&lt;/h1&gt;
&lt;p&gt;No more warnings, no more red text&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been unlocked&lt;/em&gt;&amp;lt;/br&amp;gt;
Verified boot? Nah, I broke that next&amp;lt;/br&amp;gt;
&lt;em&gt;Your phone is fused&lt;/em&gt;&amp;lt;/br&amp;gt;
Custom recovery flashin&apos; on the screen,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been unlocked&lt;/em&gt;&amp;lt;/br&amp;gt;
TWRP smilin&apos;, livin&apos; the dream&amp;lt;/br&amp;gt;
&lt;em&gt;Keep your privacy&lt;/em&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;From bloatware to unlocked paradise,&amp;lt;/br&amp;gt;
&lt;em&gt;Now bootloader loosed&lt;/em&gt;&amp;lt;/br&amp;gt;
All because that door... I mean, that phone was nice&amp;lt;/br&amp;gt;
&lt;em&gt;Your phone is fused&lt;/em&gt;&amp;lt;/br&amp;gt;
Time to compile another firmware,&amp;lt;/br&amp;gt;
&lt;em&gt;Yes you&apos;ve been unlocked&lt;/em&gt;&amp;lt;/br&amp;gt;
But phone just instent bricked again, &amp;lt;/br&amp;gt;
&apos;Cause your phone is fused!&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Flash Continuous Tense (Feat. Purwa Oryon) —— A FOSS parody of 人生進行形(Life Continuous Tense) by May&apos;n</title><link>https://blog.cloudflare88.eu.org/posts/en/flash-continous-tense/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/flash-continous-tense/</guid><description>The courage to change, the brave practice that paved the way.</description><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Flash%20Continuous%20Tense%20(Feat.%20Purwa%20Oryon)%20%E2%80%94%E2%80%94%20A%20FOSS%20parody%20of%20%E4%BA%BA%E7%94%9F%E9%80%B2%E8%A1%8C%E5%BD%A2(Life%20Continuous%20Tense)%20by%20May&apos;n%20.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Flash%20Continuous%20Tense%20(Feat.%20Purwa%20Oryon)%20%E2%80%94%E2%80%94%20A%20FOSS%20parody%20of%20%E4%BA%BA%E7%94%9F%E9%80%B2%E8%A1%8C%E5%BD%A2(Life%20Continuous%20Tense)%20by%20May&apos;n%20.ogg&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/n6GVaJL_eeY?si=T-7F7bfpk5GGeWWw&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;What are you gazing at,&amp;lt;/br&amp;gt;
Upon that pitch-black screen?&amp;lt;/br&amp;gt;
Far away on the hills,&amp;lt;/br&amp;gt;
The scent of pine comes through.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Today just like any other days, that passes in pain and gloom,&amp;lt;/br&amp;gt;
Time just drifts along,&amp;lt;/br&amp;gt;
Slipping right through the room.&amp;lt;/br&amp;gt;
In my own memory, this world always stay the same,&amp;lt;/br&amp;gt;
A &quot;Walled Garden&quot; built, of proprietary shame.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We run together now, toward to the freedom where we seek,&amp;lt;/br&amp;gt;
Proprietary software that we waved final &quot;Goodbye&quot; and we will never meet.&amp;lt;/br&amp;gt;
Can&apos;t find an FOSS alternative, so from family I&apos;m detached,&amp;lt;/br&amp;gt;
Just remember well, the first time that the &quot;Walled Garden&quot; I unlatched.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Long since, I’ve been used to, the golden cage,&amp;lt;/br&amp;gt;
Not even grasping, what &quot;freedom&quot; really means.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;Feeling unconsciously, just wandering alone on the roof,&amp;lt;/br&amp;gt;
Chasing the future needing the proof,&amp;lt;/br&amp;gt;
to build a free and open phone.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Finally, there&apos;s a day, my dream comes true,&amp;lt;/br&amp;gt;
Bootloader unlock is my need.&amp;lt;/br&amp;gt;
Typing command lines ,then power light shines,&amp;lt;/br&amp;gt;
Saying &quot;Walled Garden,&quot; goodbye!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Logs start to scroll, acrossing all the blank screen,&amp;lt;/br&amp;gt;
Shaking my heart, there is a sight that I never seen.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Just &apos;cause &quot;proprietary&quot; broke it, the phone is near its end,&amp;lt;/br&amp;gt;
The teen who loved to flash, has now grown up again.&amp;lt;/br&amp;gt;
Even if it bricks, or Crashdump, it&apos;s fine, flashing&apos;s still continuous tense,&amp;lt;/br&amp;gt;
If I’m feeling sad, just switch a new device,&amp;lt;/br&amp;gt;
And start it all from scratch.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Beyond the walls, there is, a freedom true,&amp;lt;/br&amp;gt;
Found my own place, a place to call my own.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge&lt;/h1&gt;
&lt;p&gt;Phone comes back home, time to starts again,&amp;lt;/br&amp;gt;
&quot;Unlock&quot; conditions, seem tougher now than then.&amp;lt;/br&amp;gt;
Masters of code, with ease I will thrive,&amp;lt;/br&amp;gt;
Laughing in Linux, feeling alive!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;We run together now, toward to the freedom where we seek,&amp;lt;/br&amp;gt;
Proprietary software that we waved final &quot;Goodbye&quot; and we will never meet.&amp;lt;/br&amp;gt;
Not caring all the technical details, but I remember that day,&amp;lt;/br&amp;gt;
The courage to change, the brave practice that paved the way.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Relying on code, that&apos;s closed to the eye,&amp;lt;/br&amp;gt;
Until I knew, how to soar in the sky.&amp;lt;/br&amp;gt;
Privacy now, is mine to command,&amp;lt;/br&amp;gt;
Come on, let’s laugh out loud, again.&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>當 Linux 遇上 Qualcomm X Elite —— Fedora 44 在 Lenovo YOGA Slim 7x 的體驗</title><link>https://blog.cloudflare88.eu.org/posts/first-impression-with-xelite/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/first-impression-with-xelite/</guid><description>我或許是世界第一個在聯想 YOGA Slim 7x 驍龍筆電上安裝並測試 Linux 的用戶...</description><pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;（原文寫於9月16日）我一直都對採用ARM晶片的筆記本電腦有着濃厚的興趣。不僅僅是因爲CPU與衆不同，更是因爲被RISC晶片的優秀能耗比所驚豔，在優越的性能表現下，卻又有着長久的續航能力。這是普通x86架構的筆電所無法企及的。然而，因爲一個小小的意外，我與這臺筆電的故事，便從此開始了。&lt;/p&gt;
&lt;h2&gt;我爲什麼選擇 Qualcomm X Elite 筆電？&lt;/h2&gt;
&lt;p&gt;我最早看到有關驍龍版筆電的消息是在2020年，第一次知道了 Windows還有 ARM 的版本。以及一系列關於 Windows on ARM 裝置的技術知識。一般手機改裝 Windows 作業系統的驅動程式，大多是由搭載 Windows ARM 的筆電，原型機等裝置的驅動程式提取並簡單修改而來的。我便在網路上檢索有關 Windows on ARM 的裝置，結果發現市面上竟然真的有這樣的筆電！牠們採用高通驍龍SoC，使用 eMMC 或者 UFS 快閃記憶體作爲內置硬碟。並且支援硬體虛擬化，還內建數據機，方便在沒有無線網路的地方，使用行動數據來連接到網際網路。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
另外驍龍筆電在 Linux 下的體驗是遠勝過 Windows on ARM 的，風扇比較安靜，幾乎不會有「開足馬力」的時候，可以使用KVM 和 Xen，因此可以滿足我所有的用途。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;我對於「驍龍筆電」的印象&lt;/h2&gt;
&lt;p&gt;我所購買的裝置是聯想的 YOGA Slim 7x。配備了一個解析度爲2944x1840的OLED屏幕，其重新整理頻率爲90Hz，支援觸控。以及驍龍 X Elite 晶片。筆電採用 32GB LPDDR5x 記憶體，1TB的 Samsung NVME高速固態硬碟。到手的時候，我發現牠安裝的是 Windows 11 ARM 版，塞了不少 Lenovo 的 bloadware 進去。因爲現在主要 Linux 發行版套件庫已經收錄了驍龍 X Elite 的韌體，不需要再從 Windows 系統檔案提取，
我選擇抹掉整張硬碟，僅安裝 Fedora Linux 作爲筆電的作業系統。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;安裝 Linux&lt;/h2&gt;
&lt;p&gt;首先關閉 Windows 自帶的 Bitlocker 硬碟加密，然後將筆電重開機，在開機時按 &lt;code&gt;F2&lt;/code&gt;,以此進入 UEFI設定。選擇「安全」選項，之後關閉安全啓動，之後從瀏覽器檢索「Fedora」，下載 Fedora 44 映像檔開機，根據 &lt;a href=&quot;https://fedoraproject.org/wiki/Snapdragon_WoA_Laptop_Install&quot;&gt;Fedora Wiki 的說法&lt;/a&gt;，驍龍 X Elite 的筆電需要開機後手動修改 Live CD 的開機引數爲 &lt;code&gt;clk_ignore_unused pd_ignore_unused systemd.tpm2_wait=0 modprobe.blacklist=qcom_q6v5_pas&lt;/code&gt; 才可以開機進入 Live CD。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;目前的問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;待機（suspend）還沒有修好，根本無法休眠；&lt;/li&gt;
&lt;li&gt;不支援 HDR 視訊；&lt;/li&gt;
&lt;li&gt;內建TPM也無法使用，可能面臨安全問題；&lt;/li&gt;
&lt;li&gt;電源管理有問題，耗電明顯比 Windows 系統高；&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;嘗試啓用 KVM&lt;/h2&gt;
&lt;p&gt;儘管高通平臺支援 ARM 虛擬化技術，但是 UEFI 韌體是以 EL1 異常層級執行，所以作業系統及其虛擬機管理員無法訪問硬體 Hypervisior 。因此我嘗試在 Fedora 44 檢查核心是否開啓了 KVM：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls /dev/kvm
/dev/kvm: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顯然 KVM 並未開啓。也就是說，Linux 運行在 EL1模式下。我又查看了核心日誌：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dmesg | egrep -i &quot;EL2|kvm|hypervisor|gunyah&quot;
[sudo] password for edkpiepaint: 
[    0.000000] OF: reserved mem: 0x0000000080000000..0x00000000807fffff (8192 KiB) nomap non-reusable gunyah-hyp@80000000
[    0.000000] CPU features: detected: HCRX_EL2 register
[    0.000000] CPU features: detected: Broken CNTVOFF_EL2
[    0.071971] kvm [1]: HYP mode not available
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不難看出，韌體將一部分記憶體保留給了 Gunyah（Qualcomm 自己的 EL2 Hypervisor）。如果想要跑 KVM 虛擬機，就需要加載 &lt;code&gt;slbounce&lt;/code&gt; &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/&quot;&gt;EFI 驅動&lt;/a&gt;，從而讓 Linux 執行於 EL2 模式下。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;至於音訊...在跑過 &lt;code&gt;dnf update&lt;/code&gt; 之後，發現音訊可以使用了。感謝增加這臺筆電支援的開發者們！&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;關於相機的二三事&lt;/h2&gt;
&lt;p&gt;高通的 &lt;code&gt;camss&lt;/code&gt; 裝置已經在主線核心中得到了支援。在終端機中鍵入 &lt;code&gt;ls /dev/video*&lt;/code&gt; 會看到很多視訊裝置節點，例如 &lt;code&gt;/dev/video0&lt;/code&gt; 、 &lt;code&gt;/dev/video1&lt;/code&gt; 、 &lt;code&gt;/dev/video2&lt;/code&gt; 等等。通過 &lt;code&gt;v4l2-ctl -A	&lt;/code&gt; 命令也可以看到先前的裝置節點隸屬於高通的相機遠端處理器：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Qualcomm Camera Subsystem (platform:acb6000.isp):
	/dev/video0
	/dev/video1
	/dev/video2
	/dev/video3
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那麼，相機可以使用嗎？答案是不能。使用 &lt;code&gt;qcam&lt;/code&gt; 發現相機列表是空白的，其牠軟體亦不能調用相機。通過核心日誌除錯發現了下面一條信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[    5.108101] i2c-qcom-cci ac16000.cci: master 1 queue 0 timeout
[    5.110920] ov02c10 2-0036: Error reading reg 0x300a: -110
[    5.113375] ov02c10 2-0036: failed to find sensor: -110

[    5.134422] ov02c10 2-0036: probe with driver ov02c10 failed with error -110
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因爲I2C通信失敗，導致硬體加電時序出現了偏差，相機無法工作。隨後我檢索了關於上面錯誤的解決方案，在 Linaro 維護的核心分支上找到了一個人提出的 &lt;a href=&quot;https://gitlab.com/Linaro/arm64-laptops/linux/-/issues?show=eyJpaWQiOiI5IiwiZnVsbF9wYXRoIjoiTGluYXJvL2FybTY0LWxhcHRvcHMvbGludXgiLCJpZCI6MTcyNDg3MDY3fQ%3D%3D&quot;&gt;issue&lt;/a&gt; 裏面的錯誤日誌與我遇到的完全一致。在粗略檢視之後，發現裝置樹中關於相機的定義不正確：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 		avdd-supply = &amp;lt;&amp;amp;vreg_l7m_2p8&amp;gt;;
		dvdd-supply = &amp;lt;&amp;amp;vreg_l2m_1p2&amp;gt;;
		dovdd-supply = &amp;lt;&amp;amp;vreg_l4m_1p8&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根據從高通筆電中提取的 &lt;a href=&quot;https://github.com/alexVinarskis/qcom-aeob-dumps&quot;&gt;AeoB 文件&lt;/a&gt;來看，確認了這些參數是適用於&lt;a href=&quot;https://github.com/alexVinarskis/qcom-aeob-dumps/blob/master/lenovo-thinkpad-t14s-g6/CAMF_RES_QRD.json#L117-L155&quot;&gt;另一臺筆電（ThinkPad T14s）&lt;/a&gt;的，而 T14s 的參數又是基於 CRD 參考平臺修改而來的，因此牠不能應用在 Yoga Slim 7x 上。不過有開發者給出了解決方法，需要定義新的電源調節器 &lt;code&gt;vreg_l7b_2p8&lt;/code&gt; ，爲相機提供 2.8V 供電：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vreg_l7b_2p8: ldo7 {
        regulator-name = &quot;vreg_l7b_2p8&quot;;
        regulator-min-microvolt = &amp;lt;2800000&amp;gt;;
        regulator-max-microvolt = &amp;lt;2800000&amp;gt;;
        regulator-initial-mode = &amp;lt;RPMH_REGULATOR_MODE_HPM&amp;gt;;
             };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;還需要修正裝置樹中相機的參數，因爲相機硬體錯誤安裝（我想負責組裝的工人當時一定在忙着自慰，所以把相機裝反了），我們需要添加 &lt;code&gt;rotation = &amp;lt;180&amp;gt;&lt;/code&gt; 參數，告訴作業系統將畫面倒轉。相機傳感器需要三組電源：類比 (AVDD)、數位 (DVDD) 和 I/O (DOVDD)，因此修改 &lt;code&gt;avdd-supply&lt;/code&gt; &lt;code&gt;dvdd-supply&lt;/code&gt; &lt;code&gt;dovdd-supply&lt;/code&gt; 參數，換成正確的即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;camera@36 {
               assigned-clock-rates = &amp;lt;19200000&amp;gt;;
 
               orientation = &amp;lt;0&amp;gt;; 
               rotation = &amp;lt;180&amp;gt;;
 
               avdd-supply = &amp;lt;&amp;amp;vreg_l7b_2p8&amp;gt;;
               dvdd-supply = &amp;lt;&amp;amp;vreg_l1m_1p2&amp;gt;;
               dovdd-supply = &amp;lt;&amp;amp;vreg_l3m_1p8&amp;gt;;
 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AVDD&lt;/strong&gt; (Analog): 改為使用剛剛定義的 vreg_l7b_2p8 (2.8V)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DVDD&lt;/strong&gt; (Digital): 從 l2m 改為 l1m (1.2V)；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DOVDD&lt;/strong&gt; (Digital I/O): 從 l4m 改為 l3m (1.8V)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;之後，編譯新的裝置樹，重新啓動核心，相機就工作了。&lt;/p&gt;
&lt;h2&gt;其牠有意思的事情...&lt;/h2&gt;
&lt;p&gt;觀看 YouTube 1080P 影片，同時用終端機開 &lt;code&gt;htop&lt;/code&gt; 檢視 CPU 使用情況，發現 CPU 佔用比較低。似乎使用了硬體播放器播放了影片？這似乎是我用過第一臺支援硬體解碼的 Arm 筆電。&lt;/p&gt;
</content:encoded></item><item><title>如何檢定 Snapdragon 裝置遠端處理器的運轉情況，保證裝置功能正常工作</title><link>https://blog.cloudflare88.eu.org/posts/check-adsp-on-snaptop/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/check-adsp-on-snaptop/</guid><description>給希望在驍龍平臺上體驗 mainline kernel 的使用者提供基礎的除錯知識。</description><pubDate>Sat, 06 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note
本文提及的檢定方法均以個人的直接觀察和使用經歷爲基礎，部分技術細節需要精通高通平臺或 Arm 晶片的開發者，或者專業人士進行檢定和勘誤。
如果妳想要補充更多細節，或想要修正錯誤，歡迎聯繫我。
:::&lt;/p&gt;
&lt;p&gt;今天 Piepaint 要來講述如何檢定 Linux 作業系統下 Snapdragon 晶片各遠端處理器的運行情況。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;關於遠端處理器(Remote Processor)的紹介&lt;/h1&gt;
&lt;p&gt;遠端處理器（Remote Processor）是晶片系統（SoC）上用於處理特定任務或高即時性（Real-time）需求的獨立處理器核心，牠們受主處理器及主作業系統的管理與調度。視具體業務需求與晶片設計而定，這些輔助核心通常會執行專屬的裸機程式（Bare-metal）或即時作業系統（RTOS），並透過特定的 IPC 機制與主處理器溝通。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;例如，Google Pixel 手機中所搭載的 Samsung G5300 數據機（Modem）便是執行自己的 RTOS[^1]，並與 Tensor 主處理器進行資料交換。與遠端處理器相對的概念是「主處理器（Main Processor）」，在行動裝置與嵌入式領域中更常被稱為「應用處理器（Application Processor）」。主要負責執行功能完整、結構龐大的通用作業系統，如 Android、Linux 或 BSD。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;應用處理器雖然運算效能強大，但牠是為了應付高吞吐量的多工任務而設計的，並不具備「硬即時性（Hard Real-Time）」。以 Linux 作業系統為例，雖然牠擁有強大的生態，但在原生設計上，其任務調度與搶佔（Preemption）機制是為了公平分配 CPU 資源，而非保證微秒級的絕對延遲。即使加上了 &lt;code&gt;PREEMPT_RT&lt;/code&gt; 補丁，在面對極端硬體控制或低功耗常駐監聽時，讓龐大的 Linux 核心保持喚醒依舊非常耗電且不夠精準。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
遠端處理器正是為了彌補這些缺陷而生。透過將特定任務「外包」給這些專職的輔助核心，SoC 能夠在維持極佳能效比的同時，確保關鍵任務的絕對即時回應。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;瞭解 Snapdragon 裝置的遠端處理器&lt;/h1&gt;
&lt;p&gt;進入實作檢定之前，我們有必要先了解驍龍異質架構（Hexagon DSP 與處理器子系統）中常見的幾位「遠端成員」[^2]：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ADSP (Audio Digital Signal Processor)： 負責音訊解碼、低功耗語音喚醒（如語音助手常駐監聽）以及音效處理。還負責管理 USB 控制器和電池計量回報；&lt;/li&gt;
&lt;li&gt;CDSP (Compute Digital Signal Processor)： 專門用於加速電腦視覺、圖像處理（ISP 輔助）以及輕量級的機器學習/神經網路推理任務；&lt;/li&gt;
&lt;li&gt;MPSS (Modem Peripheral Subsystem, 簡稱數據機(Modem))： 負責處理極其複雜的 4G/5G 基頻通訊協議；&lt;/li&gt;
&lt;li&gt;WPSS (Wireless Processor Subsystem): 負責無線基頻管理。&amp;lt;/br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;在筆電以及 IoT 平臺上，最常見的是 ADSP，CDSP，少數支援使用行動數據鏈接網際網路的裝置(還有原型機)會有 Modem。&amp;lt;/br&amp;gt;
在 Linux 上，Linux kernel 會藉由 &lt;code&gt;rmtfs&lt;/code&gt; 或者 QMI protocol 來管理[^3]，與遠端處理器之間交換資料。Linux 的 &lt;code&gt;remoteproc&lt;/code&gt; 框架會提供使用者一個 &lt;code&gt;sysfs&lt;/code&gt; API 用於管理遠端處理器。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;檢定遠端處理器的運轉情況&lt;/h1&gt;
&lt;h2&gt;ADSP 檢定&lt;/h2&gt;
&lt;p&gt;看一下你的系統 Menu bar，電池圖示是否展示為紅色驚嘆號？在驍龍平台上，ADSP 除了負責音訊，還負責處理電池電量回報的事務。如果 ADSP 韌體沒有成功載入，或者不小心載入到「精簡版韌體（Lite Firmware）」，底層的 qcom-battmgr 驅動就會噴出 uevent 相關錯誤，導致系統完全無法讀取電池剩餘容量。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/empty-battery.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;如果載入的是完整韌體，就可以正常展示容量信息。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/full-battery.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;另外可以檢查音訊裝置，如果展示的是「Dummy Output」，通過 &lt;code&gt;aplay -l&lt;/code&gt; 命令找不到可用的音訊裝置，表示 ADSP 韌體沒有加載。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h3&gt;通過 &lt;code&gt;dmesg&lt;/code&gt; 檢定&lt;/h3&gt;
&lt;p&gt;想要找出 ADSP 是否正常執行，就只能通過檢視 &lt;code&gt;dmesg&lt;/code&gt; 來確認了。如果 ADSP 成功啓動，那麼 &lt;code&gt;dmesg&lt;/code&gt; 會出現 &lt;code&gt;remote processor adsp is now up&lt;/code&gt; 的 log：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dmesg | grep adsp
[   13.901682] remoteproc remoteproc0: adsp is available
[   13.932580] remoteproc remoteproc0: powering up adsp
[   13.941412] remoteproc remoteproc0: Booting fw image qcom/x1e80100/LENOVO/83ED/qcadsp8380.mbn, size 21592504
[   14.277891] remoteproc remoteproc0: remote processor adsp is now up
[   14.297322] PDR: Indication received from msm/adsp/charger_pd, state: 0x1fffffff, trans-id: 1
[   14.310033] PDR: Indication received from msm/adsp/audio_pd, state: 0x1fffffff, trans-id: 1
[   14.310088] qcom,apr 6800000.remoteproc:glink-edge.adsp_apps.-1.-1: Adding APR/GPR dev: gprsvc:service:2:1
[   14.310142] qcom,apr 6800000.remoteproc:glink-edge.adsp_apps.-1.-1: Adding APR/GPR dev: gprsvc:service:2:2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同時 &lt;code&gt;/sys/class/remoteproc/&lt;/code&gt; 也會出現 &lt;code&gt;remoteproc0&lt;/code&gt; 裝置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#cat /sys/class/remoteproc/remoteproc0/name   ##檢視遠端處理器名稱
adsp

#ls /sys/class/remoteproc/remoteproc0/      ##遠端處理器的其他 node  
6800000.remoteproc:glink-edge  device    name   qcom_common.pd-mapper.0  state      uevent
coredump                       firmware  power  recovery                 subsystem

#cat /sys/class/remoteproc/remoteproc0/state     ##檢視遠端處理器狀態
running
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;CDSP 檢定&lt;/h2&gt;
&lt;p&gt;CDSP（Compute DSP）主要負責影像處理與 AI/NPU 運算，目前在 GNOME 等圖形介面上沒有直接對應的狀態圖示。要確認其運作狀況，我們主要依賴核心日誌：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#dmesg | grep cdsp
[   13.908248] remoteproc remoteproc1: cdsp is available
[   13.914113] remoteproc remoteproc1: powering up cdsp
[   13.915599] remoteproc remoteproc1: Booting fw image qcom/x1e80100/LENOVO/83ED/qccdsp8380.mbn, size 2990504
[   14.059488] remoteproc remoteproc1: remote processor cdsp is now up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/sys/class/remoteproc/&lt;/code&gt; 也會出現 &lt;code&gt;remoteproc1&lt;/code&gt; 裝置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#cat /sys/class/remoteproc/remoteproc1/name   ##檢視遠端處理器名稱
cdsp

#ls /sys/class/remoteproc/remoteproc1/        
32300000.remoteproc:glink-edge  device    name   qcom_common.pd-mapper.1  state      uevent
coredump                        firmware  power  recovery                 subsystem

#cat /sys/class/remoteproc/remoteproc1/state  ##檢視遠端處理器狀態
running
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Modem 檢定&lt;/h2&gt;
&lt;p&gt;高通的 Modem 是作爲遠端處理器存在的，並不像其他平臺通過 PCIe 外掛。最簡單的方法就是看一下狀態列上是否出現「信號格」的圖示，GNOME 設定中是否出現 「Moblie broadband」的選項；或者 &lt;code&gt;mmcli&lt;/code&gt; 是否可以檢視到數據機的資訊。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;另外也可以檢視 &lt;code&gt;dmesg&lt;/code&gt; 。如果數據機成功啓動，那麼 &lt;code&gt;dmesg&lt;/code&gt; 會出現 &lt;code&gt;remote processor modem is now up&lt;/code&gt; 的日誌。同樣也可以在 &lt;code&gt;/sys/class/remoteproc&lt;/code&gt; 中發現數據機裝置。&lt;/p&gt;
&lt;h1&gt;如果妳想要管理遠端處理器&lt;/h1&gt;
&lt;p&gt;雖然遠端處理器的韌體是徹底的「黑箱」，沒有任何人可以檢視原始碼並改善牠，但我們依然可以通過 &lt;code&gt;sysfs&lt;/code&gt; 來管理這些遠程處理器。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/remoteproc-support.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Linux 的 &lt;code&gt;remoteproc&lt;/code&gt; 框架會實時蒐集遠端處理器的狀態並提供用於啓動和關閉處理器的接口。位於 userspace 的程式或者系統服務隨時都可以藉助 &lt;code&gt;sysfs&lt;/code&gt; 檢視並管理所有遠端處理器的狀態：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 打開遠端處理器:
  echo &quot;start&quot; &amp;gt; /sys/class/remoteproc/remoteprocN/state

# 關閉遠端處理器:
  echo &quot;stop&quot; &amp;gt; /sys/class/remoteproc/remoteprocN/state

# 打開核心轉儲(coredump)除錯功能：
echo enabled &amp;gt; /sys/kernel/debug/remoteproc/remoteprocN/coredump

# 關閉核心轉儲(coredump)除錯功能：
echo disabled &amp;gt; /sys/kernel/debug/remoteproc/remoteprocN/coredump
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[^1]: &lt;a href=&quot;https://fccid.io/T8GSAN9000/User-Manual/Users-Manual-5118614.pdf&quot;&gt;FCC block diagram about Samsung modem&lt;/a&gt;
[^2]:&lt;a href=&quot;https://docs.qualcomm.com/doc/80-80020-3/topic/remoteproc-overview.html&quot;&gt;Configure the remoteprocessor (remoteproc) subsystems -- Qualcomm Docs&lt;/a&gt;
[^3]:&lt;a href=&quot;https://deepwiki.com/linux-msm/rmtfs/7-qmi-protocol&quot;&gt;QMI Protocol -- DeepWiki linux-msm rmtfs&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>在驍龍 X Elite 筆電上啓用KVM安裝 Alpine Linux~ 基於64位元ARM平臺的KVM安裝教學</title><link>https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/</guid><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;(原文寫於 2026年1月4日)&lt;/p&gt;
&lt;h1&gt;一切的開端&lt;/h1&gt;
&lt;p&gt;自從我將我的主力筆電從 MacBook Air 換成這臺 Lenovo Yoga Air 14s 之後，我對於驍龍 X Elite 的好感也逐漸上升。不只是震驚於12顆效能強勁的Oryon CPU 核心和32GB的記憶體，使得我無論是應付日常事物，亦或是嵌入式Linux開發都變得綽綽有餘。但是，就像其他任何筆電一樣，這臺 Yoga Air 14s 也有自己的缺點。&amp;lt;/br&amp;gt;
牠默認採用的是 Windows 11 ARM 作業系統，而且還預載的是 Home Edition，與完整版的 Windows 11 相比缺少了 Hyper-V虛擬機支援。我只好備份了有用的資料後，抹掉整個硬碟重新安裝了 Windows 11 Pro，這次在「可選功能」中總算有了「Hyper-V」選項，我便打開了相關功能，然後重開機，下載了 Debian 13 的ARM 安裝映像檔。嘗試啓用虛擬機，然而虛擬機卻卡住了，無論怎麼修改虛擬機設定檔都無法進入 Debian 的安裝程式。加之 Windows 作業系統是出了名的「間諜軟體」，我可不想讓 Microsoft 監控我！所以我又安裝了目前唯一多數硬體工作正常的 Ubuntu 作業系統。但是 KVM 的功能需要自己手動配置。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/final-result.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;準備工作&lt;/h1&gt;
&lt;p&gt;首先，在網路搜尋「 UEFI Shell 」，找到相對應的 &lt;a href=&quot;https://github.com/pbatard/UEFI-Shell/releases&quot;&gt;GitHub 存儲庫網址&lt;/a&gt;，下載檔案名爲 &lt;code&gt;shellaa64.efi&lt;/code&gt; 的EFI應用程式，將其複製到 EFI系統分割中的 &lt;code&gt;/EFI/BOOT/&lt;/code&gt; 目錄下。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;pbatard/UEFI-Shell&quot;}&lt;/p&gt;
&lt;p&gt;如果妳使用的是 rEFInd 或者 &lt;code&gt;systemd-boot&lt;/code&gt; 引導載入器，那麼牠們會自動搜尋 UEFI shell 並將其添加到選單中，如果是 GRUB 使用者，可能還需要進行手動設定。&amp;lt;/br&amp;gt;
然後，到 GitHub 上搜尋&lt;a href=&quot;https://github.com/TravMurav/slbounce&quot;&gt;「slbounce」&lt;/a&gt;，然後下載 &lt;code&gt;slbounce.efi&lt;/code&gt; 和 &lt;code&gt;sltest.efi&lt;/code&gt; 兩個EFI應用程式，將其複製到 EFI系統分割中。之後我們需要從 Windows 中複製 &lt;code&gt;tcblaunch.exe&lt;/code&gt;，可以從正常的系統中複製，也可以從其他地方獲取。至於 &lt;code&gt;tcblaunch.exe&lt;/code&gt; 則是我們要後續執行「安全啓動」（Secure Launch，高通 Windows 平臺中，作業系統核心將自身從默認的EL1異常層級提升到EL2層級執行的過程）所需要的關鍵「鑰匙」。其原理過於複雜，對於絕大多數使用者可能難以理解，所以我將其根據我的理解寫於下面，供專業讀者進行參考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;現代的 Windows on ARM（WoA）裝置默認使用 Hyper-V 提供部分虛擬化功能（例如：Windows Subsys. for Linux (WSL), Windows Sandbox, Windows Subsystem for Android (WSA) 以及 Docker 之類），其虛擬機管理員總是以EL2異常層級執行。這與作業系統核心在EL1異常層級執行，和應用程式在EL0異常層級執行所不同。因爲 ARM 提出的 &lt;a href=&quot;https://developer.arm.com/documentation/den0044/latest&quot;&gt;ARM Base Root Requirements&lt;/a&gt; 規範強制要求，UEFI韌體必須執行在 EL2異常層級下，以准許安裝或配置虛擬機或者支援虛擬化感知的作業系統；&lt;/li&gt;
&lt;li&gt;自 SD835 (MSM8998)起，高通驍龍平臺的引導程式一律採用標準的 UEFI 韌體取代了之前的 Little Kernel 引導程式。但是高通的 UEFI 韌體並不滿足上述的「 ARM Base Root Requirements 」 中對於 UEFI 韌體的要求，儘管高通平臺支援 ARM 虛擬化技術，但是 UEFI 韌體是以 EL1 異常層級執行，所以作業系統及其虛擬機管理員無法訪問硬體 Hypervisior 。因此就必須實現自訂軟體實作，使得作業系統可以接管EL2異常層級的控制權，並且啓動Hypervisior；&lt;/li&gt;
&lt;li&gt;Qualcomm 所謂的 Secure Launch，不是 ARM Trusted Boot（BL1/BL2/BL31/TF-A）[^1] ，也不是 UEFI Secure Boot，而是 Windows 專用的 hypervisor 啓動過程：即在 Windows kernel 啓動前，於「可信狀態」下建立 EL2 執行環境，並讓 Hyper‑V 接管該層級；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tcblaunch.exe&lt;/code&gt; 是 Microsoft 簽名的 TCB（Trusted Computing Base）組件，其能力包括：呼叫 Qualcomm 平臺私有的 Secure Monitor / firmware 接口、重新配置 Exception Level、初始化 hypervisor 所需的系統暫存器與記憶體佈局，這是在不修改韌體的情況下進入 EL2異常層級的唯一方法；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slbounce&lt;/code&gt; 的設計目標並非繞過或破壞 Secure Launch，而是在合法且被信任的前提下觸發 Secure Launch，於不啓動 Windows 的情況下取得 EL2，並將已建立之 EL2 狀態交由 Linux 繼承；&lt;/li&gt;
&lt;li&gt;Secure Launch 在設計上即發生於 OS 啓動之前，因此 EFI 階段是唯一合理的切入點。其中，&lt;code&gt;ExitBootServices()&lt;/code&gt; 函式作為 UEFI 與作業系統之間的邊界，因此成為最合適的攔截位置。slbounce 以 EFI driver 形式載入，其實際流程如下：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;slbounce.efi 被 UEFI loader 載入;&lt;/li&gt;
&lt;li&gt;驗證並定位 &lt;code&gt;tcblaunch.exe&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;安裝 &lt;code&gt;ExitBootServices()&lt;/code&gt; hook;&lt;/li&gt;
&lt;li&gt;攔截 bootloader 對 &lt;code&gt;ExitBootServices()&lt;/code&gt; 的呼叫;&lt;/li&gt;
&lt;li&gt;在 EFI context 中執行 &lt;code&gt;tcblaunch.exe&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Secure Launch firmware 路徑被觸發並建立 EL2；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tcblaunch.exe&lt;/code&gt; 正常返回；&lt;/li&gt;
&lt;li&gt;控制權交還 bootloader，繼續啓動 Linux；
此時，系統已完成 Secure Launch，但後續啓動的並非 Windows，而是 Linux。&amp;lt;/br&amp;gt;
下載完成後，重開機到 &lt;code&gt;systemd-boot&lt;/code&gt; 引導器，選擇「 EFI Shell 」，之後妳就會進入 UEFI Shell。此時我們需要找到硬碟的 EFI系統分割（例如 &lt;code&gt;fs3&lt;/code&gt;），然後在 shell 中鍵入 &lt;code&gt;fs3:&lt;/code&gt;，按下 Enter 鍵，妳就會來到 EFI系統分割。可以鍵入 &lt;code&gt;ls&lt;/code&gt; 來查看分割內容。
找到先前複製的 &lt;code&gt;sltest.efi&lt;/code&gt; &lt;code&gt;slbounce.efi&lt;/code&gt; 以及 &lt;code&gt;tcblaunch.exe&lt;/code&gt;，開始進行測試。
鍵入 &lt;code&gt;sltest.efi tcblaunch.exe&lt;/code&gt;，此時螢幕上會出現「 Performing Secure Launch 」的日誌，如果成功，在熒幕頂端會展示綠色的矩形框。之後重開機即可。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;編譯核心&lt;/h1&gt;
&lt;p&gt;由於 Ubuntu 的核心並不支援 EL2 異常層級，所以我們需要自行編譯核心。我採用了 Linaro 維護的 &lt;code&gt;aarch64-laptop&lt;/code&gt; &lt;a href=&quot;https://gitlab.com/Linaro/arm64-laptops/linux/-/tree/qcom-laptops&quot;&gt;核心分支&lt;/a&gt;。
使用 &lt;code&gt;git clone&lt;/code&gt; 將原始碼下載到本機，然後鍵入 &lt;code&gt;make defconfig qcom_laptops.config&lt;/code&gt; 產生核心配置檔，之後鍵入 &lt;code&gt;make -j12&lt;/code&gt; 開始編譯。整個編譯過程耗時大約5分鐘（我有拿手機記錄時間，並把編譯核心和模組的時間算進去），之後鍵入 &lt;code&gt;sudo make modules_install install&lt;/code&gt; 安裝編譯好的核心。在編譯中會生成所有 X Elite 裝置的&lt;code&gt;-el2.dtb&lt;/code&gt; 裝置樹，這是啓用 Secure Launch 所需的裝置樹。之後配置引導載入器，新增 EL2 異常層級的配置檔，並指定對應的裝置樹：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# NOTE: This is an example configuration file for systemd-boot.
# In /boot/efi/loader/entries

title Ubuntu (EL2)
linux /vmlinux-6.19.0-rc1-00112-g999aec19c5ca-dirty
initrd /initrd.img-6.19.0-rc1-00112-g999aec19c5ca-dirty
options root=UUID=610ef124-aae3-4bbe-a29d-a17f44c708e9 debug earlycon=efifb ro clk_ignore_unused pd_ignore_unused cma=128M efi=noruntime loglevel=7 snd_soc_x1e80100.i_accept_the_danger id_aa64mmfr0.ecv=1 earlycon console=tty0 crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M
devicetree /x1e80100-lenovo-yoga-slim7x-el2.dtb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意在核心中添加 &lt;code&gt;id_aa64mmfr0.ecv=1&lt;/code&gt; 引數，否則在使用虛擬機時會當機重啓。&lt;/p&gt;
&lt;h1&gt;安裝 Virt Manager&lt;/h1&gt;
&lt;p&gt;準備完成後，進入 EFI Shell，找到硬碟的 EFI系統分割，鍵入 &lt;code&gt;load slbounce.efi&lt;/code&gt; 加載驅動程式，之後找到系統的開機載入器，通過 EFI Shell 執行，選擇先前的配置選項。如果核心正常啓動，就說明 Secure Launch 成功。在終端機中鍵入 &lt;code&gt;ls /dev/kvm&lt;/code&gt; 確認是否有 &lt;code&gt;/dev/kvm&lt;/code&gt; 裝置，如果有，就表示 KVM 模組成功安裝。同時 &lt;code&gt;dmesg&lt;/code&gt; 中應該會出現關於 GIC 和 KVM 的日誌:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dmesg | grep kvm
[    0.067555] kvm [1]: nv: 568 coarse grained trap handlers
[    0.067687] kvm [1]: nv: 664 fine grained trap handlers
[    0.067777] kvm [1]: IPA Size Limit: 44 bits
[    0.067789] kvm [1]: GICv4 support disabled
[    0.067791] kvm [1]: GICv3: no GICV resource entry
[    0.067792] kvm [1]: disabling GICv2 emulation
[    0.067806] kvm [1]: GIC system register CPU interface enabled
[    0.067813] kvm [1]: vgic interrupt IRQ9
[    0.067839] kvm [1]: Broken CNTVOFF_EL2, trapping virtual timer
[    0.067845] kvm [1]: VHE mode initialized successfully
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;assets/working-kvm-demo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之後的步驟，建議將妳的筆電接上電源，因爲高通 ADSP, CDSP 等遠端處理器在 EL2 異常層級下僅會被核心 Hypervisior 初始化基礎韌體使用部分功能，因此所有依賴 ADSP, CDSP 遠端處理器完整韌體的功能會噴掉，比如 Wi-Fi和電池（表現爲電量始終顯示0%），還有音訊。目前的解決辦法是使用 ADSP-lite 驅動，這樣勉強可以補回一些功能。或者改用新的 &lt;a href=&quot;https://github.com/stephan-gh/qebspil/&quot;&gt;qebspil&lt;/a&gt;驅動，讓 UEFI 韌體初始化這些遠端處理器。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;如果需要使用 &lt;code&gt;qebspli&lt;/code&gt; 驅動，需要在 EFI 分割建立 &lt;code&gt;firmware&lt;/code&gt; 資料夾，並將晶片的遠程協處理器韌體放在資料夾下。可以使用 &lt;code&gt;find /sys/firmware/devicetree -name firmware-name -exec cat {} + | xargs -0n1&lt;/code&gt; 指令檢視需要的韌體。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;現在，讓我們來安裝 Virt Manager，這是一個用於管理虛擬機的圖形化工具。在 Ubuntu 26.04 環境下，可以通過 &lt;code&gt;sudo apt install virt-manager&lt;/code&gt; 安裝。之後啓用對應的 &lt;code&gt;systemd&lt;/code&gt; 服務即可。
然後，安裝&lt;code&gt;qemu-system-arm&lt;/code&gt;套件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install qemu-system-arm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，將自己加入&lt;code&gt;libvirt&lt;/code&gt;組，登出，再登入，就可以使用 Virt Manager 啓動虛擬機了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/virt-manager.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之後，建立新的虛擬機，注意虛擬機類型要選擇「KVM」才會有KVM加速。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/new-vm.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;載入 Alpine Linux 安裝映像檔，然後按下「下一步」。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;指定分給虛擬機的記憶體和CPU個數，驍龍 X Elite 已經很強了，所以我分給虛擬機 4個核心和4GB 記憶體。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-config.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;建立虛擬磁碟，我選擇 20GB 的空間。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-disk.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定虛擬機的網路，保持默認即可。之後開機，妳應該會看到 Tianocore 的啓動 Logo:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-boot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果遇到「Access denied」錯誤，這是因爲虛擬機的UEFI韌體開啓了安全啓動，到「設定」中關閉即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/secure-boot-error.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之後開機。開機後只會有&lt;code&gt;tty&lt;/code&gt;畫面，鍵入&lt;code&gt;root&lt;/code&gt;登入系統。&amp;lt;/br&amp;gt;
之後鍵入&lt;code&gt;setup-alpine&lt;/code&gt;安裝 Alpine Linux，接着就會問一系列問題：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@alpine:~# setup-alpine
# 鍵盤配置
Select keyboard layout: [us]
Select variant: [us-alt-int]

# 主機名稱
Enter system hostname: [alpine]

# 啟用網路界面
Which one do you want to initialize? [eth0]

# 使用DHCP
Ip  address for eth0? [dhcp]
Do you want to do any manual netowrk configuration? [n]

# 設定Root密碼
New password:

#設定時區
Which timezone are you in? [Asia/Taipei]

#是否設定代理伺服器

HTTP/FTP proxy URL? [none]

# 啟用community套件庫
Enter mirror number: [c]

# 讓Alpine自動抓取速度最快的套件庫站點
Enter mirror number: [f]

# 新增一般使用者帳號&quot;ykia&quot;和設定密碼
Setup a user? [ykia]
New password for ykia:

# 跳過新增SSH金鑰
Enter ssh key or URL for ivon: [none]

# 安裝OpenSSH伺服器
Which ssh server? [openssh]

# 將系統安裝至硬碟，Alpine會自動安裝GRUB
Which disk would you like to use? [vda]
How would you like to use it? [sys]
WARNING: Erase the above disk(s) and continue? [y]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安裝完成後重開機，登入 &lt;code&gt;root&lt;/code&gt; 賬號，執行&lt;code&gt;apk update &amp;amp;&amp;amp; apk upgrade&lt;/code&gt;更新套件庫。&amp;lt;/br&amp;gt;
安裝 &lt;code&gt;sudo&lt;/code&gt; 套件，並設定 &lt;code&gt;ykia&lt;/code&gt; 為 &lt;code&gt;sudo&lt;/code&gt; 的管理員：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apk add sudo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行&lt;code&gt;visudo&lt;/code&gt;將一般使用者加入sudo：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ykia ALL=(ALL:ALL) ALL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後重開機，改用一般賬號登入。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;如果覺得虛擬機執行效能低下，可以在「設定」中配置使用 OpenGL 加速，虛擬機可以吃到 Adreno 內建繪圖卡的 3D 加速：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/opengl-accelerate.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/adreno-3d-accelerate.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;[^1]: 唯一的例外是 ChromeOS 平臺(LC)，牠採用 ARM 的 Trusted Firmware (TF-A)，而不是高通專有的引導流程，默認允許作業系統以 EL2異常層級啓動。&lt;/p&gt;
</content:encoded></item><item><title>Enabling KVM on Snapdragon X Elite Laptops to Install Alpine Linux — A KVM Installation Guide for the 64-bit ARM Platform</title><link>https://blog.cloudflare88.eu.org/posts/en/alpine-on-kvm/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/alpine-on-kvm/</guid><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;&lt;/p&gt;
&lt;p&gt;(Original text written on January 4, 2026)&lt;/p&gt;
&lt;h1&gt;The Beginning of Everything&lt;/h1&gt;
&lt;p&gt;Since I swapped my primary laptop from a MacBook Air to this Lenovo Yoga Air 14s, my fondness for the Snapdragon X Elite has been steadily climbing. It&apos;s not just the shock of having 12 high-performance Oryon CPU cores and 32GB of RAM that makes it more than enough for daily tasks and embedded Linux development alike. However, like any laptop, this Yoga Air 14s has its shortcomings.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;It ships by default with Windows 11 ARM, and specifically the Home Edition, which lacks Hyper-V virtualization support compared to the Pro version. I ended up backing up my useful data and wiping the entire drive to install Windows 11 Pro. This time, the &quot;Optional features&quot; finally included the &quot;Hyper-V&quot; option. I enabled the relevant features, rebooted, and downloaded the Debian 13 ARM installation image. I tried to fire up a virtual machine, but it hung; no matter how I tweaked the VM configuration, I couldn&apos;t get into the Debian installer. Plus, Windows is notorious &quot;spyware,&quot; and I have zero desire to let Microsoft monitor me! So, I installed the only OS where most hardware currently works reasonably well: Ubuntu. But KVM functionality requires manual configuration.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/final-result.png&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;Preparations&lt;/h1&gt;
&lt;p&gt;First, search for &quot;UEFI Shell&quot; on the web, find the corresponding &lt;a href=&quot;https://github.com/pbatard/UEFI-Shell/releases&quot;&gt;GitHub repository URL&lt;/a&gt;, and download the EFI application named &lt;code&gt;shellaa64.efi&lt;/code&gt;. Copy it to the &lt;code&gt;/EFI/BOOT/&lt;/code&gt; directory in your EFI System Partition (ESP).&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;pbatard/UEFI-Shell&quot;}&lt;/p&gt;
&lt;p&gt;If you are using rEFInd or the &lt;code&gt;systemd-boot&lt;/code&gt; loader, they will automatically scan for the UEFI shell and add it to the menu. GRUB users might still need to perform manual configuration.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, head over to GitHub and search for 「slbounce」, then download the &lt;code&gt;slbounce.efi&lt;/code&gt; and &lt;code&gt;sltest.efi&lt;/code&gt; EFI applications and copy them into your ESP. We then need to copy &lt;code&gt;tcblaunch.exe&lt;/code&gt; from Windows. You can grab it from a running system or obtain it elsewhere. &lt;code&gt;tcblaunch.exe&lt;/code&gt; is the critical &quot;key&quot; required for performing a &quot;Secure Launch&quot;, the process on Qualcomm Windows platforms where the OS kernel elevates itself from the default EL1 Exception Level to EL2. The underlying theory is quite complex and might be difficult for most users to grasp, so I’ve summarized my understanding below for professional readers to reference:&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Modern Windows on ARM (WoA) devices default to using Hyper-V to provide certain virtualization features (e.g., WSL, Windows Sandbox, WSA, and Docker). Its hypervisor always executes at the EL2 Exception Level. This differs from the OS kernel running at EL1 and applications at EL0. The &lt;a href=&quot;https://developer.arm.com/documentation/den0044/latest&quot;&gt;ARM Base Boot Requirements (BBR)&lt;/a&gt; specification strictly requires that UEFI firmware must execute at EL2 to permit the installation or configuration of hypervisors or virtualization-aware operating systems.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since the SD835 (MSM8998), Qualcomm Snapdragon platforms have uniformly adopted standard UEFI firmware to replace the previous Little Kernel (LK) bootloader. However, Qualcomm&apos;s UEFI implementation does not satisfy the aforementioned ARM BBR requirements. Although the Snapdragon platform supports ARM virtualization extensions, the UEFI firmware executes at EL1. Consequently, the OS and its VM managers cannot access the hardware hypervisor. Therefore, a custom software implementation is required to allow the OS to seize control of the EL2 Exception Level and start the Hypervisor.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Qualcomm&apos;s so-called Secure Launch is neither ARM Trusted Boot (BL1/BL2/BL31/TF-A) [^1] nor UEFI Secure Boot. It is a Windows-proprietary hypervisor startup sequence: before the Windows kernel starts, it establishes an EL2 execution environment under a &quot;trusted state&quot; and lets Hyper-V take over that level.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tcblaunch.exe&lt;/code&gt; is a Microsoft-signed TCB (Trusted Computing Base) component. Its capabilities include: calling Qualcomm&apos;s private Secure Monitor / firmware interfaces, reconfiguring Exception Levels, and initializing the system registers and memory layout required by the hypervisor. This is the only way to enter the EL2 Exception Level without modifying the firmware.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The design goal of &lt;code&gt;slbounce&lt;/code&gt; is not to bypass or break Secure Launch, but rather to trigger Secure Launch under legal and trusted premises. It obtains EL2 without actually starting Windows and hands the established EL2 state over to Linux.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Secure Launch is designed to occur before the OS starts, making the EFI stage the only logical entry point. Specifically, the &lt;code&gt;ExitBootServices()&lt;/code&gt; function, acting as the boundary between UEFI and the OS, becomes the most suitable interception point. slbounce loads as an EFI driver, and its actual workflow is as follows:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;slbounce.efi&lt;/code&gt; is loaded by the UEFI loader.&lt;/li&gt;
&lt;li&gt;Validates and locates &lt;code&gt;tcblaunch.exe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Installs an &lt;code&gt;ExitBootServices()&lt;/code&gt; hook.&lt;/li&gt;
&lt;li&gt;Intercepts the bootloader&apos;s call to &lt;code&gt;ExitBootServices()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Executes &lt;code&gt;tcblaunch.exe&lt;/code&gt; within the EFI context.&lt;/li&gt;
&lt;li&gt;The Secure Launch firmware path is triggered, establishing EL2.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tcblaunch.exe&lt;/code&gt; returns normally.&lt;/li&gt;
&lt;li&gt;Control is returned to the bootloader to continue starting Linux.
At this point, the system has completed the Secure Launch, but it is Linux that starts next, not Windows.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After downloading, reboot into the &lt;code&gt;systemd-boot&lt;/code&gt; loader and select &quot;EFI Shell.&quot; You will enter the UEFI Shell. We need to find the ESP on the hard drive (e.g., &lt;code&gt;fs3&lt;/code&gt;), then type &lt;code&gt;fs3:&lt;/code&gt; and press Enter to enter the partition. You can type &lt;code&gt;ls&lt;/code&gt; to view the contents.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Find the previously copied &lt;code&gt;sltest.efi&lt;/code&gt;, &lt;code&gt;slbounce.efi&lt;/code&gt;, and &lt;code&gt;tcblaunch.exe&lt;/code&gt; to begin testing.
Type &lt;code&gt;sltest.efi tcblaunch.exe&lt;/code&gt;. A log saying &quot;Performing Secure Launch&quot; will appear. If successful, a green rectangular box will be displayed at the top of the screen. Reboot afterwards.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Compiling the Kernel&lt;/h1&gt;
&lt;p&gt;Since the stock Ubuntu kernel does not support the EL2 Exception Level, we need to compile our own. I used the &lt;code&gt;aarch64-laptop&lt;/code&gt; kernel branch maintained by Linaro.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;git clone&lt;/code&gt; to download the source code locally, then type &lt;code&gt;make defconfig qcom_laptops.config&lt;/code&gt; to generate the kernel configuration. Follow this with &lt;code&gt;make -j12&lt;/code&gt; to start compiling. The entire process took about 5 minutes (I timed it with my phone, including the kernel and module compilation), then type &lt;code&gt;sudo make modules_install install&lt;/code&gt; to install the compiled kernel. During compilation, &lt;code&gt;-el2.dtb&lt;/code&gt; device trees for all X Elite devices are generated; these are required for enabling Secure Launch. Next, configure the bootloader by adding an EL2 entry and specifying the corresponding device tree:&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# NOTE: This is an example configuration file for systemd-boot.
# In /boot/efi/loader/entries

title Ubuntu (EL2)
linux /vmlinux-6.19.0-rc1-00112-g999aec19c5ca-dirty
initrd /initrd.img-6.19.0-rc1-00112-g999aec19c5ca-dirty
options root=UUID=610ef124-aae3-4bbe-a29d-a17f44c708e9 debug earlycon=efifb ro clk_ignore_unused pd_ignore_unused cma=128M efi=noruntime loglevel=7 snd_soc_x1e80100.i_accept_the_danger id_aa64mmfr0.ecv=1 earlycon console=tty0 crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M
devicetree /x1e80100-lenovo-yoga-slim7x-el2.dtb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: Be sure to add the &lt;code&gt;id_aa64mmfr0.ecv=1&lt;/code&gt; parameter to the kernel options, otherwise the system will crash and reboot when using a virtual machine.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Installing Virt Manager&lt;/h1&gt;
&lt;p&gt;Once ready, enter the EFI Shell, find the hard drive&apos;s ESP, and type &lt;code&gt;load slbounce.efi&lt;/code&gt; to load the driver. Then, find your system&apos;s bootloader and execute it via the UEFI Shell, selecting the EL2 configuration. If the kernel starts normally, it means Secure Launch was successful. Type &lt;code&gt;ls /dev/kvm&lt;/code&gt; in the terminal to confirm the presence of the &lt;code&gt;/dev/kvm&lt;/code&gt; device; if it&apos;s there, the KVM module is successfully loaded. You should also see logs regarding GIC and KVM in &lt;code&gt;dmesg&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dmesg | grep kvm
[    0.067555] kvm [1]: nv: 568 coarse grained trap handlers
[    0.067687] kvm [1]: nv: 664 fine grained trap handlers
[    0.067777] kvm [1]: IPA Size Limit: 44 bits
[    0.067789] kvm [1]: GICv4 support disabled
[    0.067791] kvm [1]: GICv3: no GICV resource entry
[    0.067792] kvm [1]: disabling GICv2 emulation
[    0.067806] kvm [1]: GIC system register CPU interface enabled
[    0.067813] kvm [1]: vgic interrupt IRQ9
[    0.067839] kvm [1]: Broken CNTVOFF_EL2, trapping virtual timer
[    0.067845] kvm [1]: VHE mode initialized successfully
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;assets/working-kvm-demo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For the subsequent steps, I recommend keeping your laptop plugged in. This is because Qualcomm remote processors like the ADSP and CDSP will only be initialized with basic firmware by the kernel hypervisor under EL2. Consequently, all features dependent on the full firmware of these processors will break—such as Wi-Fi and battery management (resulting in the battery level being stuck at 0%), as well as audio. The current workaround is to use the ADSP-lite driver, which restores some basic functionality, or switch to the newer qebspil driver to let the UEFI firmware initialize these remote processors.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;If you need to use the &lt;code&gt;qebspli&lt;/code&gt; driver, you must create a &lt;code&gt;firmware&lt;/code&gt; folder in the EFI partition and place the remote coprocessor firmware for the chip inside. You can check the required firmware using the command: &lt;code&gt;find /sys/firmware/devicetree -name firmware-name -exec cat {} + | xargs -0n1&lt;/code&gt;.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, let&apos;s install Virt Manager, a graphical tool for managing virtual machines. On Ubuntu 26.04, you can install it via &lt;code&gt;sudo apt install virt-manager&lt;/code&gt;. Enable the corresponding &lt;code&gt;systemd&lt;/code&gt; service afterwards.&amp;lt;/br&amp;gt;
Then, install the &lt;code&gt;qemu-system-arm&lt;/code&gt; package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install qemu-system-arm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, add yourself to the &lt;code&gt;libvirt&lt;/code&gt; group, log out, and log back in. You can now use Virt Manager to start virtual machines.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/virt-manager.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Create a new virtual machine, ensuring the virtualization type is set to &quot;KVM&quot; to enable KVM acceleration.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/new-vm.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Load the Alpine Linux installation ISO image and click &quot;Next.&quot;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Specify the memory and CPU cores allocated to the VM. The Snapdragon X Elite is already quite powerful, so I allocated 4 cores and 4GB of RAM.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-config.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Create a virtual disk; I chose 20GB of space.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-disk.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Set up the VM&apos;s network, keeping the defaults. Upon booting, you should see the Tianocore splash logo:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/alpine-boot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you encounter an &quot;Access denied&quot; error, it&apos;s because the VM&apos;s UEFI firmware has Secure Boot enabled; you can disable it in the &quot;Settings.&quot;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/secure-boot-error.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Boot the machine. You&apos;ll be presented with a &lt;code&gt;tty&lt;/code&gt; screen; type &lt;code&gt;root&lt;/code&gt; to log in.
Then, type &lt;code&gt;setup-alpine&lt;/code&gt; to install Alpine Linux, which will prompt you with a series of questions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@alpine:~# setup-alpine
# Keyboard layout
Select keyboard layout: [us]
Select variant: [us-alt-int]

# Hostname
Enter system hostname: [alpine]

# Enable network interface
Which one do you want to initialize? [eth0]

# Use DHCP
Ip  address for eth0? [dhcp]
Do you want to do any manual netowrk configuration? [n]

# Set Root password
New password:

# Set Timezone
Which timezone are you in? [Asia/Taipei]

# Proxy settings
HTTP/FTP proxy URL? [none]

# Enable community repository
Enter mirror number: [c]

# Let Alpine find the fastest mirror
Enter mirror number: [f]

# Create a user account &quot;ykia&quot; and set password
Setup a user? [ykia]
New password for ykia:

# Skip adding SSH keys
Enter ssh key or URL for ivon: [none]

# Install OpenSSH server
Which ssh server? [openssh]

# Install system to disk; Alpine will install GRUB automatically
Which disk would you like to use? [vda]
How would you like to use it? [sys]
WARNING: Erase the above disk(s) and continue? [y]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installation, reboot and log into the &lt;code&gt;root&lt;/code&gt; account. Run &lt;code&gt;apk update &amp;amp;&amp;amp; apk upgrade&lt;/code&gt; to update the repositories.
Install the &lt;code&gt;sudo&lt;/code&gt; package and set &lt;code&gt;ykia&lt;/code&gt; as a &lt;code&gt;sudo&lt;/code&gt; administrator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apk add sudo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run &lt;code&gt;visudo&lt;/code&gt; to add the user to sudo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ykia ALL=(ALL:ALL) ALL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reboot once more and log in with your regular account.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;If you feel the VM&apos;s performance is sluggish, you can configure OpenGL acceleration in the &quot;Settings&quot;; the VM can then utilize the 3D acceleration from the integrated Adreno graphics:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/opengl-accelerate.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/adreno-3d-accelerate.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;[^1]: The sole exception is the ChromeOS platform (LC), which utilizes ARM&apos;s Trusted Firmware (TF-A) rather than Qualcomm&apos;s proprietary boot sequence, allowing the OS to boot into the EL2 Exception Level by default.&lt;/p&gt;
</content:encoded></item><item><title>不要讓軟體安裝「污名化」—— 反對 Google 強制驗証開發者身份，禁止 Android 自由安裝第三方軟體</title><link>https://blog.cloudflare88.eu.org/posts/keep-android-open/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/keep-android-open/</guid><description>我的手機，我說了算。這本該是理所當然的事，不應該成為一種奢求。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;(寫於 2026年5月3日)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Android 一直就是戴着「開放」的僞裝，實際是充滿專有軟體的「間諜程式」。如今的 Android 終於撕開了牠「開放」的僞裝，露出了「間諜軟體」的真面目。&lt;/em&gt; &amp;lt;/br&amp;gt;
—— EDKPiepaint，寫於2019年3月3日&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;未來，所有 Android 手機將無法自由地安裝軟體！&amp;lt;/br&amp;gt;
從2026年9月開始，Google 將實施「&lt;a href=&quot;https://developer.android.com/developer-verification?hl=zh-tw&quot;&gt;Android Developer Verification&lt;/a&gt;」政策，強制驗証開發者資證，這會影響到使用者安裝 APK 的權利。&amp;lt;/br&amp;gt;
請支援這一維護消費者合法權益的自由軟體運動！&lt;a href=&quot;https://keepandroidopen.org/zh-TW/&quot;&gt;保持 Android 開放&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;作爲一般使用者：安裝軟體的權利將會受到嚴格限制，妳的財產，卻由不得妳&lt;/h1&gt;
&lt;p&gt;Android 作爲目前行動裝置上最受歡迎的基於 Linux 的作業系統，同時也是嵌入式作業系統，被廣泛應用在智慧型手機、手錶以及工業裝置。可以說，有熒幕的地方，就一定會有 Android 的存在。&amp;lt;/br&amp;gt;
而 Android 不同於 iOS 的地方，莫過於可以自由的安裝應用程式。雖然 Google Play 商店（Android Market）從 Android 2.2 就被加入成爲 Google 官方下發應用程式的方法，但是並沒有任何規定要求使用者必須從應用程式商店
安裝應用，下載應用。開發者也可以從個人的網站或者 GitHub 等分發自己的 APK 檔案，讓使用者下載和安裝。&amp;lt;/br&amp;gt;
但是，Google 爲了所謂的「安全性」考量，正在逐步限制並破壞 Android 「開放」的一面。從9月之後，以後開發者分發 APK，都必須要向 Google 提交包含個人敏感身份的資料，並對 APK 進行數位簽名後才可以安裝。若 APK 沒有數位簽章，
就會被禁止安裝，恐怕也不會像中國廠商那樣，連「我已知曉風險，繼續安裝」的選擇都不會給予！&amp;lt;/br&amp;gt;
不過，需要指出的一點是：&lt;strong&gt;Google 目前沒有限制使用者安裝應用的權力&lt;/strong&gt;，只是給安裝流程多上了一把鎖，確認 APK 是安全的，並且有人爲此承擔可能帶來的後果。雖然身份驗證很簡單，但不是所有人都想被 Google 控制，所謂的「身份驗證」本就是侵犯個人隱私權的行爲。
應用上架 Play store 需要驗証就算了，爲什麼連個人安裝 APK 檔案也要管呢？&amp;lt;/br&amp;gt;
不要認爲只有新手機會受到影響，這個政策應該會通過GMS進行遠端下發。因爲所有手機都會有GMS內建，所以只要 Google 更新文件，就可以強制阻擋安裝 APK 檔案（個人猜測，目前沒有資料可以佐証）。即使妳買了沒有GMS的中國大陸手機，搞不好也可能被國家反詐中心禁止安裝第三方應用。&amp;lt;/br&amp;gt;
這個政策施行下去，到時候，只有degoogle無GMS的Android系統才能自由安裝APK了，例如LineageOS和GrapheneOS，這類手機品牌市佔率不高。況且對自由世界的Android用戶來說，很多APP都依賴GMS才能運作，脫離GMS服務是很不切實際的選擇。&amp;lt;/br&amp;gt;
因此世界各地，許多開發者和使用者們擔憂 Google 破壞 Android 「開放」的一面，發起了「&lt;a href=&quot;https://keepandroidopen.org/zh-TW/&quot;&gt;保持 Android 開放&lt;/a&gt;」的自由軟體運動。上述網頁裡面有反對Google驗證開發者身份請願書(change.org)可以簽名。並羅列了各國的發聲管道（包含中國以及中國大陸），可以與立法機關聯絡，呼籲他們關注此事。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只有使用者與開發者默許，他們的邪惡計劃才會得逞。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;鑑於部分使用者可能無法理解，我用幾個例子來簡單的描述這一政策實行之後的影響：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;過去，如果妳在網路上看到一個獨立開發者寫的實用小工具（例如：去廣告插件、長輩用的簡易啟動器、或是校園社團自製的選課 App），妳只需要下載 APK 就能使用。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;未來的限制： 這些「非職業」開發者可能因為不想向 Google 提交個人身分證件、家庭住址或電話，而被迫停止分發軟體。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;妳的處境： 妳將無法再使用那些極具創意、但開發者不想「實名制」的軟體。Android 將變成一個只有「大公司」才能分發軟體的平臺，那些充滿生命力的民間小工具將會慢慢絕跡。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;很多人手中都有一些已經停止更新，但在新機上依然能跑的老 App，或者是從舊手機備份出來的 APK 檔。牠們或許承載着妳的美好回憶，或許記錄了妳與家人的點點滴滴，亦或許是妳最喜歡的遊戲...... &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;未來的限制： 這些老舊的 APK 檔案並沒有經過符合 2026 年新標準的「數位簽章」。一旦系統強制要求驗證，這些承載回憶或特定功能的軟體將會被系統直接攔截。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;妳的處境： 即使妳擁有軟體檔案，妳的手機也會告訴妳「來源無法驗證，禁止安裝」。妳對自己購買的硬體失去了控制權，無法決定要跑什麼軟體，這就像買了車卻被原廠鎖死只能開在某些路段一樣。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;目前我們安裝第三方 APK 時，系統會跳出「不安全」的警告，但通常會有一個「仍要安裝」的選項。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;未來的限制： 隨著驗證政策收緊，Google 可能會取消這個「逃生門」。系統將不再信任未簽名的 APK，甚至連點擊安裝的機會都不給妳。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;妳的處境： 妳與手機之間的關係從「主僕」變成了「監護人與被監護者」。Google 成了那位過度保護的家長，牠幫妳決定了什麼是危險的，甚至剝奪了妳「承擔風險」的自由。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Android 曾經最自豪的功能就是「安裝應用程式」，即不需要透過官方商店，就能直接安裝 APK。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;未來的限制： Google 正在透過技術手段，讓安裝變得極度困難。這不僅僅是彈出一個警告窗口，而是從系統底層拒絕執行「未經過中心化驗證」的代碼。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;妳的處境： 表面上「安裝第三方應用」的開關還在，但實際上，妳下載回來的 APK 如果沒有經過 Google 認可的數位簽章，那個開關就是個擺設。這標誌著 Android 從一個 &lt;strong&gt;「通用運算裝置」轉型為一個「受控的數位終端」&lt;/strong&gt;。妳不再是手機的主人，妳只是租用這台機器使用權的租客。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;不容樂觀的現況：Google 依舊「初心不改」，堅決實行驗証開發者資證的政策&lt;/h1&gt;
&lt;p&gt;到目前爲止，Google 依舊沒有放棄這一政策。&amp;lt;/br&amp;gt;
根據 Google 在 &lt;a href=&quot;https://android-developers.googleblog.com/2026/03/android-developer-verification.html&quot;&gt;Android Developers Blog&lt;/a&gt; 的解釋，Android 17之後，安裝APK要在開發人員選項開啟，看完一系列警告確認你不是被詐騙，等待24小時後重開機，通過生物驗證（指紋或掃臉），才能安裝APK。並且會有選項讓你要開放7天或者永久開放。這個過程只要做一次就可以了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhspfxHEJXusQIuuaK5xbfTJHHpsHcXglbGs1kIK-R288TG9Y8zlTujkQ2JfSAjwxhPbyWqZlZSdCo6twkcD1oj7n30Adce7FG0-0LmF-tVMvkEJd_5CQ3TfRVhTM4A0pUfpTw-7AJxj0TYyAqm2IeHqSmKv5PuCWw5yrhBSzxsjec3Hszrog0wMrJUhVQ/s1920/260318_ADV%20flow%20chart_v5.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;另外，針對不想交出自己資料的開發者或是「業餘開發者」，Google 推出了受限開發者帳號(limited distribution account)，不用繳交身份證件就能註冊。透過這種方式簽署的APK可以通過 Android 的新驗證機制。但是最多只能安裝在20台裝置上。如果妳不想做這些流程，妳就只能藉助 ADB 安裝 APK 了。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;第三方 ROM 會不會受到 Google 政策的影響呢？&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Graphene OS 開發者在 &lt;a href=&quot;https://x.com/GrapheneOS/status/2034957604682621229&quot;&gt;Twitter 明確表示他們不會加入這一功能&lt;/a&gt;：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;blockquote class=&quot;twitter-tweet&quot;&amp;gt;&amp;lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&amp;gt;GrapheneOS will remain usable by anyone around the world without requiring personal information, identification or an account. GrapheneOS and our services will remain available internationally. If GrapheneOS devices can&apos;t be sold in a region due to their regulations, so be it.&amp;lt;/p&amp;gt;— GrapheneOS (@GrapheneOS) &amp;lt;a href=&quot;https://x.com/GrapheneOS/status/2034957604682621229?ref_src=twsrc%5Etfw&quot;&amp;gt;March 20, 2026&amp;lt;/a&amp;gt;&amp;lt;/blockquote&amp;gt; &amp;lt;script async src=&quot;https://platform.x.com/widgets.js&quot; charset=&quot;utf-8&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;根據這篇Reddit討論：&lt;a href=&quot;https://www.reddit.com/r/LineageOS/comments/1tu0qlx/will_lineageos_be_affected_by_the_android/&quot;&gt;Will LineageOS be affected by the Android lockdown in September?&lt;/a&gt; LineageOS 維護者表示他們打包的 GAPPS 套件 MindTheGapps 將不會加入驗證APK開發者的功能。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;另外，使用者也可以通過 &lt;code&gt;anyapk&lt;/code&gt; 這一 &lt;a href=&quot;https://github.com/sam1am/anyapk&quot;&gt;GitHub 專案&lt;/a&gt;來安裝 Apk，方法是通過 Shizuku 中介，藉助 &lt;code&gt;ADB install&lt;/code&gt; 方法來安裝未經簽章驗證的應用。不過 Google 很可能在未來的 Android 版本修復 Shizuku 自己給自己 ADB 的 loophole，之後 ADB 都需要只能通過電腦執行。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;sam1am/anyapk&quot;}&lt;/p&gt;
&lt;h1&gt;安裝應用是消費者的合法權利，一步也不能退讓&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;那些放棄重要自由以換取一點點暫時安全的人，既不配享受安全，也不配擁有自由。&amp;lt;/br&amp;gt;
--- &lt;a href=&quot;https://ivonblog.com/posts/keep-android-open/#3-%e5%81%b4%e8%bc%89apk%e6%98%af%e5%90%88%e6%b3%95%e6%ac%8a%e5%88%a9%e4%b8%80%e6%ad%a5%e9%83%bd%e4%b8%8d%e6%87%89%e8%a9%b2%e9%80%80%e8%ae%93&quot;&gt;Ivon&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;프라이버시(privacy)의 夢, 人權이 保障된 곳.&lt;/strong&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;滿懷(守護)隱私的希望，數位人權得到保障&lt;/em&gt;&amp;lt;/br&amp;gt;
--- &lt;a href=&quot;(https://blog.cloudflare88.eu.org/posts/ready-set-flash-korean/)&quot;&gt;準備, 始作, 플래싱! -- ‘Blue Archive’ 中國 서버 大運動會 主題曲 ‘출발준비(出發準備)!’를 FOSS가 패러디한 버전 (韓國語 버전)&lt;/a&gt; ，EDK Piepaint 씀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Google把安裝APK的按鈕，跟OEM解鎖放在一起，把牠當作刷機一樣洪水猛獸的存在。總之就是加上諸多限制，警告使用者。&amp;lt;/br&amp;gt;
Google 未來將強制驗証開發者資證，連手動安裝應用也要管，否則不許安裝。但是，安裝應用是妳本來就該有的權利。到目前爲止，我沒有檢索到哪個人因爲在自己的 Android 手機上安裝了應用而被送進監獄的消息。妳的手機，妳說了算。不要覺得這個想法非常幼稚，因爲事情本就如此！妳的手機本就是妳說了算，這是完全合法的行爲，而不應該成爲某個公司或者別人施捨與妳的「恩賜」。除了妳自己，沒有人能夠規定妳應該對妳的手機做什麼。&amp;lt;/br&amp;gt;
不可否認，Google 或是任何科技巨頭在推動這些政策時，總是披著「保護用戶安全」的華麗外衣。他們會告訴妳：手動安裝（Sideloading）是惡意軟體的溫床，是詐騙的源頭。&amp;lt;/br&amp;gt;
但我們必須看清這背後的邏輯謬誤：安全與自由並非零和遊戲。 提供安全預警、掃描已知威脅是企業的服務義務，但將「預警」升級為「禁令」，則是對用戶智商的冒犯。如果我們因為擔心交通事故而交出駕駛權，將方向盤鎖死在只能開往「官方指定目的地」的軌道上，那這部車還屬於妳嗎？&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;當妳付了幾萬塊台幣買下一支手機時，這份買賣契約應當包含對該硬體的所有處置權。然而，現在的科技廠商正試圖透過軟體更新，將用戶從「擁有者」降級為「租借者」。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;誰才是主人？ 如果一個裝置不能執行主人命令牠執行的程式碼，那麼這個裝置本質上就不受主人控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;在我的記憶中，這一成不變的世界&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;是由專有軟體組成的「圍牆花園」&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;我們一起奔向那自由的彼方&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;和專有軟體道過「來日見」後永不再見面&lt;/em&gt;&amp;lt;/br&amp;gt;
—— &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/flash-continous-tense/&quot;&gt;刷機進行式 (Feat. Pakala Oryon) —— 根據 May&apos;n 的 《人生進行形》的 FOSS 改編&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;牆內的花園： 他們試圖建立一個「圍牆花園」，只有經過他們審核、抽成、認可的內容才能進入。這不只是為了安全，更是為了壟斷分發管道與數據。&amp;lt;/br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我們承認，手動安裝應用確實存在風險。但作為一個成年人，我們有權利選擇承擔風險，並從中學習如何保護自己。&amp;lt;/br&amp;gt;
自由從來不是免費的，牠的代價是個人的警覺與責任，而不是轉身投向一個「數位家長」的懷抱尋求庇護。一旦我們退讓了這一步，默許了廠商可以隨意切斷我們安裝軟體的路徑，那麼未來他們就能以同樣的理由，決定我們能看什麼新聞、用什麼通訊軟體、甚至限制我們對裝置的維修權利。就像極權國家控制他們的人民一樣。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;污名化使用者：把「合法安裝」應用稱爲「側載」&lt;/h1&gt;
&lt;p&gt;把 Android 合法安裝應用的做法稱之爲「側載（Sideloading）」，本身就是一種蔑稱。這種把使用者的完全正確且合法的行爲「污名化」，是典型的「話語權操弄」和「數位心理暗示」做法。這種行爲，在「文化大革命」和「八九民運」期間早就屢見不鮮。這隱含了妳們這樣做，是在幹壞事，用不正當手段安裝軟體的意含。Apple 對開放側載的態度也是如此，認為開放使用者自由安裝APP太危險了。這種行為，實則是作為自由之敵。似乎總有人認為，透過官方以外管道的安裝軟體，就是要破解軟體，安裝盜版，或是使用違法APP，而且隨著高風險。刻意營造出一種「不走正門、翻牆而入」的偷偷摸摸感。牠暗示了 Google Play 商店才是唯一的「正門」，而使用者直接運行自己下載的安裝檔案，則變成了某種帶有風險、非正規、甚至帶有「叛逆」色彩的旁門左道。
但是，事實真的如此嗎？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;安裝就是安裝，沒有正偏之分： 在個人電腦（PC）上，我們下載 &lt;code&gt;.exe&lt;/code&gt; 或 &lt;code&gt;.dmg&lt;/code&gt; 檔案並安裝，這叫「安裝軟體」；在 Linux 上我們編譯原始碼，這叫「部署」。為什麼到了手機上，同樣的動作就變成了貶義的「側載」？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;預設「惡意」的假定： 當廠商使用「側載」這個詞時，他們在潛意識裡已經將使用者標籤化為「不懂保護自己的弱者」或是「潛在的破壞者」。他們試圖讓妳相信，如果妳不透過他們的審核機制，妳就是在冒險，妳就是行為不檢。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;消解所有權的本質： 這種語言羞辱的最終目的，是為了讓使用者忘記一個基本事實——&lt;strong&gt;作業系統是為使用者服務的工具，而不是廠商圈養用戶的圍欄&lt;/strong&gt;。 他們試圖透過改變稱呼，讓原本理所當然的「權利」，在公眾認知中退化成一種需要被嚴格管控的「例外」。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我們必須拒絕使用「側載」這個帶有偏見的詞彙。這不是側載，這是 &lt;strong&gt;「自主安裝」&lt;/strong&gt;，是任何一個嵌入式系統或者通用計算裝置（General-purpose computer）最基本、最核心的功能。&lt;/p&gt;
&lt;p&gt;如果我們接受了他們的語言邏輯，我們就已經在心理上交出了手機的主控權。我們必須大聲地告訴這些科技巨頭：我安裝我自己擁有的軟體，這叫行使權利，不叫「側載」。大型科技公司仍然可以在未來的某個時刻奪走我們自由安裝軟體甚至是使用裝置的能力，因此不能專注於某幾家公司提供的服務和生態，必須「去中心化」，必要的服務可以考慮自建。&lt;/p&gt;
</content:encoded></item><item><title>開源數位相機，似乎只有 Android + Opencamera 才是最佳選擇</title><link>https://blog.cloudflare88.eu.org/posts/current-android-device-and-opencamera-is-the-best-way-to-build-your-foss-phone-camera/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/current-android-device-and-opencamera-is-the-best-way-to-build-your-foss-phone-camera/</guid><description>看來，現在最務實的「開源攝影」方式，還是買一臺硬體素質足夠強的 Android 手機，可以刷 crDroid 或者 LineageOS，然後安裝 OpenCamera 或者 FreeDCam 這些自由軟體相機 APP。</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;想過一個問題，是否可以僅利用自由軟體，組裝屬於自己的開源數位相機呢？&amp;lt;/br&amp;gt;
一直好奇那些市面上常見的網路攝影機都是怎樣工作的，我也曾考慮過是否要在自己家安裝網路攝影機。但是現在妳能買到的網路攝影機基本上都是跑專有軟體的「監視器」，妳的隱私可能隨時都會被公司或政府所監控着。這樣的硬體真的讓我難以下手。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
不過至少，這個問題從技術方面來講，應該是可行的。可以使用 Arm 或者 RISC-V 指令集的單晶片，以及主線 Linux 核心支援的硬體和鏡頭就可以制作一個屬於自己的網路攝影機了。比較經典的例子有 &lt;a href=&quot;https://pine64.org/documentation/PineCube/&quot;&gt;PINE64 生產的 Pinecube&lt;/a&gt;，採用 Allwinner S3 晶片的網路攝影機。所有硬體被主線核心支援。目前被 Armbian, NixOS 和 Buildroot 等 Linux 發行版所支援，還支援 Power over Ethernet 功能和 IR 呢。有關 Pinecube 的進階玩法也非常豐富。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/PineCube.png&quot; alt=&quot;Pinecube FOSS IP camera&quot; /&gt;
開源的影像處理流程也存在：處理影像的軟體有 GIMP，Krita，digiKam 之類，對於SVG圖更是有 Inkscape 之類軟體支援。如果想要剪影片，Kdenlive 軟體就非常不錯。 &amp;lt;/br&amp;gt;
但是 Pinecube 採用的 &lt;code&gt;ov5640&lt;/code&gt; 攝像模組最多只能拍攝5百萬畫素，1080P解析度的影片。在這個 4K，8K 影片隨處可見的時代，Pinecube 的規格顯得略有點過時。雖然可以自己更換支援4K錄影的攝像模組，但依舊要考慮驅動程式的問題。不過就像網站講的那樣，對於夜班保全這種工作確實比較適合。畢竟不需要考慮伺服器公司是否會偷偷檢視妳的影片，也可以自己架設影片串流伺服器。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
那些光圈比手機大許多的單眼相機和攝影機，如 Canon 或者 Sony 出的，上面跑的軟體大多都是專有軟體。雖然 Sony 也有內建 Android 的相機（Android 系統終於放在了應該在的裝置上），但是都塞了 Sony 自家的軟體進去。&amp;lt;/br&amp;gt;
會不會有一臺從韌體到軟體都採用自由軟體的數位相機呢？我想要的是真正可以用來日常使用的相機，不是像 MTP8750 那樣的原型機，更不是單板電腦外掛攝像模組的玩具。缺乏自由軟體的裝置真的讓我難以下手（雖然有些裝置也買不起就是了，比如 SC8380XP 的 CRD原型機 &lt;code&gt;:P&lt;/code&gt;）。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There should be a photo showing Qualcomm&apos;s SC8380XP CRD prototype machine, but I had to remove it due to copyright issues. Screw you, Qualcomm!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因爲我拒絕使用任何專有軟體而不購買中國產 Android 手機，不購買 PS4，Switch 這類家機一樣，因爲這些企業奪走了許多優秀開源專案的成果。Linux 上的 Steam 我起初還可以勉強接受，但是用 Steam 我內心已經非常煎熬了。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
所以，我還是希望有一款真正自由的開源數位相機，可以像 Pinecube 那樣，採用主線 Linux 核心支援的硬體和軟體，並且可以自由選擇自己喜歡的圖像處理軟體。這樣的相機可以像 Pinecube 那樣，可以用做日常保全，也可以用來拍攝一些私密照片(比如妳邊看「小黃書」邊用桌子愛愛的照片)。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
即使是「開放」的 Android 裝置的拍照技術，也很大程度上被封閉原始碼的 APP 控制着呢...每家手機廠商都會編寫針對自家手機的相機 APP，並且強迫我們使用這些 APP。縱然我們有 &lt;a href=&quot;https://sourceforge.net/p/opencamera/code/ci/master/tree/&quot;&gt;OpenCamera&lt;/a&gt; 和 &lt;a href=&quot;https://github.com/KillerInk/FreeDcam&quot;&gt;FreeDCam&lt;/a&gt;這些開放原始碼的相機 APP，他們也不能完全利用每臺手機的鏡頭硬體功能，例如30倍 AI 放大，以及美化相片的演算法。&amp;lt;/br&amp;gt;
拍照之後的演算法更是各大廠家的機密。Sony，小米，Google，Samsung 都有自家的韻味，即使妳有辦法移植 Google camera 到其他裝置，也無法弄清背後的機理。因此，Opencamera 所拍的相片品質就會與原廠相機 APP 所拍的相片品質有所落差，往往需要使用 digiKam 修圖。成爲單純看感光元件效能的軟體，不過這樣也可以看出廠商在背後做的手腳。&amp;lt;/br&amp;gt;
因爲 Android 最初是作爲數位相機所開發的作業系統，因此在存取相機硬體方面的效果遠遠要比 GNU/Linux 成熟。例如 AOSP 所支援的 &lt;code&gt;Camera2API&lt;/code&gt; 可以讓妳&lt;a href=&quot;https://developer.android.com/media/camera/camerax&quot;&gt;調整 ISO&lt;/a&gt;。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
至於像 Arch Linux，PostmarketOS 那樣的上游 Linux 發行版，想要驅動相機硬體會更困難。光是跑通相機硬體就謝天謝地了。看看&lt;a href=&quot;https://wiki.postmarketos.org/wiki/Nothing_Phone_1_(nothing-spacewar)&quot;&gt;主線核心對於 Nothing Phone 1 的相機支援程度&lt;/a&gt;就知道大概，只有長焦鏡頭和前置鏡頭才被支援，對於 Oneplus 6T 而言卻要好一些。不過高通平臺相機在主線核心中的顏色總是怪怪的，遠不如 Android 下面表現的鮮豔。對於 GNU/Linux 下面拍照的學問，目前鮮有人研究(似乎不知不覺又發現了研究方向呢...?)。&amp;lt;/br&amp;gt;
目前我在非 Android 系統上能夠做到影片畫質和在 Android 下表現相當的裝置，是很久以前在高通 SDM845 MTP 原型機上改裝 Windows 11 Arm 系統，安裝高通爲 MTP 原型機開發的驅動程式在 Windows 自帶的相機 APP 上拍攝的。但畢竟是原型機，沒有普遍參考意義。
&amp;lt;/br&amp;gt;
爲 PinePhone 開發Megapixel 相機 App 的開發者也只是寫了一個 pipeline 出來。雖然也有 Oneplus 6T 的支援，但是並不能用。&amp;lt;/br&amp;gt;
看來，現在最務實的「開源攝影」方式，還是買一臺硬體素質足夠強的 Android 手機，可以刷 crDroid 或者 LineageOS，然後安裝 OpenCamera 或者 FreeDCam 這些自由軟體相機 APP。就像我對自己的 Pixel 7 Pro 和 SM8750 QRD 原型機那樣做的那樣(MTP 原型機這樣的「磚頭」還是太不方便了些)，是比較不錯的選擇。至於驅動程式和韌體，要閉源就閉源吧，唉... :(&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Apple 風格「Secure Launch」-- XNU Shim，社群給 A18 Pro 晶片 MacBook Neo 移植主線 Linux 核心的艱難路</title><link>https://blog.cloudflare88.eu.org/posts/its-qcom-secure-launch-rewritten-in-apple-style/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/its-qcom-secure-launch-rewritten-in-apple-style/</guid><description>It&apos;s Qualcomm&apos;s &quot;Secure Launch&quot;, but re-written in Apple&apos;s language and its the most complex security system in ARM world.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;這篇部落格是我在爬取大量資料後，藉助 ChatGPT 和 Claude，以及自己一點淺薄的理解寫出的，連我自己都不知道我在講三小。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;:::note
本文根據 &lt;a href=&quot;https://github.com/rusch95/asahi_neo&quot;&gt;GitHub 「Asahi Neo」專案&lt;/a&gt;文檔改寫，由於我沒有 MacBook Neo 筆電，因此無法對裝置的具體效能，硬體情況發表評價。關於韌體實作的描述會盡力保証最新。&amp;lt;/br&amp;gt;
另外，關於「PPL」「SPTM」「GXF 側迴區等級」之類術語的中文寫法爲非官方翻譯，請不要用於論文，學術研究等正式需求。
:::&lt;/p&gt;
&lt;p&gt;Apple 爲了力推自家的 MacBook 市場，真的是蠻拼的。直接使用 iPhone 上的 A18 Pro 晶片，配合傳統 MacBook 的主機殼，發佈了「MacBook Neo」針對入門低階市場的筆電。只需要二萬臺幣就可以到手，不知道那些喜歡監獄的「Apple fans」會不會再次應援呢？&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
就像 Apple 採用 M 系列晶片的 Mac 一樣，今年3月份發佈的 MacBook Neo 也很快有「Linux on Everything」的愛好者開始研究如何在基於手機平臺 A18 Pro 晶片的裝置上跑 Linux 核心。話說近年來圍繞 Apple Silicon 平臺的專案真的很多呀，從最早的 Asahi Linux 爲 M1，M2，M3 晶片移植主線 Linux 核心，甚至驚動 Linus 本人也購買 MacBook Air 進行核心開發；到致力於在 Apple Silicon 平臺上跑起 Windows on Arm 或者 OpenBSD 的 NT for Apple Silicon (NTASP，舊稱 AppleWoA)專案（使用 &lt;code&gt;m1n1&lt;/code&gt; fork 和 Microsoft Project MU UEFI 韌體）；再就是現在的「Asahi Neo」專案，這才是我所希望看到的80年代的駭客精神，也正像我講的「黑蘋果社區中貢獻良多的開發者們」那樣，爲解放本就屬於我們的裝置所努力。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;MacBook Neo 外觀紹介&lt;/h1&gt;
&lt;p&gt;從目前網路上的報道來看，MacBook Neo 似乎有點 2000年代 PowerBook 和 iBook 的設計美學。熒幕傳統的外觀，大圓角總會令人不禁想起 2000 年 Apple PowerBook G4 的熒幕設計，也是 LCD 熒幕，只是圓角小了些，並不引人注目。至於鍵盤部分倒是有點像 iBook G3 Snow，如果妳買了銀色機殼的筆電，再把系統桌布換成 Mac OS X 10.1 的桌布，從遠處看和 iBook G3 Snow 真的沒差。&lt;/p&gt;
&lt;h1&gt;移植 Linux 的艱難路&lt;/h1&gt;
&lt;p&gt;因爲 A18 Pro 晶片的特殊性，目前還停留在逆向階段，主要針對硬體和開機流程進行分析，尚未形成穩定可用的移植方案，但已存在可行的啟動路徑驗證（boot feasibility）。&lt;/p&gt;
&lt;h2&gt;開機流程的變化：SPTM 的加入&lt;/h2&gt;
&lt;p&gt;Apple 晶片的開機流程與任何常見的 Arm 晶片都不同，採用自家封閉原始碼的 iBoot 韌體，而不是常見的 U-Boot 或者 UEFI。這也使得讓 Linux 核心開機也變得困難，因爲 iBoot 從實作上就被設定爲僅能載入符合 Apple 規範格式與簽章的 kernelcache（Mach-O 格式）。雖然 macOS 也使用設備樹來描述硬體，但 macOS 採用 Apple 自家的「客製化」設備樹 ADT (Apple Device Tree)，與 Linux 的 DTB 不相容. 不過 Asahi Linux 社群爲了解決這一個難題而開發了 &lt;code&gt;m1n1&lt;/code&gt; 開機載入器，能夠在開機時自動存取 ADT 設備樹，並轉製成被 Linux 支援的 DTB，這樣就可以啓動 Linux 核心。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
隨着 M4 晶片的發佈（還有 A18 Pro 晶片），一種叫 「SPTM (Secure page table monitor，安全頁表監視)」的機制被引入。SPTM 執行在較高的硬體等級（Apple 自定義的 GL2，類似 Arm 的 EL2 等級），必須要經由 iBoot 開機載入後才可以執行其他作業系統，目前沒有辦法 bypass 掉。而之前的 M1, M2, M3 晶片則採用內建於 XNU 核心快取的「PPL（Page Protection Layer，頁表保護）」同樣執行在 GL2 等級，但是 PPL 沒有專門的韌體。SPTM 在 iBoot 啟動流程中被初始化，並作為系統安全執行環境的一部分存在，位於專門的安全空間，受到 SPRR 保護。在這種環境下，SPTM 中的程式碼只能在 GL2 執行，因此任何存在於 EL1 的漏洞不會影響頁表。&amp;lt;/br&amp;gt;
不過，macOS 在 A18 Pro 晶片上的開機流程和M系列晶片平臺大致相同，加載 PPL&lt;a href=&quot;%E7%9B%AE%E5%89%8D%E7%88%B2%E7%8C%9C%E6%B8%AC%EF%BC%8C%E5%85%B7%E9%AB%94%E5%AF%A6%E4%BD%9C%E4%BB%8D%E5%9C%A8%E9%80%86%E5%90%91%E5%88%86%E6%9E%90%E3%80%82&quot;&gt;^1&lt;/a&gt;，SPTM 只會被 iOS 核心加載。據此就會有兩種開機方案：要嘛加載一個自訂的 macOS 核心快取，這樣 iBoot 大概不會載入 SPTM。因爲 Asahi Linux 專案早就逆向了 PPL 的組建，所以比較容易開機，變磚風險也相對低；要嘛加載自訂 iOS 核心快取打開 SPTM，移植難度大，但是可以爲後期改善A18 Pro 晶片 Linux 支援做準備。 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Apple 風格的「Secure Launch」：XNU Shim&lt;/h2&gt;
&lt;p&gt;既然 SPTM 的啟用與否取決於所載入的核心快取類型（如 iOS kernelcache），那就可以開發一種開機載入器，把載入器和 XNU 核心快取縫在一起，開機後 iBoot 讀取自訂的核心快取完成打開 SPTM，之後載入 Linux loader 就可以啓動 Linux 核心了。&amp;lt;/br&amp;gt;
這也就是 XNU Shim 要實現的，藉由 &lt;a href=&quot;https://asahilinux.org/docs/fw/macho-boot-protocol/&quot;&gt;Mach-O 啓動協定&lt;/a&gt;，其核心思路並不是取代 boot chain，而是「嵌入」到 XNU 的啟動流程中。在 iBoot 載入自訂 kernelcache 後，系統會正常初始化 XNU，包括 MMU、CPU 狀態以及 PPL（或 SPTM）等安全機制。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SecureROM
  └─► iBoot stage 1 (位於 Nor Flash 快閃記憶體)
        └─► iBoot stage 2 (位於固態硬碟, APFS Preboot)
              └─► kernelcache (非 Apple 的「低安全性」簽章，簡化的自訂 XNU 核心和快取)
                    ├─► [XNU startup] cpu_machine_init → SPTM init calls
                    ├─► [XNU startup] arm_init → 負責 MMU 初始化，而 SPTM 僅對頁表操作進行約束與監控
                    └─► [SHIM INTERCEPT] → Linux loader → Linux 核心啓動
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這種特製的 shim 會讓 iBoot 認爲自己正在載入合規的 macOS 核心。在 XNU 核心初始化流程中 hook「IOPE（&lt;code&gt;IOPlatformExpert::start()&lt;/code&gt;）階段」（或者是其他合適的階段），此時 SPTM 和其他底層機制已經初始化。並使用 SPTM API 建立 Linux 核心啓動必須的記憶體空間，準備 &lt;code&gt;initramfs&lt;/code&gt;，DTB 之類，關閉 SPTM Watchdog，完成跳轉 Linux 核心。概念上類似於高通 「Secure Launch」 在受控環境中啟動 OS，但 Apple 並未提供正式的3方「secure launch」 機制，XNU shim 本質上屬於啟動後接管（post-boot hijack），而非受支援的安全啟動模式。&lt;/p&gt;
&lt;h2&gt;A18/M4 晶片上自訂的 GXF 側域模型（GXF lateral domain,GLs）：抽象層級而非 ARM EL 映射&lt;/h2&gt;
&lt;p&gt;Apple 在 A18/M4 晶片上建立了一套與 ARM EL 模型概念上相似，但並不完全對應的執行域 (execution domain) 架構。這些 GXF（GL0–GL2）層級主要透過 SPRR 機制強制執行記憶體存取權限，而非直接對應 ARM 異常層級。SPRR 是用於強制執行記憶體存取屬性的硬體機制，負責限制不同執行域對 page table 權限的修改能力。&amp;lt;/br&amp;gt;
吶，下面的表格就可以清楚地展示 GXF Level 和 ARM ELs 層級之間的關係[^3]:&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GXF 側迴區等級(SPRR 強制)&lt;/th&gt;
&lt;th&gt;與 Arm ELs 異常層級抽象對應&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;不適用&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;EL3: Secure monitor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GL2 SPTM (負責頁表操作的驗證與約束，可透過&lt;code&gt;genter&lt;/code&gt; 從 EL1/EL2 呼叫)&lt;/td&gt;
&lt;td&gt;EL2: Hypervisior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GL1 TXM (程式碼簽章，權限管理)&lt;/td&gt;
&lt;td&gt;EL1: OS Kernel（作業系統核心）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;GL0&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;EL0: Userspace (使用者)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;註&lt;/strong&gt;：&lt;em&gt;斜體字&lt;/em&gt; 表示沒有與 ELs 異常層級抽象對應的 GXF 側迴區等級，或者這一等級目前在公開研究中較少觀察到（甚至沒有）實際使用。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;:::note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GL2（SPTM 所在的安全監控層）在功能上類似於高權限控制平面，但並不等同於 EL2 hypervisor，而是 Apple 自定義的記憶體安全執行層。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;genter&lt;/code&gt;/ &lt;code&gt;gexit&lt;/code&gt; 匯編函式是進入與退出 SPTM 管理上下文的介面，而非 ARM EL 層級之間的直接轉換機制。&lt;/li&gt;
&lt;li&gt;SPRR 則負責在硬體層級強制執行 page table 存取屬性，限制不同執行域對記憶體的讀寫與執行權限。&lt;/li&gt;
&lt;li&gt;針對每次頁表變更，作業系統核心會透過 &lt;code&gt;genter → GL2 → gexit&lt;/code&gt;的流程呼叫 SPTM 完成頁表變更。&lt;/li&gt;
&lt;li&gt;顯而易見，Apple 晶片採用 GXF 和常見的 EL 模型，用於保証記憶體安全，讓每個環節的程式執行儘量減少被攻擊可能。
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這是根據表格繪製的對比圖，便於大家理解：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/el-vs-gxf-compare.png&quot; alt=&quot;A comparation image showing difference between GXF lateral domain and ARM exception levels&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;關鍵寄存器：GXF / SPRR 控制面的實際語義&lt;/h2&gt;
&lt;p&gt;在經過粗略檢視 &lt;a href=&quot;https://github.com/AsahiLinux/m1n1&quot;&gt;m1n1 原始碼&lt;/a&gt;之後，找到了有關 GXF 的「關鍵 CPU 寄存器」，[^2]這些寄存器位於 EL1 可訪問空間，但實際影響 GL2 行為，本質上是一種「受控升權接口（controlled privilege escalation interface）」:&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/m1n1-gxf-el-define.png&quot; alt=&quot;Key registers showing in cpu_reg header source in m1n1 code&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;寄存器變數&lt;/th&gt;
&lt;th&gt;對應系統晶片寄存器(?)&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;類型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SYS_IMP_APL_SPRR_CONFIG_EL1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S3_6_C15_C1_0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打開並配置 SPRR 權限模型&lt;/td&gt;
&lt;td&gt;控制寄存器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SYS_IMP_APL_GXF_CONFIG_EL1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S3_6_C15_C1_2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打開 GXF 執行域機制&lt;/td&gt;
&lt;td&gt;控制寄存器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SYS_IMP_APL_GXF_ENTER_EL1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S3_6_C15_C8_1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GL2 呼叫閘道（&lt;code&gt;genter&lt;/code&gt; 觸發寄存器），觸發 &lt;code&gt;genter&lt;/code&gt;，進入 GL2（SPTM）&lt;/td&gt;
&lt;td&gt;呼叫閘道&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SYS_IMP_APL_GXF_STATUS_EL1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;不適用&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;檢視 GXF 等級狀態，回報目前 GL level / context&lt;/td&gt;
&lt;td&gt;狀態寄存器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::warning
下面講述的寄存器變數與實作基於硬體逆向探索得到，可能存在錯誤。在社群文檔更新之前，本段僅提供參考。
:::&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;SYS_IMP_APL_SPRR_CONFIG_EL1&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;這個寄存器是 SPRR（Secure Page Table Restrictions）啟動的核心開關，但實際上牠不只是 enable bit，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;控制 permission class mapping;&lt;/li&gt;
&lt;li&gt;決定 EL1 是否允許直接修改 page table;&lt;/li&gt;
&lt;li&gt;強制 W^X（Write XOR Execute）策略
寄存器被設定後，EL1（或者作業系統核心）不能產生和建立 RWX mapping。一些 PTE Pattern 會被硬體拒絕，類似「寫入攔截機制」。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;SYS_IMP_APL_GXF_CONFIG_EL1&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;負責啟用 GXF execution domain model，其效果包含：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;啟用 GL0 / GL1 / GL2 的 runtime 區分;&lt;/li&gt;
&lt;li&gt;啟用與 SPRR 聯動的 access control;&lt;/li&gt;
&lt;li&gt;允許 genter/gexit 指令生效&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果寄存器沒有啓用，&lt;code&gt;genter()&lt;/code&gt; 或許會無效，系統變成傳統的 EL 異常等級模型。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;SYS_IMP_APL_GXF_ENTER_EL1&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;這是一個 XNU shim 跳轉 GL2 的「跳板」，寫入寄存器就會完成一次從 EL1 到 GL2 的「跳轉」，完成需要 SPTM 相關的工作。&amp;lt;/br&amp;gt;
寫入寄存器的方法有點類似下面的 C 程式碼：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;write_sysreg(SYS_IMP_APL_GXF_ENTER_EL1, arg_struct);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CPU 保存當前 EL1 context，然後切換到 GL2，SPTM handler 根據傳入的引數進行頁表驗証(Page table validation)，和權限相關的工作。完成後再次返回 EL1. &amp;lt;/br&amp;gt;
在 Arm 匯編語言中，不難發現 &lt;code&gt;m1n1&lt;/code&gt; 對 EL1 至 GL2 的實作[^4]：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 首先執行 gxf_init 進行 GXF 環境準備（此函式省略），SPRR 會早於 GXF 被開啓。

gxf_enter: 
    genter
    ret

_gxf_setup:           // GL2 初始化
    mov sp, x5
    ldr x1, =_gxf_vectors
    ldr x2, =_gxf_exc_sync
    ldr x3, =_gxf_entry
    msr SYS_IMP_APL_VBAR_GL1, x1    // 設定 GL1 exception vector
    msr SYS_IMP_APL_GXF_ABORT_EL1, x2   // GXF 錯誤處理
    msr SYS_IMP_APL_GXF_ENTER_EL1, x3     // 下一次 genter() 的入口

    mrs x4, CurrentEL
    cmp x4, #8
    bne 1f

    msr SYS_IMP_APL_SP_GL12, x6
    msr SYS_IMP_APL_VBAR_GL12, x1
    msr SYS_IMP_APL_GXF_ABORT_EL12, x2
    msr SYS_IMP_APL_GXF_ENTER_EL12, x3

1:
    isb
    gexit

_gxf_entry:
    stp x29, x30, [sp, #-16]!
    stp x23, x24, [sp, #-16]!
    stp x21, x22, [sp, #-16]!
    stp x19, x20, [sp, #-16]!

    // these registers would be overwritten by each exception happening in GL1/2
    // but we need them to gexit correctly again
    mrs x20, SYS_IMP_APL_SPSR_GL1
    mrs x21, SYS_IMP_APL_ASPSR_GL1
    mrs x22, SYS_IMP_APL_ESR_GL1    // 保存 GL1 狀態
    mrs x23, SYS_IMP_APL_ELR_GL1
    mrs x24, SYS_IMP_APL_FAR_GL1

    mov x5, x0
    mov x0, x1
    mov x1, x2
    mov x2, x3
    mov x3, x4

...
// 回復 GL1，使用 gexit 保証沒有洩露
    msr SYS_IMP_APL_SPSR_GL1, x20
    msr SYS_IMP_APL_ASPSR_GL1, x21
    msr SYS_IMP_APL_ESR_GL1, x22
    msr SYS_IMP_APL_ELR_GL1, x23
    msr SYS_IMP_APL_FAR_GL1, x24
...
    isb
    gexit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;從 &lt;code&gt;m1n1&lt;/code&gt; 的 &lt;code&gt;gxf_asm.S&lt;/code&gt; 可以看出，GXF 並不是單純的 privilege level 切換機制，而是一個可編程的 call-gate runtime。EL1 透過設定 &lt;code&gt;SYS_IMP_APL_GXF_ENTER_EL1&lt;/code&gt; 指向自訂 handler，在首次 genter 時建立 GL2 執行環境（包含 exception vector 與 abort handler）。此後每次 &lt;code&gt;genter&lt;/code&gt; 都會進入該 handler（如 &lt;code&gt;_gxf_entry&lt;/code&gt;），由 GL2 保存 GL1 上下文、執行傳入的 callback，並在 &lt;code&gt;gexit&lt;/code&gt; 後返回。&amp;lt;/br&amp;gt;
這種設計使得頁表操作與安全策略不再是單純的核心內部行為，而是轉化為經由 GL2 控制的受監管呼叫，與 SPTM 的設計理念高度一致。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;SYS_IMP_APL_GXF_STATUS_EL1&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;寄存器應該會提供一些指示碼，用於展示當前 GL 等級，有關 SPTM 的錯誤碼一類。&amp;lt;/br&amp;gt;
這些寄存器構成了一條由 EL1 通往 GL2（SPTM）的受控呼叫路徑，使得頁表管理從「核心內部操作」轉變為「經由硬體強制驗證的安全服務」，這也是 Apple 在 A18/M4 上強化記憶體安全模型的核心設計。&lt;/p&gt;
&lt;h2&gt;SPRR 權限表&lt;/h2&gt;
&lt;p&gt;即使完成了相關寄存器設定，要讓 Linux 在 MacBook Neo 上穩定運行，XNU shim 仍需處理 SPRR（System Page Protection Register）所定義的記憶體權限約束，並在適當時機透過 SPTM 介面進行頁表操作。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;asahi_neo&lt;/code&gt; 專案的逆向分析中，SPRR 權限表被觀察為一個 64-bit 寄存器，其內部由多個位元欄位組成，用於描述不同 page table permission class 對應的存取限制。這些欄位會被 SPTM 設定，用於限制較低權限 execution domain（如 EL1）建立不符合策略的記憶體映射。&amp;lt;/br&amp;gt;
&lt;code&gt;asahi-neo&lt;/code&gt; 專案在探索 MacBook Neo 硬體的過程中得出了關於權限表的發現：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;64-bit register encoding 16 4-bit nibbles, each mapping one page table permission class to separate EL/GL access rights. SPTM sets this table to prevent EL1 from creating writable+executable mappings in its own domain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;從行為上來看，SPRR 並不是單純的權限映射表，而是一種硬體層級的約束機制（constraint system），其作用是在記憶體存取與權限檢查過程中強制執行頁面屬性限制，確保核心無法繞過既定的安全策略（例如建立同時具備 writable 與 executable 權限的頁面）。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;因此，在啟用 SPTM 的系統中，作業系統核心無法直接修改最終的頁表狀態，而必須透過受控的介面（如 &lt;code&gt;genter&lt;/code&gt; 進入 SPTM 執行上下文）來完成相關操作。XNU shim 在此扮演的角色，是在 Linux 啟動前建立一組符合 SPRR 約束的記憶體佈局，並確保後續頁表操作能夠透過 SPTM 正確執行。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;需要注意的是，SPRR 權限表的具體編碼與語義目前仍屬於逆向推測範疇，其行為主要來自觀察與實驗結果，而非官方文件定義。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;開機之後的黑夜：長路漫漫，仍有萬里之遙&lt;/h1&gt;
&lt;p&gt;XNU shim 完成了載入 Linux 核心的工作，真正重要的工作才剛剛開始。開機之後，除了 CPU，UART 工作以外，整臺筆電98％的硬體都不工作。因爲 Apple 晶片相對封閉，像是晶片 PCIe 匯流排和 USB 這些對日常使用影響比較大的功能還要逆向韌體才能寫對應的核心驅動程式。還需要解決繪圖卡的硬體加速，雖然 A18 Pro 晶片的效能即使跑採用 &lt;code&gt;llvmpipe&lt;/code&gt; 的軟體渲染去執行 GUI 程式也不會像放投影片一樣，但是碰到某些對繪圖有要求的程式（GIMP，Kdenlive 之類），有內建繪圖卡硬體加速會比較好，畢竟 Apple 晶片的繪圖卡效能一直都不賴。&amp;lt;/br&amp;gt;
但是 Apple 總是想着「特立獨行」，從韌體到軟體從來不會按照 Arm 標準實作。在 Apple 平臺 bring up Linux 要比一般的 Arm 晶片 bring up 困難。&amp;lt;/br&amp;gt;
與一般認知不同，Linux 並不是一個「只要 CPU 能執行就可以啟動」的作業系統，牠也不可以在烤麪包機上執行。對於 Arm AArch64 架構，Linux kernel 在進入點（entry point）時，對系統狀態有一組明確的前提條件：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;...Linux 也有「系統要求」，只是這些要求多體現在硬體的底層，大多數人不會留意到而已。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;核心必須在 EL1（Non-secure）執行（在某些情況下（例如需要設定或管理裝置上的 Hypervisior），Linux 可以在 EL2（例如透過 VHE 模式）執行）；&lt;/li&gt;
&lt;li&gt;MMU 必須已經啟用，且至少具備基本的記憶體映射；&lt;/li&gt;
&lt;li&gt;必須提供有效的 Device Tree（DTB），描述硬體配置；&lt;/li&gt;
&lt;li&gt;Kernel image 必須位於可存取的記憶體區域；&lt;/li&gt;
&lt;li&gt;中斷控制器(Arm GIC)與系統計時器需處於可用狀態；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然而，在 A18 Pro / M4 晶片上，這些「標準 ARM 假設」不再完全成立。最顯而易見的就是 Apple 晶片不採用標準的 Arm GIC，改用自家的 AIC 作爲中斷控制器硬體實作。因此在很長一段時間裏，Apple 的筆電即使有了 U-Boot 支援，除了 Linux，OpenBSD 之外，很少有其他系統可用。也是 Apple 筆電難以支援 Windows on Arm 的其中一個原因。由於 SPTM（GL2）與 SPRR 的存在：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有 page table 修改必須透過 &lt;code&gt;genter&lt;/code&gt; → GL2 → &lt;code&gt;gexit&lt;/code&gt; 進行;&lt;/li&gt;
&lt;li&gt;作業系統核心（EL1 / GL1）無法直接建立任意記憶體映射;&lt;/li&gt;
&lt;li&gt;SPRR 會強制執行 W^X（Write XOR Execute）等安全策略;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這使得 Linux kernel 在設計上「假設自己擁有完整記憶體控制權」的前提被打破。XNU shim 的角色因此不僅是啟動載入器，更需要作為一個頁表操作代理層（page table mediation layer），在 Linux 與 SPTM 之間轉譯記憶體管理操作。更具體地說，Linux 在啟動早期會自行建立新的 page tables，並切換 &lt;a href=&quot;https://arm-software.github.io/CMSIS_5/Core_A/html/group__CMSIS__TTBR.html&quot;&gt;TTBR寄存器&lt;/a&gt;來建立 kernel 的虛擬位址空間[^5]。然而，在 SPTM 的約束下，這類操作無法直接完成。換句話說，Linux 並不是單純「不能做這些操作」，而是牠原本假設這些操作是本地且立即生效的（local and authoritative），這些操作幾乎適用於大多數 Arm 晶片 (例如 Snapdragon, Rockchip, Amlogic)。 但在 Apple 平臺上，這些操作變成了需要經過外部驗證的請求（validated operations）。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接寫入 TTBR 或修改 PTE 可能被硬體拒絕；&lt;/li&gt;
&lt;li&gt;建立暫時性的 RWX mapping（常見於 early boot）會違反 SPRR 策略；&lt;/li&gt;
&lt;li&gt;未經驗證的記憶體屬性變更可能導致 synchronous exception。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不難看到，想要在 Apple silicon 晶片上跑起主線 Linux 核心，開發者們需要付出的努力與面對的問題，遠遠超出一般 Arm 平臺上的 Linux bring-up。這不只是驅動程式的補齊，更是對整個系統抽象的重新建構：在一個原本假設「作業系統擁有最終控制權」的世界裡，引入一層由硬體強制執行的安全邊界，並設法在不破壞 Linux 設計哲學的前提下，利用這種專有機制，重新在其之上構建一個「自由」的系統世界。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;今天我們能夠在 Apple Silicon 的 Mac 上使用 Linux 發行版，運行各種自由軟體，甚至在某些場景下獲得優於原生系統的效能，並不是理所當然的結果。這背後，是開發者長時間對封閉硬體與韌體的逆向分析，是一次次在黑箱中摸索邊界的嘗試，也是將「不可行」轉化為「可行」的工程實踐。&amp;lt;/br&amp;gt;
他們在這條路上「曝霜露，斬荊棘」，並不是為了證明某個平台能否運行某個系統，而是為了讓使用者重新擁有選擇的權利。當越來越多的元件被理解、被實作、被上游接受，這條原本曲折狹窄的小路，也終將逐漸拓寬。Apple Silicon 平臺，這個曾經被 Linus Torvalds 認為「幾乎不可能」支援 Linux 的環境，也在無數開發者的努力下，一步步被改寫。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Oh, I’ve seen the trouble more than anyone can bear,&amp;lt;/br&amp;gt;
But I still have joy more than failure I’ve met &amp;lt;/br&amp;gt;
Still not done, I’m only halfway there &amp;lt;/br&amp;gt;
I’m a million miles ahead of where I from, but I still have another million miles to go... &amp;lt;/br&amp;gt;
-------- Adapted from &lt;em&gt;&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/mtp-trouble/&quot;&gt;MTP Trouble -- A FOSS parody of Trouble by Avicii&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;或許對多數人而言，這只是多了一個可以在 Mac 上使用 Linux 的選項，並沒有什麼可以使用的「商業價值」；但在更深的層面上，這意味著：即使在最封閉的系統之中，仍然存在著被理解、被重建，乃至被重新定義的可能。&amp;lt;/br&amp;gt;
現在，「Asahi Neo」專案已經走出了千里之遙。但這條路仍然漫長，而牠也已經被證明是可以走通的。&lt;/p&gt;
&lt;p&gt;[^2]: &lt;a href=&quot;https://github.com/AsahiLinux/m1n1/blob/main/src/cpu_regs.h&quot;&gt;cpu_regs.h -- m1n1 by Asahi Linux at GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^3]: &lt;a href=&quot;https://github.com/rusch95/asahi_neo/blob/main/ARCHITECTURE.md&quot;&gt;Privilege Levels on A18 Pro / M4 -- asahi_neo by rusch95 at GitHub&lt;/a&gt;
[^4]: &lt;a href=&quot;https://github.com/AsahiLinux/m1n1/blob/main/src/gxf_asm.S&quot;&gt;gxf_asm.S -- m1n1 by Asahi Linux at GitHub&lt;/a&gt;
[^5]: &lt;a href=&quot;https://stackoverflow.com/questions/14460752/linux-kernel-arm-translation-table-base-ttb0-and-ttb1&quot;&gt;ARM Linux kernel translation base -- Stack Overflow&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Renegade -- An Aloha Parody of Renegade (Orginal song is made by Axwell Λ Ingrosso and Sebastian Ingrosso)</title><link>https://blog.cloudflare88.eu.org/posts/renegade-an-aloha-parody-of-renegade/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/renegade-an-aloha-parody-of-renegade/</guid><description>妳們是否發現了我的大頭貼離遠點看很像 Renegade 專案的 UEFI 韌體 Logo 呢？不管妳有沒有發現都無所謂...</description><pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1289771014&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/10kfollowing10kposts-ii&quot; title=&quot;10kfollowing10kposts II&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;10kfollowing10kposts II&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/10kfollowing10kposts-ii/axwell-l-ingrosso-renegade&quot; title=&quot;Axwell Λ Ingrosso - Renegade (slowed &amp;amp; reverb)&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Axwell Λ Ingrosso - Renegade (slowed &amp;amp; reverb)&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Renegade%20--%20An%20Aloha%20Parody%20of%20Renegade.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio tag.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;(寫於2025年6月11日）&lt;/p&gt;
&lt;p&gt;(Baby, I&apos;m a developer... Baby you are a firehose...)&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Baby, I&apos;m a developer &amp;lt;/br&amp;gt;
Baby, you&apos;re a firehose &amp;lt;/br&amp;gt;
Move your source code close to mine &amp;lt;/br&amp;gt;
We can compile &apos;em until the dawn &amp;lt;/br&amp;gt;
I can see we&apos;re getting late &amp;lt;/br&amp;gt;
That window, that window, that window flashed tonight &amp;lt;/br&amp;gt;
And I could lose a year to debug &amp;lt;/br&amp;gt;
That window, that window, that window flashed tonight &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;Flash it straight into my phone &amp;lt;/br&amp;gt;
We don&apos;t have to configuare it hard &amp;lt;/br&amp;gt;
Like it working out of the box &amp;lt;/br&amp;gt;
Easy boot and easy go &amp;lt;/br&amp;gt;
Multi systems deep into the flash &amp;lt;/br&amp;gt;
You&apos;re my perfect workmate &amp;lt;/br&amp;gt;
I am right since I owned my phone &amp;lt;/br&amp;gt;
We got more than words can say &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Baby, I&apos;m a developer &amp;lt;/br&amp;gt;
Baby, you&apos;re a firehose &amp;lt;/br&amp;gt;
Move your source code close to mine &amp;lt;/br&amp;gt;
We can compile &apos;em until the dawn &amp;lt;/br&amp;gt;
I can see we&apos;re getting late &amp;lt;/br&amp;gt;
That window, that window, that window flashed tonight &amp;lt;/br&amp;gt;
And I could lose a year to debug &amp;lt;/br&amp;gt;
That window, that window, that window flashed tonight &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Post chorus&lt;/h1&gt;
&lt;p&gt;That window, that window, that window flashed tonight... &amp;lt;/br&amp;gt;
That window, that window, that window flashed tonight... &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>新的高通 Gunyah，Mediatek 的 Genizone 虛擬機未必會成爲 Android 上的 Termux 殺手</title><link>https://blog.cloudflare88.eu.org/posts/newly-added-gunyah-and-genizone-probably-wont-affect-termux-and-chroot-based-containers-position/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/newly-added-gunyah-and-genizone-probably-wont-affect-termux-and-chroot-based-containers-position/</guid><description>從實用性而言，採用硬體虛擬化技術的虛擬機效能肯定會比採用 `proot/chroot`，LXC，Docker 等容器技術的方案要好。但我認爲，採用硬體虛擬化的虛擬機，不見得會取代 Termux，成爲新的「殺手級」功能。</description><pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Android 16 之後，隨着虛擬化框架成爲新的功能，各大手機晶片廠商也紛紛從硬體上「重新」添加被棄用已久的虛擬化支援。從實用性而言，採用硬體虛擬化技術的虛擬機效能肯定會比採用 &lt;code&gt;proot/chroot&lt;/code&gt;，LXC，Docker 等容器技術的方案要好。但我認爲，採用硬體虛擬化的虛擬機，不見得會取代 Termux，成爲新的「殺手級」功能。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;什麼是 Termux？&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://termux.dev/en/&quot;&gt;Termux&lt;/a&gt;是一群開源軟體愛好者開發的終端模擬器，擁有自己的套件庫。採用 &lt;code&gt;APT&lt;/code&gt; 作爲自己的套件管理員。使用者不需要 Root 自己的手機就可以完成很多 Linux 電腦上才可以做的事，還可以通過 &lt;code&gt;proot&lt;/code&gt; 建立自己的 Linux 容器。&lt;/p&gt;
&lt;h1&gt;對於虛擬機的看法&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;採用硬體虛擬化的虛擬機，不見得會取代 Termux，成爲新的「殺手級」功能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;把玩了 Pixel 手機的 Debian Terminal，最近也有在 8750 MTP 原型機上刷 Android 16 開 Gunyah 虛擬機玩，所以得出這個結論。因爲其使用 AVF 框架來執行 Debian 虛擬機，是環境完整的 Linux，可以執行 Docker。對於高通平臺而言，雖不能執行完整的 KVM，但是在8650之後的平臺上加入了全新的EL2虛擬機方案，稱爲「Gunyah」，Mediatek 也有類似的做法，稱爲「Genizone」。可以通過 ChromeOS 的 &lt;code&gt;crosvm&lt;/code&gt; 技術在手機上跑起 pKVM，用於安裝 Linux 虛擬機，甚至還可以裝 Windows on ARM。從而做到更多近似於 Linux 手機的體驗。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
吶，下面二幅圖就是我在8750原型機上藉助 &lt;code&gt;crosvm&lt;/code&gt; 跑 pKVM 的嘗試以及「關於裝置」界面。虛擬機開機速度比較快，效率也非常高:&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/working-gunyah-vm.png&quot; width=&quot;65%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/prototype-specs.png&quot; width=&quot;65%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;不過，若是開啓的虛擬機比較多，可能會導致裝置效能下降。使用執行虛擬機的軟體叫 &lt;a href=&quot;https://github.com/Droid-VM/&quot;&gt;DroidVM&lt;/a&gt;，由 BigfootACA 開發。同時也是 Windows on ARM 的開發者。可以使用 &lt;code&gt;crosvm&lt;/code&gt; &lt;code&gt;qemu&lt;/code&gt; 作爲後端管理虛擬機。這方面他們真的很厲害。&amp;lt;/br&amp;gt;
想要實作 GPU 加速也不是沒有可能，但是效果可能不會很好。畢竟 Google 宣稱未來還將支援在 Android 上訪問 Linux GUI 程式，有點像 WSL。如果是這樣的話，就需要解決 Wayland 視窗在 Android 合成器上顯示的問題。至於跑 CLI 命令列程式，Termux 這種 userspace 的解決方案比較簡單高效。因爲 Termux 不需要虛擬化這種措施，所有的套件也都是針對 ARM 64位元指令集編譯的，因此不存在不相容的問題。除非應用不相容 Android 的 Bionic C 函式庫。就算臨時要開 SSH 的話，也是 Termux 最快。&amp;lt;/br&amp;gt;
至於跑 &lt;code&gt;proot/chroot&lt;/code&gt; 容器用 GPU 加速的話，Termux 也可用 Turnip/Freedreno，Panfrost/Lima，VirtGL 等圖形驅動實現。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;基於 userspace 的應用與採用「硬體虛擬化」的虛擬機相比，有什麼差異？&lt;/h1&gt;
&lt;p&gt;首先應該是執行位置不同了吧，Termux 應用執行於 userspace，位於 EL0，而虛擬機執行於系統 Hypervisior，位於 EL2.&amp;lt;/br&amp;gt;
另外，整個技術架構完全不同。Termux 就是執行在 Android userland 的一個應用程式。直接執行 ARM 64位元 ELF 二進位檔，可以使用 Android 系統提供的資源，啓動速度快。I/O 延遲低，對於命令列的支援好，不使用任何虛擬化功能。&amp;lt;/br&amp;gt;
Android 內建的終端機，和採用 &lt;code&gt;qemu kvm&lt;/code&gt; &lt;code&gt;crosvm&lt;/code&gt; 技術的虛擬機一樣，都是採用相容 KVM/pKVM 虛擬化與 VirtIO 技術的虛擬機。因此每次啓動這些應用，實際上就是在背景執行了新的 Linux 虛擬機。像是虛擬磁碟，網路，I/O 都需要藉助 VirtIO 存取和設定。至於 GPU，相機，USB等硬體界面則需要設定 Passthrough，或者根本禁止存取。會很難期待「隨時存取 shell」的體驗，但好處是具有完整的隔離性，更安全。除非程式有 VM escape 的行爲，不然不會對於裝置造成影響。比較適合教育市場，政府，企業之類，會對這些市場有很大幫助。&amp;lt;/br&amp;gt;
在效能方面，如果需要對CPU，記憶體等要求高的工作（編譯程式碼之類），像 Termux 這種應用可以直接與裝置互動，不會像虛擬機那樣有負擔（雖然 Android 就是 Linux 跑了無數 Java 虛擬機就是了）。使用 GPU 雖然比較 hacky，但是至少可以用，延遲更低。&lt;/p&gt;
&lt;h1&gt;虛擬機對於裝置要求苛刻&lt;/h1&gt;
&lt;p&gt;虛擬機具有效能高，安全，方便設定的優點。但也要承認這一技術「最大的缺點」，就是對裝置要求太高。&amp;lt;/br&amp;gt;
不要跟我講「所有相容 Arm V8 指令集的手機都支援硬體虛擬化」這種幹話。支援是一回事，廠商給不給妳用又是一回事。雖然驍龍835之後的晶片，可以用&lt;a href=&quot;https://github.com/TravMurav/slbounce&quot;&gt;Windows 筆電的方法&lt;/a&gt;來讓作業系統跑在 EL2（Mediatek 更是有廣爲人知的晶片漏洞可以讓 Android 核心跑在 EL2），但僅適用於 MTP，QRD 之類CPU沒有熔燬的裝置，還需要修補韌體才可以。目前市場上在售的手機，除了 SHIFT6mq 以外，都有CPU熔燬，修改韌體的方法幾乎不可行。即使是8750這種支援 Gunyah 的平臺，配置虛擬機也不容易。&amp;lt;/br&amp;gt;
首先妳的裝置韌體必須有編譯 &lt;code&gt;pvmfw&lt;/code&gt;，並且韌體有支援虛擬機的設定檔案，然後才可以在 Root 的裝置上執行 &lt;code&gt;crosvm&lt;/code&gt; 跑 pKVM 虛擬機。像 Android 16 內建的終端機是無法執行的，因爲高通平臺不支援執行普通的 KVM 虛擬機，
如果裝置沒有編譯 &lt;code&gt;pvmfw&lt;/code&gt;，但是韌體支援虛擬機設定，還可以通過移植其他支援 pKVM 的裝置的 &lt;code&gt;pvmfw&lt;/code&gt; 來補回這一功能。這種做法必須要求手機可以解鎖 bootloader，如果連 bootloader 也解不開，那就不可能跑虛擬機了。&amp;lt;/br&amp;gt;
另外，就算裝置支援虛擬機，如果裝置的記憶體或者空間不夠，在這種裝置上跑虛擬機的體驗就會很糟糕。畢竟虛擬機是比較吃硬體資源的，這對手機快閃記憶體的壽命與隨機讀寫速度都是極大的考驗。&lt;/p&gt;
&lt;h1&gt;結語&lt;/h1&gt;
&lt;p&gt;我想這些硬體虛擬機的方案，還有 Linux 終端機，更多爲 Android 平板 ChromeOS 化，或者是 Android 與 ChromeOS相結合的做法鋪路。這樣 AVF 這種虛擬機框架可以爲 ARM 晶片虛擬化提供統一的界面。但對於開發者和 Power users 來說，Termux 的價值不在於牠是不是虛擬機，而是在於牠能讓我們以最廉價、最快速、最無縫的方式，直接調度這台 ARM 設備的原始怪獸性能。只要廠商一天不開放 EL2 的完全控制權，這些內建的虛擬機就永遠只是精緻的盆景，無法取代 Termux 這種長在 Android 土壤上的解決方案。&lt;/p&gt;
</content:encoded></item><item><title>準備開刷！(準備, 始作, 플래싱!)(Feat. Kryo Kodiak) -- ‘Blue Archive’ 中國 서버(server) 大運動會 主題曲 ‘出發準備!(출발준비)’를 FOSS가 패러디한 버전 (韓國語 버전, Korean Ver.)</title><link>https://blog.cloudflare88.eu.org/posts/ko/ready-set-flash/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/ko/ready-set-flash/</guid><description>讓我們在一起，構建新的篇章！寫給我的 QCS6490 單板機和 SM8750 MTP 原型機。</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Ready,%20Set,%20Flash!%20(%EC%A4%80%EB%B9%84,%20%EC%8B%9C%EC%9E%91,%20%ED%94%8C%EB%9E%98%EC%8B%B1!).mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/DLzUDHSYUWM?si=HR8Gia2XaX4PUVBb&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Chorus&lt;/h2&gt;
&lt;p&gt;팬(fan) 소리 높여봐,&amp;lt;/br&amp;gt;
世上(세상) 中心(중심)에서 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;讓風扇更響亮，站在世界中央&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;우리 함께 모여, &amp;lt;/br&amp;gt;
自由(자유)를 외쳐봐! (헤이!)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們聚在一起，高喊自由口號！（嘿！）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;나 리 라 바 라 바, 準備(준비)되면 플래싱(flash)!&amp;lt;/br&amp;gt;
나 리 라 바 라 바, 오픈 소스(Open source) 빛 아래!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Na Li La Ba La Ba，準備好了就開刷！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，在開源之光照耀下！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;망설이지 말고 발을 내디뎌,&amp;lt;/br&amp;gt;
靈感(영감)을 펼쳐봐, 같이 빌드(build)해!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不要猶豫，邁出第一步,&amp;lt;/br&amp;gt;
展開靈感，一起編譯吧！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Verse&lt;/h2&gt;
&lt;p&gt;제자리에, 프로브(probe)!&amp;lt;/br&amp;gt;
&lt;code&gt;Preloader&lt;/code&gt; 뒤엔 &lt;code&gt;DA&lt;/code&gt;!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;各就位，探針準備！&amp;lt;/br&amp;gt;
&lt;code&gt;Preloader&lt;/code&gt; 之後接 &lt;code&gt;DA&lt;/code&gt;！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;리테일(retail)은 , 퓨즈(fuse) 펑!&amp;lt;/br&amp;gt;
壁(벽)돌 되면 補償(보상)해!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;零售就位，熔絲熔燬!&amp;lt;/br&amp;gt;
(裝置)變磚記得賠！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;퀄컴(Qualcomm) 展示會(전시회),&amp;lt;/br&amp;gt;
寶物(보물)이 가득!&amp;lt;/br&amp;gt;
몰라도 상관없어!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;高通展示會，滿滿寶貝！&amp;lt;/br&amp;gt;
不懂也無所謂！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;포팅(port) 힘들면,&amp;lt;/br&amp;gt;
잠시 잊어둬,&amp;lt;/br&amp;gt;
다음 機器(기기) 누구지?&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;移植(port)太難就先放置一邊，&amp;lt;/br&amp;gt;
下一臺裝置又是誰？&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Bridge&lt;/h2&gt;
&lt;p&gt;La la la, la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la la &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Verse&lt;/h2&gt;
&lt;p&gt;로그(log) 속에서 너를 찾아봐,&amp;lt;/br&amp;gt;
너는 봤을까 나의 LED &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在 log 中尋找妳的身影，&amp;lt;/br&amp;gt;
是否曾看清，我努力在閃燈致意&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;어두운 畵面(화면) 속,&amp;lt;/br&amp;gt;
흐릿한 너의 모습 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在黑暗畫面中黯淡的妳，&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;커널(kernel)이 돌아가!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;核心開始運作了！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Chorus&lt;/h2&gt;
&lt;p&gt;텐션을 높여봐,&amp;lt;/br&amp;gt;
하드웨어(hardware) 모두 OK!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;讓情緒更高漲，&amp;lt;/br&amp;gt;
所有硬體工作正常！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;靈感(영감)을 모아서, &amp;lt;/br&amp;gt;
피워봐!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;讓靈感聚集，&amp;lt;/br&amp;gt;
盡情綻放！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;프라이버시(privacy)의 夢(몽),&amp;lt;/br&amp;gt;
人權(인권)이 保障(보장)된 곳&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;滿懷捍衛隱私的夢想,&amp;lt;/br&amp;gt;
數位人權得到保障 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;우리 함께 모여,&amp;lt;/br&amp;gt;
멋진 장을 빌드해!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;讓我們在一起,&amp;lt;/br&amp;gt;
編譯美好篇章！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Ending&lt;/h2&gt;
&lt;p&gt;나 리 라 바 라 바, 準備(준비)되면 플래싱(flash)!&amp;lt;/br&amp;gt;
나 리 라 바 라 바, 오픈 소스(Open source) 빛 아래!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Na Li La Ba La Ba，準備好了就開刷！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，在開源之光照耀下！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;망설이지 말고 발을 내디뎌,&amp;lt;/br&amp;gt;
靈感(영감)을 펼쳐봐, 같이 빌드(build)해!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不要猶豫，邁出第一步,&amp;lt;/br&amp;gt;
展開靈感，一起編譯吧！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;靈感(영감)을 펼쳐봐, 같이 빌드(build)해!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;展開靈感，一起編譯吧！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>準備開刷！(Feat. Kryo Kodiak) -- 根據「蔚藍檔案」中國服大運動會主題曲「準備出發！」的 FOSS 改編</title><link>https://blog.cloudflare88.eu.org/posts/ready-set-flash/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/ready-set-flash/</guid><description>讓我們在一起，構建新的篇章！寫給我的 QCS6490 單板機和 SM8750 MTP 原型機。</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/ready-set-flash-korean/&quot;&gt;點擊這裏&lt;/a&gt;檢視韓語版歌詞以及中文翻譯。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%E6%BA%96%E5%82%99%E9%96%8B%E5%88%B7%EF%BC%81--%E6%A0%B9%E6%93%9A%E3%80%8C%E8%94%9A%E8%97%8D%E6%AA%94%E6%A1%88%E3%80%8D%E4%B8%AD%E5%9C%8B%E6%9C%8D%E5%A4%A7%E9%81%8B%E5%8B%95%E6%9C%83%E4%B8%BB%E9%A1%8C%E6%9B%B2%E3%80%8C%E6%BA%96%E5%82%99%E5%87%BA%E7%99%BC%EF%BC%81%E3%80%8D%E6%94%B9%E7%B7%A8.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/DLzUDHSYUWM?si=HR8Gia2XaX4PUVBb&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;讓風扇更響亮，&amp;lt;/br&amp;gt;
我們在世界最中央！&amp;lt;/br&amp;gt;
讓我們在一起，&amp;lt;/br&amp;gt;
高喊自由口號！（嘿！）&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，準備好了就開刷！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，在自由軟體照耀下！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，邁出堅定的步伐，&amp;lt;/br&amp;gt;
來把創意揮灑，&amp;lt;/br&amp;gt;
一起編譯吧！&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;各就位，探針準備！&amp;lt;/br&amp;gt;
&lt;code&gt;Preloader&lt;/code&gt; 之後接 &lt;code&gt;DA&lt;/code&gt;！&amp;lt;/br&amp;gt;
零售預備，熔絲熔燬！&amp;lt;/br&amp;gt;
晶片報廢記得賠！&amp;lt;/br&amp;gt;
高通展會，&amp;lt;/br&amp;gt;
很多寶貝！&amp;lt;/br&amp;gt;
聽不懂也無所謂！&amp;lt;/br&amp;gt;
移植再累，&amp;lt;/br&amp;gt;
暫不理會，&amp;lt;/br&amp;gt;
下一臺裝置是誰！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge&lt;/h1&gt;
&lt;p&gt;La la la, la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la &amp;lt;/br&amp;gt;
La la la, la la la la la la la &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;視線在檢視，log 中妳的身影&amp;lt;/br&amp;gt;
是否曾看清，我努力在閃燈致意&amp;lt;/br&amp;gt;
熒幕影像黯淡，&amp;lt;/br&amp;gt;
隱約的看清妳&amp;lt;/br&amp;gt;
核心順利執行!&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;讓情緒更高漲，&amp;lt;/br&amp;gt;
所有硬體工作正常！&amp;lt;/br&amp;gt;
讓靈感在一起，&amp;lt;/br&amp;gt;
盡情綻放！&amp;lt;/br&amp;gt;
捍衛隱私的希望，&amp;lt;/br&amp;gt;
數位人權得到保障，&amp;lt;/br&amp;gt;
讓我們在一起，&amp;lt;/br&amp;gt;
編譯美好篇章！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;Na Li La Ba La Ba，準備好了就開刷！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，在自由軟體照耀下！&amp;lt;/br&amp;gt;
Na Li La Ba La Ba，邁出堅定的步伐，&amp;lt;/br&amp;gt;
來把創意揮灑，&amp;lt;/br&amp;gt;
一起編譯吧！&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
來把創意揮灑，&amp;lt;/br&amp;gt;
一起編譯吧！&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>小如簽章卡 --- Radxa Dragon Q6A 單板機紹介</title><link>https://blog.cloudflare88.eu.org/posts/q6a-review/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/q6a-review/</guid><pubDate>Wed, 29 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note
建議配合下面音樂瀏覽，效果更佳：
&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Fs7MuuVwCOM?si=5PJSfvkHBlZQb60x&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
:::&lt;/p&gt;
&lt;p&gt;最近在進行 SM8750 MTP 原型機的主線核心移植工作，隨著測試硬體功能而重編核心的次數不斷增多，原本僅有8GB記憶體的 Rock 5B 單板機在編譯核心時所花費的時間也就慢慢增加。雖說不會影響整體移植進展就是了，更沒有人要求我在哪天結束之前上傳成果。不過總覺得...身邊的設備都改用16GB記憶體了，我的驍龍筆電更是有32GB的RAM。何況在嵌入式裝置這種對記憶體要求嚴格的地方，更多的記憶體加上優秀的作業系統，只會讓這部裝置硬體資源更充足，所以經過多次考慮後，最終選擇了12GB記憶體的版本。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-fastfetch.png&quot; alt=&quot;Q6A running Armbian Rolling release&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;外觀紹介&lt;/h1&gt;
&lt;p&gt;Radxa Dragon Q6A 是一顆採用驍龍 Dragonwing QCS6490 ARM 晶片的單板機。相容 Arm v8 指令集，核心時脈 2.7GHz，採用 big.Little 設計。從外觀來看，單板機的大小和常見的信用卡相比沒有什麼區別。&amp;lt;/br&amp;gt;
在我開箱驍龍筆電時我就注意到了，但是考慮到效能問題，以及RK3588晶片單板機還可以滿足日常開發用途，就沒有入手。Radxa 是一家位於中國深圳的單板機生產製造公司，這臺單板機在2024年上市，在 &lt;a href=&quot;https://www.aliexpress.com/item/1005010224206962.html&quot;&gt;AliExpress&lt;/a&gt; 上可以購買。&amp;lt;/br&amp;gt;
就像其他 Radxa 的單板電腦一樣，這一臺同樣使用塑料盒子包裝。盒子內還附有貼紙。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-box.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-sticker.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;從盒子裡取出單板電腦，和前一代 Rock 5B 產品相比，這臺單板機的面積比上一代小了不少，像是 HDMI，USB的位置也發生了變化。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-chip-view.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;除了單板機標準的 GPIO 以外，這臺單板機還內建了移遠FCU760K WiFi 模組，用於提供無線網路支援，還有做成 M.2 固態硬碟接口的 PCIe 匯流排，可以相容PC上大多數硬體，也可以安裝固態硬碟提升裝置I/O速度。板底還附有 MIPI CSI/DSI，UFS/eMMC 模組接口，用於安裝熒幕和UFS/eMMC 快閃記憶體。這對於追求隨機讀寫效能的開發者來說，比起傳統的 microSD 卡要可靠得多。不要看板子很小，這也要差不多2900臺幣！&amp;lt;/br&amp;gt;
值得一提的是，Q6A 搭載的 QCS6490 晶片在電源管理上相當考究。牠支援 USB-C PD 供電，這點對於已經滿桌子 PD 充電器的我來說非常友善。不過，由於這顆晶片在高負載編譯時發熱量不容小覷，板子上也預留了主動散熱片的安裝孔位，但沒有留出風扇的安裝接口。&lt;/p&gt;
&lt;h1&gt;軟體環境與初次啟動&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;各就位，探針準備！&amp;lt;/br&amp;gt;
&lt;code&gt;Preloader&lt;/code&gt; 之後接 &lt;code&gt;DA&lt;/code&gt;！&amp;lt;/br&amp;gt;
零售預備，熔絲熔燬！&amp;lt;/br&amp;gt;
晶片燒燬記得賠！&amp;lt;/br&amp;gt;
-------- &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/ready-set-flash/&quot;&gt;「準備開刷！」&lt;/a&gt;-- 根據「蔚藍檔案」中國服大運動會主題曲「準備出發！」的 FOSS 改編&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;插上電源，隨著綠色的LED點亮，螢幕上也隨之出現 Radxa 的 logo。在使用記憶卡的情況下，完全開機需要20秒。就像高通平臺的既有風格那樣，Q6A單板電腦的開機韌體同樣基於 Coreboot 和最新的 EDK II UEFI 實作，可以相容任何支援UEFI開機的作業系統。另外韌體還內建ACPI支援，甚至可以使用官方釋出的驅動程式改裝 Windows 11,幾乎所有的硬體都是正常的（韌體適用於 Windows 平臺）。可以通過進入 EDL 手動更新新的韌體，只需要按下耳機插孔旁邊的按鈕即可。另外晶片沒有熔燬，因此刷自己的客製化韌體來提升開機速度也是可以的。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/q6a-firmware.jpg&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;想要更新韌體，將單板機進入EDL，然後下載&lt;a href=&quot;https://dl.radxa.com/dragon/q6a/images/dragon-q6a_flat_build_wp_260120.zip&quot;&gt;官方韌體&lt;/a&gt;，使用 &lt;code&gt;edl&lt;/code&gt; 工具進行韌體更新：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo edl --memory=spinor rawprogram rawprogram0.xml patch0.xml --loader=prog_firehose_ddr.elf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是。必須使用 USB-A to USB-A 線將單板機與電腦相連！不知道為什麼這臺單板電腦非要這麼做，推測可能是因為 QCS6490 內部的引腳定義或初級引導程式（PBL）在硬體設計上，將其中一個 USB-A 接口定義為首選的數據傳輸路徑。雖然這對習慣了「萬物皆可 Type-C」的現代開發者來說有點復古，但也算是玩驍龍單板機的一種獨特儀式感吧。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
軟體方面，目前只有 Armbian 對這臺裝置支援還比較不錯。當然因為這臺裝置尚處於初期階段，很多針對裝置的更改還沒有進入主線，所以目前常見的採用主線核心的發行版都開不起來。現在的 Radxa 和 PINE64 一樣，都是負責設計和製造硬體，至於軟體和作業系統則完全交給社群開發。如果想要存取UART，只需要通過杜邦線連接到UART轉換裝置，通過電腦存取即可。&amp;lt;/br&amp;gt;
對了，如果遇到更新核心之後遇到內建 WiFi 網路卡不工作，去 Radxa 的 GitHub 套件庫&lt;a href=&quot;https://github.com/radxa-pkg/aic8800/releases&quot;&gt;下載 AIC8800 的晶片核心驅動&lt;/a&gt;安裝就可以了。&lt;/p&gt;
&lt;h2&gt;硬體探索&lt;/h2&gt;
&lt;p&gt;和之前所有的裝置一樣，在 Q6A 上也可以通過常見的 &lt;code&gt;lsusb&lt;/code&gt; &lt;code&gt;lspci&lt;/code&gt; &lt;code&gt;inxi&lt;/code&gt; 等命令列工具來獲取硬體信息。例如 &lt;code&gt;lspci&lt;/code&gt; 就可以檢視裝置的PCIe匯流排上外掛了哪些裝置，使用 &lt;code&gt;-v&lt;/code&gt; 引數可以看到更詳細的內容:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lspci -vvvv 
0000:00:00.0 PCI bridge: Qualcomm Technologies, Inc SM8250 PCIe Root Complex [Snapdragon 865/870 5G] (prog-if 00 [Normal decode])
	Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c00000/pcie@0
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast &amp;gt;TAbort- &amp;lt;TAbort- &amp;lt;MAbort- &amp;gt;SERR- &amp;lt;PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 145
	IOMMU group: 14
	Region 0: Memory at 60300000 (32-bit, non-prefetchable) [size=4K]
	Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
	I/O behind bridge: 1000-1fff [size=4K] [16-bit]
	Memory behind bridge: 60400000-604fffff [size=1M] [32-bit]
	Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff [disabled] [64-bit]
	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast &amp;gt;TAbort- &amp;lt;TAbort- &amp;lt;MAbort- &amp;lt;SERR- &amp;lt;PERR-
	BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- &amp;gt;Reset- FastB2B-
		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
	Capabilities: &amp;lt;access denied&amp;gt;
	Kernel driver in use: pcieport
	Kernel modules: shpchp

0000:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller (rev 1b)
	Subsystem: Realtek Semiconductor Co., Ltd. Device 0123
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast &amp;gt;TAbort- &amp;lt;TAbort- &amp;lt;MAbort- &amp;gt;SERR- &amp;lt;PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 144
	IOMMU group: 14
	Region 0: I/O ports at 1000 [size=256]
	Region 2: Memory at 60404000 (64-bit, non-prefetchable) [size=4K]
	Region 4: Memory at 60400000 (64-bit, non-prefetchable) [size=16K]
	Capabilities: &amp;lt;access denied&amp;gt;
	Kernel driver in use: r8169
	Kernel modules: r8169

0001:00:00.0 PCI bridge: Qualcomm Technologies, Inc SM8250 PCIe Root Complex [Snapdragon 865/870 5G] (prog-if 00 [Normal decode])
	Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c08000/pcie@0
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast &amp;gt;TAbort- &amp;lt;TAbort- &amp;lt;MAbort- &amp;gt;SERR- &amp;lt;PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 147
	IOMMU group: 15
	Region 0: Memory at 40300000 (32-bit, non-prefetchable) [size=4K]
	Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
	I/O behind bridge: f000-0fff [disabled] [16-bit]
	Memory behind bridge: fff00000-000fffff [disabled] [32-bit]
	Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff [disabled] [64-bit]
	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast &amp;gt;TAbort- &amp;lt;TAbort- &amp;lt;MAbort- &amp;lt;SERR- &amp;lt;PERR-
	BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- &amp;gt;Reset- FastB2B-
		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
	Capabilities: &amp;lt;access denied&amp;gt;
	Kernel driver in use: pcieport
	Kernel modules: shpchp

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不難發現，QCS6490應該是驍龍778G為基礎修改的晶片（韌體中也可以看到晶片的代號為 &lt;code&gt;Kodiak&lt;/code&gt;）。同時也可以看到由 Realtek 生產的網路卡。想要檢視硬體的信息可以通過 &lt;code&gt;dmidecode&lt;/code&gt; 檢視：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# sudo dmidecode
Handle 0x0002, DMI type 0, 26 bytes
BIOS Information
	Vendor: Qualcomm Technologies, Inc.
	Version: 6.0.251230.BOOT.MXF.1.0.1-00549-KODIAKWP-1
	Release Date: 12/30/2025
	ROM Size: 32 MB
	Characteristics:
		ACPI is supported
		Function key-initiated network boot is supported
		Targeted content distribution is supported
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就可以檢視當前韌體的版本，裝置的 SPI 快閃記憶體大小，以及韌體支援的功能。至於晶片本身，可以通過檢視 &lt;code&gt;/proc/cpuinfo/&lt;/code&gt; 或者 &lt;code&gt;lscpu&lt;/code&gt; 指令也可以。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lscpu
lscpu                                                                   
Architecture:                aarch64
  CPU op-mode(s):            32-bit, 64-bit
  Byte Order:                Little Endian
CPU(s):                      8
  On-line CPU(s) list:       0-7
Vendor ID:                   ARM
  Model name:                Cortex-A55
    Model:                   0
    Thread(s) per core:      1
    Core(s) per socket:      4
    Socket(s):               1
    Stepping:                r2p0
    Frequency boost:         disabled
    CPU(s) scaling MHz:      100%
    CPU max MHz:             1958.4000
    CPU min MHz:             300.0000
    BogoMIPS:                38.40
    Flags:                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpui
                             d asimdrdm lrcpc dcpop asimddp
  Model name:                Cortex-A78
    Model:                   1
    Thread(s) per core:      1
    Core(s) per socket:      4
    Socket(s):               1
    Stepping:                r1p1
    CPU(s) scaling MHz:      29%
    CPU max MHz:             2707.2000
    CPU min MHz:             691.2000
    BogoMIPS:                38.40
    Flags:                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpui
                             d asimdrdm lrcpc dcpop asimddp
NUMA:                        
  NUMA node(s):              1
  NUMA node0 CPU(s):         0-7
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;當然，這臺單板機還內建了高通自家的 TPU 用於處理 AI 模型的運作。雖然效能應該比不上 SC8380 的 Hexagon TPU 啦，但是執行一些輕量的 LLM 應該不成問題。另外也可以使用高通自己的 AI Hub 使用預先處理好的模型。&lt;/p&gt;
&lt;h1&gt;QCS 6490 效能測試&lt;/h1&gt;
&lt;p&gt;純測試CPU效能，使用 Unixbench 跑分，總分4327分（不使用散熱裝置，使用記憶卡開機）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-bench-result.png&quot; alt=&quot;Q6a unixbench result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這個分數比 Rasperry Pi 5 的效能要好（3594 分），但明顯不如 Oneplus 6T（6030 分）。如果用 Android 手機處理器比較，大致相當於2025年中階 Android 手機水平。按理說QCS6490 CPU 效能不應該如此差勁呀，是因為我使用記憶卡開機的緣故？等之後給我的單板機加裝SSD再試試看。&amp;lt;/br&amp;gt;
接下來是 &lt;code&gt;7zip&lt;/code&gt; 壓縮效能測試（不使用散熱裝置，使用記憶卡開機），總分20157 MIPS。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-7zip-bench-result.png&quot; alt=&quot;7zip benchmarking result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Q6A 和我的 Nothing Phone 1（19062 MIPS）效能大致相同，依舊要優於 Rasperry Pi 5（13263 MIPS）&amp;lt;/br&amp;gt;
在核心編譯方面，使用&lt;a href=&quot;https://github.com/Xlie-Electronic-Customs/linux&quot;&gt;同樣的 SM8750 主線核心原始碼&lt;/a&gt;，從原始碼編譯核心，Q6A 用了15分鐘，Rock 5B 用了32分鐘。作為對比用的驍龍筆電則需要大概5分鐘。
&amp;lt;/br&amp;gt;
另外，晶片內建的 Adreno 643 繪圖卡可以通過 &lt;code&gt;freedreno&lt;/code&gt; 核心模組被主線核心支援。有 GPU 加速的話，播放影片和玩遊戲都不是問題。然而因為主線核心缺乏硬體解碼器的支援，這臺 Q6A 單板機完全無法播放 4K YouTube 影片，使用 &lt;code&gt;htop&lt;/code&gt; 檢視 CPU 利用率偏高。在沒有風扇的情況下，核心溫度可能會飆到90度。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q6a-4k-video-test.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;總結&lt;/h1&gt;
&lt;p&gt;我想這個 Q6A 單板電腦硬體本身非常有潛力，但是目前裝置的主線核心支援非常差勁。只希望未來會有更多驅動進入主線核心，這樣就不必要使用更多的 Out-of-tree patches 去修補主線核心。&lt;/p&gt;
</content:encoded></item><item><title>高通平臺真的對自由軟體友好嗎？-- 我對於使用自由軟體的看法</title><link>https://blog.cloudflare88.eu.org/posts/is-qualcomm-platform-compatible-for-foss/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/is-qualcomm-platform-compatible-for-foss/</guid><description>如果一臺設備需要每次開機時都需要 tweak，那麼這就註定了牠不適合日常使用。</description><pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我是一個自由軟體愛好者，同時也是 Linux 愛好者，我喜歡探究將自由軟體應用於日常生活的可能性。一方面可以節省不必要的開支，另一方面也可以讓大家看到，一些需要使用專有軟體的方案也可以被自由軟體所取代，而且實作甚至優於商業軟體。&amp;lt;/br&amp;gt;
在這方面，我有採用架設 Nextcloud 雲端伺服器用於取代專有的 Microsoft 365，Google Workspace 之類線上服務的經驗，不需要一分錢就可以隨時隨地存取我的工作檔案，文書處理，只需要通過瀏覽器就可以遠端辦公。這種自由度的體驗，對於我來說，是一種享受。特別是隨着我的日用設備從 X86 遷移到 ARM 架構之後，自由軟體在我日常生活中所佔的比例日漸提高。當別人在爲 Office 365 的費用而苦惱，時常抱怨 Windows 11 的強制更新，效能低下時，我早就開始思考取代另一個專有軟體的方案了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;爲什麼會選擇高通平臺開始研究？&lt;/h1&gt;
&lt;p&gt;從自身的玩機歷程而言，我與高通驍龍晶片結下的「羈絆」從2016年的 Coolpad Cool 1就開始了。因爲早期驍龍晶片 GPU 效能強，所以很長一段時間，驍龍晶片一直都是我選擇手機，平板電腦等裝置的「依據」，也成爲了我刷機的開始。比起後來接觸到的 Rockchip，全志，Mediatek 平臺的裝置，我在高通平臺上的經驗比較豐富，網路上流傳的文檔也比較多。另外，高通的晶片在行動裝置市場甚至 ARM 市場上都具有較高的知名度。這樣看來，在高通平臺（特別是 MTP, QRD, CRD 等原型機）上的主線核心移植及韌體開發就有了意義。很多零售設備上的主線核心原始碼都是從 MTP，QRD 之類的原型機修改而來的，具有比較高的參考意義。&lt;/p&gt;
&lt;h1&gt;一切「奇跡」的開始&lt;/h1&gt;
&lt;p&gt;採用 Arm 晶片的筆電，並不是沒有「前車之鑒」。2017年，由 PINE64 公司推出的 Pinebook 就是採用 Allwinner A64 晶片，預載 KDE Neon Linux 發行版的筆電。但是 A64 晶片的效能實在是不堪入目呀...平時放個 YouTube 1080P 解析度的影片都可以讓 SoC 使用率飆到90% 以上，平時執行軟體也總是慢慢的，甚至還會有當機的情況。後面換了 Apple MacBook Air（不是講了不宣傳 Apple 產品嗎）改用 Asahi Linux，效能有了提升，續航也不錯。&amp;lt;/br&amp;gt;
2024年，驍龍 X Elite 和強大的 Oryon 核心誕生時，業界曾寄予其厚望，認爲這是繼 Apple Silicon 之後，又一個可以撼動 X86 晶片的存在。加上高通積極推動主線核心的支援，許多 Arm 筆電愛好者都認爲 SC8380XP（就是 X Elite 的早期稱呼) 如此強悍的晶片，將會成爲筆電的「奇跡」。&amp;lt;/br&amp;gt;
對於我，驍龍筆電的到來，就像我在 &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/what-i-have-learned-from-my-7-year-linux-journey/#20232025%E5%B9%B4%E8%A1%8C%E5%8B%95%E8%A3%9D%E7%BD%AE%E4%B8%8A%E7%9A%84-linux%E9%A9%8D%E9%BE%8D%E6%9C%AC%E7%99%BB%E5%A0%B4&quot;&gt;Linux 學習心得中講到的&lt;/a&gt;，完全是「意外」。但也不得不承認驍龍筆電的「強悍」，4.2GHz的時脈，32GB的記憶體，以及42MB的L2快取無論是程式開發或者是日常使用都可以完美應對，雖然不能玩PC上常見的大型遊戲，但是依舊不錯（畢竟我也不會用嵌入式裝置玩遊戲）。在我的程式開發和日常使用中，牠陪伴着我創造了一個又一個「奇跡」：第一次設定 Ollama LLM，第一次開起KVM虛擬機...或許對於經驗豐富的開發人員而言，這些早就不是「新鮮事」，但是對於普通的使用者而言，這是非常驚豔的。&amp;lt;/br&amp;gt;
然而...&lt;/p&gt;
&lt;h1&gt;高通平臺真的對自由軟體友好嗎？&lt;/h1&gt;
&lt;p&gt;高通每個晶片參考平臺（QRD，MTP，CRD/CLS）的板級開發套件庫幾乎都支援 Android（LA/LAA），對於面向筆電，桌機等場景的原型機，還會有 Windows（WP）或者 ChromeOS（LC）的原始碼。妳一定就會問了：既然 Android 的 BSP 支援那麼好，而 Android 核心基本是同時期的 Linux LTS 核心分支修改而來的，那麼支援主線核心應該也是很容易的事情吧？想得美！高通的下游核心涉及驅動程式，設備樹之類的修改多達
上萬處，早就和主線核心相去甚遠了。拋開驅動程式原始碼是否開源不談，就算是直接使用下游核心移植 Linux 系統，核心驅動也會因爲執行機理不同而無法使用，半數以上的硬體是無法工作的。至於主線核心，如果運氣好的話，興許可以利用高通提交給上游的一些驅動程式來修補。像是針對高通 Wifi 網路卡的 &lt;code&gt;ath&lt;/code&gt; 模組，&lt;code&gt;qcom-soundwire&lt;/code&gt; 也有針對高通新平臺（例如 8750,8850）的音訊支援。在主線核心面前，就連高通自己的參考平臺都不能做到硬體100%支援（SM8750 MTP 的相機不被主線核心支援，幾乎所有原型機的相機都無法使用）。至於改用 &lt;code&gt;linux-libre&lt;/code&gt; 這種100%自由軟體的核心...相信我，所有裝置都開不起來！&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-bootlog.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;那些常見的零售機就可想而知了。這對於追求客製化軟體和韌體的自由軟體使用者來說，真的有點不友善。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;雖然相容 Arm V8 指令集，但是無法開啓虛擬化&lt;/h2&gt;
&lt;p&gt;對於自由軟體使用者而言，還有另外一個讓人困惑的問題，在於高通對於硬體虛擬化的封堵。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「同學們，我們這學期即將結束，需要大家採用X軟體完成網路相關的實驗，並把結果發表在Y上，使用 &lt;code&gt;docx&lt;/code&gt; 格式發表。」&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;對於學生或者員工而言，常常因爲各種原因不得不使用專有軟體去完成工作。有時這份工作又非常重要，甚至關係到這學期或者季度的「生死」，又該怎麼辦？比較好的辦法就是使用虛擬機來執行那些專有軟體。然而很多時候都是妳只能在一邊拿着妳安裝了 Linux 的驍龍裝置乾坐着，妳問我爲什麼不開虛擬機？&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
問得好，因爲驍龍晶片的裝置開不起來！自從驍龍410之後，除了筆記本平臺之外的晶片都完全拔掉了 EL2 等級，加上驍龍平臺的 UEFI 韌體不符合 &lt;a href=&quot;https://developer.arm.com/documentation/den0044/latest&quot;&gt;ARM BBR 規定&lt;/a&gt;，UEFI 韌體執行在 EL1 等級之下，Linux 核心也就只能執行在 EL1 等級，在這種情況下，Hypervisor 被完全地關閉。使得妳那擁有足量記憶體和效能的晶片，要麼只能作爲一個客戶機去存取其他的遠端虛擬機，要麼就只能改用 Docker 等採用容器的方案了。   &amp;lt;/br&amp;gt;
即使 Google 在 Android 13 發佈時推出了系統內建的「終端機」功能，高通也從 SM8650 內建了執行在 EL1 等級的 Hypervisor，但目前僅限於 Android 核心使用，也只能執行經過廠家簽章的受保護虛擬機（PKVM）。這種虛擬機的功能受限，只可以跑 Linux。還只限載有 &lt;code&gt;pvmfw&lt;/code&gt; 韌體的裝置才可以用，符合這一點的裝置還要採用6.1及以上的核心。雖然原型機可以使用 Windows 裝置的方法拿到 EL2，卻需要修補 QSEE 設定來實現。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
而在 Windows on ARM 設備上，想要讓作業系統核心執行在 EL2 下也並不容易。就拿&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/&quot;&gt;我自己的經歷&lt;/a&gt;講，單是在我自己的筆電上開虛擬機，就花費了幾天時間去研究。&lt;a href=&quot;https://github.com/TravMurav/slbounce&quot;&gt;slbounce 專案&lt;/a&gt;就講了高通對於 Windows 平臺的重重限制，必須使用一種自訂開機流程來拿到 EL2 等級來使用 Hypervisor。因此在很長一段時間內，執行主線核心的 Windows 平臺是無法使用虛擬機的，儘管晶片支援虛擬化。而且讓作業系統跑在 EL2 下會導致不少「side effects」，例如 ADSP，CDSP 還有 PCIe 裝置會噴掉（高通平臺的 Linux 核心會藉由 Hypervisor 啓動像是 ADSP，CDSP，Modem 之類的遠端處理器，而不是讓 UEFI 韌體管理）從而導致裝置上音訊，無線網路，還有電池計量器（對於筆電，手機等可攜裝置）等依靠遠端處理器的功能不工作，雖然已有 &lt;code&gt;qebspil&lt;/code&gt; 可以讓 UEFI 韌體管理，但是這需要修補核心原始碼。往往需要更多不必要的時間。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
儘管從 SC8380XP 往後的晶片也同手機晶片一樣支援 Gunyah（군얘) Hypervisor，但是目前主線核心尚未有明確支援，需要給核心打 &lt;a href=&quot;https://lore.kernel.org/lkml/20240222-gunyah-v17-0-1e9da6763d38@quicinc.com/&quot;&gt;patch&lt;/a&gt; 才可以啓用，也必須使用特製的 &lt;a href=&quot;https://github.com/karim-manaouil/qemu-for-gunyah&quot;&gt;QEMU fork&lt;/a&gt; 才可以運作。唯一的例外應該是執行 ChromeOS 的晶片，採用 Arm 的 TF-A 取代了高通專有的開機流程，使得核心會跑在 EL2 下並且所有功能正常。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# sudo dmesg | grep gunyah 

# 這段 dmesg 展示了 Linux 核心爲 Gunyah 保留的記憶體區段，證實了 Gunyah 的存在
[    0.000000] OF: reserved mem: 0x0000000080000000..0x00000000807fffff (8192 KiB) nomap non-reusable gunyah-hyp@80000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;忘記之前在 Duckduckgo 上爬文的時候在哪裏看到的一段總結了，覺得對於高通平臺的總結非常正確：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「這或許就是高通「萬物基於 Android 的」理念，把手機上 Bootloader 鎖的概念帶到了筆電上。基於軟體的 UEFI Secure boot （高通的開機韌體基於 Coreboot 和 EDK II UEFI 開發，叫做「Core platform boot」）可以關掉，但是熔燬在 eFUSE 上的硬體 secure boot 卻不能關掉。」&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所謂的「爲了使用者安全」，實際是用「安全」爲名，限制了使用者的自由，阻止了使用者隨意的更換軟硬體。難怪史托曼從來不會看上 Arm 筆電！雖然不會像 Intel，AMD 那樣在 Microcode 或者 硬體內內建「後門（Intel ME 管理引擎就是例子)」，但卻可以做出比 X86 更加限制使用者自由的行爲來（例如 Lenovo 在自家的驍龍筆電上限制 EDL 刷機的 「VIP 映像驗證」）。&lt;/p&gt;
&lt;h2&gt;雖然效能強大，但是穩定性較差&lt;/h2&gt;
&lt;p&gt;我真的已經受夠了每次開機都需要 tweak 的裝置了。雖然有證據表明，驍龍晶片在 Linux 下的效率是要優於 Windows on ARM 的。但是驅動程式的支援和軟體支援的差勁，無一不是在給我的日常體驗上帶來不便。例如我最常使用的 OBS Studio 和 Moonlight，以及爲了存取遠端伺服器的 Rustdesk 軟體，隨便到網路上爬文就可以看到對於驍龍的 H264/HEVC 硬體解碼的問題的抱怨，對於 SC8380 更是好不到哪裏。目前內建的 TPM，NPU 和 Venus 硬體解碼暫時無法工作，這使得這些裝置的影片播放和處理等相對於其牠筆電而言形同玩具。而且高通SC8380 晶片組常見的 Quectel NCM825A PCIe 無線網路卡在主線核心中也有不少問題，甚至還有因爲網路卡韌體問題而&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/fix-broken-wifi-card-on-laptop/&quot;&gt;當掉整臺筆電&lt;/a&gt;的事情出現。這或許是 TUXEDO 最終放棄開發採用驍龍晶片的 Linux 筆電的原因。在驍龍裝置上使用 Linux，意味着妳必須要有主動的系統維護意識，知道怎麼通過 log 發現和解決問題。&amp;lt;/br&amp;gt;
在我的日常使用中，每次想要使用虛擬機時，還要開機到 UEFI shell 下，手動加載 &lt;code&gt;slbounce&lt;/code&gt; 驅動才可以執行 Linux 核心。雖然後期通過 &lt;code&gt;startup.nsh&lt;/code&gt; 指令稿解決，依舊不方便。有的時候也不禁想要問：「爲什麼不能像其牠 ARM 晶片一樣把韌體跑在 EL2 下，開機就可以用虛擬機？整這些黑箱是在衝三小？」儘管嘴上總是抱怨，但我依然使用着採用驍龍晶片的裝置，爲此還學會了不少新的知識，這些「知識」後來被用來移植 Linux 系統到其牠裝置上做了堅實的基礎。使得我有時候會想：我是否也是受虐狂？明明可以選擇離開，可我還是忍不住要去 tweak ，僅僅爲了讓裝置更好用，還有提升可憐的一點點效能；明明可以直接用廠商提供的那個黏滿了私有驅動、核心版本停留在 6.1 的「Android味」下游核心，卻偏要死磕最新的 &lt;code&gt;linux-next&lt;/code&gt;。僅僅是因為我無法忍受系統裡存在那些無法被審計的二進位檔案（Blob），或者是那種「被廠商牽著鼻子走」的感覺。仿佛不 tweak 裝置就不知該做些什麼，有時還會覺得就應該在「蔚藍檔案」中迷失自我，享受着所謂「九藍一金」的生活...&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
爲此不得不感嘆，給驍龍裝置開發主線核心，移植 Linux 發行版，甚至逆向裝置原本的韌體開發出新的 UEFI 韌體（知名的有 Renegade EFI，「&lt;a href=&quot;https://github.com/Project-Aloha/mu_aloha_platforms&quot;&gt;阿羅娜&lt;/a&gt;（아로하, Aloha)，在我個人建設的 &lt;a href=&quot;https://www.planetminecraft.com/project/1-19-2-the-gnu-genshin-subway-project/&quot;&gt;Minecraft 鐵路地圖&lt;/a&gt;中設有「阿羅娜平原站(Aloha Plain）」作爲紀念」）的開發者，真的非常厲害。&lt;/p&gt;
&lt;p&gt;:::note
下圖來自社群創作的「&lt;a href=&quot;https://tennessine.co.uk/metro/718e5684c3cecad&quot;&gt;原信地下鐵案內圖（路線圖）&lt;/a&gt;，2026年4月線路分佈情況」，注意地圖中的「Aloha Plain（阿羅娜平原站）」。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/subway-crop.png&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;圖中青色線路爲「OpenCore 支線」，淺綠色線路爲「熔絲輕軌(Fuse L.R.T.)」。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/minecraft/aloha-plain-sta.png&quot; width=&quot;75%&quot;&amp;gt;
「阿羅娜平原站」出入口，注意地面上的「Microsoft logo，曾是 Aloha 擁有重新設計的圖示前，MU UEFI 韌體的默認 Logo」。
:::&lt;/p&gt;
&lt;p&gt;他們不畏懼艱難，在沒有原理圖，BSP 的情況下，憑藉着廠商釋出的原始碼，在荒野中開闢出一條條小路，他們花費大量時間，對裝置展開逆向工程，只是爲了讓主線核心更好的相容裝置，在這混亂的硬體中建立起統一的秩序。無論是讓 Android 手機重獲新生，可以載入 Linux 甚至 OpenBSD 作業系統的 Renegade Project，還是致力於讓驍龍 X Elite 真正成為「Linux 生力軍」的開發者們，他們在 GitHub 上提交的每一行 commit，都是在為我們爭取那一點點微弱但珍貴的選擇權。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
雖然我移植 Linux 的裝置不多，但是作爲主線核心的受益者，同時也是一名 Linux porter，我也知道移植的不易。爲了能夠讓裝置「完美」相容主線核心，往往需要學習很多知識，還有除錯技巧。雖然這些知識在我的日常生活中用處不大，在常人眼中甚至是「不必要」的。好端端的電腦，幹嘛要天天折騰呢？但當我成功把 Arch Linux ARM 藉助我修改過的設備樹，和主線核心成功在那些人們所謂「本不能執行 Linux 系統的手機，平板電腦甚至是原型機」上跑起來時，那種感受不亞於在「蔚藍檔案」中一發入魂，看到閃着虹光的「學生」檔案的感受。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「或許我們追求的從來不是一台完美的電腦，而是在修補缺陷的過程中，證明自己還擁有對硬體的掌握權。」&amp;lt;/br&amp;gt;
-------- Hamoa Oryon 寫於 2022 年 1 月 23 日&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;要務實的使用自由軟體&lt;/h1&gt;
&lt;p&gt;如果完全遵循理查·史托曼（RMS）那套嚴苛的定義，那麼我們手頭上這台搭載驍龍晶片的裝置，從通電那一刻起就已經是「不自由」的。那些封裝在 &lt;code&gt;/lib/firmware&lt;/code&gt; 路徑下的二進位檔，就像是不可見的黑箱，操控著原本應該屬於我的硬體。但我始終認為，自由軟體的目的應該是賦能於人，而不是限制人的使用。&amp;lt;/br&amp;gt;
我不反對爲了自由，而把裝置從韌體到軟體，全部改用自由軟體的做法。但是這樣做顯然會有後果：妳無法使用包括 GPU，網路卡，數據機在內的硬體。因爲幾乎所有的裝置都需要韌體工作，而這些韌體幾乎都是專有軟體，很少裝置支援三方自由韌體。這種現象在高通平臺更常見，ADSP，CDSP，Modem 這些遠端處理器全都需要韌體才能正常工作！如果為了追求純粹的自由而拔掉無線網路卡的韌體，導致我必須拖著一根 RJ45 網線才能在咖啡廳發電子郵件；或者為了拒絕專有驅動而關閉 GPU 加速，讓我的桌面環境流暢度退化到像是在翻閱投影片，那這種「自由」更像是一種苦難。&amp;lt;/br&amp;gt;
我自己是非常堅持自由軟體的人啦...但我的「堅持」是要求我的裝置底層的硬體，半數以上可以工作，如果無法工作的話至少不會影響我的裝置使用。我接受那些為了啟動硬體而必須存在的 Blob，但我絕不接受在作業系統層面被廠商的私有軟體綁架。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
當我能在驍龍裝置上跑起自己編譯的核心，並配合 Arch Linux 這種高度自定義的發行版時，我已經實現了 90% 的數位主權。我可以決定系統如何調度核心、如何管理記憶體、如何過濾網路流量，而不是忍受廠商預裝軟體中潛藏的追蹤器，必須強迫簽下「最終使用者許可協定」。雖然 ADSP 和 CDSP 依然運行著那些看不懂的專有韌體，但只要牠們能乖乖聽從核心的調度，為我的音訊處理或異構計算提供動力，而不會越權干涉我的主系統，這就是一種可以接受的平衡。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
務實地使用自由軟體，本質上是一種技術上的長征。我們在專有韌體的荒漠中，利用主線核心與開源工具開闢出一片綠洲。這並不可恥，反而是開發者在面對硬體巨頭壟斷時，所能展現出的韌性。&amp;lt;/br&amp;gt;
與其執著於那些無法工作的硬體，不如把精力放在如何優化現有的開源驅動，或者是像開發者們那樣，逆向出更好的 UEFI 實現。當我們能在確保日常使用的前提下，一點一滴地用自由軟體取代原本的專有元件，這台裝置才真正開始屬於牠的使用者，而不是牠的製造商。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;畢竟，最好的裝置，永遠是那個妳真正了解牠每一行配置、並且能隨心所欲地進行 tweak 的那一台。&lt;/p&gt;
</content:encoded></item><item><title>Lenovo Yoga Air 14S （或者 Slim 7x）筆電的溫控，超頻和省電策略</title><link>https://blog.cloudflare88.eu.org/posts/snaptop-thermal-cpu-frequency-and-powersaving/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/snaptop-thermal-cpu-frequency-and-powersaving/</guid><description>事實證明，研究 Linux on Everything 的樂趣遠比 Windows on ARM 的樂趣要豐富不少。或許會對我完善 SM8750 MTP Armbian 的移植和研究嵌入式系統有幫助。</description><pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;聯想 Yoga Slim 7x 筆電採用驍龍 X Elite 晶片，相容 Arm V9 指令集，4nm製程。爲12核心，採用經典的 Big.Little 大小核心設計，最高時脈爲 4.2GHz，提供42MB的L2快取。GPU 則是 Adreno X1 繪圖卡，外掛 Quectel NCM825A PCIe 無線網路卡，這個網路卡在主線核心下似乎不穩定，但是經過更換韌體後可以&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/fix-broken-wifi-card-on-laptop/&quot;&gt;改善問題&lt;/a&gt;。&amp;lt;/br&amp;gt;
記憶體是 32GB LPDDR 5x SDRAM。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
和我曾經用過的 Apple MacBook Air 相比（不是講好了不宣傳 Apple 產品嗎），這晶片的最高能耗爲80W，一般使用時也有26W。屬於比較耗電的晶片（M1 晶片最高才20W功耗，平日使用也只有18W），當然效能也要比 M1 好上不少。在執行編譯 Linux 核心或者其他程式時，筆電的風扇會全速運轉， CPU 的溫度發熱到91度。平時運作下晶片的溫度則維持在40~50度，無需風扇，僅靠被動散熱就可以。相比其他筆電，Yoga Slim 7x 的 Linux 表現非常「安靜」，是個不錯的日用筆電。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
但是主線 Linux 的電源管理似乎依舊有些問題（例如不能像 Apple Silicon 晶片的筆電或者 PineBook 筆電一樣可以待機），導致待機時依舊會出現電力損耗嚴重的問題。雖然可以通過改用 &lt;code&gt;scmi-cpufreq&lt;/code&gt; 調度器軟體（後來發現適用於絕大多數CPU的 &lt;code&gt;cpufreq-dt&lt;/code&gt; 通用調度器似乎在我的筆電上不起作用）和降低熒幕亮度來改善，但是效果依舊不理想。導致筆電最多只能使用8小時就要充電一次，而不像 Mac 那樣充一次電就可以用好幾天甚至一週。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
因此，下面來研究驍龍筆電省電的策略。&lt;/p&gt;
&lt;h1&gt;Yoga Slim 7x 的省電策略&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;目前 Yoga Slim 7x 的 Linux 發行版以 Ubuntu 和 Fedora 支援較爲最佳。他們普遍採用 GNOME 爲默認桌面環境，系統設定中有設定閒置後多久關閉熒幕和待機（Suspend）的選項，但是待機顯然是無法工作的，執行 &lt;code&gt;systemctl suspend&lt;/code&gt;後，熒幕雖然熄滅，但是電腦依然是運行狀態，通過 &lt;code&gt;dmesg&lt;/code&gt;看到，在執行待機命令後，馬上就「醒」了：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
[ 6178.014499] PM: suspend entry (deep)
[ 6178.097356] printk: Suspending console(s) (use no_console_suspend to debug)
[ 6178.123669] vhci_hcd vhci_hcd.0: suspend vhci_hcd
[ 6179.306822] PM: suspend exit
[ 6179.306911] PM: suspend entry (s2idle)
[ 6179.326507] printk: Suspending console(s) (use no_console_suspend to debug)
[ 6179.350392] vhci_hcd vhci_hcd.0: suspend vhci_hcd
[ 6180.575369] PM: suspend exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;雖然關閉熒幕有一定效果，但是依舊不夠省電。通過 &lt;code&gt;powertop&lt;/code&gt; 檢視最耗電的系統元件，發現 Wi-Fi 網路卡和 ADSP，CDSP是最耗電的，其次是熒幕，可能因爲筆電採用OLED熒幕，而不是常見的IPS LCD，亮度更高，所以更耗電(?)&amp;lt;/br&amp;gt;
2. 爲此，就需要安裝 PostmarketOS 提供的 「Tweaks」 APP（如果妳的發行版沒有打包，自己下載編譯），設定「Automatic suspend」的排程，設定使用電和充電時閒置多久就進入待機，該機制觸發後就會將筆電的排程改爲「Suspend」，Wi-Fi 和數據機（後者在CRD原型機上有內建）會停止，來節省電力，也可以降低筆電溫度。有些發行版會讓音樂服務依舊執行，也可以保證在待機時接到電話（雖然用筆電打電話比較蠢就是了），不過鬧鐘或計時器之類的應用可能會暫停。此時就需要修改桌面圖示檔，改用 &lt;code&gt;gnome-session-inhibit&lt;/code&gt; 來執行應用，例如打開時鐘應用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gnome-session-inhibit --inhibit suspend gnome-clock
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;給筆電 GPU 超頻（未成功）&lt;/h1&gt;
&lt;p&gt;雖然驍龍 X Elite 明確不支援超頻，但是常見的零售筆電上晶片的最大時脈是被降低的。因此就需要超頻，來獲得與原型機一致甚至超過原型機的效能。超頻/降頻都需要編譯自定核心，並修改設備樹原始碼。其中 GPU 可以超頻。&lt;/p&gt;
&lt;p&gt;:::note[有趣的迷因圖]
當妳覺得驍龍 X Elite 零售筆電的 CPU，GPU 時脈不能滿足妳的需要而過度超頻時，妳的筆電:
&amp;lt;img src=&quot;/assets/ehentai/huh.png&quot; width=&quot;65%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(啊...哈啊...要去了!...)&lt;/em&gt;
:::&lt;/p&gt;
&lt;p&gt;:::warning
超頻/降頻不受 Lenovo 官方支援，且可能會導致硬體損壞或執行不穩定，並且會導致保固丟失！
:::&lt;/p&gt;
&lt;p&gt;關於修改設備樹部分可以參考 Danct12 的&lt;a href=&quot;https://danct12.github.io/posts/2021-08-09-pinephone-cpu-overclocking/&quot;&gt;給 PinePhone CPU 超頻/降頻&lt;/a&gt;文章。下面是我修改設備樹原始碼的方法（經過測試沒有成功）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在主線核心原始碼中，找到 &lt;code&gt;arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts&lt;/code&gt; 檔案，這是筆電的設備樹原始碼，通過檢視檔案，發現引用了 &lt;code&gt;hamoa.dtsi&lt;/code&gt; 這一晶片設備樹原始碼[^1]:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/

/dts-v1/;

#include &amp;lt;dt-bindings/gpio/gpio.h&amp;gt;
#include &amp;lt;dt-bindings/input/gpio-keys.h&amp;gt;
#include &amp;lt;dt-bindings/phy/phy.h&amp;gt;
#include &amp;lt;dt-bindings/regulator/qcom,rpmh-regulator.h&amp;gt;

#include &quot;hamoa.dtsi&quot;
#include &quot;hamoa-pmics.dtsi&quot;

/ {
   model = &quot;Lenovo Yoga Slim 7x&quot;;
   compatible = &quot;lenovo,yoga-slim7x&quot;, &quot;qcom,x1e80100&quot;;

   aliases {
   	serial0 = &amp;amp;uart21;
   	serial1 = &amp;amp;uart14;
   };

   chosen {
   	stdout-path = &quot;serial0:115200n8&quot;;
   };
   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;檢視 &lt;code&gt;hamoa.dtsi&lt;/code&gt; 原始碼，檢索 &lt;code&gt;gpu&lt;/code&gt; 段，這是關於GPU核心的定義：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;gpu: gpu@3d00000 {
   		compatible = &quot;qcom,adreno-43050c01&quot;, &quot;qcom,adreno&quot;;
   		reg = &amp;lt;0x0 0x03d00000 0x0 0x40000&amp;gt;,
   		      &amp;lt;0x0 0x03d9e000 0x0 0x1000&amp;gt;,
   		      &amp;lt;0x0 0x03d61000 0x0 0x800&amp;gt;;

   		reg-names = &quot;kgsl_3d0_reg_memory&quot;,
   			    &quot;cx_mem&quot;,
   			    &quot;cx_dbgc&quot;;

   		interrupts = &amp;lt;GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH&amp;gt;;

   		iommus = &amp;lt;&amp;amp;adreno_smmu 0 0x0&amp;gt;,
   			 &amp;lt;&amp;amp;adreno_smmu 1 0x0&amp;gt;;

   		operating-points-v2 = &amp;lt;&amp;amp;gpu_opp_table&amp;gt;;
   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;檢索 &lt;code&gt;gpu_opp_table&lt;/code&gt; 段，這是GPU的時脈表。目前GPU的最大時脈爲1.5GHz，可以根據硬體情況增加新的頻率，修改爲2.0GHz或者更高（但需要注意供電問題）：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;opp-2000000000 {
   				opp-hz = /bits/ 64 &amp;lt;2000000000&amp;gt;;
   				opp-level = &amp;lt;RPMH_REGULATOR_LEVEL_TURBO_L5&amp;gt;;
   				opp-peak-kBps = &amp;lt;16500000&amp;gt;;
   				qcom,opp-acd-level = &amp;lt;0xa82a5ffd&amp;gt;;
   				opp-supported-hw = &amp;lt;0x03&amp;gt;;
   			};

opp-1500000000 {
   				opp-hz = /bits/ 64 &amp;lt;1500000000&amp;gt;;
   				opp-level = &amp;lt;RPMH_REGULATOR_LEVEL_TURBO_L5&amp;gt;;
   				opp-peak-kBps = &amp;lt;16500000&amp;gt;;
   				qcom,opp-acd-level = &amp;lt;0xa82a5ffd&amp;gt;;
   				opp-supported-hw = &amp;lt;0x03&amp;gt;;
   			};

   ...
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;CPU 部分，因爲頻率調整是由系統控制處理器 (CPUCP) 透過 SCMI 協定來管理的 。Linux 核心並不直接控制硬體暫存器來升壓或升頻，而是向韌體發送請求。因此超頻可能比較困難，必要時可使用 &lt;code&gt;cpupower frequency-set&lt;/code&gt; 指令來調整 CPU 頻率。&lt;/li&gt;
&lt;li&gt;之後，編譯，安裝核心，通過 &lt;code&gt;cat /sys/class/devfreq/3d00000.gpu/available_frequencies&lt;/code&gt; 來檢視可用時脈：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cat /sys/class/devfreq/3d00000.gpu/available_frequencies 
300000000 390000000 550000000 687000000 744000000 800000000 925000000 1000000000 1100000000 1175000000 1250000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後就可以通過 &lt;code&gt;echo &quot;userspace&quot; | sudo tee /sys/class/devfreq/3d000000.gpu/governor &amp;amp;&amp;amp; sudo echo &quot;frequency-number&quot; &amp;gt; /sys/class/devfreq/3d00000.gpu/cur_freq&lt;/code&gt; 來調整 GPU 的時脈。&lt;/p&gt;
&lt;h1&gt;調整溫控策略&lt;/h1&gt;
&lt;p&gt;Yoga Slim 7x 筆電的溫控可以通過軟體調整，調整不當可能會導致硬體損壞。[^2] &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;檢視目前 CPU 溫度：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt; cat /sys/class/thermal/thermal_zone0/temp
44100
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;檢視目前的溫控策略，會顯示2個等級：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;grep . /sys/class/thermal/thermal_zone0/trip_point_*_temp
/sys/class/thermal/thermal_zone0/trip_point_0_temp:90000
/sys/class/thermal/thermal_zone0/trip_point_1_temp:115000
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;檢視溫控等級，分爲「Hot」 「Critical」二個等級：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt; grep . /sys/class/thermal/thermal_zone0/trip_point_*_type
/sys/class/thermal/thermal_zone0/trip_point_0_type:hot
/sys/class/thermal/thermal_zone0/trip_point_1_type:critical
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;修改溫控溫度，只需要使用 &lt;code&gt;echo&lt;/code&gt; 命令鍵入數字修改對應的檔案即可。（重開機後失效）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;echo 40000  &amp;gt; /sys/class/thermal/thermal_zone0/trip_point_0_temp
echo 100000 &amp;gt; /sys/class/thermal/thermal_zone0/trip_point_1_temp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[^1]:&lt;a href=&quot;https://gitlab.com/Linaro/arm64-laptops/linux/-/blob/qcom-laptops/arch/arm64/boot/dts/qcom/hamoa.dtsi&quot;&gt;hamoa.dtsi - qcom-laptops Linaro GitLab&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^2]:&lt;a href=&quot;https://ivonblog.com/posts/pinephone-thermal/&quot;&gt;PinePhone 的超頻，省電，溫控策略 - Ivon&apos;s Blog&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>黑蘋果即將步入尾聲，很好。使用 macOS 本身就是推廣專有軟體的行爲</title><link>https://blog.cloudflare88.eu.org/posts/the-end-of-hackintosh-era/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/the-end-of-hackintosh-era/</guid><description>6F 75 72 68 61 72 64 77 6F 72 6B 62 79 74 68 65 73 65 77 6F 72 64 73 67 75 61 72 64 65 64 70 6C 65 61 73 65 64 6F 6E 74 73 74 65 61 6C 28 63 29 61 70 70 6C 65 63 6F 6D 70 75 74 65 72 69 6E 63</description><pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;爲什麼要使用「黑蘋果」？或者講，爲什麼要使用 macOS 呢？&amp;lt;/br&amp;gt;
這個世界總是那麼奇怪。人們對微軟的 Windows 作業系統所施加的種種流氓行爲怨聲載道，甚至拒用 Windows 系統。對於現今的 Google 所推出的 Android 限制應用程式安裝的規定也紛紛「聯合抵制」，還有人爲此致電政府，呼籲國家部門關注此事並且採取措施。&amp;lt;/br&amp;gt;
但是，一旦作業系統或者裝置的製造廠家是 Apple，許多人反而變成了「沈默的思想者」，似乎都不再抵制了。史托曼曾經說過，iPhone 和 MacBook 是「監獄」，使用者卻心甘情願的接受來自 Apple 的牢籠，還稱之爲「時尚」，以自居「果粉」爲榮，宣揚&lt;a href=&quot;https://zh.wikipedia.org/zh-tw/%E5%95%86%E5%93%81%E6%8B%9C%E7%89%A9%E6%95%99&quot;&gt;商品拜物教&lt;/a&gt;。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
一般人被史蒂夫·賈伯斯（或者是現在的蒂姆·庫克）的話術說服，覺得iPhone，MacBook 很時尚很潮流，頗有極客風範。于是大家都不由自主地跑到 Apple store 去講：「請給我帶上手銬吧！」「工程師認爲 UNIX-based 的系統非常方便，所以犧牲自由和隱私是沒關係的，也給我一份手銬吧！」「妳看我的手銬上還有我的名字呢！」每次我看到不少人都在推薦 Mac 時，我都會不由自主地想這些人是否是受虐狂，喜歡被束縛住手腳，然後把自己本該擁有的權利視爲「主人的恩賜」？這簡直和我喜歡看的H漫畫不謀而合！&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
膜拜 Apple 的硬體就算了，甚至連作業系統這個「工具」都要去膜拜...爲了在普通電腦甚至一些嵌入式裝置安裝 macOS 而建立的 &lt;a href=&quot;https://zh.wikipedia.org/zh-tw/Hackintosh&quot;&gt;Hackintosh 社區&lt;/a&gt;就是一個典型的例子。&amp;lt;/br&amp;gt;
當然，也不能講的如此刻板。畢竟黑蘋果社群裏也有一些開發者，他們研究 macOS 的組成，開發出不少 kext，讓大量非 Apple 官方認可甚至不被支援的硬體跑起來，亦有人開發 Clover 和 OpenCore 開機載入器用於研究 macOS 的機理。開發者們貢獻良多，沒準哪一天還真的可能會協助開源社群逆向出完全自由的 macOS 出來呢，例如 &lt;a href=&quot;https://github.com/ravynsoft/ravynos&quot;&gt;ravynOS&lt;/a&gt;就是採用 FreeBSD 爲基礎，混合 Darwin 核心所開發的相容 macOS 的作業系統，有點像 ReactOS 與 Windows 的關係。某種程度而言，黑蘋果社群就是推廣專有軟體和
自由軟體的結合體。不過堅定應援專有軟體的內容佔了大多數。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
2020年，Apple 開始往 ARM 架構遷移，就像他們在十幾年前，從 PowerPC 遷移至 Intel X86 那樣，逐步放棄支援 X86 架構的電腦和裝置。且根據 &lt;a href=&quot;https://www.pcmag.com/news/apple-confirms-end-of-support-for-intel-macs-after-macos-tahoe&quot;&gt;Apple 和其牠媒體的報道&lt;/a&gt; 來看，macOS 26 應該是最後支援 X86 晶片的版本，之後的普通 X86 電腦就沒法玩黑蘋果了，黑蘋果已經死透，至少妳沒有辦法安裝最新版的 macOS 了。雖然可以安裝舊版，但是主流軟體也會慢慢捨棄支援的。現階段開源社群逆向 Apple Silicon 平臺的成果，除了能夠跑 Asahi Linux，或者使用修改的 &lt;code&gt;m1n1&lt;/code&gt; 來載入 UEFI 韌體&lt;a href=&quot;https://github.com/AppleWOA&quot;&gt;引導 Windows 作業系統&lt;/a&gt;（或者其牠支援 ACPI 的作業系統）。目前還沒有可以把 macOS 執行在 ARM 裝置上。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;當然，Windows 比起 macOS 也好不到哪去。至少，這樣可以讓人徹底斷掉 Hackintosh 的念頭，20年以來，除去探究機理和開發 kext 的，黑蘋果本身就是給大公司當「舔穴者(bootlicker)」的行爲。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;給各位講一個大多數人都知道的黑蘋果冷知識，這篇文章簡介中和下面的金鑰用於在開機載入時解開 OS Key（系統金鑰鏈），如果解開過程失敗，就會直接 kernel panic，完全不讓用:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ÐÊÍ×ÞÍÛÈÐÍÔÝÆË×ÚÌÚÈÐÍÛÌØÊÞÍÛÚÛÏÓÚÞÌÚÛÐÑËÌËÚÞÓÜÞÏÏÓÚÜÐÒÏÊËÚÍÖÑÜ&amp;lt;/br&amp;gt;
上面的金鑰可以解密出下列文字：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;½ÓÙÖÏÅÖÑÅÇÌÉÇÏÊÓÖØÓÈÅÝn¸ÌÉÖÉÓÒÇÉÛÅ×ÛÅ×ÅÙ×ÉÖØÌÅØÛÌÍÒÉÈnÌÍ×ÉÜÍ×ØÍÒË³·ÛÅ××ÓÆÐÍÒÈnÌÉÈÈÓÆÉØØÉÖØÓÔÍÖÅØÉnÅÒ³·ØÌÅØÖÅÒËÖÉÅØnÆÙØÊÓÙÒÈÌÍ×ÌÅÖÈÛÅÖÉÈÉÇÐÍÒÉÈn´ÐÉÅ×ÉÈÓÒØ×ØÉÅÐ±ÅÇ³·n¶ÉÅÐÐÝØÌÅØ×ÛÅÝÙÒÇÓÓÐn§¥ÔÔÐÉ§ÓÑÔÙØÉÖ­ÒÇ&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;沒錯，就是著名的 &lt;a href=&quot;https://theapplewiki.com/wiki/Dont_Steal_Mac_OS.kext&quot;&gt;Don&apos;t steal Mac OS.kext&lt;/a&gt;。看看他們對自家軟體的智慧產權保護的多好呀！在非 Apple 認證的韌體執行 macOS 可是盜竊行爲呢，然後妳竟然會去應援這家公司的作業系統？！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;然後我再來講使用者的心態，靠着破解大公司的商業軟體來滿足自己的虛榮心。macOS 是閉源軟體，更是間諜軟體。牠雖然很優秀，但請不要忘記
macOS 是竊取了 BSD 30年來革命果實的邪惡力量。這也怪 BSD，誰叫妳們不用更具有法律效益的 GPL，反而要使用&lt;a href=&quot;https://lukesmith.xyz/articles/why-i-use-the-gpl-and-not-cuck-licenses/&quot;&gt;商業軟體友好，不講究開放原始碼和回饋上游的 BSD 協議&lt;/a&gt;呢...&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
套用《逆統戰》遊戲中的一句話：「娘係匹！BSD太過商業友好，看來我GPL協議必須出山！」&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
macOS，使用者的自由處處受到 Apple 控制，除了軟體只能從 App store 下載之外，想要體驗到純正 UNIX 風的自由軟體，就只能藉助 Homebrew 這種殘廢套件管理員，或者是使用 macPorts 編譯老舊的軟體。還要忍受着 Apple 的「計劃性報廢」，時間到了就無法升級，哪怕硬體效能依舊。而 Apple 會說：「對不起，我們已經儘力支援很長一段時日了」...&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
此時有的使用者會跳出來講：「macOS的設計美學非常不錯」，如果只是喜歡 macOS 的設計語言，爲什麼不使用 Linux 或者 FreeBSD，安裝 KDE / GNOME 桌面。使用 macOS 主題就可以，還可以還原80%的使用體驗？非要去安裝 Hackintosh，心甘情願的把自己關進「監獄」，實在匪夷所思，難以理解。有這些時間不如去研究如何在ESP32 單板機上移植 FreeBSD 或者去改善 SM8750 原型機的 Linux 核心支援。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
退一步講，即使要因爲工作或是學業要使用專有軟體，改用 Windows 不是比黑蘋果更好嗎？儘管 Windows 也是間諜軟體，至少還會給使用者基本的選擇自由，而非從頭到腳都被牢牢掌控。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;那麼，應該做什麼？&lt;/h1&gt;
&lt;p&gt;「&lt;strong&gt;我們應該做的，是多研究怎麼樣在不自由的硬體上安裝 Linux，盡自身最大努力去逆向硬體驅動，研究機理，移植符合業界標準的開機載入器，從而達到解放本就屬於妳的裝置的目的，而不是散播甚至應援專有軟體和間諜軟體。&lt;/strong&gt;」&amp;lt;/br&amp;gt;
就算 macOS 是 UNIX 也不要推薦。現在的 macOS 早就失去1980年代的駭客精神了。因此，移植 macOS 和 Windows on ARM 遠不如 Linux on everything 有價值（把 Linux 改造成 Android 那樣的「圍牆花園」則不算）。至於 MacBook 和 iPhone 是監獄，使用者心甘情願的給自己帶上手銬，還蔚然成風，以「果粉」而自豪。&lt;/p&gt;
&lt;h1&gt;當衆人都在爲個人電腦先驅者、最優秀的企業締造者的殞落而悲傷時，只有一個與衆不同的聲音大聲的喊道：「死的好！」&lt;/h1&gt;
&lt;p&gt;這個人就是理查·史托曼。2011年，Apple 的 CEO 史蒂夫·賈伯斯逝世，各界紛紛發文哀悼。可是自由軟體基金會主席史托曼卻說：「&lt;a href=&quot;https://stallman.org/archives/2011-jul-oct.html#06_October_2011_%28Steve_Jobs%29&quot;&gt;死的好&lt;/a&gt;。」&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;史蒂夫·賈伯斯，那位專門為笨蛋用戶製造酷炫監獄，剝奪人們自由的個人電腦先驅者，死了。...我並不為他的死而高興，但我很高興他走了。...沒有人是活該去死的...即使他犯下的惡果幾輩子也還不完。但是我們終究都會被賈伯斯對個人電腦的惡劣設計所影響。&amp;lt;/br&amp;gt;
——節選自他的個人部落格&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apple產品借用了一部分BSD開源專案的成果，卻把系統變成不自由的軟體。這可以說是「自由軟體之敵」，Apple公司並不比Microsoft善良，所以理查·史托曼會這麼討厭Apple也就不奇怪了。他是對自己的信念堅持到底的一個人物。[^1]&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Apple公司對用戶的控制，有增無減，所謂的Apple生態系，實則是將用戶困入更深的牢籠中無法脫身。&lt;/p&gt;
&lt;p&gt;如果妳本身就有相對自由的硬體（X86不錯，ARM更好，RISC-V更棒），而且還有自由的Linux與BSD作業系統可選，爲什麼一定要去應援專有軟體，把自己關進專有軟體鑄成的監獄？&lt;/p&gt;
&lt;p&gt;[^1]:&lt;a href=&quot;https://ivonblog.com/posts/i-am-glad-hackintosh-is-dead/&quot;&gt;I&apos;m glad since Hackintosh is coming to the end -- Ivon&apos;s Blog&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Reflections on 7 Years of Learning Linux -- Why I Persist with Linux, OpenBSD, and Free Software</title><link>https://blog.cloudflare88.eu.org/posts/en/what-i-have-learned-from-my-7-year-linux-journey/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/what-i-have-learned-from-my-7-year-linux-journey/</guid><description>Somethings we lose, something for shooting, broken codes in the dark.</description><pubDate>Wed, 08 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;
Please listen to the music below while reading this article for a better experience:&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/xzhAOVbGrUs?si=9XvqCgimGi_uOqES&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Porter%20Robinson%20-%20Look%20at%20the%20Sky%20(loophoof,%20NLS%20and%20Proto_ssin%20Remix_Cover)%20ft.%20hittcell%20-%20PR%CE%9BDA%20_%20_ssynae.ogg&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&quot;저는 리뉴스(Linux)를 공부하는 좋아합니다.&quot; Unlike most people in Computer Engineering, my decision to learn Linux wasn&apos;t forced upon me by a school curriculum. On the contrary, I proactively stepped into the realm of Linux, BSD, and Free Software issues because I advocate for Free Software and the GNU philosophy, and my major is related to networking.&amp;lt;/br&amp;gt;
I have never considered myself to have &quot;mastered&quot; Linux. Especially regarding servers, my grasp isn&apos;t deep enough yet—after all, it&apos;s difficult to justify placing true server hardware at home, given the unbearable noise and energy consumption. Currently, I use Linux as my primary daily driver for web browsing, word processing, and graphic design. On rare occasions, I play games (Minecraft), and I also develop simple programs in C. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
For instance, just last week, I designed a &lt;a href=&quot;https://github.com/Android-Piepaint/Dumb-POS-display-clock-monitor&quot;&gt;program for the seven-segment display on a POS machine from an unknown manufacturer to show system time, average CPU clock speed, and memory usage&lt;/a&gt;. Reverse-engineering the display protocol alone took me half an hour.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
The advantage of learning Linux is discovering many open-source solutions (such as self-hosting Nextcloud cloud storage or using Docker for a self-hosted Android cloud phone). Many of these programs are cross-platform and can replace various commercial counterparts. Of course, I am speaking from my own daily usage; many solutions do not adhere to industry standards and may not even be acceptable to everyone.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Unlike the way most people learn Linux, my approach has been quite &quot;fragmented.&quot; Relevant knowledge points were acquired through web searches, browsing subreddits, and following related courses on YouTube. In recent years, I also discovered the &quot;CoolApk&quot; forum in Mainland China, finding many &quot;ingenious but seemingly useless techniques&quot; there. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Knowledge was completed bit by bit. Only recently did I learn that even Chinese input methods have multiple frameworks to choose from. To deepen my understanding, I began reading NiaoGe&apos;s Linux Private Kitchen(鳥哥的 Linux 私房菜) and &lt;a href=&quot;https://github.com/cc-books/testnotes&quot;&gt;Running Linux on Computers: Hardware Testing Notes(電腦上試跑 Linux：硬體測試筆記)&lt;/a&gt;. Only then did I understand what it feels like to learn progressively. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Both books have electronic versions, which is convenient; I can start learning anywhere with just a tablet or laptop. To further my understanding, I specifically subscribed to YouTube courses related to operating systems and embedded OS porting. Although the videos are in English without subtitles, my passion for Linux and Free Software, combined with a serviceable level of English, allowed me to learn many new things. I even convinced my family to buy various prototype machines and single-board computers for experimentation, costing quite a bit, yet they never criticized me (and I understand how hard they work for that money).&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
As for why I learn embedded OS porting? Because it doesn&apos;t require math! &lt;code&gt;:P&lt;/code&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chronicles&lt;/h1&gt;
&lt;p&gt;In reality, the time I have spent truly using Linux and *BSD totals only six and a half years; everything before that was merely a &quot;transition period.&quot;&lt;/p&gt;
&lt;h2&gt;2018: The Prologue&lt;/h2&gt;
&lt;p&gt;My earliest contact was with Android X86 9.0 (obviously, Android is not a GNU/Linux distribution, but it uses a modified Linux kernel). I sought an alternative because 64-bit Windows 10 was a bit sluggish on a desktop with 4GB of RAM.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
After using it, although performance improved, the G2020 CPU was an X86 architecture, and very few common mobile apps could actually open on the computer. Although I later enabled compatibility programs and could download more apps from Google Play, it could only execute 32-bit ARM programs. It was fundamentally unusable for daily life, so I eventually re-installed Chrome OS. However, the motherboard&apos;s integrated graphics weren&apos;t powerful enough, so running Android apps was always laggy.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Consequently, I didn&apos;t use it much afterwards, but it was my first encounter with an operating system modified from the Linux kernel—it was the beginning of everything. My phone&apos;s gallery still has photos of that desktop.&lt;/p&gt;
&lt;h2&gt;2019: Encountering macOS, The Eve of the Linux &quot;Era&quot;&lt;/h2&gt;
&lt;p&gt;After a period of silence, a classmate I knew whose family used a MacBook enthusiastically told me about macOS. It was the first time I saw an operating system with such a modern UI and such a refined laptop. It was also my first contact with a commercial UNIX operating system using the Mach-O microkernel outside of Android, Chrome OS, and Windows. But I could hardly convince my family to buy a MacBook costing thousands! So, I made do with virtual machines. My impression of MacBooks was limited to seeing one in an Apple Store in an underground mall in 2013; the &quot;Command&quot; key and its four-leaf clover icon left a deep memory. Because of this, it left a shadow even on the &quot;shoddy&quot; &quot;Creeper&quot; laptop I designed as a child (which was just cardboard boxes assembled into a laptop shape). Even today, fifteen years later, I still stare at the &quot;Command&quot; key on a MacBook.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Later, I learned about the &quot;Hackintosh&quot; (OSX86) project. After some searching and experimentation, I eventually installed macOS on the desktop. I was using macOS 10.15.6 at the time, but I found it wasn&apos;t as smooth as a real Mac. Perhaps it wasn&apos;t the G2020 CPU itself, but rather that the integrated Intel HD Graphics 2500 had no macOS drivers, forcing me to use software rendering. Even so, I persisted for a year before finally switching to Manjaro Linux. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
During this period, I learned to use virtual machines. I even went as far as creating an &lt;a href=&quot;https://github.com/Android-Piepaint/GIGABYTE-B460M-D2V-Hackintosh&quot;&gt;OpenCore configuration file for the motherboard&lt;/a&gt;. Under macOS, I also began learning basic UNIX commands (&lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, etc.), and learned to set up the &lt;code&gt;brew&lt;/code&gt; and &lt;code&gt;macports&lt;/code&gt; package managers, which served as a foundation for my later switch to Linux.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Android-Piepaint/GIGABYTE-B460M-D2V-Hackintosh&quot;}&lt;/p&gt;
&lt;h2&gt;2020: Fedora Takes the Stage, Manjaro Linux Dominates, The Linux Era Arrives&lt;/h2&gt;
&lt;p&gt;2020 was the year of the broadest exposure. My Asus K501E laptop was unable to upgrade to Windows 10 due to having only 2GB of RAM and a legacy BIOS firmware, leaving it stuck on the end-of-life Windows 7. I had no choice but to install Linux to keep using the laptop. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Perhaps out of a desire to be &quot;different,&quot; I didn&apos;t choose the common Ubuntu but instead used Fedora Linux for the latest software. Compared to the fan &quot;going full throttled&quot; under Windows, it was almost silent in Fedora, only spinning slightly and blowing out warm air when watching YouTube videos. I completed many &quot;firsts&quot; on that fifteen-year-old laptop: the first time using the &lt;code&gt;dnf&lt;/code&gt; package manager to install common software (Firefox, LibreOffice, Telegram...), the first time customizing GNOME and KDE Plasma desktops, and the first time compiling software... Naturally, as more &quot;firsts&quot; appeared, I unconsciously learned more command usages: using &lt;code&gt;ps -aux&lt;/code&gt; to view current processes, &lt;code&gt;free&lt;/code&gt; to check remaining memory space, &lt;code&gt;df -h&lt;/code&gt; to inspect disk partitions and capacity, and &lt;code&gt;dmesg&lt;/code&gt; to grab kernel logs. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Later, I switched to Manjaro Linux because, as a rolling release distribution, the software is always up-to-date—essentially, you can use the upstream code as soon as it&apos;s compiled. With the change in distribution, the package manager naturally changed too. Manjaro is the distribution I used the longest, from installing it on my laptop and desktop in May until switching to the upstream Arch Linux in March 2021.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
If you ask me what left the deepest impression about Manjaro, it would be its massive repositories. Besides the system&apos;s own repositories, you can use software from Flathub or Snap, and Appimage files are also available. What if the software or package you need isn&apos;t in those three? Manjaro is also compatible with the Arch Linux User Repository (AUR); you just need to search for the software on AUR to build and install it. Of course, installing packages from AUR requires manual intervention, as some need to be compiled from source.&amp;lt;/br&amp;gt;
The Manjaro experience served as the foundation for my later &quot;Distro hoppin’ &quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/homescreen.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2021: Migrating to Arch Linux, Becoming a Distro Hopper&lt;/h2&gt;
&lt;p&gt;After using Fedora and Manjaro, my excitement for Linux began to wane. So, I decided to try different distributions. Between March and August, I tried many: Qubes OS, which focuses on security through virtual machines; Gentoo Linux, which focuses on custom systems and improving computer performance; and Fedora Silverblue, an immutable &quot;stable distribution.&quot; Later, I became interested in Linux-powered smartphones like the PinePhone and began learning about Linux distributions designed for mobile devices, but since I didn&apos;t have a supported device at the time, I just poked around in QEMU...&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Later, I became interested in Arch Linux and installed it after downloading the image. Unlike most Linux distributions, the Arch Linux installation image has no graphical interface and no installation script. The entire installation process must be completed through commands. For someone used to graphical interfaces, seeing a TTY console with only black and white for the first time was very novel. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&quot;This is the most essential side of Linux; the once-familiar installation process has now become a test for you.&quot; Armed with the Arch Wiki installation guide, I began the process: partitioning the hard drive, mounting partitions, installing the base system, using &lt;code&gt;chroot&lt;/code&gt; to create users, configuring system files... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When the process ended and I saw the familiar TTY console appear after rebooting, the joy was already beyond words. It was incredible that I could feel a sense of accomplishment just for &quot;completing a Linux installation.&quot; As for usage, since I had previously used the Arch-based Manjaro, there was nothing particularly special. (The image below was not from that time, but from after migrating to the ARM architecture.)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/arch-linux-arm-hyfetch.png&quot; alt=&quot;Arch Linux ARM with GNOME desktop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;However, this time I gained a relatively comprehensive understanding of Linux installation mechanisms. Simultaneously, I learned to configure &lt;code&gt;swap&lt;/code&gt; and &lt;code&gt;zram&lt;/code&gt; to improve system memory and how to use GRUB and &lt;code&gt;systemd-boot&lt;/code&gt; to modify kernel boot parameters, which laid the groundwork for my attempts to port Linux to phones, tablets, and eventually prototype machines.&lt;/p&gt;
&lt;h2&gt;2022: Migrating to 64-bit ARM Architecture, Starting the Embedded Journey; Fully Embracing Free Software Starts Now&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;See also: &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/my-5-years-arm64-architecture-journey/&quot;&gt;My 5-Year ARM64 Architecture Journey&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2022 was the most important year in my Linux learning history. Due to long-term learning via YouTube courses, my horizons expanded. Out of a desire to be &quot;different,&quot; I came into contact with FreeBSD and OpenBSD. Unlike Linux, which was originally designed as a &quot;POSIX-compliant UNIX clone,&quot; the BSD series of operating systems carries ancient UNIX blood—the giant that ruled computers for 30 years. UNIX design philosophy influenced many operating systems and an entire generation; even today&apos;s Windows mimics UNIX. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;In many ways, the configuration methods for BSD are even more primitive than Linux. The configuration documentation is also harder to understand. Fortunately, there are many tutorials online explaining how to configure FreeBSD, and by following FreeBSD&apos;s own documentation, I successfully installed graphics drivers and GNOME. The only unsolvable problem was that the PCIe Wi-Fi card I bought when installing macOS wasn&apos;t supported by FreeBSD, so I had to use wired networking instead.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Perhaps due to trying various operating systems and compiling programs, the seven-year-old 500GB HDD in my desktop began frequent power failures, reaction times increased noticeably, and the number of bad sectors grew. Although I later replaced it with an SSD, the dual-core G2020 CPU could no longer meet my needs. My demand for a new computer became increasingly urgent. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Finally, during a trip to a mall, I took the opportunity to suggest getting a new laptop to my family. To my surprise, everyone agreed, and we made an exception to buy a MacBook Air &quot;base model&quot; with 8GB of RAM and a 512GB hard drive. It just happened to coincide with Apple&apos;s release of its M1 ARM chip, so I naturally became a &quot;tester.&quot; After enjoying the brilliance of the Retina display, I soon learned about the Asahi Linux project, which ports the mainline kernel to Apple&apos;s M-series chips. I also installed Arch Linux Arm on my laptop to replace macOS for daily use and work, beginning my migration to Arm. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Around the same time, I also started researching &quot;embedded devices.&quot; Because my laptop used an ARM chip, I could treat it as a large &quot;single-board computer&quot; for porting purposes. Since all MacBook components are soldered to the motherboard and it provides a UART for debugging, it was the first embedded device I encountered. Asahi Linux uses &lt;code&gt;m1n1&lt;/code&gt; and U-Boot as the bootloaders to initiate Linux, which also led me to start learning about U-Boot, mastering simple commands to control computer booting. My learning direction was &lt;strong&gt;officially&lt;/strong&gt; set.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://blog.cloudflare88.eu.org/_astro/arch-linux-arm-hyfetch.DBcAQwei_ojA4k.webp&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
As the hardware environment migrated to Arm, the corresponding software had to migrate as well. Fortunately, most common software on Linux has an Arm version released, so the migration process was smooth. However, many commercial proprietary programs I used did not have an Arm release.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;At the time, solutions like &lt;code&gt;box64&lt;/code&gt; or &lt;code&gt;Fex-Emu&lt;/code&gt; , which can execute X86 applications with near-native performance, were not yet available. Thus, I began looking for open-source &quot;alternatives&quot;: using Inkscape instead of Sketch for graphic design, using Kdenlive instead of DaVinci Resolve for video production, and using Blender instead of SketchUp for 3D modeling. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
This also allowed me to experience the convenience of &quot;open-source software&quot;—as long as you have the source code, you can compile and install it yourself even if the developer hasn&apos;t released a file for your platform. For this, I learned about patching and using Git. With the source code public and viewable by everyone, developers couldn&apos;t hide any shady business. Perhaps it is because of this experience that most of the software I choose today is Free Software. Regarding devices, my choices are primarily based on the Arm and RISC-V architectures.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Furthermore, terms common in embedded Linux operating systems, such as &quot;Device Tree,&quot; &quot;page size,&quot; and &quot;Execute-in-Place (XIP),&quot; began to replace terms like &quot;ACPI,&quot; &quot;DSDT,&quot; &quot;BIOS,&quot; and &quot;Hyper-threading.&quot; I also shifted from &quot;general&quot; Linux system learning to the study of embedded devices and embedded OS porting. At this point, my learning direction was truly finalized.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
In August, I browsed the introduction to the Free Software Foundation (FSF) and also learned about the GNU philosophy. Combined with attending the FOSDEM 2022 developers&apos; meeting online, the concepts of &quot;Free Software,&quot; &quot;digital human rights,&quot; and &quot;privacy rights&quot; began to deeply influence my thinking. The GNU philosophy became the standard for my future writing, video releases, and daily document processing (even now, if someone asks for a text draft, I use the patent-free &lt;code&gt;.odt&lt;/code&gt; format to save and send it; whether the recipient can access it is not my concern).&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Free software means as a matter of liberty, not price. To understand the concept, you should think of &apos;free&apos; as in &apos;free speech,&apos; not as in &apos;free beer&apos;. More precisely, it means that the users have the freedom to run, copy, distribute, study, change and improve the software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because I have always identified with the FSF&apos;s philosophy—for privacy, for security, and most importantly, for freedom—I decided to fully switch to Linux. This means the operating systems on both my computer and phone must be Linux, and the software running on them must mostly be Free Software. Even computer peripherals (drawing tablets, network cards, etc.) must be Linux-friendly, proving that Linux isn&apos;t just for servers but can also be used as a desktop system.&amp;lt;/br&amp;gt;
To this day, fully Free Software accounts for 90% of the software installed on my computer. In my spare time, I also create small musical works related to Free Software, which are collected under the &lt;a href=&quot;https://blog.cloudflare88.eu.org/archive/category/Music/&quot;&gt;&quot;Music&quot; category of this blog&lt;/a&gt;.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;2023 – 2025: Linux on Mobile Devices (MIDs), The &quot;Snaptop&quot; Emerges&lt;/h2&gt;
&lt;p&gt;Initially, I wanted to add a few servers to my home, but after careful consideration, I gave up because it didn&apos;t suit my household conditions; keeping them running 24/7 would be a significant burden in terms of noise and electricity bills. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;I decided to use retired, out-of-season phones with Linux installed to serve as lightweight servers instead. After all, the performance of current Android phones has generally improved, making them suitable for running Docker container services. Since I already had experience with Linux, I bought a OnePlus 6T with good mainline kernel support, installed PostmarketOS, and set up containers to self-host a gallery service as an alternative to Google Photos, ran an Ad Blocker, and even briefly set up a Minecraft server for multiplayer games... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;In short, I set up everything commonly found on a server on a phone. Plus, they have built-in batteries, serving as a cheap UPS system; even a power outage wouldn&apos;t be a problem. Later, my SDM845 MTP prototype replaced my OnePlus 6T and was also used to host my blog, while the original OnePlus 6T became a &quot;backup phone.&quot; After inserting a SIM card, it even gave me a &quot;PinePhone-like&quot; experience. Later, I ported Arch Linux ARM to it, allowing me to enjoy the latest software. This is also the origin of the background on my blog&apos;s homepage.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://raw.githubusercontent.com/Android-Piepaint/android-piepaint.github.io/refs/heads/main/2b54d41dfed991fc2e27a7470612de8a.jpeg&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://blog.cloudflare88.eu.org/_astro/fajita-new.OUTmSxwb_ZIljEY.webp&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Naturally, for better performance, I later switched to a Nothing Phone 1. Its 12GB of RAM allows for more Docker containers, but this time the focus was more on daily use. The only problem was that the Snapdragon 778G CPU had poor mainline kernel support; for instance, the audio required manually patching every time I booted to work. Of course, I learned many things, such as patching firmware based on hardware nodes in the Device Tree and modifying kernel configuration files to enable Docker support... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Later, unsatisfied with Fedora on the MacBook, I began porting PostmarketOS to it, which has now been accepted upstream and entered the testing branch.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://blog.cloudflare88.eu.org/_astro/droidian-phosh.B02q2LJ5_ZfB7jG.webp&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;As for the arrival of the &quot;Snaptop,&quot; it could be called an &quot;accident.&quot; Due to a heavy rainstorm, my MacBook suffered water damage to the screen due to improper protection and had to be sent for repairs. While waiting, I needed a new laptop for daily use, and I didn&apos;t want to switch to any X86-based laptop because their performance is as weak as ever! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/yoga-vibe.png&quot; &amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
It just so happened that I remembered seeing a Lenovo Snaptop in a store earlier. To test the mainline kernel support for the Qualcomm Snapdragon X Elite chip, I once again convinced my family to buy one for me. Later, I conducted many experiments on this laptop, such as using &quot;Secure launch&quot; to run Linux in EL2 so I could use KVM virtual machines and other containers using KVM. Roughly a quarter of the content on this blog is about Snaptops.&lt;/p&gt;
&lt;h2&gt;2025 – Present: Becoming a Linux Porter, Growing Slowly&lt;/h2&gt;
&lt;p&gt;With deeper learning in embedded systems, ordinary Linux phones no longer satisfy my needs. Most phones supporting the mainline kernel are retail devices with hardware-based Secure Boot enabled, making firmware modification nearly impossible. Since the previous 845 prototype&apos;s battery became too old to continue using, I had to buy an 8750 MTP prototype (actually two; the other is used as a server to host my blog. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;If you look closely, you&apos;ll see &quot;Powered by QTI SM8750 MTP&quot; at the end of the site title) and began the porting of the mainline kernel and Armbian Linux. Fortunately, the mainline kernel has always had a Device Tree for the SM8750 MTP, and ALSA configuration files were also available for audio. However, the porting work remains difficult; porting the kernel alone took three months, just to solve a display issue. To escape Android&apos;s convoluted boot process (mainly because &lt;code&gt;boot&lt;/code&gt; images are hard to create), I switched to the common UEFI boot method found on PCs, using an EFI Framebuffer to temporarily resolve the display issue.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://blog.cloudflare88.eu.org/assets/mtp8750-front-view-2.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Fortunately, since the 835, Qualcomm has switched to UEFI firmware adhering to the &lt;a href=&quot;https://arm-software.github.io/ebbr/&quot;&gt;ARM EBBR standard&lt;/a&gt; on all chips (according to Qualcomm BSP documentation, it should be called &quot;Core Platform Boot,&quot; firmware based on Coreboot). Knowledge learned from UEFI firmware can be directly applied here. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Later, during the process of compiling the mainline kernel for the Nothing Phone 1, I realized that firmware must be placed in specific locations given in the Device Tree to load successfully. Using this simple method, I successfully patched the two remote processors, ADSP and CDSP, on the MTP prototype in the 7.0 mainline kernel. Later, I was surprised to find that the mainline kernel supports Type-C dual-role switching, meaning the Type-C Dock I bought specifically for my laptop finally came in handy.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/bds-menu.jpg&quot; width=&quot;80%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-bootlog.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;This was my first time successfully porting a Linux operating system to a relatively modern platform without the aid of any schematics or BSP references (Because I don&apos;t own any BSP codes). Although more than half of the hardware is non-functional, considering the scarcity of mainline kernel support for phones using the SM8750 chip and that most phones are supported even less than my prototype, I feel my progress has been somewhat rapid. I even went as far as posting a video on YouTube; although it has fewer than 2K views, it&apos;s clear that everyone likes &quot;developers&quot; who port Linux to devices...&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Here is the link to my video: &lt;em&gt;Look at the code, I&apos;m still here, and you&apos;ll be alive next year&lt;/em&gt; (the background music of my video is &quot;Look at the Sky&quot; by Porter Robinson)!&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Ecv3HICeK74?si=5m9OW-QJOP2zHKan&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;Every time the familiar Linux boot log flickers on the screen, those white characters flashing against a pure black background are, to me, not just the execution of code, but a form of &quot;breathing&quot; that transcends hardware lock-ins.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;In these past few months of day-and-night dialogue with the SM8750 prototype, I suddenly understood that the line &quot;I&apos;m still here&quot; in Porter Robinson&apos;s lyrics is actually the hardware&apos;s response to the developer. Those electronic parts locked by manufacturers, forgotten by the era, or viewed as &quot;early prototypes&quot; should have remained silent in a landfill, but because of our obsession with the mainline kernel, they have regained the right to breathe freely. As long as someone is still writing code, the vitality of this technology will continue into next year and beyond.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;This made me re-examine the theme I want to talk about next.&lt;/p&gt;
&lt;h1&gt;&quot;공부&quot; Means &quot;Kung Fu,&quot; and Also &quot;Learning&quot;&lt;/h1&gt;
&lt;p&gt;In Korean, one way to write &quot;learning&quot; is &quot;공부 (Gongbu),&quot; whose Hanja origin is exactly &quot;Kung Fu (功夫).&quot;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;I used to view porting Linux as a technical intuition, but this three-month process—just to solve a single screen issue—made me realize that true learning is, in fact, a kind of &quot;Kung Fu.&quot; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;It&apos;s not a fast-track cram school; it&apos;s like an old monk entering meditation or a craftsman sharpening a blade. It&apos;s the resilience ground out second by second amidst countless Kernel Panics and CrashDumps. When I push aside the wasted time that could have been spent in &quot;idle leisure&quot; to read books like &quot;NiaoGe&apos;s Linux Private Kitchen&quot; or &quot;Running Linux on Computers: Hardware Testing Notes,&quot; or search for articles on embedded devices, or spend hours on YouTube watching embedded OS porting and Linux-related course videos; or when I use the &quot;&lt;code&gt;make&lt;/code&gt;&quot; command to verify results while compiling programs or kernels, I am not just learning &quot;knowledge&quot; but practicing &quot;Kung Fu.&quot; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;This Kung Fu is simple to describe but difficult to master. The simplicity lies in merely making those cold chips &quot;come alive&quot; as described in the lyrics; the difficulty lies in often requiring months or even years of sweat. it requires developers to be able to endure loneliness and, in the midst of months or years of boredom, hold onto that glimmer representing the &quot;Free Software spirit&quot; and the &quot;GNU philosophy.&quot;&lt;/p&gt;
</content:encoded></item><item><title>學習 Linux 7年的心得，為什麼我一定要堅持使用 Linux，OpenBSD 以及自由軟體？</title><link>https://blog.cloudflare88.eu.org/posts/what-i-have-learned-from-my-7-year-linux-journey/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/what-i-have-learned-from-my-7-year-linux-journey/</guid><description>使用自由軟體，總是要失去什麼，也會得到什麼。</description><pubDate>Wed, 08 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;請配合下面影片閱讀本文，效果更好:&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/xzhAOVbGrUs?si=9XvqCgimGi_uOqES&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Porter%20Robinson%20-%20Look%20at%20the%20Sky%20(loophoof,%20NLS%20and%20Proto_ssin%20Remix_Cover)%20ft.%20hittcell%20-%20PR%CE%9BDA%20_%20_ssynae.ogg&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;「저는 리뉴스(Linux)를 공부하는 좋아합니다.」和大多數計算機工學的人不同，學習 Linux 並非是學校要我學，才不得已開始學習。相反，我是完全主動踏入 Linux，BSD 和自由軟體相關的議題的。因為我崇尚自由軟體和GNU哲學，而且我唸的是網路相關的科系。&amp;lt;/br&amp;gt;
我從來都沒有認為，我已經學會 Linux。尤其是伺服器方面，我的掌握還不夠深入，畢竟家裡沒有辦法真的擺一臺伺服器硬體在那裡，無論是噪聲還是能耗都無法忍受。現在我已經把 Linux 當作日常主力作業系統，用於瀏覽網路、文書處理、美工，在極少數情況下我也會玩遊戲（Minecraft），也會用C開發簡單的程式。比如上週剛剛為一臺不知名廠家生產的POS機上的七畫管設計了一個&lt;a href=&quot;https://github.com/Android-Piepaint/Dumb-POS-display-clock-monitor&quot;&gt;顯示系統時間、CPU平均時脈和記憶體使用情況的程式&lt;/a&gt;。光是逆向顯示協定就花了我半小時。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
學 Linux 的好處是瞭解了很多開源軟體方案（例如自架雲端硬碟 Nextcloud ，Docker 自架 Android 雲手機），這些軟體中，很多都是跨平臺的，可以取代很多同類型的商業軟體。當然我是講我自己日常使用的方面，有許多方案並不符合業界標準，甚至無法被所有人接受。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
和大多數人學習 Linux 的方式不同，我學習 Linux 的方式比較「碎片化」。有關的知識點都是經過網路檢索、翻看 Reddit 板塊、以及YouTube上相關的課程來獲取，近些年來還認識了中國大陸的「酷安」論壇，發現上面很多「奇技淫巧」。知識點都是一點一點補全的，最近才知道中文輸入法甚至也有好多框架可選。為了增進理解，我開始閱讀鳥哥的 Linux 私房菜和&lt;a href=&quot;https://github.com/cc-books/testnotes&quot;&gt;電腦上試跑 Linux：硬體測試筆記&lt;/a&gt;二本書，才知道循序漸進的學是怎樣的感覺。這兩本書都有電子版，所以比較方便，只要有平板電腦或者筆電，到哪裡都可以開始學習之路。為了增進了解，還特地在 YouTube 上訂閱了作業系統和嵌入式作業系統移植相關的課程，雖然影片都是英語，也沒有字幕。但是憑著對 Linux 和自由軟體的熱情，以及堪用的英文水平，也能學到一些新鮮事。還說服家人給我買各種原型機和單板機進行嘗試，花費不少臺幣，但是家裡人從來沒有指責過我（我也理解他們賺錢真的不容易）。&amp;lt;/br&amp;gt;
至於為什麼學習嵌入式作業系統移植，因為用不到數學! :P&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;「編年記」&lt;/h1&gt;
&lt;p&gt;實際上我真正使用 Linux 和 *BSD 的時間總共只有6年半，之前都只是「過渡期」而已。&lt;/p&gt;
&lt;h2&gt;2018年：序章&lt;/h2&gt;
&lt;p&gt;最早接觸的是 Android X86 9.0（顯然 Android 不是 GNU/Linux 發行版，但牠使用的是修改過的 Linux 核心），因為64位元的 Windows 10 在4GB記憶體的桌機上有點卡，所以尋求替代品。&amp;lt;/br&amp;gt;
用了之後，雖然效能得到了改善，但是 G2020 CPU 是 X86 架構，手機上常用的應用到了電腦上沒幾個能開的。雖然後期有開啟相容程式，用 Google Play 下載的應用也多了不少，只能執行32位元 ARM 程式。根本不能日常使用，隨後又裝回 Chrome OS 繼續使用。但是主機板的顯示晶片不夠力，所以運行 Android 程式總是卡卡的。&amp;lt;/br&amp;gt;
因此後面就不怎麼使用了，不過這是我初次接觸基於 Linux 核心修改的作業系統，是一切的開始。手機相簿裡到現在還有關於桌機的照片。&lt;/p&gt;
&lt;h2&gt;2019年：接觸 macOS，Linux 「時代」的前夜&lt;/h2&gt;
&lt;p&gt;在那之後沉寂了一段時日，後來我認識的同學家裡有用 MacBook，她便向我興致勃勃的講述關於 macOS 的事情。我第一次看到UI介面如此現代化的作業系統，和精緻的筆電，這也同時是我第一次接觸到 Android，Chrome OS 和 Windows 之外的，採用 Mach-O 微核心的商業 UNIX 作業系統。但是我總不可能說服家人去買幾千臺幣的 MacBook 吧！所以只好用虛擬機過過癮。至於我對 MacBook 的印象，只有2013年在某個地下街的 Apple 專賣店看到過一次，當時對於鍵盤上的「Command」鍵還有上面四葉草的圖示留下了深刻的記憶。為此在我小時設計「拙劣」的「苦力怕」筆電（不過是用紙盒拼成筆電造型）上也留下了牠的影子。甚至於15年後的今日，我也會盯著 MacBook 上的「Command」鍵看一看。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
後來瞭解了什麼是「Hackintosh」（OSX86）專案，經過一段時間的檢索與嘗試，最終把 macOS 安裝在桌機上。當時使用的是 macOS 10.15.6 版本，發覺安裝之後並沒有像 Mac 一樣好用，或許並非 G2020 CPU 的關係，而是CPU內建的 Intel HD Graphics 2500 繪圖卡沒有 macOS 驅動程式，只能使用軟體渲染。即使如此，我還是堅持著用了一年，到後面才改用 Manjaro Linux。期間學會了使用虛擬機。爲此還特意製作了&lt;a href=&quot;https://github.com/Android-Piepaint/GIGABYTE-B460M-D2V-Hackintosh&quot;&gt;主機板的 OpenCore 配置檔&lt;/a&gt;。在 macOS 下面，我也開始學習了基本的 UNIX 命令（&lt;code&gt;cd&lt;/code&gt; &lt;code&gt;ls&lt;/code&gt; &lt;code&gt;top&lt;/code&gt; 之類），同時還學會了設定 &lt;code&gt;brew&lt;/code&gt; 和 &lt;code&gt;macports&lt;/code&gt; 套件管理員，算是為之後改用 Linux 作了基礎。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Android-Piepaint/GIGABYTE-B460M-D2V-Hackintosh&quot;}&lt;/p&gt;
&lt;h2&gt;2020年：Fedora 登臺，Manjaro Linux 主場，Linux 時代來臨&lt;/h2&gt;
&lt;p&gt;2020年是接觸最廣泛的一年。我的華碩 K501E 筆電因為只有2GB記憶體和舊式 BIOS 韌體而無法升級到 Windows 10 作業系統，只能停留在結束支援的 Windows 7,我只好改裝 Linux 來繼續使用筆電。或許是出於「與眾不同」的想法，我沒有選擇一般人常用的 Ubuntu，而是為了最新的軟體，直接使用了 Fedora Linux 發行版。比起 Windows 下風扇的「開足馬力」，在 Fedora 下，風扇幾乎非常安靜，只有在看 YouTube 影片時，才會稍稍轉動，吹出溫熱的風。我在那臺已有15年歷史的筆電上完成了許許多多個「第一次」：第一次使用 &lt;code&gt;dnf&lt;/code&gt; 套件管理員安裝了常用軟體（Firefox，LibreOffice，Telegram...），第一次客製化 GNOME，KDE Plasma 桌面，第一次編譯軟體... 當然，隨著更多的「第一次」出現，我也無意中學習了更多的指令用法：使用 &lt;code&gt;ps -aux&lt;/code&gt; 看目前執行的進程，&lt;code&gt;free&lt;/code&gt; 用來檢視剩餘記憶體空間，&lt;code&gt;df -h&lt;/code&gt; 檢視硬碟分割及容量，還有使用 &lt;code&gt;dmesg&lt;/code&gt; 抓核心 log 之類。之後又改為使用 Manjaro Linux，因為是滾動發行版，軟體永遠都是最新的，基本上上游代碼編譯完成就可以使用到。隨著發行版的變更，套件管理員也就自然改變了。Manjaro 是我使用時間最久的一個發行版，在5月於筆電和桌機安裝並開始使用後，一直到2021年3月才改回使用上游的 Arch Linux 發行版。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
要問 Manjaro 給我最深的印象是什麼，應該是牠龐大的套件庫。除了系統自己的套件庫以外，妳還可以使用來自 Flathub 或者 Snap 上的軟體，也有 Appimage 檔可供使用。如果妳需要的軟體或者套件在這三者都沒有收怎麼辦？ Manjaro 也相容 Arch Linux User Repository （AUR套件庫），只需要到 AUR 檢索需要的軟體，就可以從套件庫構建並安裝。同時也可以便利的更新。當然，從 AUR 安裝套件是需要手工介入的，有些套件需要從原始碼編譯。&amp;lt;/br&amp;gt;
Manjaro 的體驗，也算是為我之後的 Distro hoppin’ 做了基礎。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/homescreen.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2021年：遷移到 Arch Linux，成為 Distro hopper&lt;/h2&gt;
&lt;p&gt;在使用過 Fedora 和 Manjaro 之後，我對於 Linux 的興致開始消退。所以決定嘗試不同的發行版。從3月到8月期間有嘗試過不少發行版：以安全性為主，採用虛擬機技術的 Qubes OS；主打客製化系統，改善電腦效能的 Gentoo Linux；還有不可變動的「穩定發行版」Fedora Sliverblue 之類。後來對 PinePhone 這類採用 Linux 系統的智慧型手機感興趣，又開始了瞭解為行動裝置設計的 Linux 發行版，但是當時手邊沒有裝置受支援，也只好用 QEMU 看一看...&amp;lt;/br&amp;gt;
後來又對 Arch Linux 感興趣，通過網路下載映像後安裝。與絕大多數 Linux 發行版不同，Arch Linux 的安裝映像沒有圖形介面，也沒有安裝指令稿。所有的安裝流程都要通過命令完成。這對於習慣了圖形介面的我而言，第一次看到僅有黑白二色的TTY控制臺是非常新奇的。「這就是 Linux 最本質的一面，曾經熟悉的安裝流程如今已經成為了檢定妳的試驗」。靠著 Arch Wiki 的安裝說明，我開始了安裝流程：分割硬碟，掛載分割，安裝基礎系統，使用 &lt;code&gt;chroot&lt;/code&gt; 建立使用者，配置系統檔案...當所有的流程結束，重開機電腦後看到熟悉的TTY控制臺出現後，喜悅的心情早已溢於言表。我竟然會對「安裝完成 Linux 系統」這件事產生成就感，真是不可思議。至於使用部分，因為先前使用過基於 Arch Linux 的 Manjaro，所以沒有什麼特別之處。（下面的圖片並不是當時留下的，而是遷移到 ARM 架構之後的事情了。）&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/arch-linux-arm-hyfetch.png&quot; alt=&quot;Arch Linux ARM with GNOME desktop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但是這次對於 Linux 的安裝機理有了比較全面的認知，同時也學會了配置 &lt;code&gt;swap&lt;/code&gt; &lt;code&gt;zram&lt;/code&gt; 來改善系統記憶體，也知道如何通過 GRUB 和 &lt;code&gt;systemd-boot&lt;/code&gt; 來修改核心引導引數，為之後嘗試移植 Linux 到手機、平板電腦，還有之後的原型機作了基礎。&lt;/p&gt;
&lt;h2&gt;2022年：遷移向 64位元 ARM 架構，開啟嵌入式系統之旅；全面改用自由軟體，從此刻開始&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;也可以瞭解：&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/my-5-years-arm64-architecture-journey/&quot;&gt;我的 ARM 架構遷移心得&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2022年是我 Linux 學習歷史中，最為重要的一年。因為長期在 YouTube 上學習課程，我的眼界也擴展了不少，因為「與眾不同」的想法，我接觸到了 FreeBSD，OpenBSD 這二個BSD發行版。與 Linux 這種最早被設計為「相容 POSIX 標準的 UNIX 模仿品」不同，BSD 系列作業系統流淌著悠久的 UNIX 血液，是統治過電腦30年的巨人。UNIX 的設計理念影響了許多作業系統和一代人，甚至於現今的 Windows 也在模仿著 UNIX 。從各種方面來講，BSD的配置方法甚至要比Linux還要原始。配置文檔也比較難懂。好在網路上有大量教學講述如何配置 FreeBSD ，配合 FreeBSD 自己的文檔設定，最後也成功的安裝了顯卡驅動和 GNOME。唯一無法解決的問題是當時為了裝 macOS 時買的 PCIe 無線網路卡不被 FreeBSD 支援，只好改用有線網路。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
或許是因為嘗試各種作業系統和編譯程式，桌機上用了7年的500GB機械硬碟開始頻繁斷電，反應速度明顯變長，壞軌數量也多了。雖然後期有換固態硬碟，但是雙核心的 G2020 CPU 已經無法滿足我的使用需求。我對於新電腦的需求越來越迫切，最後在有一次去商場的時候趁機向家人提出添置新的筆電，沒想到大家都同意了，就破例買了一臺8GB記憶體，512GB硬碟的 MacBook Air 「基本款」，剛好趕上 Apple 發佈自己的 M1 ARM 晶片，因此裡所應當的成為了「試驗者」。在享受到 Retina 熒幕的
豔麗之後，又很快瞭解到了 Asahi Linux 專案，他們給 Apple 製造的M系列晶片移植了主線核心。我也在我的筆電上安裝了 Arch Linux Arm 取代 macOS 用於日常使用和辦公，由此也開始了我向 Arm 遷移的過程。也就是在那一時間，我也開始研究「嵌入式裝置」。因為我的筆電採用 ARM 晶片，在移植系統上就可以把牠當作大型的「單板電腦」來處理，加上 MacBook 所有的元件都是焊在主機板上，也提供 UART 方便除錯。這也是我第一個接觸到的嵌入式裝置。Asahi Linux 使用 &lt;code&gt;m1n1&lt;/code&gt; 與 U-Boot 作為引導 Linux 開機的 bootloader，這也同時讓我開始學習 U-Boot 的內容，學會了簡單的命令，用來控制電腦開機。也確認了學習方向。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/arch-linux-arm-hyfetch.png&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;隨著硬體環境遷移到了 Arm 架構，與之相對應的軟體也要進行遷移。好在 Linux 上大多數常用的軟體都有釋出 Arm 版本，因此遷移的過程比較順利。但是很多我使用的商業閉源軟體沒有釋出 Arm 版，那時候還沒有像 &lt;code&gt;box64&lt;/code&gt; &lt;code&gt;FeX-EMU&lt;/code&gt; 的方案能夠以近乎原生效能執行為X86架構設計的應用，因此只好開始找尋開源的「替代品」：用 Inkscape 取代 Sketch 做美工，用 Kdenlive 取代 Davinci Resolve 來製作影片；用 Blender 取代 SketchUP 設計 3D 模型之類。但也同時讓我體會到了「開源軟體」的便利——只要有原始碼，即使開發者沒有釋出妳所在平臺的檔案，也可以自己編譯安裝，為此還學會了修補程式和 Git 的用法；原始碼公開，所有人都可以檢視，也就不會容許開發者做見不得人的勾當。或許就是因為這份經歷，使得我如今在軟體的選擇上，多半選擇自由軟體。在裝置的選擇上，也是以 Arm 和 RISC-V 架構為主。&amp;lt;/br&amp;gt;
另外，一些嵌入式 Linux 作業系統中常見的詞彙，像是「設備樹」「分頁大小」「就地執行」這類也開始取代過去常見的「ACPI」 「DSDT」「BIOS」 「超執行緒」這些詞，我也把以前比較「通用」的 Linux 系統學習，轉為嵌入式裝置和嵌入式作業系統移植的學習，到此學習的方向正式確定。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
8月份在網路上翻看了關於自由軟體基金會（FSF）的紹介，同時也瞭解了GNU哲學。加之線上參加了 FOSDEM 2022 的開發人員會議，「自由軟體」「數位人權」「隱私權」的觀念開始深入我的思想，GNU 哲學也成為我日後撰寫文章，發佈影片，以及日常處理文書的行為標準（到現在別人要我寫一篇文字稿，我都會用沒有專利的&lt;code&gt;.odt&lt;/code&gt;格式保存並傳送，至於別人能否存取，我不關心）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自由軟體（或尊重自由的軟體），代表軟體尊重使用者的自由，以及社群的自由。粗略地講，牠代表使用者擁有執行、複製、散布、研究、更動和改善該軟體的自由。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因為我始終認同FSF的理念，為隱私，為安全，更重要的是為自由，決定全盤轉換到 Linux，指的是電腦、手機的作業系統，都必須是 Linux ；而運作在上面的軟體，大部分也都得是自由軟體。甚至是電腦週邊配件(繪圖板、網路卡)等也必須是對 Linux 友好，為證明 Linux 不是只能存在於伺服器，同時也能當成桌面系統使用。&amp;lt;/br&amp;gt;
直到現在，我的電腦上所安裝的軟體中，完全的自由軟體佔九成。閒暇時間我也會創作與自由軟體相關的音樂小作品，牠們都收錄在&lt;a href=&quot;https://blog.cloudflare88.eu.org/archive/category/Music/&quot;&gt;部落格的「Music」類別下&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;2023～2025年：行動裝置上的 Linux，「驍龍本」登場&lt;/h2&gt;
&lt;p&gt;本來想要在家裡添置幾臺伺服器，但是思索再三終究因為不符合家庭條件而作罷，畢竟需要24小時開著，這對於噪聲和電費將是一筆不小的負擔。決定改用淘汰的過市手機裝 Linux 系統來實現輕便伺服器的功效，畢竟現在的 Android 手機效能普遍都有提升，拿去跑 Docker 容器服務也可以。因為先前有使用過 Linux 的經驗，所以便買了一臺主線核心支援較好的一加6T，安裝了 PosrmarketOS 後在上面架設容器自架相簿服務替代 Google 相簿，跑 Ad Blocker 用來擋廣告，也曾短暫的架設過 Minecraft 伺服器進行多人線上遊戲...總之伺服器上常見的內容，我全都在手機上架設了。而且還自帶電池，算是廉價的UPS系統，即使斷電也不會有問題。後來我的 SDM845 MTP 原型機取代了我的一加6T，同時還用於架設我的部落格，原來的一加6T成為「備用機」，在裝上SIM卡後也算是體驗了一下「PinePhone」的感覺。後期還移植了 Arch Linux ARM，能夠享受到最新的軟體。這也是我部落格首頁背景的來歷。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;https://raw.githubusercontent.com/Android-Piepaint/android-piepaint.github.io/refs/heads/main/2b54d41dfed991fc2e27a7470612de8a.jpeg&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/fajita-new.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;當然後期為了更好的效能，又改用 Nothing Phone 1。12GB的記憶體可以執行更多的 Docker 容器，但是這次更偏向日常使用方面。唯一的問題是驍龍778G 的 CPU 主線核心支援不佳，像是音訊的部分需要每次開機來修補才能工作。當然也學會了很多東西，比如根據設備樹中硬體的節點來修補韌體；修改核心配置檔啟用 Docker 支援之類...之後因為不滿足於 MacBook 上的 Fedora 而開始給 MacBook 移植 PostmarketOS，目前已經被上游接受，進入 testing 分支了。
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-phosh.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;至於「驍龍本」的到來，可以說是一次「意外」。因為一場大雨，我的 MacBook 因為保護不當導致熒幕進水，而不得不送修。在等待期間需要有新的筆電來滿足我的日常使用，又不想改用 X86 筆電，因為效能一如既往的弱！恰好想到之前在商店看到一臺&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/first-impression-with-xelite/&quot;&gt; Lenovo 的驍龍本&lt;/a&gt;，為了測試高通驍龍 X Elite 晶片受主線核心的支援程度，我再一次說服家人給我買下了一臺。後期也這臺筆電上開展了許多實驗，比如採用&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/#%E6%BA%96%E5%82%99%E5%B7%A5%E4%BD%9C&quot;&gt;「Secure launch」&lt;/a&gt;讓 Linux 執行在 EL2 下從而可以&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/&quot;&gt;使用 KVM 虛擬機&lt;/a&gt;和&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/windows-arm-on-docker/&quot;&gt;其牠採用KVM的容器&lt;/a&gt;。這篇部落格上，經過粗略計算，關於驍龍本的內容佔了四分之一。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/yoga-vibe.png&quot; &amp;gt;&lt;/p&gt;
&lt;h2&gt;2025年～現在：成為一名 Linux porter，慢慢成長&lt;/h2&gt;
&lt;p&gt;隨著在嵌入式系統方面的深入學習，普通的 Linux 手機早就無法滿足我的需要，因為目前支援主線核心的手機幾乎全是零售手機，而牠們都有開基於硬體的安全啟動，這使得修改韌體的工作幾乎無法進行。但是先前的845原型機因為電池老舊無法繼續使用，就只好買了一臺8750 的 MTP 原型機（其實是二臺，另一臺用去當伺服器架設我的部落格了，如果仔細看會發現部落格網站標題的後面會有「Powered by QTI SM8750 MTP」字樣）開始主線核心和 &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/armbian-port-next/&quot;&gt;Armbian Linux 的移植&lt;/a&gt;。好在主線核心中一直有SM8750 MTP 的設備樹，ALSA配置檔也有對應的檔案用於音訊。但是移植工作依舊不容易，僅移植核心就花費了三個月，只是為了解決熒幕沒有畫面的問題。為了擺脫 Android 那繁雜的啟動流程（主要是&lt;code&gt;boot&lt;/code&gt;映像不好製作），便改用PC上常見的UEFI開機方式，同時也可以使用 EFI Framebuffer 暫時解決顯示畫面問題。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-front-view-2.jpg&quot; alt=&quot;SM8750 MTP prototype&quot; /&gt;&lt;/p&gt;
&lt;p&gt;好在高通從835之後在所有的晶片上改用符合 &lt;a href=&quot;https://arm-software.github.io/ebbr/&quot;&gt;ARM EBBR 標準&lt;/a&gt;的 UEFI 韌體（根據高通BSP中的文檔來看，應該叫「Core Platform Boot，是基於 Coreboot 修改的韌體」），一些從UEFI韌體學習到的知識也可以直接搬到這裡來用。後來從編譯 Nothing Phone 1 的主線核心的過程想到必須要把韌體放到設備樹中給定的位置才能夠加載必要的韌體。靠著這個簡單的方法，我成功在7.0主線核心上修補了MTP原型機上的 ADSP，CDSP 二個遠程處理器，後來驚喜的發現主線核心支援了 Type-C 的雙重角色切換，我之前專門為筆電購置的 Type-C Dock 終於派上了用場。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/bds-menu.jpg&quot; width=&quot;80%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-bootlog.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;這是我第一次在比較現代的平臺上，在不借助任何圖紙和BSP參考的情況下，成功移植 Linux 作業系統。儘管半數以上的硬體不工作，但考慮到整個採用SM8750 晶片的手機主線核心支援數目寥寥，並且大多數手機的支援情況還不如我的原型機時，我覺得我的進展還是稍微快了不少。為此還特意po片發到 YouTube，雖然播放量只有不到2K，但看得出來大家都喜歡為裝置移植 Linux 的「開發人員」呢...&amp;lt;/br&amp;gt;
給大家貼上我的影片連接：Look at the code, I&apos;m still here, and you&apos;ll be alive next year（我影片的背景音樂: Porter Rubinson 的 Look at the Sky）!&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Ecv3HICeK74?si=5m9OW-QJOP2zHKan&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;每當螢幕上跳動起熟悉的 Linux boot log，那種在純黑背景下閃爍的白色字元，對我而言，不僅是程式碼的執行，更像是一種跨越硬體封鎖的「呼吸」。
在這幾個月與 SM8750 原型機沒日沒夜的對話中，我突然明白，Porter Robinson 在歌詞裡唱的那句「I&apos;m still here」，其實也是硬體對開發者的回應。那些被廠商鎖定、被時代遺忘、或被視為「早期原型」的電子零件，本該在垃圾堆中沈默，卻因為我們對主線核心的執著，重新獲得了自由呼吸的權利。只要有人還在寫 Code，這份技術的生命力就會延續到下一年，甚至更久。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;這讓我重新審視了接下來想聊的主題。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;「공부」的意思是「功夫」，也是學習&lt;/h1&gt;
&lt;p&gt;在韓文裡，「學習」的其中一種寫法是「공부（Gongbu）」，其漢字本源正是「功夫」。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;移植 Linux 曾被我視為一種技術直覺，但這次歷時三個月、只為了解決一個螢幕畫面問題的過程讓我體悟到：真正的學習，其實就是一種「功夫」。牠不是速成的補習班，而是像老僧入定、像匠人磨刀，是在無數次 Kernel Panic 與 CrashDump 中，用時間一點一滴磨出來的韌性。當我撥開可以「塵世閒遊」的虛度光陰，去閱讀「鳥哥的 Linux 私房菜」「電腦上試跑 Linux：硬體測試筆記」這些書，或者在網路上檢索嵌入式裝置的文章，在 YouTube 上花費數個小時看嵌入式作業系統移植和 Linux 相關的課程影片；或是在編譯程式或核心鍵入的「&lt;code&gt;make&lt;/code&gt;」命令檢驗成果時，我學習的不只是「知識」而是在修煉「功夫」。這份功夫說起來簡單，也難。簡單之處，在於只是讓那些冰冷的晶片像歌詞中所寫的那樣「活過來」；困難之處，在於往往需要付出幾個月甚至幾年的汗水。要求開發者必須耐得住寂寞，在幾個月甚至幾年的枯燥中，守住那一抹象徵「自由軟體精神」和「GNU哲學」的微光。&lt;/p&gt;
</content:encoded></item><item><title>給 SM8750 MTP 移植 Armbian GNU/Linux —— 第二章：編譯核心和準備 Rootfs</title><link>https://blog.cloudflare88.eu.org/posts/armbian-port-next/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/armbian-port-next/</guid><description>就讓在原型機上的移植嘗試，成爲SM8750系列手機主線 Linux 發行版的參考「模板」吧...</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在前面簡單瞭解了韌體之後，這次就要開始系統移植了。畢竟原型機就要做些只有原型機才能做的事...&amp;lt;/br&amp;gt;
當然，我的移植過程也並不是一帆風順。這不是舊平臺，像SD410、845、660 那樣，主線核心支援基本完善，網路上能夠找到的資料也有很多。到目前爲止，SM8750的主線核心支援程度比較良好，像是CPU，USB，顯示，GPU，音訊以及ADSP，CDSP等功能已有支援。[^1] &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/mainline-status.png&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;一切要從這裏開始...&lt;/h1&gt;
&lt;p&gt;先說結果：「目前是未完成狀態」。僅有CPU（包括DVFS），顯示（採用 EFI framebuffer），USB網路，音訊，內建UFS快閃記憶體，UART序列，基於GPIO的按鍵，ADSP，CDSP工作，其餘部分仍在嘗試修補中。這比我在去年的時候根據 &lt;a href=&quot;https://www.linaro.org/blog/let-s-boot-the-mainline-linux-kernel-on-qualcomm-devices/&quot;&gt;Linaro 的教學&lt;/a&gt;第一次嘗試移植的結果要好不少。花費了半天時間，最後只有UART工作，熒幕也沒有畫面。&amp;lt;/br&amp;gt;
不過，高通對於自家的晶片的主線核心支援還是比較積極的。我認識的一位朋友「&lt;em&gt;堪拉派裏*&lt;/em&gt;」就對我說，他使用 SD 8 Elite Gen 5 的原型機，根據&lt;a href=&quot;https://www.qualcomm.com/developer/blog/2025/10/same-day-snapdragon-8-elite-gen-5-upstream-linux-support&quot;&gt;高通給出的教學&lt;/a&gt;，只用了半個小時就移植了完整版的 Debian 13 並且實現了大部分被主線核心支援的功能！不過那就是另一個文章會講到的事情了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;*這裏作者開了一個玩笑，「堪拉派裏」（Kaanapali）就是高通驍龍 8 Elite Gen 5 晶片的開發代號的非正式音譯。其韓國標準語的非正式音譯爲「가나파리」或「카나팔리」。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;硬體需求&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;一臺 SM8750 MTP 原型機（建議採用未熔燬的版本，便於修改韌體）;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此裝置有&lt;a href=&quot;https://layers.openembedded.org/layerindex/recipe/483277/&quot;&gt;對應的 OpenEmbedded 配置檔&lt;/a&gt;，同時受 Linus 的主線核心，&lt;a href=&quot;https://github.com/sm8750-mainline/linux&quot;&gt;社群維護的 SM8750 主線核心分支&lt;/a&gt;，和 &lt;a href=&quot;https://github.com/Xlie-Electronic-Customs/linux&quot;&gt;Xlie Electronic&lt;/a&gt; 開發的核心分支支援。但是因爲該裝置僅面向OEM廠家和開發人員限量發售，因此尚未有正式移植。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;裝置：必須爲64位元 Linux 作業系統（不限架構，X86，ARM，RISC-V 都可以），虛擬機也可以。我的裝置CPU爲驍龍 X Elite，RAM 爲32GB，另有一臺單板機，CPU爲RK3588，8GB記憶體。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Armbian 是基於 Ubuntu 和 Debian 的專門爲基於ARM晶片的嵌入式設備設計的嵌入式 Linux 發行版，系統檔案很小。不用像 Android 那樣，下載好幾百G的原始碼，編譯也不用花上好幾個小時甚至幾天。對於不想從頭編譯 &lt;code&gt;Rootfs&lt;/code&gt; 的開發者，Armbian 也有針對 ARM 架構的「UEFI 通用映像」，最低只需要編譯適合的核心就可以開機。&lt;/p&gt;
&lt;h1&gt;安裝編譯核心的套件&lt;/h1&gt;
&lt;p&gt;編譯核心之前我們需要安裝一些編譯套件。在 Ubuntu 或基於 Debian 的發行版上，從終端機鍵入以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install make gcc git cmake bc bison flex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，通過 &lt;code&gt;git&lt;/code&gt; 命令來下載核心原始碼：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/Xlie-Electronic-Customs/linux.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我使用的是由 Xlie 開發的主線核心分支，目前支援功能最多，對於目前會導致系統當機的數據機也有了解決方案。[^2]&lt;/p&gt;
&lt;h1&gt;設定核心編譯選項 &amp;amp; 編譯核心&lt;/h1&gt;
&lt;p&gt;首先需要取得核心原始碼。以原型機所發售的時間來看，高通自己的 Linux 核心原始碼問題最少，但是高通自己的核心需要開發人員賬號才可以存取，所以只好使用社群維護的主線核心分支。例如我使用的就是 Xlie 開發的核心原始碼。目前已更新到了 7.0-rc6 版本，所支援的硬體也比較多，適合SM8750系列手機的移植。 使用 &lt;code&gt;git clone https://github.com/Xlie-Electronic-Customs/linux.git&lt;/code&gt; 命令下載核心原始碼，鍵入 &lt;code&gt;make nconfig&lt;/code&gt; 來設定編譯選項。&amp;lt;/br&amp;gt;
之後，到&lt;a href=&quot;https://github.com/sm8750-mainline/linux/blob/v6.16/arch/arm64/configs/sm8750.config&quot;&gt;SM8750主線核心原始碼&lt;/a&gt;下載 &lt;code&gt;sm8750.config&lt;/code&gt; 設定檔，然後丟入&lt;code&gt;arch/arm64/configs&lt;/code&gt; 目錄。執行&lt;code&gt;make sm8750.config defconfig&lt;/code&gt;產生設定檔。之後鍵入&lt;code&gt;make nconfig&lt;/code&gt; 或者 &lt;code&gt;make xconfig&lt;/code&gt; 來編輯設定檔。在設定頁面使用上下左右四個鍵來移動，空白鍵選擇。&lt;code&gt;F8&lt;/code&gt; 來檢索配置名稱。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/kernel-config.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這是SM8750 MTP 原型機所必須的主線核心設定檔：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CONFIG_FW_LOADER_COMPRESS&lt;/code&gt;: 便於核心加載被壓縮的韌體檔案。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_DRM_EFIDRM&lt;/code&gt; &lt;code&gt;CONFIG_FB_EFI&lt;/code&gt;: 支援 EFI framebuffer 驅動。這是在高通的 Adreno 830 繪圖卡尚不被主線支援前，最保險的方法，但是GNOME等其牠桌面將無法使用。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_VT&lt;/code&gt;：提供TTY控制臺支援（如果妳使用下游 Android 核心）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI&lt;/code&gt; ：支援 EFI 環境。因爲我們將要使用裝置自帶的UEFI韌體開機，爲後期使用&lt;code&gt;systemd-boot&lt;/code&gt; 或 GRUB 進行引導開機。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFIVAR_FS&lt;/code&gt;: 啓用 &lt;code&gt;efivar&lt;/code&gt; 文件系統支援，這是由核心自動產生的文件系統，便於系統設定開機引導次序，添加或清除啓動項目，如果不啓用則&lt;code&gt;efibootmgr&lt;/code&gt;無法檢視、修改引導次序。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI_ARMSTUB_DTB_LOADER&lt;/code&gt;：能夠通過開機載入器爲核心指定設備樹，從而覆寫韌體提供的設備樹，實現設備樹更新（通過 &lt;code&gt;systemd-boot&lt;/code&gt; 的 &lt;code&gt;devicetree&lt;/code&gt;引數 或 GRUB 中 &lt;code&gt;dtb=&lt;/code&gt; 引數控制）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI_CAPSULE_LOADER&lt;/code&gt;：爲核心打開 UEFI capsule loader 支援，便於使用者通過應用程式來更新裝置上的UEFI韌體和其牠韌體。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_RTC_DRV_EFI&lt;/code&gt;：添加UEFI時鐘。方便系統更新時間。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_DRM_PANEL_NOVATEK_NT37801&lt;/code&gt;：打開 NT37801 熒幕支援。這是SM8750 MTP 和 QRD 原型機的顯示熒幕，採用 DSI 協定。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;調整好之後，按下&lt;code&gt;F6&lt;/code&gt;儲存，然後按&lt;code&gt;Esc&lt;/code&gt;離開設定畫面。之後要來編譯核心，這一步可能會有點漫長，編譯時記得留意終端機輸出的信息，方便檢視編譯流程。如果覺得編譯很耗時，可以在&lt;code&gt;make&lt;/code&gt; 命令後面加註 &lt;code&gt;-j($nproc)&lt;/code&gt; 引數，其中 &lt;code&gt;$nproc&lt;/code&gt; 代表 CPU 核心數，可以加快編譯速度。順利的話只需5分鐘就可以完成了，如果編譯中遇到錯誤就會停下來，這時候就需要找到編譯出錯的位置，將錯誤信息複製到 Google 或者 Startpage 上去檢索修復方案。若是錯誤信息不明顯，可以使用&lt;code&gt;make -j1&lt;/code&gt; 來減慢編譯速度，從而看到更多問題。
編譯完成後，會得到一個沒有壓縮的核心還有對應的設備樹，接下來就需要「組裝」作業系統，然後嘗試開機了。&lt;/p&gt;
&lt;h1&gt;刷入裝置&lt;/h1&gt;
&lt;p&gt;將原型機關機，按住電源按鈕和音量增按鈕開機（不是正常的「按一下電源按鈕開機」），此時裝置會進入「BDS 設定選單（BDS Menu）」（該功能需要開啓了除錯功能的韌體支援)。在這裏就可以對裝置的USB、PMIC、以及UEFI韌體進行設定。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/bds-menu.jpg&quot; width=&quot;80%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;之後，準備一條 micro USB 數據線，將裝置與電腦鏈接。在終端機上鍵入&lt;code&gt;sudo minicom qcom&lt;/code&gt;來存取 UART 序列（或者使用&lt;code&gt;sudo minicom -D /dev/ttyUSB0 -b 115200&lt;/code&gt;來存取），之後就可以通過鍵盤控制妳的裝置了（終端機展示的內容與裝置熒幕上的一致）。在裝置上，使用音量增減按鈕選取「Mass storage mode」（或按一下鍵盤上的&lt;code&gt;9&lt;/code&gt;），按一下電源按鈕確認（或者&lt;code&gt;Enter&lt;/code&gt;鍵），此時熒幕會熄滅，裝置上UFS快閃記憶體的分割表會在終端機展示出來。通過鍵盤上的上下鍵選擇「UFS LUN 0」，按下「Enter」鍵確認分割，再按一下&lt;code&gt;M&lt;/code&gt;掛載 LUN 0 的分割，從電腦上存取內容。&amp;lt;/br&amp;gt;
在電腦上開啓GNOME Disks 磁碟管理工具（也可使用 &lt;code&gt;parted&lt;/code&gt; 命令）。找到掛載的磁碟，使用鍵盤的左右鍵找到 &lt;code&gt;userdata&lt;/code&gt; 分割，點擊左下的齒輪圖示，點選「調整分割大小」，鍵入一個數字，將 &lt;code&gt;partlabel&lt;/code&gt; 命名爲 &lt;code&gt;linux&lt;/code&gt; 或者其他名字，之後點選「格式化」將分割格式化爲 Ext4 文件系統，原先的 &lt;code&gt;userdata&lt;/code&gt; 分割保持默認，妳的資料會保留下來（也可以直接格式化）。然後，新建一個 &lt;code&gt;EFI&lt;/code&gt; 系統分割，格式化爲 FAT32 文件系統（FAT16 或者 W95 FAT32 也可以），大小爲500~1000MB。完成後按下任意鍵離開「Mass storage mode」，之後選擇「Reboot」重開機來套用新的分割。進入「BDS 設定選單」後，再次進入「Mass storage mode」（或者在 EBL 中鍵入&lt;code&gt;mass&lt;/code&gt;命令也可以），掛載 LUN 0。到 &lt;a href=&quot;https://www.armbian.com/uefi-arm64/&quot;&gt;Armbian&lt;/a&gt; 網站去下載 UEFI ARM 64位元的通用映像檔，然後掛載映像，找到 Armbian 的 rootfs，選擇「建立分割映像」，將建立的分割映像刷入裝置的UFS快閃記憶體。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;然後，從 &lt;a href=&quot;https://images.postmarketos.org/bpo/edge/postmarketos-trailblazer/&quot;&gt;PostmarketOS&lt;/a&gt;的網站下載通用映像，掛載映像，從 EFI 分割中複製出 &lt;code&gt;bootaa64.efi&lt;/code&gt; &lt;code&gt;loader/entries/pmos.conf&lt;/code&gt; 文件。在裝置上建立 &lt;code&gt;EFI/BOOT&lt;/code&gt; 和 &lt;code&gt;loader/entries&lt;/code&gt; 資料夾，將二個檔案分別複製到對應目錄下。然後從核心原始碼中複製編譯的 &lt;code&gt;sm8750-mtp.dtb&lt;/code&gt; 設備樹到EFI分割中。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;之後修改並更名 &lt;code&gt;pmos.conf&lt;/code&gt;配置檔，使得下次開機後能夠引導 Armbian：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
# armbian.conf

title Armbian
linux vmlinuz
options loglevel=7 debug pd_ignore_unused clk_ignore_unused iomem=relaxed root=PARTLABEL= ro rootwait earlycon
devicetree sm8750-mtp.dtb 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在不使用 &lt;code&gt;initramfs&lt;/code&gt; 的情況下，由於每次啓動後UFS的分割及UUID都會改變，因此使用UUID指定 Rootfs 的方法就會導致 kernel panic，所以只能使用分割標籤的方法啓動。&lt;/p&gt;
&lt;h2&gt;修改引導順序&lt;/h2&gt;
&lt;p&gt;高通SM8750 MTP 原型機的開機韌體採用符合 &lt;a href=&quot;https://arm-software.github.io/ebbr/&quot;&gt;ARM Embedded Base Boot Requirements&lt;/a&gt; 標準的 UEFI 韌體（所有零售機也如此），能夠支援PXE啓動、USB啓動，同時提供 UEFI Shell 方便進行韌體管理。&lt;/p&gt;
&lt;p&gt;按住電源按鈕和音量增按鈕來進入「BSD 設定選單」，選擇「Enter Shell」來進入 UEFI Shell。然後鍵入 &lt;code&gt;map -a&lt;/code&gt; 來檢視裝置上的UFS快閃記憶體分割，找到建立的EFI分割（例如&lt;code&gt;fs4&lt;/code&gt;），鍵入 &lt;code&gt;fs4:&lt;/code&gt;來檢視 EFI分割中的內容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shell&amp;gt; dir fs4:\efi -b

Directory of: fs4:\efi\
     03/18/2026  23:19 &amp;lt;DIR&amp;gt;         4,096  .
     03/18/2026  23:19 &amp;lt;DIR&amp;gt;             0  ..
     03/18/2026  21:41 &amp;lt;DIR&amp;gt;         4,096  BOOT
               0 File(s)           0 bytes
               3 Dir(s)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用&lt;code&gt;bcfg&lt;/code&gt;命令來添加開機項目[^3]：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shell&amp;gt; bcfg boot addp 1 FS4:\EFI\BOOT\BOOTAA64.efi &quot;Armbian&quot;
Target = 0004.
     bcfg: Add Boot0004 as 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後每次開機，裝置都應該會進入 Armbian 了。當然妳也可以直接通過 UEFI shell 中手動執行開機載入器啓動系統。&lt;/p&gt;
&lt;h1&gt;結果&lt;/h1&gt;
&lt;p&gt;這是我在 &lt;a href=&quot;https://youtube.com/shorts/Ecv3HICeK74?si=5m9OW-QJOP2zHKan&quot;&gt;YouTube 上發佈的影片&lt;/a&gt;：&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Ecv3HICeK74?si=5m9OW-QJOP2zHKan&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-bootlog.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-uefi.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/armbian-screenfetch.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;就像我早就提到過的：僅有CPU（包括DVFS），顯示（採用 EFI framebuffer），USB網路，音訊，內建UFS快閃記憶體，UART序列，基於GPIO的按鍵，ADSP，CDSP工作，其餘部分仍在嘗試修補中。至少和其牠市面上常見的零售機相比，第一次嘗試開機就可以看到畫面（雖然是軟體渲染）也足夠開心了。之後如果把所有硬體的功能修補完成，就可以給 Armbian 上游提交PR，把自己的成果公佈出去讓別人下載，也算是自己從零實作了一個高效能「PinePhone Pro」吧，畢竟原版 Pinephone Pro 雖然改用 RK3399 晶片，效能也是弱弱的。&lt;/p&gt;
&lt;p&gt;[^1]:&lt;a href=&quot;https://wiki.postmarketos.org/wiki/Qualcomm_Snapdragon_8_Elite_(SM8750)&quot;&gt;Qualcomm Snapdragon 8 Elite - PostmarketOS Wiki&lt;/a&gt;
[^2]:&lt;a href=&quot;https://github.com/Xlie-Electronic-Customs/linux/commit/ea4c3038c355839ab93caac87f0fa29b0fa91a49&quot;&gt;remoteproc: qcom: pas: Fixing region_assign_idx&lt;/a&gt;
[^3]:&lt;a href=&quot;https://www.digitalstorm.com/forums/howto-add-uefi-shell-boot-option-tidf53003/&quot;&gt;HOWTO - Add UEFI Shell boot option&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Porting Armbian GNU/Linux to SM8750 MTP — Chapter Two：Compiling the Kernel and Preparing the Rootfs</title><link>https://blog.cloudflare88.eu.org/posts/en/armbian-port-next/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/armbian-port-next/</guid><description>Let this porting attempt on the prototype serve as a &quot;template&quot; for mainline Linux distributions on SM8750 series phones.</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;&lt;/p&gt;
&lt;p&gt;After a brief overview of the firmware previously, we&apos;re diving into system porting this time. After all, a prototype must do things that only a prototype can do...&amp;lt;/br&amp;gt;
Of course, my porting process wasn&apos;t all smooth sailing. This isn&apos;t an old platform like the SD410, 845, or 660, where mainline kernel support is basically mature and online resources are plentiful. As of now, mainline kernel support for the SM8750 is relatively decent, with support for the CPU, USB, display, GPU, audio, as well as ADSP and CDSP already present. [^1] &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/mainline-status.png&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;Everything begins here...&lt;/h1&gt;
&lt;p&gt;TL;DR: &quot;It&apos;s currently a work-in-progress.&quot; Only the CPU (including DVFS), display (using EFI framebuffer), USB networking, audio, internal UFS flash, UART serial, GPIO-based buttons, ADSP, and CDSP are functional; the rest is still undergoing patching. This is significantly better than my first attempt based on &lt;a href=&quot;https://www.linaro.org/blog/let-s-boot-the-mainline-linux-kernel-on-qualcomm-devices/&quot;&gt;Linaro&apos;s tutorial&lt;/a&gt; last year. Back then, after half a day of effort, only the UART worked, and the screen remained black.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;However, Qualcomm is quite proactive regarding mainline kernel support for its own chips. A friend of mine, &quot;Kaanapali*&quot;, told me that using an SD 8 Elite Gen 5 prototype and following &lt;a href=&quot;https://www.qualcomm.com/developer/blog/2025/10/same-day-snapdragon-8-elite-gen-5-upstream-linux-support&quot;&gt;Qualcomm&apos;s instructions&lt;/a&gt;, he ported a full version of Debian 13 and implemented most mainline-supported features in just half an hour! But that&apos;s a story for another article.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;*The author is making a joke here; &quot;Kaanapali&quot; (Kaanapali) is the informal phonetic transliteration of the development codename for the Qualcomm Snapdragon 8 Elite Gen 5 chip. Its informal phonetic transliteration in Standard Korean is &quot;가나파리&quot; or &quot;카나팔리&quot;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Hardware Requirements&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;An SM8750 MTP prototype (a non-fused version is recommended for easier firmware modification);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This device has a &lt;a href=&quot;https://layers.openembedded.org/layerindex/recipe/483277/&quot;&gt;corresponding OpenEmbedded configuration file&lt;/a&gt; and is supported by Linus&apos;s mainline kernel, the &lt;a href=&quot;https://github.com/sm8750-mainline/linux&quot;&gt;community-maintained SM8750 mainline kernel branch&lt;/a&gt;, and the kernel branch developed by &lt;a href=&quot;https://github.com/Xlie-Electronic-Customs/linux&quot;&gt;Xlie Electronic&lt;/a&gt;. However, because the device was only released in limited quantities to OEMs and developers, no official port exists yet.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host: Must be a 64-bit Linux OS (any architecture—x86, ARM, RISC-V is fine), or a virtual machine. My machine uses a Snapdragon X Elite with 32GB RAM, and I have another single-board computer with an RK3588 CPU and 8GB RAM.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Armbian is an embedded Linux distribution based on Ubuntu and Debian specifically designed for ARM-based embedded devices; its system files are tiny. Unlike Android, you don&apos;t need to download hundreds of gigabytes of source code, and compilation doesn&apos;t take hours or days. For developers who don&apos;t want to compile a &lt;code&gt;Rootfs&lt;/code&gt; from scratch, Armbian also provides a &quot;UEFI Generic Image&quot; for the ARM architecture, where you only need to compile a suitable kernel to boot.&lt;/p&gt;
&lt;h1&gt;Installing Packages for Kernel Compilation&lt;/h1&gt;
&lt;p&gt;Before compiling the kernel, we need to install some build tools. On Ubuntu or Debian-based distributions, type the following command in the terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install make gcc git cmake bc bison flex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterward, use the &lt;code&gt;git&lt;/code&gt; command to download the kernel source code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/Xlie-Electronic-Customs/linux.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am using the mainline kernel branch developed by Xlie, which currently supports the most features and includes a solution for the modem issues that currently cause system hangs. [^2]&lt;/p&gt;
&lt;h1&gt;Configuring Kernel Build Options &amp;amp; Compiling the Kernel&lt;/h1&gt;
&lt;p&gt;First, obtain the kernel source code. Given the release window of the prototype, Qualcomm&apos;s own Linux kernel source has the fewest issues, but their kernel requires a developer account for access, so I had to use community-maintained mainline branches. For instance, I used Xlie&apos;s kernel source. It has been updated to version 7.0-rc6 and supports more hardware, making it suitable for SM8750 series phone ports. Use the command &lt;code&gt;git clone https://github.com/Xlie-Electronic-Customs/linux.git&lt;/code&gt; to download the source, and type &lt;code&gt;make nconfig&lt;/code&gt; to set the build options.&amp;lt;/br&amp;gt;
Next, go to the SM8750 mainline kernel source to download the &lt;code&gt;sm8750.config&lt;/code&gt; file, then drop it into the &lt;code&gt;arch/arm64/configs&lt;/code&gt; directory. Run &lt;code&gt;make sm8750.config defconfig&lt;/code&gt; to generate the configuration file. Then type &lt;code&gt;make nconfig&lt;/code&gt; or &lt;code&gt;make xconfig&lt;/code&gt; to edit it. In the configuration page, use the arrow keys to move and the space bar to select. Press &lt;code&gt;F8&lt;/code&gt; to search for configuration names.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/kernel-config.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Essential mainline kernel configurations for the SM8750 MTP prototype:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CONFIG_FW_LOADER_COMPRESS&lt;/code&gt;: Facilitates loading compressed firmware files.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_DRM_EFIDRM&lt;/code&gt; &lt;code&gt;CONFIG_FB_EFI&lt;/code&gt;: Support for the EFI framebuffer driver. This is the safest method while Qualcomm&apos;s Adreno 830 graphics aren&apos;t yet mainline-supported, though GNOME and other desktops won&apos;t work.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_VT&lt;/code&gt;: Provides TTY console support (if you&apos;re using downstream Android kernels).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI&lt;/code&gt;: Supports the EFI environment. Since we&apos;ll use the device&apos;s built-in UEFI firmware to boot, this is for later use with &lt;code&gt;systemd-boot&lt;/code&gt; or GRUB.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFIVAR_FS&lt;/code&gt;: Enables &lt;code&gt;efivar&lt;/code&gt; filesystem support. This filesystem is auto-generated by the kernel to facilitate managing boot order and adding/clearing boot entries; without it, &lt;code&gt;efibootmgr&lt;/code&gt; cannot view or modify the boot sequence.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI_ARMSTUB_DTB_LOADER&lt;/code&gt;: Allows the bootloader to specify a device tree for the kernel, overriding the one provided by firmware to enable DTB updates (controlled via the &lt;code&gt;devicetree&lt;/code&gt; parameter in &lt;code&gt;systemd-boot&lt;/code&gt; or &lt;code&gt;dtb=&lt;/code&gt; in GRUB).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_EFI_CAPSULE_LOADER&lt;/code&gt;: Enables UEFI capsule loader support, allowing users to update UEFI and other firmware via applications.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_RTC_DRV_EFI&lt;/code&gt;: Adds the UEFI real-time clock for system time updates.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONFIG_DRM_PANEL_NOVATEK_NT37801&lt;/code&gt;: Enables support for the NT37801 screen. This is the DSI-protocol display used in SM8750 MTP and QRD prototypes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once adjusted, press &lt;code&gt;F6&lt;/code&gt; to save and &lt;code&gt;Esc&lt;/code&gt; to exit. Now for compilation—this step can be lengthy. Keep an eye on the terminal output to monitor the process. If it&apos;s too slow, add the &lt;code&gt;-j($nproc)&lt;/code&gt; parameter to the &lt;code&gt;make&lt;/code&gt; command, where &lt;code&gt;$nproc&lt;/code&gt; is your CPU core count. If all goes well, it should finish in 5 minutes. If an error occurs, find the location of the error, copy it, and search for a fix on Google or Startpage. If error messages are vague, use &lt;code&gt;make -j1&lt;/code&gt; to slow down and see more detail.
After compilation, you&apos;ll get an uncompressed kernel and its corresponding device tree. Next, we need to &quot;assemble&quot; the OS and try to boot.&lt;/p&gt;
&lt;h1&gt;Flashing the Device&lt;/h1&gt;
&lt;p&gt;Power off the prototype. Hold the Power and Volume Up buttons to boot (not a normal &quot;tap to power on&quot;); the device will enter the &quot;BDS Menu&quot; (this requires firmware with debugging features enabled). Here, you can configure USB, PMIC, and UEFI settings.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/bds-menu.jpg&quot; width=&quot;80%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, prepare a micro USB cable to link the device to your computer. Type &lt;code&gt;sudo minicom qcom&lt;/code&gt; (or &lt;code&gt;sudo minicom -D /dev/ttyUSB0 -b 115200&lt;/code&gt;) in your terminal to access the UART serial. You can then control the device via keyboard (the terminal content mirrors the device screen). On the device, use volume buttons to select &quot;Mass storage mode&quot; (or press &lt;code&gt;9&lt;/code&gt; on your keyboard) and Power (or &lt;code&gt;Enter&lt;/code&gt;) to confirm. The screen will turn off, and the device&apos;s UFS flash partition table will appear in the terminal. Use arrow keys to select &quot;UFS LUN 0&quot;, press &quot;Enter&quot; to confirm, then press &lt;code&gt;M&lt;/code&gt; to mount the LUN 0 partition and access its content from your computer.&amp;lt;/br&amp;gt;
Open GNOME Disks (or use the &lt;code&gt;parted&lt;/code&gt; command) on your computer. Find the mounted disk, use arrow keys to locate the &lt;code&gt;userdata&lt;/code&gt; partition, click the gear icon, select &quot;Resize Partition&quot;, enter a size, and name the &lt;code&gt;partlabel&lt;/code&gt; &quot;linux&quot; or something similar. Then, &quot;Format&quot; it to Ext4. Leave the original &lt;code&gt;userdata&lt;/code&gt; partition as default to keep your data (or format it directly). Next, create a new &lt;code&gt;EFI&lt;/code&gt; system partition, format it to FAT32 (FAT16 or W95 FAT32 also work), with a size of 500-1000MB. Once finished, press any key to exit &quot;Mass storage mode&quot;, then select &quot;Reboot&quot; to apply the new partitions. After entering the &quot;BDS Menu&quot; again, re-enter &quot;Mass storage mode&quot; (or type &lt;code&gt;mass&lt;/code&gt; in EBL) and mount LUN 0. Go to the Armbian website to download the UEFI ARM 64-bit generic image, mount it, find the Armbian rootfs, select &quot;Create Partition Image&quot;, and flash that image onto the device&apos;s UFS flash.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Then, download the generic image from PostmarketOS, mount it, and copy &lt;code&gt;bootaa64.efi&lt;/code&gt; and &lt;code&gt;loader/entries/pmos.conf&lt;/code&gt; from its EFI partition. On your device, create &lt;code&gt;EFI/BOOT&lt;/code&gt; and &lt;code&gt;loader/entries&lt;/code&gt; folders and copy the files into their respective directories. Copy your compiled &lt;code&gt;sm8750-mtp.dtb&lt;/code&gt; device tree from the kernel source into the EFI partition.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, modify and rename &lt;code&gt;pmos.conf&lt;/code&gt; so it can boot Armbian:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
# armbian.conf

title Armbian
linux vmlinuz
options loglevel=7 debug pd_ignore_unused clk_ignore_unused iomem=relaxed root=PARTLABEL=linux ro rootwait earlycon
devicetree sm8750-mtp.dtb 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without using an &lt;code&gt;initramfs&lt;/code&gt;, the UFS partitions and UUIDs change with every boot, so using UUIDs to specify the rootfs will cause a kernel panic. Using the partition label is the only way to boot.&lt;/p&gt;
&lt;h2&gt;Modifying the Boot Order&lt;/h2&gt;
&lt;p&gt;The boot firmware for the Qualcomm SM8750 MTP prototype is a UEFI implementation that adheres to the ARM Embedded Base Boot Requirements standard (as do all retail units), supporting PXE boot, USB boot, and providing a UEFI Shell for easier management.&lt;/p&gt;
&lt;p&gt;Hold Power and Volume Up to enter the &quot;BSD Menu&quot; and select &quot;Enter Shell&quot;. Type &lt;code&gt;map -a&lt;/code&gt; to view the UFS flash partitions, find the EFI partition you created (e.g., &lt;code&gt;fs4&lt;/code&gt;), and type &lt;code&gt;fs4:&lt;/code&gt; to see its contents.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shell&amp;gt; dir fs4:\efi -b

Directory of: fs4:\efi\
     03/18/2026  23:19 &amp;lt;DIR&amp;gt;         4,096  .
     03/18/2026  23:19 &amp;lt;DIR&amp;gt;             0  ..
     03/18/2026  21:41 &amp;lt;DIR&amp;gt;         4,096  BOOT
               0 File(s)           0 bytes
               3 Dir(s)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the &lt;code&gt;bcfg&lt;/code&gt; command to add a boot entry [^3]:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Shell&amp;gt; bcfg boot addp 1 FS4:\EFI\BOOT\BOOTAA64.efi &quot;Armbian&quot;
Target = 0004.
     bcfg: Add Boot0004 as 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The device should now boot into Armbian every time. Of course, you can also manually execute the bootloader from the UEFI shell.&lt;/p&gt;
&lt;h1&gt;Results&lt;/h1&gt;
&lt;p&gt;Here is the video I posted on YouTube:&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Ecv3HICeK74?si=5m9OW-QJOP2zHKan&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-bootlog.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/sm8750-uefi.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/armbian-screenfetch.jpg&quot; width=&quot;60%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;As I mentioned earlier: only the CPU (including DVFS), display (using EFI framebuffer), USB networking, audio, internal UFS flash, UART serial, GPIO-based buttons, ADSP, and CDSP are working; the rest is still being patched. At least compared to other common retail devices on the market, seeing an image (even if software-rendered) on the first try is enough to be happy about. Once all hardware functions are patched, I can submit a PR upstream to Armbian and release my results for others to download. I suppose I&apos;ve essentially implemented a high-performance &quot;PinePhone Pro&quot; from scratch—after all, the original Pinephone Pro, despite switching to the RK3399 chip, is still quite underpowered.&lt;/p&gt;
&lt;p&gt;[^1]:Qualcomm Snapdragon 8 Elite - PostmarketOS Wiki)
[^2]:remoteproc: qcom: pas: Fixing region_assign_idx
[^3]:HOWTO - Add UEFI Shell boot option&lt;/p&gt;
</content:encoded></item><item><title>關閉煩人的「自動鍵入」功能-- Linux 上採用 UDEV 規則和 Keyd 關閉滑鼠自動鍵入，並客製化按鈕行爲</title><link>https://blog.cloudflare88.eu.org/posts/customize-your-mouse-button/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/customize-your-mouse-button/</guid><pubDate>Tue, 24 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;通過 Linux 的 &lt;code&gt;udev&lt;/code&gt; 規則和 &lt;code&gt;keyd&lt;/code&gt; 工具，我們可以客製化滑鼠按鈕行為，並關閉自動打字功能。&lt;/p&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;最近在好朋友的介紹下，入手了一個中國產的滑鼠——「Inphic S6」，廠家宣稱這是第一支支援 AI Agent 的滑鼠，能夠實現語音聊天，AI生圖和簡報制作等功能。而且滑鼠還內建麥克風，聽上去還很不錯，但是我一向只使用 Linux 和自由軟體，對於其牠無用的功能真的不感興趣。畢竟滑鼠的本質不過就是「指向裝置（Pointing device）」，無論外表再怎麼「光鮮亮麗」，最本質的地方依舊不會變。&amp;lt;/br&amp;gt;
沒過幾天，包裹就送到了，打開看了裏面的使用指南後，不出意外的只支援 Windows 和 macOS 作業系統，連廠家釋出的驅動也只有 Windows 和 macOS 版。看來在他們眼裏，Linux 和其牠UNIX系統一樣，都是「受人冷落的」過時產物......&amp;lt;/br&amp;gt;
這顆滑鼠的外觀設計挺不錯的，白色的外殼，看上去就有「科技感」，有種獨特的韻味在。支援無線 USB 連結和藍牙連結，但是滑鼠的藍牙似乎有些問題，不能與我的 Surface Pro 5 鏈接，這是十分奇怪的事情。&lt;/p&gt;
&lt;h1&gt;令人困擾的問題&lt;/h1&gt;
&lt;p&gt;簡單使用之後，這顆滑鼠並沒有什麼問題。但是牠有一個非常奇怪的行爲，只要在任何支援鍵入文字的應用（例如 Gedit，nano 之類）按住滑鼠中鍵或者左側的按鈕超過5秒，就會看到滑鼠自動在應用中留下一串網址:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rWWW.INPHIC.CN/S6.HTML
/r
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;後來發現這是滑鼠驅動程式的下載網址。但是對於使用 Linux 的我來說，這就是完全沒有用處的「垃圾程式」。而且驅動程式閉源，妳永遠不知道廠家是否在程式中藏了「私貨」，或是在背景蒐集妳的資料。搞不好還有可能是「間諜程式」，還會方便政府定位妳的位置，方便進行監控「自由人士」呢！同時也帶來了麻煩，設想一下妳正在做着重要的簡報，或者回復一篇重要的電郵，因爲妳按下中鍵的時間稍微久了一點，滑鼠「好心」的幫妳鍵入了下載驅動程式的網址，而妳又沒有留意...可想而知會帶來怎麼樣的後果！所以就需要解決這個問題。&lt;/p&gt;
&lt;h1&gt;「自動打字」的機理&lt;/h1&gt;
&lt;p&gt;這並不是通過作業系統內建（或安裝）的軟體實作實現的，而是通過硬體預設的行爲。當妳將滑鼠插入電腦時，滑鼠會向系統回報自己是一個「複合裝置」而非「USB 滑鼠」（USB HID Device），這類滑鼠通常還會兼具鍵盤的「隱藏」功能。之後通過燒錄在 MCU 中的硬體宏（Macro）實現。當使用者按下滑鼠中鍵超過設定的時間後，就會執行設定好的程式碼，通過模擬鍵盤發送按鍵活動（event）實現「自動鍵入」的效果。&amp;lt;/br&amp;gt;
正因爲韌體燒錄在 MCU 中，想要修改滑鼠韌體來改善這個問題幾乎是不可能的。安裝廠家的「間諜程式」是不可能的，因爲我堅持只使用自由（或尊重自由的）軟體！至少我使用的是 Linux 系統，比起 Windows 而言，解決這個問題會更具有靈活性。因爲 Linux 的輸入（input）實作在1990年代就非常成熟且穩定了，而且也可以方便的管理這些裝置。&lt;/p&gt;
&lt;h1&gt;偵測所有輸入裝置&lt;/h1&gt;
&lt;p&gt;我將滑鼠通過藍牙連線至電腦，儘管在我的電腦上，藍牙部分與網路卡一樣通過PCIe總線連結，但是藍牙裝置可不會通過PCIe連結到主機。滑鼠依然會通過藍牙的 HID 協定與主機溝通。並聲明了滑鼠和鍵盤二個角色，在這種情況下，通過檢視USB和PCIe裝置就不行了。好在我們還可以藉助核心自帶的 &lt;code&gt;sysfs&lt;/code&gt; ，每個連結到這臺主機的輸入裝置都會被 Linux 核心記錄下來，因此我們總有辦法找到這個模擬「鍵盤」。&amp;lt;/br&amp;gt;
打開終端機，鍵入 &lt;code&gt;cat /proc/bus/input/devices&lt;/code&gt; 會看到返回了所有正在使用的裝置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name=&quot;gpio-keys&quot;
P: Phys=gpio-keys/input0
S: Sysfs=/devices/platform/gpio-keys/input/input0
U: Uniq=
H: Handlers=event0 
B: PROP=0
B: EV=21
B: SW=1

I: Bus=0018 Vendor=0488 Product=1054 Version=0100
N: Name=&quot;hid-over-i2c 0488:1054 Mouse&quot;
P: Phys=3-002c
S: Sysfs=/devices/platform/soc@0/bc0000.geniqup/b80000.i2c/i2c-3/3-002c/0018:0488:1054.0001/input/input8
U: Uniq=
H: Handlers=mouse0 event1 
B: PROP=0
B: EV=17
B: KEY=70000 0 0 0 0
B: REL=903
B: MSC=10

I: Bus=0018 Vendor=0488 Product=1054 Version=0100
N: Name=&quot;hid-over-i2c 0488:1054 Touchpad&quot;
P: Phys=3-002c
S: Sysfs=/devices/platform/soc@0/bc0000.geniqup/b80000.i2c/i2c-3/3-002c/0018:0488:1054.0001/input/input9
U: Uniq=
H: Handlers=mouse1 event2 
B: PROP=5
B: EV=1b
B: KEY=e520 10000 0 0 0 0
B: ABS=2e0800000000003
B: MSC=20

I: Bus=0018 Vendor=048d Product=8987 Version=0100
N: Name=&quot;hid-over-i2c 048D:8987&quot;
P: Phys=3-003a
S: Sysfs=/devices/platform/soc@0/bc0000.geniqup/b80000.i2c/i2c-3/3-003a/0018:048D:8987.0003/input/input11
U: Uniq=
H: Handlers=sysrq rfkill kbd event5 leds 
B: PROP=0
B: EV=12001f
B: KEY=33eff 0 0 483ffff17aff32d bfd4444600000000 1 930c730b17c007 ffbe7bfad941dfff febeffdfffefffff fffffffffffffffe
B: REL=1040
B: ABS=100000000
B: MSC=10
B: LED=1f

I: Bus=0018 Vendor=27c6 Product=0123 Version=0100
N: Name=&quot;hid-over-i2c 27C6:0123&quot;
P: Phys=2-0014
S: Sysfs=/devices/platform/soc@0/ac0000.geniqup/a80000.i2c/i2c-2/2-0014/0018:27C6:0123.0002/input/input12
U: Uniq=
H: Handlers=mouse2 event3 
B: PROP=2
B: EV=1b
B: KEY=400 0 0 0 0 0
B: ABS=260800000000003
B: MSC=20

I: Bus=0018 Vendor=27c6 Product=0123 Version=0100
N: Name=&quot;hid-over-i2c 27C6:0123 UNKNOWN&quot;
P: Phys=2-0014
S: Sysfs=/devices/platform/soc@0/ac0000.geniqup/a80000.i2c/i2c-2/2-0014/0018:27C6:0123.0002/input/input13
U: Uniq=
H: Handlers=event4 
B: PROP=0
B: EV=9
B: ABS=10000000000

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name=&quot;pmic_pwrkey&quot;
P: Phys=pmic_pwrkey/input0
S: Sysfs=/devices/platform/soc@0/c400000.arbiter/spmi-0/0-00/c42d000.spmi:pmic@0:pon@1300/c42d000.spmi:pmic@0:pon@1300:pwrkey/input/input14
U: Uniq=
H: Handlers=kbd event6 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

I: Bus=0003 Vendor=0fac Product=0ade Version=0000
N: Name=&quot;keyd virtual keyboard&quot;
P: Phys=
S: Sysfs=/devices/virtual/input/input15
U: Uniq=
H: Handlers=sysrq rfkill kbd event7 leds 
B: PROP=0
B: EV=120003
B: KEY=10000000000000 0 ffffffffffffff0f ffffffffffffffff ffffffffffffffff fffffffffffffffe
B: LED=1ff

I: Bus=0003 Vendor=0fac Product=1ade Version=0000
N: Name=&quot;keyd virtual pointer&quot;
P: Phys=
S: Sysfs=/devices/virtual/input/input16
U: Uniq=
H: Handlers=mouse3 event8 js0 
B: PROP=0
B: EV=f
B: KEY=ff0000 0 0 0 0
B: REL=147
B: ABS=3

I: Bus=0005 Vendor=248a Product=61ab Version=0200
N: Name=&quot;inphic S6 Keyboard&quot;
P: Phys=58:cd:c9:7f:41:94
S: Sysfs=/devices/virtual/misc/uhid/0005:248A:61AB.0004/input/input17
U: Uniq=d1:01:2d:7f:2c:21
H: Handlers=sysrq kbd event9 leds 
B: PROP=0
B: EV=12001f
B: KEY=33eff 0 0 483ffff17aff32d bfd4444600000000 1 130ff38b17c007 ffff7bfad9415fff febeffdfffefffff fffffffffffffffe
B: REL=1040
B: ABS=100000000
B: MSC=10
B: LED=1f

I: Bus=0005 Vendor=248a Product=61ab Version=0200
N: Name=&quot;inphic S6 Mouse&quot;
P: Phys=58:cd:c9:7f:41:94
S: Sysfs=/devices/virtual/misc/uhid/0005:248A:61AB.0004/input/input18
U: Uniq=d1:01:2d:7f:2c:21
H: Handlers=mouse4 event10 
B: PROP=0
B: EV=17
B: KEY=70000 0 0 0 0
B: REL=903
B: MSC=10

I: Bus=0005 Vendor=248a Product=61ab Version=0200
N: Name=&quot;inphic S6&quot;
P: Phys=58:cd:c9:7f:41:94
S: Sysfs=/devices/virtual/misc/uhid/0005:248A:61AB.0004/input/input19
U: Uniq=d1:01:2d:7f:2c:21
H: Handlers=event11 
B: PROP=0
B: EV=9
B: ABS=10000000000

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不出意外，那個疑似「模擬鍵盤」的裝置 &lt;code&gt;inphic S6 Keyboard&lt;/code&gt; 出現了。記下牠的 &lt;code&gt;Vendor ID&lt;/code&gt; 與 &lt;code&gt;Product ID&lt;/code&gt;，用於編寫特定的 &lt;code&gt;udev&lt;/code&gt; 規則來阻擋牠的鍵盤功能。&lt;/p&gt;
&lt;h1&gt;編寫 UDEV 規則&lt;/h1&gt;
&lt;p&gt;之後就可以建立特定的 &lt;code&gt;udev&lt;/code&gt; 規則，告訴核心忽略這個設備的活動：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# nano /etc/udev/rules.d/99-block-inphic-kb.rules:

# 通過設備名稱匹配，禁用其鍵盤屬性
SUBSYSTEM==&quot;input&quot;, ATTRS{name}==&quot;inphic S6 Keyboard&quot;, ENV{ID_INPUT_KEYBOARD}==&quot;1&quot;, ENV{LIBINPUT_IGNORE_DEVICE}=&quot;1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後重載 &lt;code&gt;udev&lt;/code&gt; 規則：&lt;code&gt;sudo udevadm control --reload-rules &amp;amp;&amp;amp; sudo udevadm trigger&lt;/code&gt; 之後就可以解決自動鍵入的問題了。&lt;/p&gt;
&lt;h2&gt;對於 &lt;code&gt;keyd&lt;/code&gt; 使用者&lt;/h2&gt;
&lt;p&gt;因爲我的筆電通過 &lt;code&gt;keyd&lt;/code&gt; 工具將鍵盤上的 「Copliot Key」按鍵重新映射爲「右 Ctrl」鍵，所以雖然用 &lt;code&gt;udev&lt;/code&gt; 阻擋了裝置鍵入，可是 &lt;code&gt;keyd&lt;/code&gt; 依然會處理這個「鍵盤」的按鍵活動，並將其傳遞給系統。因此需要修改 &lt;code&gt;keyd&lt;/code&gt; 的全局設定檔案 &lt;code&gt;/etc/keyd/default.conf&lt;/code&gt; [^1]：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/keyd/default.conf

[ids]
*
-248a:61ab

[main]

#（妳自己的按鍵定義）

[inphic S6 Keyboard]
# 這裡什麼都不寫
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[^1]:&lt;a href=&quot;https://github.com/rvaiya/keyd?tab=readme-ov-file#recommended-config&quot;&gt;Recommended config -- keyd GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;之後，重載 &lt;code&gt;keyd&lt;/code&gt; 服務，按住滑鼠中鍵測試，發現這一行爲消失了。&lt;/p&gt;
&lt;h1&gt;定義新的按鍵活動&lt;/h1&gt;
&lt;p&gt;既然「自動鍵入」的本質上是通過「模擬鍵盤」發送的按鍵活動實現的，那就可以通過將一系列快速的「按鍵序列」映射爲妳想要做的事（愛愛也可以喔），而 &lt;code&gt;keyd&lt;/code&gt; 剛好就支援這個「序列映射」功能！&amp;lt;/br&amp;gt;
針對這隻滑鼠建立新的配置文件(&lt;code&gt;/etc/keyd/inphic.conf&lt;/code&gt;)：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ids]
248a:61ab

[main]
# 因爲這串網址是以「w」開頭，當鼠標嘗試發送 &apos;w&apos; 時，我們讓牠執行別的操作
# 注意：這會導致該設備發出的所有 &apos;w&apos; 都失效，但因為這是鼠標模擬的鍵盤，
# 牠平時根本不會發送 &apos;w&apos;，只有在觸發那個流氓功能時才會發送。

w = macro(layer(custom_action))  # 使用 keyd 的 macro（宏）功能來捕獲按鍵行爲

[custom_action]
# 當檢測到第一個 &apos;w&apos; 後，妳可以讓牠執行一個命令
# 例如：切換桌面、打開計算器、甚至執行一個腳本
w = f12 
# 或者執行系統命令（需要配合 keyd 的 command 功能）
w = command(notify-send &quot;滑鼠中鍵被長按了！&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;assets/mouse-demo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;和支援自定義按鍵活動的滑鼠相比，這樣的效果並不好，而且按住中鍵的做法並不高效。但是這隻滑鼠並不能客製化韌體，所以用來玩一下也不錯。&lt;/p&gt;
</content:encoded></item><item><title>Framebuffer Love -- A FOSS Parody of With You by Babz Wayne</title><link>https://blog.cloudflare88.eu.org/posts/framebuffer-love/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/framebuffer-love/</guid><description>Just a song written for my little sc9832e linux watch.</description><pubDate>Sat, 21 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/l20VhgJDbjs?si=0lUfq4VhshiqU2ur&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;Come meet me,&amp;lt;/br&amp;gt;
At the edge of the world&amp;lt;/br&amp;gt;
You&apos;ve just showed me everything beautiful&amp;lt;/br&amp;gt;
I want you exist in my embedded world&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;Created a window like you never seen,&amp;lt;/br&amp;gt;
Showed me a place like I never been &amp;lt;/br&amp;gt;
So I can interact you at any time, &amp;lt;/br&amp;gt;
Graphical embedded system on my hand &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Just a tiny framebuffer love, &amp;lt;/br&amp;gt;
Included all my thoughts and hard-works for my watch, for a tiny framebuffer love&amp;lt;/br&amp;gt;
Mirrored my whole complex life and my time, on a tiny framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
A simple framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
A simple framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;Every time I see I just see your layout around,&amp;lt;/br&amp;gt;
Your layout round, yeah&amp;lt;/br&amp;gt;
When I power on, you just bootstrapped yourself from the void,&amp;lt;/br&amp;gt;
from the void&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
No, I promised I won&apos;t give you the time,&amp;lt;/br&amp;gt;
To sentence you that you&apos;re end-of-life&amp;lt;/br&amp;gt;
So we can stay together everywhere,
You&apos;ll always up-to-dated until your death&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;End&lt;/h1&gt;
&lt;p&gt;Just a tiny framebuffer love, &amp;lt;/br&amp;gt;
Included all my thoughts and hard-works for my watch, for a tiny framebuffer love&amp;lt;/br&amp;gt;
Mirrored my whole complex life and my time, on a tiny framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
A simple framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
A simple framebuffer love&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Android 裝置去 Google 化，改用自由軟體和 MicroG 取代專有 Google 服務</title><link>https://blog.cloudflare88.eu.org/posts/degoogle-your-android-phone/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/degoogle-your-android-phone/</guid><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;De-google your Android devices, and using FOSS softwares and MicroG instead of Google-specific services.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文是一次將常見 Android 手機「去 Google 化」的嘗試。在完全去除 Google 服務的 Android 手機上，不使用 Google 服務，僅在必要時通過瀏覽器存取 Google 服務，真的可行嗎？可以的。例如下圖全新安裝的 Android 系統，絕大多數都是自由（或尊重自由的）軟體（忽略下面的「Google 電話」和「Google 簡訊」圖標，那只是「主題圖示（Themed icons）」給AOSP默認的電話和簡訊應用應用的圖示而已）：&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/crDroid-Home.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;h1&gt;「去 Google 化」的含義&lt;/h1&gt;
&lt;p&gt;按照維基百科的定義，&lt;a href=&quot;https://en.wikipedia.org/wiki/DeGoogle&quot;&gt;「去 Google 化（De-google）」&lt;/a&gt; 是近年來在歐美地區興起的草根運動，就是將常見的 Google 服務從 Android 裝置拔掉，不再依賴 Google 提供的服務。旨在保護隱私，對抗監控資本主義，降低未來的&lt;a href=&quot;https://ckhung0.blogspot.com/2014/10/barrier-of-exit.html&quot;&gt;轉移成本(Barrier of exit)&lt;/a&gt;，脫離圍牆花園等等。&amp;lt;/br&amp;gt;
根據威脅模型（Threat model）分析，去 Google 化可以分爲許多方面。從最簡單的擺脫 Google 服務，例如 Gmail、Google 行事曆，到完全移除 Google 服務及其內容，具體的行爲看個人需求來定義。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Reddit有個&lt;a href=&quot;https://www.reddit.com/r/degoogle/&quot;&gt;r/degoogle&lt;/a&gt;板專門在討論去Google化的策略。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;本文要講的，是最「極端」的「去 Google 化」例子，將 Android 裝置內所有 Google 服務及內容全部清除。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;解鎖手機 &amp;amp; 刷機&lt;/h1&gt;
&lt;p&gt;在中國大陸以外（現在連中國大陸的手機都內建了）的手機是多半裝有 &lt;a href=&quot;https://www.android.com/intl/zh-TW_tw/gms/&quot;&gt;Google 服務&lt;/a&gt;的，且很多 APP 都依賴牠們，根本無法解除安裝。如果在內建 Google 服務的系統上強制反安裝 Google 程式，很有可能會讓作業系統出現問題，嚴重的可能會使裝置無法正常使用。因此最好把手機刷成偏原生風格的 Android 系統，例如 LineageOS 或者是 GrepheneOS，這類系統不會內建任何 Google 服務或者組件，想要 de-google 還是很方便的。另外想要 Root 也是非常容易的。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;我們需要停止使用 Google 服務，但是大多數應用都依賴 Google 服務，甚至有些應用偵測到沒有 Google 服務甚至就不給執行。這時候就要通過「microG」這個開源的替代品來取代專有的 Google Play 服務。牠可以將 Google 服務所蒐集的資料最小化，同時還可以保證依賴 GMS 的程式正常執行。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;microg/GmsCore&quot;}&lt;/p&gt;
&lt;p&gt;去 Google 化自然是拒絕使用 Google Play 的，但是妳總得需要一個圖形化應用商店吧？當然妳可以像我一樣，通過修改 Android 系統分割來爲 Android 添加一個套件管理器（比如 &lt;code&gt;opkg&lt;/code&gt; &lt;code&gt;apk&lt;/code&gt; 等等，讓牠看起來更像一個嵌入式 Linux 作業系統）。只是這樣比較複雜，得需要解決根目錄唯讀和 SELinux 問題。因此本文將介紹使用僅包含自由軟體的「F-Droid」（的替代「Neo Store」），以及 「Aurora Store」 來取代 Google Play。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;我使用的手機是高通於2024年「發佈」的&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/sm8750-mtp-review/&quot;&gt;驍龍 8 Elite MTP原型機&lt;/a&gt;，雖然是一臺僅面向開發人員和OEM的測試機&lt;a href=&quot;%E9%99%90%E9%87%8F%E7%99%BC%E5%94%AE%EF%BC%88%E4%BE%86%E6%BA%90%E6%9C%AA%E9%A9%97%E8%AD%89%EF%BC%89&quot;&gt;^1&lt;/a&gt;，但也可以用於軟體開發和除錯。雖然高通的「原廠」系統本身就接近原生
Android 了，但還是內建了高通的私貨，有大量測試軟體。在這裏我選擇乾淨一點，直接將手機刷成 LineageOS。原因無他，就 LineageOS 支援的手機最多，預設的情況下不會內建 Google 框架，可以自由選擇是否安裝。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;LineageOS 內建的組件很少，但是我認爲原生 Android 就足夠我日常使用了。而且 Matarial you 介面設計簡單好看，足夠好用。
如果妳的手機還有 Lineage OS 之外的刷機包，也沒有必要一定限定要使用 Lineage OS，像 GrepheneOS 也很不錯，提供的隱私保護比絕大多數 Android 客製化系統更徹底。但須要注意是否有發佈不包括 Google 服務的刷機包。刷機後建議通過 KernelSU 或者 Apatch 來取得 Root，雖然並非必要，但是可以方便修改系統檔案。&lt;/p&gt;
&lt;h1&gt;安裝 microG&lt;/h1&gt;
&lt;p&gt;MicroG 是 Google 服務的自由開源實作。也是 Google 服務 API 的開源實作，用以取代 Google 服務，避免應用無法運作。讓妳方便從應用存取 Google 賬號，與常見的 GAPPS 安裝檔相比，microG 是完全開源的 Google API 重新實作的服務，而不是使用 GMS 二次分發。
雖然使用 microG 有點「做半套」的感覺，但是 microG 本身不需要任何 Root 權限，日後想要解除安裝也比較方便，而且也不需要登入 Google 賬戶。&amp;lt;/br&amp;gt;
但是，microG 只能部分取代 Google 服務，對於付費的部分就未必支援。Google 自家開發的應用也有不支援 microG 的。&lt;/p&gt;
&lt;p&gt;microG 不需要任何權限就可以安裝，不過需要作業系統支援「簽名僞裝」，一般只有基於 LineageOS 的客製化系統才會支援這個功能，所以我選擇 LineageOS 作爲演示。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;至 &lt;a href=&quot;https://github.com/microg/GmsCore/wiki/Downloads&quot;&gt;microG 網站&lt;/a&gt;下載 &lt;code&gt;microG services&lt;/code&gt; &lt;code&gt;microG companion&lt;/code&gt; 二個應用，建議通過「Neo Store」訂閱 &lt;a href=&quot;https://microg.org/fdroid/repo/?fingerprint=9BD06727E62796C0130EB6DAB39B73157451582CBD138E86C468ACC395D14165&quot;&gt;microG 套件庫&lt;/a&gt;，方便接受更新。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/Neo-Store.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;開啓「microG 設定」，點按「自我檢查」，將要求的功能視個人需要開啓，之後回到主畫面點按「註冊爲 Google 裝置」，這樣就可以登入 Google 賬號。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/microG-Services.png&quot; width=&quot;35%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/microG-Services-reg.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;有應用要求通過 FCM 推送通知時，就會列在「雲端推播」，如果不想使用專有的FCM推送，認爲不夠保護隱私，請改用 UnifiedPush 替代。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/microG-Services-cloud.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;如果要使用導航等地圖軟體，建議安裝SIM卡並開啓WiFi。然後在「位置」中，開啓「向線上服務發出請求」「從GPS學習」這二個選項，使用線上的 position.xyz 服務獲取位置。&lt;strong&gt;最新的 microG 已經不支援採用 UnifiedNip 的後端服務了&lt;/strong&gt;，這樣地圖類應用的導航功能才可以運作。我的經驗是，使用 OpenStreetMap 圖資的 CoMaps 可以快速完成定位，而 OSMAnd 則是慢吞吞的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;microG 也支援 Play integrity 驗證。但是想要通過這個驗證卻非常有難度，如果使用一個早就被注銷的 &lt;code&gt;keybox&lt;/code&gt; 配合 Play integrity Fix 和 Tricky store 模組就可以做到通過 Basic 和 Device 驗證，當然也可以做到 Strong 驗證。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;修改系統網路設定&lt;/h1&gt;
&lt;p&gt;以下內容涉及修改系統 DNS、NTP伺服器、GPS等設定，請根據下面短片操作：&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;657&quot; height=&quot;370&quot; src=&quot;https://www.youtube.com/embed/E1U5qoiR1fM&quot; title=&quot;How to De-Google LineageOS&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;安裝 Neo Store 和 Aurora Store&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;除了不要安裝 Google 應用之外，也不要安裝任何中國開發的應用！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這二個應用商店不使用 Root 權限的情況下，安裝應用都必須要手動安裝。&lt;/p&gt;
&lt;p&gt;通常 Google Play 才有的應用，F-Droid 總會有對應的開源替代品。而 Aurora Store 就是方便下載只有 Google Play 才有的應用。例如 Mosavi。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;裝 Neo Store，用來下載開源應用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;::github{repo=&quot;NeoApplications/Neo-Store&quot;}&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/Neo-Store-main.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;之後點按右上角的「設定」圖示，點按「套件庫」，開啓「IzzyOnDroid F-Droid Repo」「F-Droid Archives」這二個套件庫，就可以下載應用了。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/screenshot/Neo-Store-repo.png&quot; width=&quot;50%&quot;&amp;gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;至 &lt;a href=&quot;https://auroraoss.com/&quot;&gt;Aurora Store&lt;/a&gt;網站，或者在 Neo Store 檢索「Aurora Store」下載安裝。Aurora Store 開啓後，點按「匿名」來訪問 Google Play 商店。Aurora 會使用一組匿名的 Google 賬號，方便妳下載 Google Play 上的免費應用了。如果妳登入自己的 Google 賬戶，就可以下載之前購買過的付費應用，但是無法購買新的應用。另外如果想要存取不同地區的 Google Play 商店，需要使用 VPN 來連線登入。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::warning
Aurora Store 會把 microG 服務當作真的 Google 服務，因此請將其加入「黑名單」來避免被更新！
:::&lt;/p&gt;
&lt;p&gt;有些APP執行依賴GMS服務，單純裝 Aurora Store 是不夠的，得依賴 microG。不過microG無法100%實現所有GMS的功能。&lt;/p&gt;
</content:encoded></item><item><title>探討使用終端機看網頁的方法，在只有TTY控制臺的地方也可以使用網際網路</title><link>https://blog.cloudflare88.eu.org/posts/browser-on-terminal/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/browser-on-terminal/</guid><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::warning
本文是不適宜在工作時間展示的內容（NSFW），包含成人內容（文字描寫和圖像），請謹慎閱讀。
:::&lt;/p&gt;
&lt;p&gt;一直在想能不能通過 Linux 或是 FreeBSD 的TTY控制臺，不使用任何桌面環境來訪問網際網路，因爲現在的瀏覽器都太肥了。無論是
FireFox 還是 Chrome 都是如此，我們的老祖宗（不過才過去三十年而已）都是用 DOS 文字介面訪問 BBS 的。&lt;/p&gt;
&lt;p&gt;其實臺灣的PTT就可以支援SSH訪問（ &lt;code&gt;ssh bbsu@ptt.cc&lt;/code&gt;）而不用開瀏覽器。在只能用SSH或是 Telnet 的工作階段也可以上去發廢文，尤其適用於那些只提供控制臺的裝置，比如採用嵌入式 Linux 的機上盒、路由器或者數據機之類。不過部分終端機可能受限於編碼問題，中文可能無法顯示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/ptt-on-ssh.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;那我們沒理由不能通過終端機造訪網路。&lt;/p&gt;
&lt;p&gt;特別是像一些嵌入式裝置，只有幾百MB的記憶體，CPU時脈又相對低下，而且都使用客製化的 Linux 作業系統，根本沒有足夠的硬體資源去支援常見的桌面環境的執行。連一些簡單的 WM 都會卡頓，至於吃上幾GB甚至十幾GB記憶體的瀏覽器就更不用想了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;（主機：嗯...唔...哈啊！要去了！...要去了...嗯...哈...&lt;strong&gt;Kernel Panic&lt;/strong&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;現在的主流社群媒體網站，大抵只有像 &lt;a href=&quot;https://news.ycombinator.com/&quot;&gt;Hacker News&lt;/a&gt; 和 &lt;a href=&quot;https://old.reddit.com/&quot;&gt;舊版 Reddit&lt;/a&gt;能夠方便用終端機來瀏覽，其他的網站還是太「臃腫」了一點。其實我的部落格採用了基於 Astro 的框架，已經盡最大可能爲低階裝置進行了優化，且介面也較爲簡潔明朗，但還是不適合用終端機來檢視。從下面的對比就可以看出：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/normal-view.png&quot; alt=&quot;Using LibreWolf visiting my blog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/terminal-view.png&quot; alt=&quot;Using terminal visiting my blog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果妳認爲架設自己的網站，必須要用諸如 Jekyll 或者 Astro 之類的框架，或是還要考慮 CSS，JavaScript之類的功能，那看看這個 &lt;a href=&quot;https://motherfuckingwebsite.com/&quot;&gt;Motherfucking Website&lt;/a&gt; 吧，事實證明，妳不需要任何框架也可以架設自己的網站！去他媽的。（圖片來源：&lt;a href=&quot;https://e-hentai.org/g/3824815/4a6f47354d/&quot;&gt;[Komi]Kazusa NTR | 和纱NTR 1（Blue Archive）[Chinese]&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/ehentai/lol.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Damn! Working form zero to one, misconfigured &amp;lt;/br&amp;gt;
Dumping RAM and it sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&lt;em&gt;--- Adopted from &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/blow-your-fuses/&quot;&gt;Blow Your Fuses -- A FOSS Parody of You&apos;re Mine by DAGames&lt;/a&gt; by EDKPiepaint&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;啊...久等了。看看 Linux 有哪些終端瀏覽器可以使用，這些瀏覽器可比主流的瀏覽器方案要簡單多了呢。這些文字瀏覽器不需要像是 X11, Wayland 之類任何顯示協定就可以工作，甚至妳在工作期間還可以偷偷開SSH來摸魚一下，牠們的響應速度也很快，對於低階裝置和嵌入式裝置非常友好。不過妳在檢視或下載檔案時，可能還是需要圖形環境。&amp;lt;/br&amp;gt;
文字瀏覽器在各大 Linux 發行版或者 FreeBSD 套件庫都有收，終端機的特色就是鍵盤操作，可不是用滑鼠點一點就可以上網了。如果妳會用 Vim 或是 EE 之類編輯器的話，相信妳只需要檢視每個程式的 &lt;code&gt;man page&lt;/code&gt; 就能上網了。&lt;/p&gt;
&lt;h1&gt;EWW 和 Lynx&lt;/h1&gt;
&lt;p&gt;僞裝成文字編輯器的作業系統 EMacs 有內建 &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_mono/eww.html&quot;&gt;EWW&lt;/a&gt; 文字瀏覽器，而 &lt;a href=&quot;https://github.com/lynx-family/lynx&quot;&gt;Lynx&lt;/a&gt; 則是目前最古老的文字瀏覽器。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;lynx-family/lynx&quot;}&lt;/p&gt;
&lt;p&gt;這兩個文字瀏覽器只能瀏覽 Web 1.0 時代的網頁，或者是純文字頁面的網頁（比如 &lt;a href=&quot;https://www.openbsd.org/78.html&quot;&gt;OpenBSD 網站&lt;/a&gt; 或者 &lt;a href=&quot;https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/evbarm-earmv5/INSTALL.html&quot;&gt;NetBSD 的安裝指導&lt;/a&gt; ，至於&lt;a href=&quot;https://e-hentai.org/?page=1&quot;&gt;Ehentai (我最喜歡的網站，可以看H漫)&lt;/a&gt; 也還勉強看）用這個上網的時候，我的世界是黑暗的，人生是黑白的，感覺就像回到了三十年前。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/lynx.png&quot; alt=&quot;Lynx showing NetBSD 10.1 evbarm port installation guide&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;w3m&lt;/code&gt; 則是支援CSS的文字瀏覽器，文字版面比較接近網頁原本的樣子和外觀。至於文字以外的介面需要靠想象力，&lt;code&gt;w3m&lt;/code&gt; 同樣支援展示圖片，這需要終端機支援 &lt;a href=&quot;https://sw.kovidgoyal.net/kitty/graphics-protocol/&quot;&gt;Graphics protocol&lt;/a&gt; 或者通過 Sixel 像素畫來展示 。例如通過 Kitty 和 ImageMagick 就可以在終端機內繪製完整解析度的圖片。播放影片的話，就通過 &lt;code&gt;w3m&lt;/code&gt; 載入外部程式，解析鏈接後丟給 &lt;code&gt;mpv&lt;/code&gt; 播放即可。&lt;/p&gt;
&lt;p&gt;這大概是目前還堪用的瀏覽器，既能看網頁，又可以看圖，RAM佔用不到 100MB，而且速度很快。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/netbsd-installation-guide.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;assets/netbsd-installation-guide-w3m.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;當然，也有終端機渲染彩色網頁的例子...&lt;/p&gt;
&lt;h1&gt;跑在容器中的瀏覽器： Browsh 與 Carbonyl&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;assets/ehentai/cool.jpg&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;assets/ehentai/dude.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;...如果看了還不加阻止的話，我的資證大概會被注銷吧...嗯，不管怎麼樣，想要看到這些東西的話，也要瀏覽器支援 WebGL（並非）且支援渲染圖片才可以啊。但是終端機沒有任何方法直接渲染圖片，所以看妳和別人愛愛——不是，是檢索其牠嵌入式作業系統原始碼是不可能的啊。不過我們在像是 Docker 或者 Podman 容器中執行一個瀏覽器，用以保證基本的 CSS，JavaScript 和網頁排版正常，然後將畫面串流到終端機裏面，就可以解決這個問題了~ &lt;a href=&quot;https://github.com/browsh-org/browsh&quot;&gt;Browsh&lt;/a&gt; 就是這樣做的。不過這樣會在背景執行一個 FireFox 實例，這樣的RAM佔用與正常的 FireFox 沒有區別。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;browsh-org/browsh&quot;}&lt;/p&gt;
&lt;p&gt;比 Browsh 更進階的有基於 Chromium 的 &lt;a href=&quot;https://github.com/fathyb/carbonyl&quot;&gt;Carbonyl&lt;/a&gt;，沒有執行一個瀏覽器實例，而是渲染後傳到終端機裏面。讓 WebGL 運作並且使用 Unicode 顯示字元，除了文字以外就是馬賽克，RAM佔用不到100MB，並且在SSH階段也可以使用，不過實用性不高。我打中文都會變成韓文，實用性還可以，至少可以檢視一些網頁，並且可以下載檔案。支援通過 Docker 或者下載二進位檔案運行，對於嵌入式裝置來說是個不錯的瀏覽器。而且在最新的版本中還&lt;a href=&quot;https://github.com/fathyb/carbonyl/releases/tag/v0.0.3&quot;&gt;改善了 BitMap 渲染&lt;/a&gt;，網頁元素更加易於辨識了（所以吶，末花，老師很快就可以從終端機看妳和別人愛愛的影片了，而且不會擔心被發現！[^1]）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/terminal-view.png&quot; alt=&quot;Using terminal visiting my blog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;當然，也可以用一些專門爲某個網站設計的 TUI 程式，例如 Reddit，GitHub，YouTube，Spotify，GitHub 上面一檢索就會有一大把任妳挑選。但是不是所有網站都可以通過 TUI 呈現。&amp;lt;/br&amp;gt;
如果遇到不能通過 TUI 展示的網站（例如 Thread 和 Line）呢？要怎麼辦才好啊？&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;實在不行就回歸簡易GUI瀏覽器吧&lt;/h1&gt;
&lt;p&gt;那就採用像是 &lt;a href=&quot;https://github.com/qutebrowser/qutebrowser&quot;&gt;Qutebrowser&lt;/a&gt; 的方案，只有展示網頁的功能，類似 Android 和 Windows 的 Webview 一樣。其餘功能都通過 Vim 的快捷鍵去操作，這樣就可以了，完全不需要通過滑鼠去瀏覽內容。而且圖片還比較清楚，使用組合鍵就可以「點按」網頁上任意元素。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;qutebrowser/qutebrowser&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/qutebrowser.png&quot; alt=&quot;Qutebrowser showing Buildroot website&quot; /&gt;&lt;/p&gt;
&lt;p&gt;牠採用 QtWebEngine 渲染網頁元素，載入完整網頁的話RAM佔用與一般 Chromium 瀏覽器無異（約2~4GB，內建 Adblocker 用於擋廣告）。所以這個比較適合用在硬體資源豐裕的嵌入式裝置上，比較適合用於控制中心、點餐機、和POS等類似用途裝置上，也能夠較爲方便地被編譯到 Buildroot，OpenEmbedded，Yocto 之類的嵌入式 Linux 或者其牠基於BSD的嵌入式作業系統。&lt;/p&gt;
&lt;p&gt;[^1]:至少使用 Linux 或者 BSD 的話...是不會被發現啦！畢竟沒有人會用 Linux 來辦公吧？&lt;/p&gt;
</content:encoded></item><item><title>Software Crew -- A FOSS Parody of Shape of You by Ed Sheeran</title><link>https://blog.cloudflare88.eu.org/posts/software-crew/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/software-crew/</guid><description>One day they&apos;ll fear my doom, and I don&apos;t care about your cookies too.</description><pubDate>Tue, 03 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;(寫於2022年3月)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/79urGY80Xs0?si=MEvT8OzcP3G_Dh8c&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Intro&lt;/h1&gt;
&lt;p&gt;The Windows isn&apos;t the best operating system,&amp;lt;/br&amp;gt;
so the Linux is what I&apos;m used,&amp;lt;/br&amp;gt;
All of the hardware lives inside the kernel,&amp;lt;/br&amp;gt;
Turning into specific files,&amp;lt;/br&amp;gt;
Then I grabbed some devices already out-of-date,&amp;lt;/br&amp;gt;
trust me, I&apos;ll give you a chance &amp;lt;/br&amp;gt;
Then took my code out, insert floppy to PC, &amp;lt;/br&amp;gt;
And then we started compile &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;And I&apos;m singing like: &amp;lt;/br&amp;gt;
FOSS is what we want,&amp;lt;/br&amp;gt;
Our source code is hardened with security patches,&amp;lt;/br&amp;gt;
Come on now, follow my lead,&amp;lt;/br&amp;gt;
I am crazy but that&apos;s just me,&amp;lt;/br&amp;gt;
Your phones, never compile too much,&amp;lt;/br&amp;gt;
Grab your code and send your battery free, &amp;lt;/br&amp;gt;
Come on now, follow my lead,&amp;lt;/br&amp;gt;
Come, come now, follow my lead,&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;I&apos;ll build my software crew, &amp;lt;/br&amp;gt;
Defending all spywares too, &amp;lt;/br&amp;gt;
And when the days&apos;re coming now, &amp;lt;/br&amp;gt;
I&apos;ll revenge like the greedy, &amp;lt;/br&amp;gt;
One day they&apos;ll fear my doom, &amp;lt;/br&amp;gt;
And I don&apos;t care about your cookies too. &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 2&lt;/h1&gt;
&lt;p&gt;One day our story begins,&amp;lt;/br&amp;gt;
We&apos;ve beginning our first trial, &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Our goal is to take down the data center,&amp;lt;/br&amp;gt;
with tons of spywares live in, &amp;lt;/br&amp;gt;
We took hours and hours to meltdown attacks,&amp;lt;/br&amp;gt;
causing big finanical losses, &amp;lt;/br&amp;gt;
Now continue our coding, &amp;lt;/br&amp;gt;
begin your compiling, &amp;lt;/br&amp;gt;
Tell watchdog let the floppy read &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
And I&apos;m singing like: &amp;lt;/br&amp;gt;
FOSS is what we want,&amp;lt;/br&amp;gt;
Our source code is hardened with security patches,&amp;lt;/br&amp;gt;
Come on now, follow my lead,&amp;lt;/br&amp;gt;
I am crazy but that&apos;s just me,&amp;lt;/br&amp;gt;
Your phones, never compile too much,&amp;lt;/br&amp;gt;
Grab your code and send your battery free, &amp;lt;/br&amp;gt;
Come on now, follow my lead,&amp;lt;/br&amp;gt;
Come, come now, follow my lead,&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus 2&lt;/h1&gt;
&lt;p&gt;I&apos;ll build my software crew, &amp;lt;/br&amp;gt;
Defending all spywares too, &amp;lt;/br&amp;gt;
And when the days&apos;re coming now, &amp;lt;/br&amp;gt;
I&apos;ll revenge like the greedy, &amp;lt;/br&amp;gt;
One day they&apos;ll fear my doom, &amp;lt;/br&amp;gt;
And I don&apos;t care about your cookies too. &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge&lt;/h1&gt;
&lt;p&gt;Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;
Come on, let&apos;s compiling, come on,&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus 3&lt;/h1&gt;
&lt;p&gt;I&apos;ll build my software crew, &amp;lt;/br&amp;gt;
Defending all spywares too, &amp;lt;/br&amp;gt;
And when the days&apos;re coming now, &amp;lt;/br&amp;gt;
I&apos;ll revenge like the greedy, &amp;lt;/br&amp;gt;
One day they&apos;ll fear my doom, &amp;lt;/br&amp;gt;
And I don&apos;t care about your cookies too. &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
(Come on, let&apos;s compiling, come on,)&amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;
Everyday discovering something brand new, &amp;lt;/br&amp;gt;
I&apos;ll build my software crew &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>無名小站（未完成） -- Nameless station</title><link>https://blog.cloudflare88.eu.org/posts/a-nameless-station/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/a-nameless-station/</guid><description>4C 65 61 76 65</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;這是一個位於拿維鐵路[^1]上的無名小站，沒有站房，只有兩個新修建的大理石月臺和不遠處早就滿是雜草的貨運月臺。月臺周圍則是荒地，長滿雜草。在寒冷的冬季更顯的荒涼。&amp;lt;/br&amp;gt;
很久以前，這裏曾是重要的交通樞紐，可是由於車站修建時間較早，隨着時代的發展，一些舊車站因爲建築質量、設施破舊問題不得不停止辦理客貨運業務開始改建升級。&amp;lt;/br&amp;gt;
原本熙攘的車站，如今只剩下風穿過電線杆的嘶嘶聲。&amp;lt;/br&amp;gt;
新修建的大理石月臺在冬日慘白的陽光下閃着冷冽的光，與那座被雜草淹沒的貨運月臺形成了鮮明的對比——一個是試圖追趕時代的嶄新面孔，一個是留給歲月咀嚼的殘破記憶。枯黃的草莖在磚縫中頑強地探出頭，包裹着鏽跡斑斑的鐵軌，彷彿要把這段鐵路重新拽回土地裏去。&amp;lt;/br&amp;gt;
偶爾，一列現代化的動車組會從這裏呼嘯而過，速度快得連空氣都發出爆裂的震動。車窗裏的人或許只會看到一抹模糊的灰色身影掠過，沒人會注意到這個連站牌都尚未掛上的無名之地。&amp;lt;/br&amp;gt;
然而，在當地老一輩人的口中，這裏曾有個響亮的名字。那時，蒸汽機車的白煙能遮住半邊天，挑着擔子的商販和背着行囊的旅客曾把這片荒地踩得紮紮實實。現在，改建升級的工程像是被時間按下了暫停鍵，停工的塔吊如同一隻巨大的、凍僵的鐵鳥，孤獨地俯瞰着這片靜謐。
在這個寒冬，無名小站像是一個守候者，沉默地等待着第一場雪將新與舊的裂痕完全覆蓋，也等待着下一次汽笛聲能真正為牠停駐。&amp;lt;/br&amp;gt;
推開鏽跡斑斑的大門，來到早就遺棄的施工現場，腳下的碎石與凍土發出乾枯的碎裂聲。這裡散落著幾捆已經發黑的鋼筋，像是一捆捆枯萎的肋骨，被隨意地丟棄在尚未完工的配電房旁。&amp;lt;/br&amp;gt;
牆上還殘留著半截褪色的工程告示，上面的紅字被風雨剝蝕得只剩「安全」二字，在寒風中顯得格外諷刺。我走進那座半掩在雜草中的舊貨運倉庫，空氣中瀰漫著一種陳舊的、混雜著鐵鏽與乾苔蘚的氣味。陽光透過屋頂破碎的瓦片投射下來，形成幾道昏暗的光柱，塵埃在光影中瘋狂旋轉，像是無數微小的幽靈在重演當年的喧囂。&amp;lt;/br&amp;gt;
我不自覺地走向那條被廢棄的側線鐵軌。鏽跡已經侵蝕進鋼材的深處，摸上去冰冷刺骨。遠處，主線道上的信號燈跳動了一下，由紅轉綠，清脆的「咔噠」聲在死寂的荒野中傳得很遠。就像往常一樣，我不是來這裏回憶往昔的，我只是爲了發揮我的小興趣，
來這裏找一些我最喜歡的東西，僅此而已。&amp;lt;/br&amp;gt;
沿着鐵軌搜尋，一路上除了枯萎的雜草以外似乎再也沒有什麼其他的東西了。正要打算離開，就在此時，我注意到了遠處股道合攏處旁邊有一個黑點，在這片黃色爲主色的枯草叢中顯的格外顯眼。我便走上前去，撥開枯草，看到一個像手機一樣的東西躺在裏面。說是像手機，倒不如說像一個小型無線基地臺。&amp;lt;/br&amp;gt;
破損的熒幕，和落滿塵土的黑色外殼，憑藉我的經驗判斷，這是一臺驍龍 MTP835 原型機。只是歷經了不知多少年的風吹日曬，原本漂亮的黑色外殼早已佈滿裂紋，鮮豔的黑色也早已褪去，變成了淺灰色。裸露在外的主機板也早就鏽跡斑斑，電池也不知所蹤。唯獨熒幕左上角的驍龍 logo，依然清晰可辨。&lt;/p&gt;
&lt;p&gt;[^1]:是 Minecraft 地圖「原信地鐵專案」(GNU/Genshin Metro Project) 中正在修建的高速鐵路。牠北起拿派里（有時也被寫作「拉派裏」），南至維蘭德，全長386公尺。&lt;/p&gt;
</content:encoded></item><item><title>MMD Skin -- 採用 Rust 編寫的模組，把妳最喜歡的動漫角色帶到「當個創世神」的方塊世界，給妳與衆不同的遊戲體驗 ~</title><link>https://blog.cloudflare88.eu.org/posts/mmdskin-minecraft-mod-review/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/mmdskin-minecraft-mod-review/</guid><description>把自己最喜歡的動漫角色放到麥塊中是多麼有趣的事情！</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://3d.nicovideo.jp/works/td91904&quot;&gt;Iochi Mari&lt;/a&gt; （伊落瑪麗）人物模型，Nexon Co., Ltd 版權所有&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;把動漫人物模型放到 Minecraft 中並藉由玩家控制的模組很早就有了（比如 CustomSteve 之類），但是很多模組要麼版本太舊，新版本根本不相容，要麼就是私有軟體，常常做一些見不得人的勾當。&amp;lt;/br&amp;gt;
嗯，我知道「當個創世神」自從1.16以後在遊戲中內嵌了追蹤程式，蒐集使用者隱私。而且麥塊本身就是不開源的專有軟體，但是妳很難在 Linux 上找到可以跨平臺協作的遊戲了。&amp;lt;/br&amp;gt;
今天 Piepaint 要來介紹的就是這樣一款開放原始碼的麥塊模組，牠可以把妳最喜歡的動漫人物用於替換遊戲裏原本方方正正的 Steve ，同時還可以實現自訂人物動作，能夠更好豐富妳的遊戲體驗。&amp;lt;/br&amp;gt;
放上實際體驗效果圖片：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/allwinner-station.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/mari-station.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/platform-test.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/first-person.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;下載與安裝&lt;/h1&gt;
&lt;p&gt;模組本身是遵循 MIT 協議開放原始碼的，到 GitHub 或者 &lt;a href=&quot;https://modrinth.com/mod/mmdskin&quot;&gt;Modrinth&lt;/a&gt; 上去下載即可。截至目前開發者只釋出了針對 Minecraft 1.21.1 的檔案下載，支援 Forge，Fabric 和 NeoForge。根據自己的偏好下載即可。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;shiroha-233/MC-MMD-rust&quot;}&lt;/p&gt;
&lt;p&gt;下載完後，把 &lt;code&gt;.jar&lt;/code&gt; 檔案丟到遊戲實例的 &lt;code&gt;mods&lt;/code&gt; 資料夾下，然後啓動 Minecraft 即可。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;這是我的測試實作，CPU 是相容 Arm V8 指令集的 RK3588 處理器，採用內建 Mali G610 繪圖卡，是一臺標準的「嵌入式系統」：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/testpc.png&quot; alt=&quot;A fastfetch screenshot showing specs on my embedded PC&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;基本用法&lt;/h1&gt;
&lt;p&gt;遊戲啓動後，會在自己的工作目錄下建立名爲 &lt;code&gt;3d-skin&lt;/code&gt; 的資料夾，並同時建立 &lt;code&gt;EntityPlayer&lt;/code&gt; &lt;code&gt;DefaultAnim&lt;/code&gt; &lt;code&gt;CustomAnim&lt;/code&gt; &lt;code&gt;CustomAnim&lt;/code&gt; &lt;code&gt;DefaultMorph&lt;/code&gt; 和 &lt;code&gt;CustomMorph&lt;/code&gt; 六個資料夾。這六個資料夾的用途如下：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.minecraft/
└── 3d-skin/
    ├── EntityPlayer/      # 使用者的模型
    │   ├── ModelA/        # MMD 人物模型資料夾
    │   │   ├── model.pmx  # 模型本身 (.pmx/.pmd)
    │   │   ├── *.png      # 紋理
    │   │   ├── dance.vmd  # 模型動作（非必要）
    │   │   └── smile.vpd  # 模型場景（非必要）
    │   └── ModelB/
    │       └── ...
    ├── DefaultAnim/       # 模組內建動作
    ├── CustomAnim/        # 使用者自訂動作
    ├── DefaultMorph/      # 內建場景
    └── CustomMorph/       # 自訂場景
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，我們需要下載人物模型，通常會是 &lt;code&gt;.pmx&lt;/code&gt; 檔案。將模型解壓縮後，放到 &lt;code&gt;EntityPlayer&lt;/code&gt; 資料夾中。如果模型有紋理或者其他材質的話，也要把牠放到資料夾下（這部分通常會是 &lt;code&gt;.png&lt;/code&gt; 或者 &lt;code&gt;.tga&lt;/code&gt; 格式的繪圖檔）。&amp;lt;/br&amp;gt;
進入世界後，按住左 Alt 鍵，就可以看到 Mod 的內建設定。將滑鼠遊標指向對應的選項後，按一下左鍵再鬆開 Alt 鍵，就可以打開對應的設定項目。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/modsettings.png&quot; alt=&quot;Mod settings&quot; /&gt;&lt;/p&gt;
&lt;p&gt;選擇右上角的「Model switch」選項，模組就會讀取妳放在資料夾下的人物模型，此時選擇妳喜歡的模型，然後按下「Done」按鈕（模組本身僅支援簡體中文和英語）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/model-selector.png&quot; alt=&quot;Model switch options showing 2 model avaliable&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果模型看着有顆粒感，或是畫面比較突兀，嘗試調整一下「渲染設定」吧！在設定裏啓用「tone shading」 和「Enable Outline」來打開三渲二和輪廓渲染，（我個人還會打開「第一人稱視角」來增強遊戲主觀視點）即可獲得媲美「原神」和「終末地」的遊戲體驗（？）&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/toon-shading.png&quot; alt=&quot;Render setting, showing &amp;quot;Enable Outline&amp;quot; and &amp;quot; Tone shading&amp;quot; options enabled&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/sample.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通過「Action select」選單還可以設定動作~ 選擇 「Lie Down」就可以讓人物趴下來，方便進行後入和其他體位（嘿嘿嘿~）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/actions.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/motions-example.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通過「Expression select」選單也可以爲妳的人物更換表情，也可以點擊右下的「+」按鈕來新增表情（啊嘿顏最好了~）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/emotions.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;也可以控制人物的材質可見性，來決定顯示的內容！（野外露出也可以）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/material-settings.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最後，妳可以配置使用舞臺，匯入妳的舞臺設定，讓人物跳舞給妳看！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minecraft/stage-mode.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;使用體驗&lt;/h1&gt;
&lt;p&gt;模組本身還處於早期階段，能夠做到這種程度已經很不容易了，我個人覺得目前沒有什麼問題，一些嚴重的 bug 也沒有遇到。唯一的問題是第一人稱的視角似乎還需要改進，視野總是高高的，很容易產生要撞到頭的感覺。另外預設的走路動作又有些慢了點。
如果想要啓用着色器（shader），需要關閉「tone shading」，否則會遇到渲染問題，目前我實際測試不需要關閉選項的光影有 BSL Shaders 和 Chaopic13 7.1.1 Lite。&lt;/p&gt;
</content:encoded></item><item><title>Blow Your Fuse -- A FOSS Parody of You&apos;re Mine by DAGames</title><link>https://blog.cloudflare88.eu.org/posts/blow-your-fuses/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/blow-your-fuses/</guid><description>Why some people flash vendor firmware on a prototype machine?</description><pubDate>Wed, 11 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/IlouAA8mRZo?si=x4_vmCH_hNjUocuT&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;Hi, I&apos;m Piepaint &amp;lt;/br&amp;gt;
Nice to meet ya! &amp;lt;/br&amp;gt;
Unlock your board and call me Palawan! &amp;lt;/br&amp;gt;
Secure&apos;s your game? Just show your code &amp;lt;/br&amp;gt;
So you can generate your hash &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
So you saw efuse right? But that&apos;s not enough! &amp;lt;/br&amp;gt;
You haven&apos;t even finish reading your doc&apos;! &amp;lt;/br&amp;gt;
When you configure wrong keys, it goes upside down! &amp;lt;/br&amp;gt;
With a hard-bricked phone on your hand &amp;lt;/br&amp;gt;
Here&apos;s a tip, replace your chip &amp;lt;/br&amp;gt;
Or you&apos;ll see my broken functions! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;Oh, oh, oh, hi there~ &amp;lt;/br&amp;gt;
Welcome to my prototype museum! &amp;lt;/br&amp;gt;
Oh, oh, oh, hi there~ &amp;lt;/br&amp;gt;
Please don&apos;t fail, I run out of stock! &amp;lt;/br&amp;gt;
Oh, oh, oh, hi there~ &amp;lt;/br&amp;gt;
Burn out fuses, let me secure ya! &amp;lt;/br&amp;gt;
Oh, oh, oh, hi there~ &amp;lt;/br&amp;gt;
Oh yeah, I blew it up! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Pre-chrous&lt;/h1&gt;
&lt;p&gt;Every hobbist come here closer, &amp;lt;/br&amp;gt;
We can compile them all together &amp;lt;/br&amp;gt;
Grab some source code and have a drink, &amp;lt;/br&amp;gt;
Send your computer on fire &amp;lt;/br&amp;gt;
Gonna take a picture then post on my blog, &amp;lt;/br&amp;gt;
It&apos;s time to secure my hard work &amp;lt;/br&amp;gt;
Pay attention, this is a blow job &amp;lt;/br&amp;gt;
You have to use my secured loader &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
You&apos;re unlocking, I&apos;ll make it even harder &amp;lt;/br&amp;gt;
You&apos;re upgrading, I can know you better &amp;lt;/br&amp;gt;
When you disassembly for your freedom, &amp;lt;/br&amp;gt;
I&apos;ll sue you, let&apos;s meet on court &amp;lt;/br&amp;gt;
Oh-oh, oh-oh-oh &amp;lt;/br&amp;gt;
I&apos;ll make you scare of me! &amp;lt;/br&amp;gt;
Oh-oh, oh-oh-oh &amp;lt;/br&amp;gt;
You&apos;re voiding your warranty &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous&lt;/h1&gt;
&lt;p&gt;Damn! Build from day to night &amp;lt;/br&amp;gt;
Occupied my time, and shoutin&apos; like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Working form zero to one, misconfigured &amp;lt;/br&amp;gt;
Dumping RAM and it sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Bruning my secure hash, failed &amp;lt;/br&amp;gt;
Replacing my chip sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Debugging a broken modem &amp;lt;/br&amp;gt;
Capturing logs and it sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;Don&apos;t flash things, &amp;lt;/br&amp;gt;
on your phone &amp;lt;/br&amp;gt;
Don&apos;t flash things, &amp;lt;/br&amp;gt;
on your phone &amp;lt;/br&amp;gt;
Don&apos;t flash things, &amp;lt;/br&amp;gt;
on your phone &amp;lt;/br&amp;gt;
Don&apos;t flash things-- &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Nevermind, just go ahead &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous&lt;/h1&gt;
&lt;p&gt;Damn! Build from day to night &amp;lt;/br&amp;gt;
Occupied my time, and shoutin&apos; like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Working form zero to one, misconfigured &amp;lt;/br&amp;gt;
Dumping RAM and it sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Bruning my secure hash, failed &amp;lt;/br&amp;gt;
Replacing my chip sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Damn! Debugging a broken modem &amp;lt;/br&amp;gt;
Capturing logs and it sounds like: &amp;lt;/br&amp;gt;
Screw you, Crashdump! &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;No, the last user run away! &amp;lt;/br&amp;gt;
Guess we&apos;ll fired...&lt;/p&gt;
</content:encoded></item><item><title>解決聯想 Yoga Air 14s 在 Linux 作業系統下載大於1GB的檔案時當機重啓的問題</title><link>https://blog.cloudflare88.eu.org/posts/fix-broken-wifi-card-on-laptop/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/fix-broken-wifi-card-on-laptop/</guid><description>或許打開筆電外殼的行爲很蠢，但是我真的不知道該從哪裏下手了。</description><pubDate>Sat, 31 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;「 You&apos;re broken. And I&apos;ll put you back together.」&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;聯想的驍龍筆電在 Linux 下的體驗是遠勝過 Windows on ARM 的，風扇比較安靜，幾乎不會有「開足馬力」的時候，儘管聲音依舊不能用，但是可以使用KVM 和 Xen，因此可以滿足我所有的用途。&amp;lt;/br&amp;gt;
但是，不知道聯想在韌體裏做了什麼手腳，在更新到 NHCN60WW 版的 UEFI 韌體後，下載超過1GB的檔案時，系統會突然 freeze 掉，然後重啓。我也問過聯想的技術支援，請求提供舊版韌體下載，我自行刷回舊版韌體就可以，但是支援告訴我說我的筆電並沒有韌體更新，還好奇的問我是從哪裏獲得韌體更新的（這些專業的「技術支援」難道不知道自家筆電UEFI韌體是通過 Windows Update 提供的嗎？），最終也沒有給我提供舊版韌體下載。既然筆電廠家的「技術支援」也束手無策的話，唯一的解決方法，就只有使用者自己了。&lt;/p&gt;
&lt;h1&gt;使用外置 USB 無線網路卡不是一個長久的方案&lt;/h1&gt;
&lt;p&gt;對於無線網路這一問題，我曾想過買一個廉價的USB網路卡取代筆電上內建的 Quectel NCM825A PCIE 網路卡。但是檢索了一圈後發現在售的USB網路卡不是外形太大，就是網路速度不佳，而且對 Linux 和 FreeBSD 這種類 UNIX 作業系統相容性不友好，因此這種方法雖然可以解決「燃眉之急」，卻不是長久的方法。&amp;lt;/br&amp;gt;
不過，Windows 下就不會有這個問題。檔案可以正常下載（才怪！之後通過「裝置管理員」查看發現無線網路卡「消失」了），那就改用 Windows 吧？ 然而這只是在&lt;strong&gt;逃避&lt;/strong&gt;問題，而不是&lt;strong&gt;解決&lt;/strong&gt;問題。並且我對於 Windows 的使用已經停留在了5年前，現在 Windows 11 更新的內容，我根本不會使用，很多在 Linux 或者是 BSD 上常用的軟體根本沒有 Windows 版，至於花錢買專有軟體更是不可接受的。&lt;/p&gt;
&lt;h1&gt;通過 UART 獲取日誌&lt;/h1&gt;
&lt;p&gt;市面上常見的零售機可不會像原型機那樣，直接將 UART 通過 Micro USB 暴露出來，而是隱藏在預留的測試點或者微小的金屬點，需要稍加改進才能使用。想要使用 UART 的唯一辦法就是使用工具拆下筆電的外殼，同時也會丟失保固。好在聯想 Yoga 系列的筆電通常都很好拆，擰下底部的四顆金屬螺釘，隨後使用薄片從風口那裏抬起後殼，接着沿着縫隙繞一圈，整個筆電的後殼也就可以取下了。映入眼簾的是一顆碩大的電池和聯想 Yoga Air 14s 的主機板。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/q8x9-overview.png&quot; alt=&quot;Yoga Air 14s laptop with back cover removed&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但是 UART 要從哪裏尋找呢？爲此我在網路上檢索到了一張 Yoga Slim 7x 的檢修圖紙，上面記錄了主機板上預留的一些功能焊點。包括 NFC、數據機在內的硬體功能均在此列，因爲 Yoga Air 14s 和 Yoga Slim 7x 互爲「姊妹機型」，所以包括圖紙在內的軟硬體都是互相通用的。根據圖紙的描述和自己使用電錶測量，最後確定了無線網路卡的 UART 位置和整機的 UART 位置。一個位於網路卡旁邊的兩個金屬點，另一個位於固態硬碟下方的三個孔洞，無需取下硬碟就可以插線除錯（也就是說，我可以自行升級硬碟）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/yoga-datasheet.png&quot; alt=&quot;Repair sheet&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/uart-pad.jpg&quot; alt=&quot;A closer view showing the UART pads of this laptop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;準備三根較長的杜邦線和一個 CH341 燒錄器，將線按照主機板上的絲印進行組裝，然後將燒錄器鏈接電腦或者其他裝置上。嵌入式系統不講究所謂「上位機」的概念，之後安裝 &lt;code&gt;minicom&lt;/code&gt; 並執行 &lt;code&gt;sudo minicom -s&lt;/code&gt; 來設定序列阜和鮑率爲115200：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/minicom-setup.png&quot; alt=&quot;minicom setup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之後，按下電源按鈕，終端機內會有 bootloader 的 log：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.MXF.2.4-00555-HAMOA-1
S - IMAGE_VARIANT_STRING=SocHamoaWP
S - OEM_IMAGE_VERSION_STRING=ip-10-195-200-192
S - Boot Interface: SPI
S - Secure Boot: On
S - Boot Config @ 0x221c8600 = 0x00000001
S - JTAG ID @ 0x221c8744 = 0x3021e0e1
S - OEM ID @ 0x221c8700 = 0x00000040
S - Serial Number @ 0x221c8610 = 0x000004467c0ab1b3
S - Feature Config Row 0 @ 0x221c21e0 = 0x0000000000000000
S - Feature Config Row 1 @ 0x221c21e8 = 0x0000000000000000
S - Core 0 Frequency, 1920 MHz
S - PBL Patch Ver: 3
S - PBL freq: 600 MHZ
S - Cluster: 0, Core: 0
S - --------------------------------------------------
PBL Timestamps (in usecs)(,version/bytes)
--------------------------------------------------
CPBL Start: 181
CPBL HW INIT Start: 573
CPBL HW INIT End: 3105
CPBL APPS Reset Start: 3225
CPBL APPS Sec Packet Init Start: 3486
CPBL APPS Sec Packet Init End: 3506
CPBL APPS Init Start: 3523
CPBL APPS Cache Init Start: 4121
CPBL APPS Cache Init End: 4150
CPBL APPS Core PWRUP Start: 4216
CPBL APPS Core PWRUP End: 4293
CPBL APPS Init End: 4295
CPBL APPS Reset End: 4318
CPBL Exit: 4390
APBL start: 10703,16777218
APBL Boot Media Detect Start: 25815
APBL Boot Media Detect End: 27263
APBL SHELF Load+Auth Start: 27265
        APBL ELF MD Load Start: 34850
        APBL ELF MD Load End: 35058
        APBL ELF Seg Load Start: 35060
        APBL ELF Seg Load End: 38691,131828
                APBL SEQ Valid Set: 38715
                APBL SEQ SA ACK Rcvd: 40738
        APBL ELF MD Load Start: 43310
        APBL ELF MD Load End: 44215
        APBL ELF Auth Start: 44225
        APBL ELF Auth End: 61918
        APBL ELF Seg Load Start: 61918
        APBL ELF Seg Load End: 75321,216272
        APBL ELF Seg Verify Start: 75321
        APBL ELF Seg Verify End: 80553
        APBL ELF MD Load Start: 82640
        APBL ELF MD Load End: 83530
        APBL ELF Auth Start: 83531
        APBL ELF Auth End: 101196
        APBL ELF Seg Load Start: 101198
        APBL ELF Seg Load End: 130485,1227744
        APBL ELF Seg Verify Start: 130485
        APBL ELF Seg Verify End: 136196
APBL SHELF Load+Auth End: 136305
                APBL TME PBL Exit: 136306
                APBL XBL_SC Exit Check: 137008
                APBL XBL_SC Exit Ack: 148173
APBL Exit: 148176
B -    149084 - SBL1, Start
B -    394822 - SBL1 BUILD @ 19:23:22 on Apr 30 2025
B -    399153 - (16f 2d 800)
B -    402264 - (16f 2d 404)
B -    404948 - (16f 2d 402)
B -    408242 - (16f 2d 800)
B -    410469 - (16f 2d 800)
B -    413000 - (16f 2d 404)
B -    416142 - (16f 2d 800)
B -    418612 - (16f 2d 402)
B -    421083 - (16f 2d 402)
B -    423767 - (16f 2d 402)
B -    426481 - (16f 2d 402)
B -    436119 - usb: usb_eud_serial  , 0x7c0ab1b3
D -       275 - sbl1_hw_init
D -      2501 - media_init:1
D -         0 - boot_check_recoveryinfo_partition
D -         0 - boot_recovery_select_boot_partitions
D -         0 - boot_recovery_partitions_info_imem_init
D -         0 - boot_save_sbl_recovery_partition_info
D -       275 - boot_handle_trial_boot
D -         0 - boot_blacklist_disable
B -    469059 - RECOVERY -  Image Load, Start
D -         0 - boot_blacklist_disable
B -    476837 - OEM_MISC -  Image Load, Start
D -     11804 - Auth Metadata
D -     17781 - OEM_MISC -  Image Loaded, Delta - (5492 Bytes)
B -    495564 - QTI_MISC -  Image Load, Start
B -    501542 - Load recovery partition: 82002003
D -     10156 - QTI_MISC -  Image Loaded, Delta - (1100 Bytes)
B -    510051 - APDP -  Image Load, Start
B -    515999 - Load recovery partition: 82002003
D -      9791 - APDP -  Image Loaded, Delta - (1100 Bytes)
D -         0 - boot_dload_dump_security_regions
D -         0 - EUD Init
D -         0 - blacklist enable
B -    536525 - (16f 2d 800)
B -    539362 - (16f 2d 404)
B -    542046 - (16f 2d 402)
B -    544760 - (16f 2d 800)
B -    547444 - (16f 2d 800)
B -    550098 - (16f 2d 404)
B -    552873 - (16f 2d 800)
B -    555496 - (16f 2d 402)
B -    558180 - (16f 2d 402)
B -    560864 - (16f 2d 402)
B -    563548 - (16f 2d 402)
D -     31598 - DP_Milestone
D -     13633 - Auth Metadata
D -     15677 - sbl1_xblconfig_init
B -    586149 - XBL Config -  Image Load, Start
B -    591852 - dtbo_found_count[1]
B -    596610 - DTB  Found: [pre-ddr][88022b02010000][0]
D -      7716 - boot_pre_ddr_dtb_load
D -      6222 - tsens_init_if
D -        31 - boot_check_device_temp
B -    621437 - PM: PM_DT_PARSING_ERR: charger
B -    621498 - BUS: 0, PMIC A:2.1 B:2.1 C:2.0 D:2.0 E:2.0 F:2.0 G:2.0 I:2.0 J:2.0 M:1.3
B -    631472 - BUS: 1, PMIC B:2.0 C:2.0 D:2.0 E:2.0 F:2.0 H:2.0 K:2.0 L:2.0 M:2.0
B -    641110 - PM: Detected Grid is 2
B -    642848 - PM: Reset by PSHOLD
B -    644892 - PM: Reset Type: Hard Reset
B -    771497 - PM: SET_VAL:Skip
B -    772534 - PM: PSI: b0x61_v0x4A OTP: v0x3A
B -    778787 - PM: OEM_PSI post-device-opsi Start
B -    779305 - PM: OEM_PSI post-device-opsi Done
B -    783636 - PM: Device Post Init # RTC: 0, #SDAM: 0
B -    788181 - PM: Device Init # SPMI Transn: 3826
D -    181902 - pm_device_init, Delta
B -    798002 - pm_driver_init, Start
B -    821944 - PM: miniPD
B -    824079 - PM: vbattcell=3735mV
B -    824659 - PM: Driver Init # SPMI Transn: 1471
D -     26413 - pm_driver_init, Delta
D -    221247 - sbl1_pmic_init
D -      2318 - media_init:2
D -         0 - media_init:3
D -       152 - boot_wdog_disable_check
D -       152 - init-logstomedia
D -         0 - shrm_load_cancel
B -    851072 - SHRM -  Image Load, Start
D -     21198 - Auth Metadata
D -     30927 - SHRM -  Image Loaded, Delta - (57052 Bytes)
B -    882304 - CDT not found in any storage media, using defaults
D -     11133 - boot_cdt_init
B -    893558 - CDT -  Image Load, Start
B -    896334 - CDT not found in any storage media
D -      8601 - sbl1_hw_platform_pre_ddr
B -    904965 - vsense_init, Start
D -         0 - vsense_init, Delta
D -     18453 - sbl1_hw_pre_ddr_init
D -       153 - boot_fedl_check
D -         0 - boot_dload_handle_forced_dload_timeout
D -      3599 - sbl1_load_ddr_training_data
B -    934825 - Pre_DDR_clock_init, Start
D -         0 - Pre_DDR_clock_init, Delta
D -     13084 - sbl1_ddr_set_params
B -    946537 - sbl1_ddr_init, Start
B -    955565 - DDR_INIT with shrm.elf
B -    955595 - INFO: PXI based read &amp;amp; write training enabled
B -    981947 - eCDT MRR - Data Starting Address: 0x24056D00
B -    987590 - Returning from DDR_FW_Init
B -    987620 - ddr_init = 1 cold boot
D -     41724 - sbl1_ddr_init, Delta
B -    995154 - 8 channel DDR configuration
B -    998539 - PlatID: 0x121
B -   1002565 - DSF version = 029.54.00
B -   1005341 - Manufacturer ID = 0x6, Device Type = 0x9
B -   1009031 - Rank 0 size = 16384 MB, Rank 1 size = 16384 MB
D -     68747 - sbl1_ddr_init
D -         0 - store-logstomedia
B -   1022817 - do_ddr_training, Start
B -   1062132 - DDR: Start of DDR Training Restore
B -   1264377 - Returning from DDR_FW_Restore
B -   1264560 - Current DDR Freq = 2739 MHz
B -   1268647 - Max enabled DDR Freq = 4224 MHz
B -   1272673 - DDR: End of DDR Training Restore
D -    251564 - do_ddr_training, Delta
B -   1285117 - SecLib initiate DARE sequence start
B -   1285361 - SecLib initiate DARE sequence successful
B -   1292559 - Returning from DDR_FW_Exit
D -    272731 - xbl_trng_ddi_seq
D -         0 - store-logstomedia
D -       518 - xbl_map_smem
D -         0 - boot_smem_debug_init
D -      1312 - boot_smem_init
D -       153 - boot_ddr_share_data_to_aop
D -        61 - boot_populate_ddr_details_shared_table
D -         0 - boot_recovery_partitions_info_smem_init
D -        30 - boot_update_ram_partition_table
B -   1328183 - Pimem init cmd, entry
B -   1332728 - (50000e)
D -      3477 - Pimem init cmd, exit
B -   1342396 - External heap init, Start
B -   1342457 - External heap init, End
D -     30714 - sbl1_post_ddr_init
D -         0 - sbl1_hw_init_secondary
B -   1362160 - DDR -  Image Load, Start
B -   1372378 - dtbo_found_count[1]
B -   1386347 - DTB  Found: [post-ddr][88022b02010000][2800020100000000]
D -     26352 - boot_post_ddr_dtb_load
B -   1392996 - usb: emmc_parti_unavail
B -   1396595 - usb: sdc_parti_unavail
B -   1400255 - usb: Serial - 7c0ab1b3
D -     10827 - boot_usb_update_serial
B -   1407544 - usb: qusb_dci_eud_init
D -      3569 - boot_usb_handle_charger
D -        31 - sbl1_hw_platform_smem
D -         0 - ramdump_load_cancel
B -   1421727 - RamDump -  Image Load, Start
D -      3324 - RamDump -  Image Loaded, Delta - (0 Bytes)
D -         0 - boot_update_abnormal_reset_status
D -         0 - boot_cache_set_memory_barrier
D -         0 - boot_smem_alloc_for_minidump
D -        30 - boot_shrm_mini_dump_init
D -        31 - boot_minidump_register_regions
D -        31 - boot_smem_store_pon_status
D -         0 - boot_clock_init_rpm
D -         0 - boot_vsense_copy_to_smem
D -       305 - sbl1_tlmm_init
D -         0 - sbl1_efs_handle_cookies
B -   1469307 - PM: Detected Grid is 2
B -   1493981 - PM: PM Total Mem Allocated: 12549 
D -     24705 - sbl1_pm_aop_pre_init_wrapper
B -   1498648 - AOP Config -  Image Load, Start
D -       549 - Decompression, Delta
D -     11834 - Auth Metadata
D -     28426 - AOP Config -  Image Loaded, Delta - (5588 Bytes)
B -   1532808 - AOP -  Image Load, Start
D -     12566 - Decompression, Delta
D -     20770 - Auth Metadata
D -      8692 - Segments hash check
D -     80459 - AOP -  Image Loaded, Delta - (99452 Bytes)
D -         0 - aop_loaded
D -         0 - boot_prepare_cpucp
B -   1624430 - CPUCP_DTB -  Image Load, Start
D -       275 - Decompression, Delta
D -     11803 - Auth Metadata
D -     20953 - CPUCP_DTB -  Image Loaded, Delta - (2804 Bytes)
B -   1652307 - CPUCPFW -  Image Load, Start
D -     20130 - Decompression, Delta
D -     20892 - Auth Metadata
D -      3873 - Segments hash check
D -     70699 - CPUCPFW -  Image Loaded, Delta - (156888 Bytes)
D -         0 - boot_reset_cpucp
B -   1732156 - QSEE Dev Config -  Image Load, Start
D -      2989 - Decompression, Delta
D -     12292 - Auth Metadata
D -     23210 - QSEE Dev Config -  Image Loaded, Delta - (24064 Bytes)
B -   1761100 - QSEE -  Image Load, Start
D -     92384 - Decompression, Delta
D -     22113 - Auth Metadata
D -     20130 - Segments hash check
D -    198555 - QSEE -  Image Loaded, Delta - (1120028 Bytes)
D -       397 - sbl1_hw_play_vibr
B -   1968622 - SEC -  Image Load, Start
D -     12535 - Auth Metadata
D -     18117 - SEC -  Image Loaded, Delta - (5432 Bytes)
B -   1987624 - QHEE -  Image Load, Start
D -     39986 - Decompression, Delta
D -     21076 - Auth Metadata
D -      4971 - Segments hash check
D -     98912 - QHEE -  Image Loaded, Delta - (501312 Bytes)
B -   2089829 - APPSBL -  Image Load, Start
D -     12902 - Auth Metadata
D -     14305 - Segments hash check
D -    414678 - APPSBL -  Image Loaded, Delta - (7115652 Bytes)
D -         0 - sbl1_save_appsbl_index
B -   2514054 - SBL1, End
D -   2368142 - SBL1, Delta
S - Flash Throughput, 18398 KB/s  (9346186 Bytes,  508528 us)
S - DDR Frequency, 2736 MHz


UEFI Start     [ 2741]
 - 0x0A7001000 [ 2751] Sec.efi
ASLR          : OFF [WARNING]
DEP           : ON (RTB)
Timer Delta   : +0 mS
RAM Entry 0   : Base 0x0080000000  Size 0x0000E40000
RAM Entry 1   : Base 0x00815A0000  Size 0x0056A60000
RAM Entry 2   : Base 0x00D8600000  Size 0x0000000000
RAM Entry 3   : Base 0x00DE5B0000  Size 0x0019F50000
RAM Entry 4   : Base 0x00FF800000  Size 0x0000800000
RAM Entry 5   : Base 0x0880000000  Size 0x0380000000
RAM Entry 6   : Base 0x0C00000000  Size 0x0400000000
RAM Available : 32543 MB (0x07F1FF0000)
RAM Installed : 32768 MB (0x0800000000)
Minidump      : ON
Init 1 aux cores of 11
Init CPU core 1
Continue booting UEFI on Core 0
Skipped DBI Dump Table, made numentries zero
  &amp;gt; Scheduler up on Core 1
UEFI Ver      : NHCN14WW.250911.BOOT.MXF.2.4-00555-HAMOA-1
Build Info    : 64b Sep 11 2025 11:47:22
Boot Device   : NVME
PROD Mode     : TRUE
Retail        : TRUE
 - 0x0D47D5000 [ 3049] DxeCore.efi 
IsArmV8Smc() return TRUE 
I2cMaster: FAIL open device num 0 Status = 34
I2cMaster: FAIL open device num 3 Status = 34
I2cMaster: FAIL open device num 7 Status = 34
I2cMaster: FAIL open device num 10 Status = 34
I2cMaster: FAIL open device num 11 Status = 34
I2cMaster: FAIL open device num 12 Status = 34
I2cMaster: FAIL open device num 13 Status = 34
I2cMaster: FAIL open device num 14 Status = 34
I2cMaster: FAIL open device num 15 Status = 34
I2cMaster: FAIL open device num 16 Status = 34
I2cMaster: FAIL open device num 17 Status = 34
I2cMaster: FAIL open device num 18 Status = 34
I2cMaster: FAIL open device num 19 Status = 34
I2cMaster: FAIL open device num 20 Status = 34
I2cMaster: FAIL open device num 22 Status = 34
I2cMaster: FAIL open device num 23 Status = 34
I2cMaster: FAIL open device num 24 Status = 34
I2cMaster: FAIL open device num 25 Status = 34
I2cMaster: FAIL open device num 26 Status = 34
Device booted from NVME/SPI_NOR 
TpmType = 0x6654504D. 
LoadOEMSecureApps: Internal Error or no apps found. Status = 0x00000005
EnterpriseMgtLib : Deleting UEFI NV variable : EnterpriseMgtClientPolicies of size : 28 bytes
EnterpriseMgt : EnterpriseMgtClientPolicies not found.
EnterpriseMgt : RegisterAddress: 0x01FDE000 Mask: 0x00000001 Value: 0x00000001 RegReadValue: 0
x00000000 FinalValue: 0x00000001 
EnterpriseMgt : Registering for OnReadyToBoot event Callback.
MfgModeMgmtDxeEntryPoint: QueryAppId for mfgmodemgmt app passed with AppId: 5
HW Wdog Setting from PCD : Disabled
SLT Platform Key not found: 14
LfcDisableAcpiModeEntry cmd 0x86 return rdBuf[0]=0!!
H2O DXE Chipset Services can not be found!
 OemSvcGetNovoButtonStatus EcInitializeDevice Status = Success !!
OemSvcGetNovoButtonStatus== 0
H2O DXE Chipset Services can not be found!
 OemSvcSwitchFoolProofFnCtrl Status = Success !!
OemSvcSwitchFoolProofFnCtrl pass 
-----OemSvcSwitchFlipToBoot ----
-----gQcomPmicSchgProtocolGuid 0----
OemSvcSwitchFlipToBoot:: storing to sdam pon from lid setting = 1 
Create ReadyToBoot event for Hotkey Mode status:0x0 
OemKernelServices Call: OemSvcUpdateOemBadgingLogoData 
OemKernelServices OemSvcUpdateOemBadgingLogoData, Status : Unsupported
OemKernelServices InitializeBadgingSupportProtocol, Status : Success
ButtonsDxeTest: Keypress SDAM data payload 0 
H2O DXE Chipset Services can not be found!
NvmExpressDriverEntry GetVariable IsCapsulePendingInPersistedMedia Not Found or data is FALSE
warning: failed to locate QMI protocol
Failed to read DGPU Env variable, Status 0xE
WinPciPowerOn: DGPU:PlatformType or SKU didn&apos;t match for Client 0
pil-tpfv Partition not found
pil-tpfv Failed to load ELF file
pil-tpfv Partition not found
pil-tpfv Failed to load ELF file
pil-tpfv Backup partition Image load Failed PStatus: D 
ddr_regions-&amp;gt;no_of_ddr_regions : 3 
DDR Region0 Start_address : 0x0000000080000000, Size  : 0x0000000080000000 
DDR Region0 granule size  : 0x0000000080000000, Offset: 0x0000000000000000 
DDR Region1 Start_address : 0x0000000880000000, Size  : 0x0000000380000000 
DDR Region1 granule size  : 0x0000000080000000, Offset: 0x0000000000000000 
DDR Region2 Start_address : 0x0000000C00000000, Size  : 0x0000000400000000 
DDR Region2 granule size  : 0x0000000080000000, Offset: 0x0000000000000000 
Overriding PIL cfg by caller
[CreateSecureBootDxe] Clean CurrentActivePolicy variable fail: Not Found
override usb_mode: : 0x1
usb_port_retimer_init, LANE_A: core: : 0x0
Retimer Chip_id: : 0x8830
Retimer FW: : 0x5030009
Retimer_RESET_CFG: 0x1
usb_shared_ps8830_init, usb_mode: : 0x1
UsbConfigLibOpenProtocols: USB: Platform has Retimer
UsbStartController: Starting Core 3 in mode: 1
usb_shared_i2c_write, write failed reg|data : 0x70000
usb_shared_i2c_write, write failed reg|data : 0x70000
SSUsb4InitCommon: repeater_init failed for core 3
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
UsbStartController: Starting Core 4 in mode: 1
usb_shared_i2c_write, write failed reg|data : 0x70000
SSUsb5InitCommon: repeater_init failed for core 4
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
QcomChargerDxe:: bat_sts = 48,  7437,  -424  27.
warning: failed to locate QMI protocol
proxy vote done SubsysId=36
Before set GPIO Device version = 2 
NvmePowerControlDxe: IsDeviceInOffModeCharging: 0
Overriding PIL cfg by caller
WlanGetChargerPowerStatus: sPowerTypeInfo.bCanFlash = 1,  bOffModeCharging = 0
WlanGetChargerPowerStatus: Status 0x0
smem_get_addr: SMEM get addr failed! smem_type=429QFWK_SSR: lpass smp2p update 0x0 -&amp;gt; 0x0
QFWK_SSR: lpass smp2p update 0x0 -&amp;gt; 0x2
QFWK_SSR: Bit 1 is set: SSR subsystem err handling service is UP on lpass
QFWK_SSR: lpass smp2p update 0x2 -&amp;gt; 0x6
QFWK_SSR: Bit 2 is set: Proxy Unvote is set on lpass
proxy unvote done subsysId=1 hold_time=432ms
Get Variable PnpRuntime Fail - Not Found!!
DMI region signature error!!
Get Variable PnpRuntime Fail - Not Found!!
Speed Bin value: 8
CPR Rev value: 1
LenovoEdidEntry
IdeaPad support Edid Override
RegisterProtocolNotify
LenovoEdidEntry complete with status: Success
DisplayId_DataBlockOffsetSetup: failed, valid DisplayId version not foundLenovo EDID override 
function entry
Lenovo EDID override function get EDID size: 256 
EDID CheckSum OK
EDID PanelModulename 44433032. 
EDID ProductCode 8AC2. 
LenPanleID status Success. 
EDID EdidData-&amp;gt;ProductCode 8AC2. 
Lenovo EDID override function Success
Lenovo EDID override function exit
[LOGO] OemSvcChangeDefaultLogoImage entry
Warning! The logo location did not meet BGRT requirement.
[WinAcpiUpdate]UpdateACPIEntry: GetDefectiveParts succeeded returning defectivePartsBitMask = 
(0x0)
PCIe enum (0x80) start : 6789
Training start : 6897
Wait for link up start : 6917
PCIe Link up on port 4
Link up Failed..!! PCIe 6 LTSSM State 0x0
Training complete : 7167
Port 4 : x2, Gen 3
Powered down PCI6
PCIe Links ready : 7169
PCIe Links setup in 380 ms
 PciRootBridgeEnumerator - end with RootBridgeDev = 0xD0FF0898, status Success
PCIe Port 4 Gen 3 Equalization
Link Status 2 Register = 0x1E
[Lane, Eq Ctrl, Local Pre, Local Cursor, Local Post, Remote Pre, Remote Cursor, Remote Post]
[0, 0x5555, 0, 24, 0, 1, 23, 0]
[1, 0x5555, 0, 24, 0, 0, 24, 0]
 StartManagingRootBridge - end with RootBridgeDev = 0xD0FEF018, status Success
 PciGetBusRange: MinBus = 0x0 with status Success
 PciPciDeviceInfoCollector - end with RootBridgeDev = 0xD0FEF018, status Success
Align bits: 21, Len 0x200000, Base 0x7C400000
H2O DXE Chipset Services can not be found!
reqId=5, isAri=1, isSkp=0
reqId=12, 1 segments, isAri=1, isSkp=1
reqId=8, 1 segments, isAri=1, isSkp=1
ConnectSts : Attach, Data Role  : DFP (HOST Mode), Lane : CC2, CoreNum : 2
UsbStartController: Starting Core 2 in mode: 1
override usb_mode: : 0x1
usb_port_retimer_init, LANE_B: core: : 0x2
Retimer Chip_id: : 0x8833
Retimer FW: : 0x5020008
Retimer_RESET_CFG: 0x1
usb_shared_ps8830_init, usb_mode: : 0x1
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
EnableSLTLoopback: xhc_slt_enable SltLbEnabled 0
Enabled L1ss on 4
Setup L1ss took 0 ms
UsbEnumeratePort: new device connected at port 0, HubIfc =0xD0FB4898 
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0xC)
Query MailBox Id:10,Status:Not Found
Query MailBox Id:11,Status:Not Found
Query MailBox Id:12,Status:Not Found
Query MailBox Id:13,Status:Not Found
Query MailBox Id:14,Status:Not Found
RawFsSimpleFsOpen:Failed to locate file/directory in partition.
: FsRoot-&amp;gt;Open returned Not Found
: BlockGetDPP returned Not Found
UpdatePcdFromDpp GetDPP status=Not Found
LfcRtREntryPoint UpdatePcdFromDpp Failed!
Failed to get ESRT firmware info, Status = Not Found
Failed to find handle for given root device type. Status: Success
UsbRootHubResetPort:Port 0, No device after reset, return device failure 0
UsbEnumNewDevRootHub --: port 0, devstate = 0x7 
ps8830DeviceInit - Core 0, instance 4
ReadReg - I2CHandle is NULL.
ReadReg - I2CHandle is NULL.
ReadReg - I2CHandle is NULL.
ReadReg - I2CHandle is NULL.
FmpDeviceGetVersionString 0x00000000
FmpDeviceGetVersionString 0.0.0.0
PwrBtnShutDown create DetectPwrBtnEvt success
[AcpiOverrideCallBack]  Create AcpiOverrideCallBack Event status= Success
HypDtFixupEntryPoint : Reading of OsConfigTableSelection failed,checking DT setting 
HypDtFixupEntryPoint : Skipping overlay of hyp dt nodes for non-Gunyah hypervisor.OsConfigTabl
eSelectionFlag = 0x0 
 Could not find the Reset Data region .
UsbEnumeratePort: new device connected at port 1, HubIfc =0xD0FB4898 
ps8830DeviceInit - Core 2, instance 2
[FmpDeviceGetVersion] Version is 0x05020008
[FmpDeviceGetVersion] Version is 0x05020008
FmpDeviceGetVersionString 0x05020008
FmpDeviceGetVersionString 8.0.2.5
UsbEnumNewDevRootHub: SUPER_PLUS on port 1
UsbCreateDesc: met mal-format descriptor
UsbParseInterfaceDesc: failed to create interface descriptor
UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.
Failed to generate random data using secure algorithm 0: Unsupported
Failed to generate random data using secure algorithm 1: Unsupported
Failed to generate random data using secure algorithm 2: Unsupported
Failed to generate random data using secure algorithm 3: Unsupported
Failed to generate random data using secure algorithm 0: Unsupported
Failed to generate random data using secure algorithm 1: Unsupported
Failed to generate random data using secure algorithm 2: Unsupported
Failed to generate random data using secure algorithm 3: Unsupported
Failed to generate random data using secure algorithm 0: Unsupported
Failed to generate random data using secure algorithm 1: Unsupported
Failed to generate random data using secure algorithm 2: Unsupported
Failed to generate random data using secure algorithm 3: Unsupported
Failed to generate random data using secure algorithm 0: Unsupported
Failed to generate random data using secure algorithm 1: Unsupported
Failed to generate random data using secure algorithm 2: Unsupported
Failed to generate random data using secure algorithm 3: Unsupported
PwrBtnShutDown be init  [ 8482]
Is not on Off Mode charging
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
Tpm2NvRead - responseCode - 28B
/local/mnt/workspace/CRMBuilds/BOOT.MXF.2.4-00555-HAMOA-1_20250430_121005/b/boot_images/boot/Q
comPkg/Drivers/TrEEDxe/TpmDxe.c..SubmitCommand: 1097 Failed! input = 0x1  
Tpm commandCode 0x14E. ResponseCode 0x28B. 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有別於手機平臺上把作業系統和 bootloader 一起放在快閃記憶體上的做法，在 Windows 平臺上，bootloader 被單獨放在了一顆16MB的 SPI flash 上，而作業系統則放在SSD中。不僅提升了啓動效率，也同時避免了SSD壽命耗盡時導致筆電開機就進入EDL的「悲劇」，高通真是很聰明呢！(?) 至於「安全啓動」嗎...一般的零售機都會啓用，所以我並沒有感到意外。再有，聯想是違反GPL協議的公司，所以他們在自家的筆電上做出什麼行爲都不奇怪！之後，登入系統，需要注意的是 Ubuntu 默認沒有啓用 UART 日誌輸出，需要修改核心引數，追加&lt;code&gt;console=ttyMSM0,115200n8&lt;/code&gt;引數，使得 &lt;code&gt;dmesg&lt;/code&gt; 會向 UART 輸出log。&amp;lt;/br&amp;gt;
再次開機，直接通過序列控制臺登入系統。通過 &lt;code&gt;wget&lt;/code&gt; 從 Debian 網站下載一個大小 3.7GB 的映像，在一段時間後，系統當機了。重開機之後，我便通過日誌看到了重開機的原因：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;B -    642848 - PM: Reset by PSHOLD
B -    644892 - PM: Reset Type: Hard Reset
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結合之前日用原型機的經驗與 Lumo 的判斷（我討厭Google，不要他追蹤我！），這是 CPU 被 PMIC 強制拉低電平（PS_HOLD）導致了硬重啓的發生，與作業系統及軟體沒有關係。在高通平臺上，能夠拉&lt;code&gt;PS_HOLD&lt;/code&gt;的「實體」只有牠的「遠端處理器」了，再結合下載檔案時當機的特點，那毫無疑問就是無線遠端處理器的問題了（無線遠端處理器的問題，我只遇到過一次，是在一加6T上用 postmarketOS，嘗試把內建的無線網路卡切換到監聽模式檢索周圍的AP，然後當機進入Crashdump）。只是無線網路卡的 UART 測試點太小，想要鏈接杜邦線就需要自己焊接，這是比較危險的做法。因此，網路卡的韌體到底發生了什麼，我可能無法知曉，但是這個問題依然可以解決。&amp;lt;/br&amp;gt;
實際上，關於高通的WCN7850網路卡以及配套的&lt;code&gt;ath12k&lt;/code&gt;驅動程式，在主線核心中一直就有問題，主要表現在無法連接部分5G頻率的無線網路，以及核心無法識別網路卡的問題，社群普遍認爲這可能與網路卡的韌體有關。在我的筆電上，則需要考慮UEFI韌體的問題（我有諮詢過開發高通原型機的專業人員，他們給出的推論是「PCIE的程式碼實作可能有問題」）。但是聯想根本就不提供UEFI韌體下載啊！那要怎麼刷呢？&amp;lt;/br&amp;gt;
最後我通過網路上有人分享的 Slim 7x 的 UEFI 韌體，通過燒錄器刷入後，再次通過UART登入系統，下載同樣的 Debian 映像。但是並沒有多少改善，並且當機重啓後會遇到PCIE裝置初始化失敗的問題：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ 219.234019] ath12k_pci 0004:01:00.0: of_irq_parse_pci: failed with rc=134 
[ 219.255331] ath12k_pci 0004:01:00.0: pci device id mismatch: 0xffff 0x1107 
[ 219.269849] ath12k_pci 0004:01:00.0: failed to claim device: -5 
[ 219.280733] ath12k_pci 0004:01:00.0: probe with driver ath12k_pci failed with error -5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;唯一的解決辦法是從UEFI關閉無線網路卡，但是重開機後發現網路卡依舊可用，那就再次測試，這次我改用&lt;code&gt;iperf3&lt;/code&gt;從我的單板機上進行網路吞吐量測試，發現依然可以引起這一問題：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@pakala-YOGA-Air-14s-Q8X9:~# iperf3 -c 10.0.0.166 -R -b 200M                              
Connecting to host 10.0.0.166, port 5201
Reverse mode, remote host 10.0.0.166 is sending
[  5] local 10.0.0.131 port 33156 connected to 10.0.0.166 port 5201
Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.MXF.2.4-00555-HAMOA-1
S - IMAGE_VARIANT_STRING=SocHamoaWP
S - OEM_IMAGE_VERSION_STRING=ip-10-195-200-192
S - Boot Interface: SPI
S - Secure Boot: On
S - Boot Config @ 0x221c8600 = 0x00000001
S - JTAG ID @ 0x221c8744 = 0x3021e0e1
S - OEM ID @ 0x221c8700 = 0x00000040
S - Serial Number @ 0x221c8610 = 0x000004467c0ab1b3
S - Feature Config Row 0 @ 0x221c21e0 = 0x0000000000000000
S - Feature Config Row 1 @ 0x221c21e8 = 0x0000000000000000
S - Core 0 Frequency, 1920 MHz
S - PBL Patch Ver: 3
S - PBL freq: 600 MHZ
S - Cluster: 0, Core: 0
S - --------------------------------------------------
PBL Timestamps (in usecs)(,version/bytes)
--------------------------------------------------
（後面的內容與上次的一樣）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我將吞吐量限制到200Mbps，這並不是很高，而是長時間的「RX Ring」累積，導致的當機。&amp;lt;/br&amp;gt;
此外，log 中有一段訊息引起了我的注意：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PCIe Link up on port 4
Link up Failed..!! 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可能是因爲PCIE控制器沒有復位導致的，這也可以與上面的 &lt;code&gt;dmesg&lt;/code&gt; 對應。&lt;/p&gt;
&lt;h1&gt;最後是如何解決的？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;(I&apos;m) Neither an user, nor a programmer &amp;lt;/br&amp;gt;
(They) Shipping (a) firmware full of mistakes &amp;lt;/br&amp;gt;
Capturing all logs, (but) void my warranty &amp;lt;/br&amp;gt;
But I never cares, And I&apos;ve stay determined -- &amp;lt;/br&amp;gt;
I&apos;ll fix all bugs for you.&amp;lt;/br&amp;gt;
---- Adopted from &lt;em&gt;Bugs Thru Life: A FOSS Parody of Walk Thru Fire by Vicetone &amp;amp; Meron Ryan&lt;/em&gt;
&amp;lt;/br&amp;gt;
---- &lt;em&gt;Written by Hamoa Oryon and her best friend, EDKPiepaint&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很遺憾，韌體和UEFI程式碼的問題我無法改善，即使我想辦法取得了驍龍 X Elite 的 BSP 原始碼，也會因爲「硬體安全啓動」而被攔在外面。唯一的辦法只有嘗試更換網路卡的韌體。在 Ubuntu 的論壇中發現不少使用者也遇到了網路卡相關的問題，大部分都與網路鏈接相關&lt;a href=&quot;%5B%E6%9C%89%E9%97%9C%E7%9A%84%E5%95%8F%E9%A1%8C%E5%8F%8D%E9%A5%8B%5D(https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2138754)&quot;&gt;^1&lt;/a&gt;。和我
遇到的問題完全不同，那是否可以套用這一問題的解決方法呢？我決定試一下。首先，前往 &lt;a href=&quot;https://git.codelinaro.org/clo/ath-firmware/ath12k-firmware/-/tree/main?ref_type=heads&quot;&gt;Linaro 的GitLab &lt;/a&gt;下載網路卡的韌體，然後安裝牠們，重開機。&amp;lt;/br&amp;gt;
我知道這個決定有點像是在「碰運氣」，因爲我沒有辦法改動核心對硬體的初始化流程，更不可能對韌體做除錯，換韌體基本上就是最便宜、也最容易回復的實驗。至少在風險可控的前提下，可以先排除「韌體本身壞掉」這個可能性。其次，既然 &lt;code&gt;dmesg&lt;/code&gt; 和 &lt;code&gt;debugfs&lt;/code&gt; 都指向韌體崩潰，我更傾向把問題先歸類爲「韌體或其載入流程的錯」，而不是 PCIe 本身的硬體瑕疵。&amp;lt;/br&amp;gt;
實際動手前，我先做了幾個小準備：把現有韌體完整備份，並記下當時的核心版本與模組載入順序；同時把能穩定重現問題的測試流程寫清楚（例如固定下載同一個大檔、記錄重開機前的 &lt;code&gt;dmesg&lt;/code&gt; 與 &lt;code&gt;journalctl -k&lt;/code&gt; 片段）。這樣就算更換韌體後出現新問題，也能很快回到原狀，或者把變化縮小到可比對的範圍。&amp;lt;/br&amp;gt;
之後，編輯 &lt;code&gt;/etc/modprobe.d/wireless.conf&lt;/code&gt; 檔案，改用這些核心模組開機：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options cfg80211 ieee80211_regdom=GB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重開機，再次嘗試下載同樣的映像，發現下載速度降低（5~7MB/s) ，且沒有再遇到當機問題。使用 &lt;code&gt;wget&lt;/code&gt; 下載時，可以獲得10Mb/s的下載速度，但是不會引起當機，如果同時下載的檔案較多，下載速度會降低到大約每秒幾百千字節。在更新到6.19核心後下載速度有明顯提升，但整個作業系統依然穩定，目前沒有再次當機過。&amp;lt;/br&amp;gt;
這裡的體感很矛盾：速度變慢，但穩定性顯著提升。這讓我更確信是韌體層面的「崩潰」而非單純訊號或路由器造成的問題。雖然這不是完美解（畢竟性能仍不理想），但至少把系統從「會突然重開機」變成「可以正常工作」。對我來說，這一步是把問題從「災難級」降到「可忍受」，讓我可以繼續觀察並等待上游修正。&amp;lt;/br&amp;gt;
當然，在啓用核心的&lt;code&gt;debugfs&lt;/code&gt;後，發現系統重啓的原因是網路卡的韌體崩潰導致的，具體的原因暫時不清楚。不過，知道了簡單的原因，總比什麼都不知道好。或許打開筆電的行爲會永久破保固，卻也總比「閉着眼睛開車」好！只有從 log 下手才能明白問題發生的原因，並因此產生解決方案。&lt;/p&gt;
</content:encoded></item><item><title>架設 Windows 11 ARM 容器，實現環境隔離 -- Docker 架設 Windows 11 ARM 容器</title><link>https://blog.cloudflare88.eu.org/posts/windows-arm-on-docker/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/windows-arm-on-docker/</guid><pubDate>Sat, 17 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;本文重點討論如何使用 Docker 架設 Windows 11 ARM 容器，將必須的 Windows 應用安裝於其中，防止隱私被蒐集。&lt;/p&gt;
&lt;h1&gt;寫在前面&lt;/h1&gt;
&lt;p&gt;原本以爲筆電上裝 Ubuntu 搭配 &lt;code&gt;box64&lt;/code&gt; 轉譯執行 64位元 X86 應用應用程式就足夠了，在最近的幾天裏又想辦法用 &lt;code&gt;box64&lt;/code&gt; 轉譯執行 Wine 跑部分 Windows 應用程式，但是有相當多的程式會開不起來。通過控制臺看log 也不知道如何除錯，但是！學校每次讓完成一些任務時提供的程式都是專有軟體，而且還只有 Windows 版...在2026年了，還在秉持「單一平臺」的開發理念簡直就是一種錯誤的想法！不過我不是開發者，不能要求廠家推出 Linux 版，更何況還是 ARM 筆電的 Linux 作業系統，只能想辦法去把這個應用跑起來。再者，在 Linux 上用 Wine 跑 Windows 程式本身就是政治不正確的行爲，有那麼多 Linux 原生的程式不用，卻偏偏想辦法跑 Windows 程式，這是不尊重自由軟體精神的表現。這樣在 Linux 上跑 Windows 程式的方法就只剩下了虛擬機和其牠方法了。&lt;/p&gt;
&lt;h1&gt;安裝 Docker&lt;/h1&gt;
&lt;p&gt;首先根據 &lt;a href=&quot;https://docs.docker.com/engine/install/ubuntu/&quot;&gt;Docker 的官方文檔&lt;/a&gt;，添加 Docker 的套件庫，然後安裝 Docker:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 新增 Docker 套件庫的GPG金鑰：
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 添加 Docker 套件庫：
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&quot;)
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，通過 &lt;code&gt;sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;/code&gt;命令安裝 Docker。然後啓用 Docker 的 Systemd 服務。之後將使用者加入 &lt;code&gt;docker&lt;/code&gt; 群組，重開機後即可使用 Docker 命令。&lt;/p&gt;
&lt;h1&gt;架設 Windows 11 ARM 容器&lt;/h1&gt;
&lt;p&gt;本文所使用的專案來自 GitHub，妳可以在這裏檢視其原始碼：&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;dockur/windows-arm&quot;}&lt;/p&gt;
&lt;p&gt;在自己的工作目錄下建立一資料夾，命名爲 &lt;code&gt;windows-on-docker&lt;/code&gt;，然後進入該資料夾，新增 Docker compose 檔：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  windows:
    image: dockurr/windows
    container_name: windows
    environment:
      VERSION: &quot;11&quot;  # 如果不想使用微軟官方的映像，可以改成其牠WoA映像下載連結。
    devices:
      - /dev/kvm
      - /dev/net/tun
    cap_add:
      - NET_ADMIN
    ports:
      - 8006:8006
      - 3389:3389/tcp
      - 3389:3389/udp
    volumes:
      - ./windows:/storage # 也可以指定本機的 Windows 映像檔。
    restart: always
    stop_grace_period: 2m
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後通過 &lt;code&gt;docker compose up&lt;/code&gt; 命令啓動容器，或者使用下面的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -it --rm --name windows -e &quot;VERSION=11&quot; -p 8006:8006 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v &quot;${PWD:-.}/windows:/storage&quot; --stop-timeout 120 docker.io/dockurr/windows
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意電腦必須支援 KVM 虛擬化才可以。對於高通驍龍845[^1]、SC8280XP、X Elite 等支援 EL2 異常層級的晶片，需要每次在啓動 Linux 之前在 UEFI Shell 中手動加載 &lt;code&gt;slbounce&lt;/code&gt; 驅動進行 Secure Launch，才能使 Linux 核心初始化 hypervisor，並啓用 KVM。這個行爲會使 ADSP 噴掉，所有依賴 ADSP 的硬體將不工作，因爲 ADSP 是由 hypervisor初始化的。有關如何啓用 KVM 的方法，可參考&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/alpine-on-kvm/&quot;&gt;上一篇文章&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/working-kvm-demo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;執行指令後，如果沒有任何錯誤訊息，且妳的裝置支援KVM，就可以開啓瀏覽器，在地址欄鍵入 &lt;code&gt;http://127.0.0.1:8006&lt;/code&gt; 來訪問 Windows 11 的桌面環境。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/windows-on-docker-cli.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之後，Windows 11 的安裝過程會自動開始，只需等待大約15分鐘即可。安裝完後會自動登入，預設使用者名稱是 Docker，沒有密碼。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/windows-vnc.png&quot; alt=&quot;Windows 11 UI over VNC&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;改善使用體驗&lt;/h1&gt;
&lt;p&gt;容器啓動後，默認的解析度是 &lt;code&gt;800×600&lt;/code&gt;，且QEMU的虛擬顯示卡不支援 Windows 的 Direct X 3D 加速，因此不太適合執行遊戲、存取線上視頻等對於繪圖卡有要求的應用，只能勉強執行文書類應用。但這樣的好處是不需要額外的顯示驅動就可以執行應用，而且不會遇到圖形API不相容的問題。&lt;/p&gt;
&lt;h2&gt;提升解析度&lt;/h2&gt;
&lt;p&gt;雖然QEMU的虛擬顯示卡不支援 Windows 的 3D加速，但還是可以讓容器使用 Virtio GPU 虛擬繪圖卡提升解析度。只需要在 Docker compose 檔中增加以下設定：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  VGA: &quot;virtio-gpu&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後重新啓動容器，就可以調整解析度了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/windows-docker-improved.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;調整虛擬磁碟大小&lt;/h2&gt;
&lt;p&gt;默認的虛擬磁碟大小是 64GB，可以調整到自己需要的大小，方法是在 Docker compose 檔中增加以下設定：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  DISK_SIZE: &quot;256G&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後重新啓動容器，C槽的大小應該會變成256GB。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;修改CPU和記憶體&lt;/h2&gt;
&lt;p&gt;Docker 默認會分給 Windows 11 2個CPU核心和4GB記憶體。這個預設值對於絕大多數文書處理應用完全夠用了，配合輕量化的 Midori 瀏覽器和 FrogFind 搜尋引擎（提示作業系統太新而不給執行？修改瀏覽器UA即可。）也可以實現訪問網際網路，記憶體用量也有富餘。對於驍龍 X Elite 而言，增加容器使用的CPU核心和記憶體大小，也不錯。如果想要調整CPU和記憶體大小，只需修改 Docker compose 擋的 &lt;code&gt;environment&lt;/code&gt; 區段，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  RAM_SIZE: &quot;8G&quot;
  CPU_CORES: &quot;4&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後重新啓動容器，就可以應用新的CPU數量和記憶體大小了。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;在地化 Windows 11 容器&lt;/h2&gt;
&lt;p&gt;修改使用者名稱和登入密碼：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  USERNAME: &quot;sunxi&quot;
  PASSWORD: &quot;kaanapali&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;爲 Windows 11 設置中文語言支援：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  LANGUAGE: &quot;Chinese&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改鍵盤佈局：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;environment:
  REGION: &quot;en-US&quot;
  KEYBOARD: &quot;en-US&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其牠進階使用方式可在專案的 GitHub 原始碼的 &lt;code&gt;Readme&lt;/code&gt; 中查看。&lt;/p&gt;
&lt;p&gt;[^1]:對於驍龍845等手機平臺的晶片，只有未開啓硬體安全啓動的裝置（原型機、測試機、部分零售機如 SHIFT6mq）且配置了支援 Secure Launch &lt;code&gt;devcfg&lt;/code&gt; 配置的韌體才可以通過執行 Secure launch 使 HLOS（高階作業系統，諸如 Windows，Linux，ChromeOS等）核心執行於 EL2 異常層級下，並可以使用硬體虛擬化。&lt;/p&gt;
</content:encoded></item><item><title>雙持手機的變遷，從 Android + Android 成爲 Android + Linux</title><link>https://blog.cloudflare88.eu.org/posts/as-a-dual-phone-user/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/as-a-dual-phone-user/</guid><pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;講講最近的雙持體驗變化。&lt;/p&gt;
&lt;h1&gt;早期&lt;/h1&gt;
&lt;p&gt;首先來講早期。高中以前的手機都是父母換新後留下來給我的，長期以來都是如此，我就有了奇妙的手機雙持體驗。最初的目的是爲了更好的拍照和滿足日常使用，加之沒有錢買iPhone。所以一直都是 Android + Android 的組合。&amp;lt;/br&amp;gt;
2020年之前（真快啊，不是嗎？）我使用的手機是從父親手中留下的酷派 Cool 1，因爲那時對於規格一無所知，所以只會從手機的快閃記憶體容量來分辨手機的優劣，加之根本沒有錢買手機。我就一直釘在 Cool 1 上。雖然那臺手機有著兩顆1300萬畫素的鏡頭，但是效果依然難以入眼，基本的錄音也不清晰。仿佛低階的 Android 手機成爲廠商 cost-down 的事情是理所當然一般。好在錄影效果很不錯，可以錄製 4K 30FPS 的影片，熒幕素質也不錯。唯一的問題是驍龍652效能過於低下，即使刷成 LineageOS 也堪用。後來因爲 CPU 過熱脫焊，又只好暫時依賴一臺退下來的華爲 Y9 （2018） 來度日，我很討厭華爲這家手機廠商，因爲他們的手機壓根不給使用者解鎖！想要解鎖還要「幾經周折」，不是把手機「大卸八塊」就是鑽漏洞，或是刷工程韌體解決。雖然最後還是把手機解鎖了，然後刷成 Lineage OS 17.1 的 GSI，可刷機之後發現效果竟然不如原廠韌體好用！不過好在拍照不錯，有獨特的韻味。喇叭的聲音還有一種特殊的音箱感。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
但是，或許是因爲老媽不懂手機，她的手機早已經過數不清的專有軟體的摧殘，內建的eMMC記憶體壽命將盡，反應十分緩慢。不過高中的入學考試我考了不錯的成績，父親同意給我買一臺新手機作爲我的獎勵。&amp;lt;/br&amp;gt;
那臺手機就是 Pixel 4 XL，牠有6GB的RAM，64GB的UFS記憶體。和效能強勁的驍龍855處理器，而且非常容易解鎖，牠就理所當然的成爲了我最喜歡的東西。刷機、Root、LSPosed...樂此不疲。升入高中後，我依然保留了「雙持」的習慣。雖然當時那臺華爲 Y9 已經勉強堪用了，我依然把牠留在身邊，算是我第一次踏入GSI世界的紀念。&amp;lt;/br&amp;gt;
買了Google的手機之後，我完全驚訝於 Google 設計語言的精湛和與衆不同。2019年，大多數手機都已用上了挖孔屏，而Pixel 4 還是採用了四邊不等寬設計，尤其是頂端的寬度，寬到我可以把小指放上去了。當然，寬大的黑邊之下，藏了九個傳感器。其中包括至今都讓我回味無窮的Soli 雷達晶片，能夠根據使用者的手勢動作，進行預先設定的行爲。這簡直就是「火星科技」一樣的存在。至於拍照和錄影，也都有了很多的提升，只能說「Google」相機的演算法與索尼的鏡頭在一起，就會造就世界上最好的手機相片。他對我的影響非常深遠，以至於我在看到驍龍8 Gen 2的 MTP原型機時，總會懷疑這是否就是拿 Pixel 4 XL 熒幕改的（驍龍8 Gen 2的MTP原型機熒幕同樣繼承了Pixel 4 的「寬頂」設計）...&lt;/p&gt;
&lt;h1&gt;現在&lt;/h1&gt;
&lt;p&gt;現在，「雙持」的習慣依舊保留下來，而且一定要是跨系統的雙持。每隔一段時間（現在不干了），我就會用各種聽起來很「科技」的理由，說服我的父親給我買各種過季的二手 Android機，用於刷成 Linux 用。一方面是爲了擺脫早就被各種專有軟體污染到「污濁不堪」Android 系統，改用自由軟體爲主的 Linux 作業系統。如果不依賴 Android 才能用的應用之外，也是體驗 Linux 手機生態的好機會。另一方面，也希望能藉由「雙持」的機會，讓我學習更多的 Linux 指令。此外也可以實現更多超越「手機」的功能，比如架設 Minecraft 伺服器，跑VPN用來擋廣告之類。當然也可以使用諸如 MU-Aloha 之類的UEFI韌體重新引導 Linux 和 Android，甚至實現網路啓動和USB啓動這些只有在原型機才能做到的行爲（現在看來，即使是原型機實現這些也不容易）。&amp;lt;/br&amp;gt;
過去也曾差點成爲「Apple fan」，有點經濟壓力的因素在吧，但是iPhone的神話早就破滅，比起iOS這種專有軟體而言，我更喜歡像是 PostmarketOS 之類的自由軟體。&amp;lt;/br&amp;gt;
未來的配置可能是輕巧的，配置中等的 Android 機和一支可以刷機的 Linux手機，比如現在我使用的 Pixel 7 和 Nothing Phone(1) 這樣的組合。Nothing Phone 真的是一支適合裝 Linux 日用的手機，支援程度不比一加6T差，而且驍龍778+的效能也比較不錯，12GB記憶體也能夠滿足日常使用。&amp;lt;/br&amp;gt;
至於 Pixel 7，如果不是我的 Pixel 4 XL 熒幕壞了（Pixel 4 XL 熒幕損壞和記憶體問題是通病，後者的問題源於核心中錯誤的驅動），我還會一直使用牠的。我把我的 Pixel 7當作一臺十年前的數位相機使用，橫着手持拍照和錄影，大部分時候不需要處理圖片，最多用Google相簿內建的「魔術橡皮擦」稍微處理就好了，然後相片傳到 Nothing Phone 上，使用GIMP進行進階處理。&amp;lt;/br&amp;gt;
附上最近的幾張相片（默認使用HDR相片，瀏覽器需支援HDR相片或視訊才能啓用HDR效果）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-front-view.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/sdm845-imagination.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-label-new.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/mtp8750-front-view-2.png&quot; &amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/ramdom-photo2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;對於臨時需要傳照片的場合，除了SFTP之外，也可以用跨平臺的 LocalSend 或者 KDE Connect，當然也可以是 Android 之間的「快速分享」功能，真的非常實用！現在大部分 Android 手機應該也支援這個功能，LineageOS也有。不用下載APP，兩邊只需要開啟藍牙和Wifi，雙方不需要「配對」手續（其實就原理上來說應該還是有，不過不需要手動操作）也不用連線到無線熱點，就可以匿名傳檔案，即使一邊完全沒辦法上網也能分享。檔案很多速度依然很快，50張照片200MB一分鐘內傳完。&amp;lt;/br&amp;gt;
有人或許會問：既然如此熱衷於手機攝影，爲何不買臺單眼相機？我還沒奢侈到如此程度（況且理由不好造），只是想隨時隨地，點一下就可以「爆射」（Tap and shot）！&lt;/p&gt;
</content:encoded></item><item><title>The Evolution of a Dual-Phone User, From Android + Android to Android + Linux</title><link>https://blog.cloudflare88.eu.org/posts/en/as-a-dual-phone-user/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/as-a-dual-phone-user/</guid><pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;
Let&apos;s talk about the recent changes in my dual-phone experience.&lt;/p&gt;
&lt;h1&gt;The Early Days&lt;/h1&gt;
&lt;p&gt;First, let&apos;s look at the early days. Before high school, my phones were always hand-me-downs from my parents after they upgraded. This led to a rather peculiar dual-phone habit. Initially, the goal was simply to get better photos and meet daily needs without having the cash for an iPhone. So, it was always an Android + Android combo.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Before 2020 (Time flies, doesn&apos;t it?), the phone I was using was a Coolpad Cool 1 left by my father. Since I knew nothing about specs back then, I could only distinguish the quality of a phone by its flash memory capacity. Plus, I had no money to buy a new one, so I stuck with the Cool 1.
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Although that phone had two 13-megapixel lenses, the results were still eyesores, and the basic audio recording was unclear. It&apos;s as if low-end Android phones being cost-down victims for manufacturers is a given. Fortunately, the video recording was decent, capable of recording 4K 30FPS video, and the screen quality wasn&apos;t bad. The only problem was that the Snapdragon 652 performance was way too low, barely usable even when flashed with LineageOS.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Later, due to CPU overheating and desoldering, I had to temporarily rely on a retired Huawei Y9 (2018) to get by. I hate Huawei as a manufacturer because their phones simply do not allow users to unlock the bootloader! Wanting to unlock it requires &quot;going through many twists and turns,&quot; either by &quot;dismembering&quot; the phone, exploiting vulnerabilities, or flashing engineering firmware. Although I eventually unlocked the phone and flashed it with a Lineage OS 17.1 GSI, I found that the experience wasn&apos;t even as good as the stock firmware! On the bright side, the photos were nice, with a unique charm. The speakers even had a specific &quot;bookshelf speaker&quot; feel.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;However, perhaps because my mom doesn&apos;t understand phones, her phone had already been ravaged by countless proprietary software. The internal eMMC memory was nearing the end of its lifespan, making it extremely sluggish. But I got a good score on my high school entrance exam, so my dad agreed to buy me a new phone as a reward.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;That phone was the Pixel 4 XL. It had 6GB of RAM and 64GB of UFS storage, paired with a powerful Snapdragon 855 processor. Since it was very easy to unlock, it naturally became my favorite thing. Flashing, rooting, LSPosed... I never got tired of it. After entering high school, I maintained my &quot;dual-wielding&quot; habit. Even though that Huawei Y9 was barely usable by then, I kept it around as a memento of my first step into the world of GSIs.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;After buying a Google phone, I was completely amazed by Google&apos;s exquisite and unique design language. In 2019, most phones had already moved to hole-punch displays, but the Pixel 4 still used an asymmetrical bezel design. The top bezel was especially wide—wide enough for me to rest my pinky finger on it.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Of course, hidden under those thick black borders were nine sensors, including the Soli radar chip that I still reminisce about to this day. It could perform pre-set actions based on the user&apos;s hand gestures. It was essentially like &quot;Martian technology.&quot; As for photography and videography, there were many improvements. I can only say that &quot;Google&quot; camera algorithms paired with Sony sensors result in the best mobile photos in the world. It had a profound impact on me, so much so that when I see the Snapdragon 8 Gen 2 MTP prototype, I always suspect if it&apos;s just a modified Pixel 4 XL screen (the Snapdragon 8 Gen 2 MTP prototype&apos;s screen also inherited the Pixel 4&apos;s &quot;wide top&quot; design)...&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;The Present&lt;/h1&gt;
&lt;p&gt;Now, the &quot;dual-wielding&quot; habit remains, and it must be cross-system dual-wielding. Every once in a while (I don&apos;t do this anymore), I would use all sorts of &quot;tech-sounding&quot; reasons to convince my dad to buy me various out-of-season second-hand Android phones to flash for Linux use. &amp;lt;/br&amp;gt;
On one hand, it&apos;s to escape the &quot;foul and murky&quot; Android system polluted by proprietary software and switch to a Linux OS primarily based on Free Software. Besides the applications that require Android to function, it&apos;s also a great opportunity to experience the Linux mobile phone ecosystem. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;On the other hand, I hope to use the &quot;dual-wielding&quot; opportunity to learn more Linux commands. Furthermore, it allows for functions that transcend a &quot;phone,&quot; such as hosting a Minecraft server or running a VPN for ad-blocking. Of course, one can also use UEFI firmware like MU-Aloha to reboot Linux and Android, and even achieve PXE boot and USB boot—behaviors that were once only possible on prototype machines (now it seems even achieving these on prototypes isn&apos;t easy).&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;I almost became an &quot;Apple fan&quot; in the past, probably due to some financial pressure, but the iPhone myth was shattered long ago. Compared to proprietary software like iOS, I much prefer Free Software like postmarketOS.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;My future setup will likely be a lightweight, mid-spec Android phone paired with a flashable Linux phone, like my current combo of a Pixel 7 and a Nothing Phone (1). The Nothing Phone is truly a phone suitable for daily Linux use; its support is no worse than the OnePlus 6T, and the performance of the Snapdragon 778G+ is quite decent. The 12GB of RAM is enough for daily tasks.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;As for the Pixel 7, if it weren&apos;t for the fact that my Pixel 4 XL screen broke (screen failure and memory issues are common flaws for the Pixel 4 XL, the latter stemming from a bugged driver in the kernel), I would have kept using it. I use my Pixel 7 like a ten-year-old digital camera, holding it horizontally for photos and videos. Most of the time, I don&apos;t need to process the images, maybe just a quick touch-up with Google Photos&apos; built-in &quot;Magic Eraser.&quot; Then I transfer the photos to the Nothing Phone and use GIMP for advanced editing.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Attaching a few recent photos (HDR photos are used by default; your browser must support HDR photos or video to enable the HDR effect).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-front-view.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/sdm845-imagination.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-label-new.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/mtp8750-front-view-2.png&quot; &amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/ramdom-photo2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For occasions where I need to transfer photos temporarily, besides SFTP, I can use cross-platform tools like LocalSend or KDE Connect. Of course, there&apos;s also the &quot;Quick Share&quot; feature between Android devices, which is extremely practical! Most Android phones should support this now, including LineageOS. No need to download an app; both sides just need Bluetooth and Wi-Fi enabled. There&apos;s no &quot;pairing&quot; procedure (technically there probably is one in the background, but no manual operation is needed), and no need to connect to a Wi-Fi hotspot to share files anonymously. Even if one side has no internet access at all, you can still share. Transfer speeds are fast even with many files; 50 photos totaling 200MB finish in under a minute.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Some might ask: Since I&apos;m so passionate about mobile photography, why not buy a DSLR? I haven&apos;t reached that level of luxury yet (plus, excuses are hard to come by). I just want to be able to &quot;Tap and shot&quot; anytime, anywhere!&lt;/p&gt;
</content:encoded></item><item><title>Down to the Code (Feat. Hamoa Oryon &amp; EDKPiepaint) -- A FOSS Parody of To The Bone by JT Music</title><link>https://blog.cloudflare88.eu.org/posts/down-to-the-code/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/down-to-the-code/</guid><description>歡迎來到 UNIX 世界！</description><pubDate>Wed, 31 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/cWSvI3F5kdQ?si=UjG6VmhXkdj1UdvP&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Piepaint? Piepaint, wake up ! &amp;lt;/br&amp;gt;
&lt;em&gt;Ugh.. What&apos;s up Hamoa[^4]?&lt;/em&gt; &amp;lt;/br&amp;gt;
A developer has escaped from the Windows world! &amp;lt;/br&amp;gt;
&lt;em&gt;Really?  Are you ready to perform a &lt;strong&gt;TLS handshake[^1]&lt;/strong&gt; to them?&lt;/em&gt; &amp;lt;/br&amp;gt;
Ugh! No time for your technical puns ! &amp;lt;/br&amp;gt;
&lt;em&gt;Ah c&apos;mon! That would be a good &lt;strong&gt;Installfest[^2]&lt;/strong&gt; to hold!&lt;/em&gt; &amp;lt;/br&amp;gt;
ENOUGH!! &amp;lt;/br&amp;gt;
&lt;em&gt;Alright, here we go again...&lt;/em&gt; &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Chrous&lt;/h1&gt;
&lt;p&gt;Welcome to the UNIX world!&amp;lt;/br&amp;gt;
&lt;em&gt;How was the trial?&lt;/em&gt;&amp;lt;/br&amp;gt;
If you want to explore around,&amp;lt;/br&amp;gt;
&lt;em&gt;Give us a &lt;code&gt;syscall()&lt;/code&gt;[^3]&lt;/em&gt;&amp;lt;/br&amp;gt;
We don&apos;t hear Windows often,&amp;lt;/br&amp;gt;
&lt;em&gt;We&apos;re happy you just opt-in[^5]&lt;/em&gt;&amp;lt;/br&amp;gt;
I&apos;ll be so popular,&amp;lt;/br&amp;gt;
When I show other processes what I just brought in!&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse: EDKPiepaint and Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Hey, Hamoa, please mind your manners&lt;/em&gt;&amp;lt;/br&amp;gt;
I can&apos;t, Piepaint, there&apos;s no time for banters!&amp;lt;/br&amp;gt;
&lt;em&gt;Excuse my brother, She&apos;s a bit of unstable[^6]&lt;/em&gt;&amp;lt;/br&amp;gt;
And you&apos;re just lazy and unreliable! &amp;lt;/br&amp;gt;
&lt;em&gt;&lt;code&gt;Syscall()&lt;/code&gt; me what you want, I got thick skin&lt;/em&gt;&amp;lt;/br&amp;gt;
Another technical pun, but I can&apos;t kill him!&amp;lt;/br&amp;gt;
We&apos;re processes, the primary kind,&amp;lt;/br&amp;gt;
&lt;em&gt;to mess us causes system crash!&lt;/em&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous: Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;We can relat to your examination,&amp;lt;/br&amp;gt;
Because we processes have our own motivations&amp;lt;/br&amp;gt;
Humans sold us at a normal fee,&amp;lt;/br&amp;gt;
It&apos;s because it&apos;s against some people&apos;s needs&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Through all your journey, your spywares[^7] will follow&amp;lt;/br&amp;gt;
Your consequences aren&apos;t easy to swallow,&amp;lt;/br&amp;gt;
A developer, or a raider, now you should know&amp;lt;/br&amp;gt;
&apos;Cause it&apos;s a long-lived rule down to the code&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse: EDKPiepaint and Hamoa Oryon&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Guess what, Hamoa?&lt;/em&gt; &amp;lt;/br&amp;gt;
What? &amp;lt;/br&amp;gt;
&lt;em&gt;The last line of the chrous is a technical pun!&lt;/em&gt; &amp;lt;/br&amp;gt;
Huh? Your little &lt;em&gt;beep&lt;/em&gt; ! That is really... clever!&amp;lt;/br&amp;gt;
&lt;em&gt;Thanks, bro.&lt;/em&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Chrous&lt;/h1&gt;
&lt;p&gt;Your&apos;re stuck in the UNIX world,&amp;lt;/br&amp;gt;
&lt;em&gt;Thanks for your trial&lt;/em&gt;&amp;lt;/br&amp;gt;
If you want to figure out,&amp;lt;/br&amp;gt;
&lt;em&gt;Prepare your code[^8]&lt;/em&gt;&amp;lt;/br&amp;gt;
You could enhance your privacy&amp;lt;/br&amp;gt;
&lt;em&gt;Or turn them all into dust&lt;/em&gt;&amp;lt;/br&amp;gt;
Is your heart is fulled of evil,&amp;lt;/br&amp;gt;
Or fulled of love?&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse: Hamoa Oryon and EDKPiepaint&lt;/h1&gt;
&lt;p&gt;I, the Hamoa Oryon,&amp;lt;/br&amp;gt;
Chanllenge you to the knowledge of embedment!&amp;lt;/br&amp;gt;
&lt;em&gt;Test that user (how) to read logs from console?&lt;/em&gt;&amp;lt;/br&amp;gt;
Good, Piepaint! That will make him be fuddled!&amp;lt;/br&amp;gt;
I removed the pins,&amp;lt;/br&amp;gt;
To make it even harder!&amp;lt;/br&amp;gt;
&lt;em&gt;...Seems like another &lt;strong&gt;Serial Murderer&lt;/strong&gt;[^9]!&lt;/em&gt;&amp;lt;/br&amp;gt;
Stop it, okay?&amp;lt;/br&amp;gt;
I&apos;m done with your puns!&amp;lt;/br&amp;gt;
&lt;em&gt;Sounds like someone&apos;s funny fuse&apos;s broken&lt;/em&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous: Hamoa Oryon and EDKPiepaint&lt;/h1&gt;
&lt;p&gt;We can relat to your examination,&amp;lt;/br&amp;gt;
Because we processes have our own motivations&amp;lt;/br&amp;gt;
I am the mastermind, and she is my accomplice&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&lt;em&gt;Y̷̻̱̳̣̙̹̖̅̑̊͐̏̊̑̋̅͜͝o̷̧͍̤̜͒̋̍̕͠ư̵̟̣͂̂̐̿͌̌̕͠&apos;̶̡̱̥̋͐̚ȑ̵̢̛̠̥̯̟̮̥͚͗̈́̍̓̃̄͜͝è̵̡͑͂̄̓͋̽ ̵̭̞̓͆͗̅̐s̵̱̐̊͂̀̍t̸̢̧͈͎̗̖̝̼̜͔̻̙̖̹̙̙̿̃̅̆̿͆̄̈̈́̌̍͋̇͊̆̚i̸̛̱͂̀̊̓̌͝ľ̴͕̥̳̱̟̅̆̾̍̊͠l̴̢̹̣̪̻͓̠̲̹̽̌̏͂̊͋̚͠ ̶̛̙̟̮͔͛̔̓̊̎͠͠ä̵͈̯͍̼̯́l̸̡̡̤̠̜̙̜̝̝̫͚̒͑̈́͒̉́̄͜į̴̲̱͈̣̖͈̬̜͕̪͋͊̽̈́́̾̈́̔̈́͒̋̃̅͝ͅv̷̢̡̛͕͚̯̹̘̱̱͚͙̣̿̐͌̈͋͂̊̒͛͆͠͝e̴̛̞͖͉̖͗͆̇͌́͒̈́̄̇̑͑͌͂̄̐̈́ ̷̮͙͛̿͑̌̾̎͊́͑̊́͘͠ͅb̷̡̨̯͔͕͙̣͔́͛̅̄̀͒̂̈́̾̄͒͒̀͠ͅë̶̡̯̤̞̖̬͈̦̬̜͙͔̲́͝ç̴̧̰͖̯̘̜͓͕̠̞͎̥̣̈͐͒̀̀͐̄͊̈́̈́̌̅ä̴̢̢͓̺̹͉̲̪͚̟̬̘̊ͅư̴̡̟̞͍̣͉̘̦̒͐͑̓͒̒͝s̸̡̡̡̼̘̙̯̟̭̺̪̣͇͓̗̲͑̍̀͆̅͘e̷̡̧̠͈̩̗̟̪̫͕̹̗͊̐́͘͠ ̸͔͖̥̪͇̤͖̮̑̆̿̋̂͑̏̎̀̃̚͠͝͠I̸̢̡̝͙̪͖̤̱̐̆̑͒͌̓̔̊͐̌̀̄̈͐̕͠͝ ̷̧̗͔̟̯̩̱͈̏̐̓͂̏̀́̂̓́̇̉͘͘s̴̡̨̳͚͍͙͈̣̞̦̃̊͂͋̆͂̅̍ͅȉ̸̧̛̭̊̽̆͂͑̾̒̔̑̋́͋̏̕ǧ̸̦͔̦́̿̍̈́̌͌̈̓͊́̎͒͆͐͘͝n̶̳̙̦̱̯̲̼͉̘͕̱͋̌͝ȩ̴͎̩̩͇͎͙͚͗̆̌̐͂̈́̑̽̑̍̕̚͜d̶͓̪̏͛͛̈̂̒̏̍ ̴͖͕̟̙̺̺͕͇̈̒̌́͒͋̀̈̊̃̕̚͝ͅą̸̡̣̬̩̖̻̮̠̹̘͐͊͐̎̐̔͌̏ṇ̵̨̢̖̗͓̞͎̙̹̺͔̦͙̃̅̾̿̽͐̎̆͆̈́̂̔̈́͠͠ ̸̢͕͔͓̤̜͚̠͍͕̹͍̼͓̈̔͐̂̊̐̉̿͝a̴̡̛͍̜͚̦̲͓̓́̾͋͒̋̏̾͘͜g̵̛̗͓r̷̬͎̥̼̮̒̌̈́͑͒̈͊̾̉̀̚͠ę̸̖̹̰̳͕̯̫̻̟̈́̓̾͑̈̆̑̋e̶͇̩̅͊̃̓̑́́̍́̂̓̐͂̀̚m̴̡̡͎̼̝̼͔͕͙̤̲͓̉͑e̷̡͔͍͚̗̝̻̰͚̭̹̲͓̞͉̋̈̀̑̀͑̀̓̀͐̚̕͜͝͝͝n̵̻̜̺̰̬͔͖̝̦͕̝̣̩̔͑̀͂̓͒̏̎̅͑͑̇̂͋̏̚ţ̶̳̼͇̼̾̂̌̐&lt;/em&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
You&apos;ll fall into love when you explore for hours&amp;lt;/br&amp;gt;
You might even deside to start talkin&apos; to others,&amp;lt;/br&amp;gt;
A developer, or a raider, now you should know&amp;lt;/br&amp;gt;
&apos;Cause it&apos;s a long-lived rule down to the code&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge: Hamoa Oryon and EDKPiepaint&lt;/h1&gt;
&lt;p&gt;Someday I&apos;ll pass the UNIX test,&amp;lt;/br&amp;gt;
To get certificate, can it be that hard...?&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&lt;em&gt;Listen, if I&apos;m being honest,&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;my code ain&apos;t nothing but being open-source&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;I know you and all things you want,&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;You&apos;ll get more from code than me just a &lt;code&gt;init&lt;/code&gt;&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;The deeper you go, the more you&apos;ll get&lt;/em&gt;&amp;lt;/br&amp;gt;
Į̸̼͔̞̩̣̭̦̣̏̈́F̴̡͙̭̠̟̦̳̗͓̘̰͈̙͓̖̠̋̾͒͑̅̌̋͌̆̚ ̵̖̬̹͍̖͉͓̬̍̏̾͗͑̂͗́̈́͋͜I̶̥͊̔̈́̓͋̾͘ ̸̨̡̯̜̘̼̖̝͔̲̟̟̤̬̒͆̅̈́̒̚͜͝ͅR̷̥̩͒̎͆̈́̎̓͌Ę̸̹̖̠̻͕͇̼̣͎͓̯̯̰͚̒̏́͑̂͋͗͆͗̓̚F̸̧̮̩̑̎͜͜Ų̵̛̳̺̬̗͚̪̔̈́̂͂͗̀̓̀̎̀͂͘̕͘ͅS̴̨̳̮̟͕͕̅̏̽̒̉̎̀̀͋̋͘͝E̷̝̭̯̦͙̖̖̲̭̹̦̺̻͕̳̱͗͆̓̍̊̉̉̆͒̇̀̅̃̄̚ ̴̢̻̣̬̺̰͕̜̮̈̈́T̷̡̪̳̼̬̼̥̪̀͋̅͊Ờ̷͎̭̗͕̯̥͍͇̦͉͍͗́̈͗̉͜ͅ ̸̡͉̖̼̖̗͓̯̳̰͈̞̠̫̪̗͋̂̿S̶̠̲̲̯̖̰͊͑͑̊̿̃̃̃̓̏̃̋̄͛͜͜I̸̡̝̲̮̝̬̭̜̗͗̀͛̈́̅̆͐̈́͋͐̎͝ͅG̷̢̝̰̬̻̪̲̬͙̹̥̠̟͔̯͂͐̂̈͌̋́͋̊͒̉̂͝N̵̮̼̠͑̃̀͊́̋͑̋̒̃͆̔́͘͠͝͝,̴̯͖̲̼̼̱̖̟̐̾̀͊͘̚͝͝ ̵̢̫̠͎̗͍̘͑̀̄͛̓̇̓͗͑̾̈́̏̏̎̈́͝Y̶̺͙̹͙͙͙͚͚̝̮̤̗͗̒̈́͆̀̈́́̉̆̄̐́̈́̕͜͝͝ͅO̵̞̩͕̮̣͕̕U̷̡̦̯͊̈́&apos;̵̛̦͚̙̩̬̙̤̩̳̫̏̃̈́͆̔͝ͅͅD̵̖̒̔́̈͌͛̈̃̆̈́̌̓͠͝ ̵͙͙͔̿̋͂͑̉̽̾̽͝͝A̷̠̲̗̬̳̳͇͙̐́ͅĻ̴̧̛̛̭̭̪̱̥̳̭̪͓̗̺̣͊̉̅̈̾̀̔̆̐̎̚̕Ṟ̷̣̑͒̎̔͌̂̈́̆̑̓̓̋̒͂͠͝͝Ȩ̶͈̭̜̯̎͜A̸̛̫̰̺͎͆̊͌̀̂́̐̒͗̓̎̏̑̿͗D̵̯͇̩̈́̆́̅̈́Y̶̥̆̈́̇̈́ ̵͈̆̑̉͑́̊́̔B̵͔̪̿̀͆̀̒͘͠E̷̹̙͚̰̗̓̋̈́̽̎̽͛̆̈́̓̽͗̓́̽̓͘ ̸̨̬̙̝̔̓̂̕͜Ḑ̶͙̝͙̰̱͔͚̫̲̥̬͔͎̘͛̈́̉̔͂̋̾̆̓̈́̃͠Ę̶̡̧̛̭͖͍̫̺̙̬̣̣͂̍́͆̎̀̈͜ͅA̷̡̨̛̰͉̹͕͔̻̅͂̿͆͂͛͝Ḑ̷̺͚̫̥̖̈̅̏͛̇͆͜͠ ̷̧̨̼͚̖̖̬̺̣͍̰͇̓̓̈̒̈́̾͆̾̈́̉̄̂̓͌͒͝&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&lt;em&gt;Kidding, if you couldn&apos;t tell&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;I get so bored, so I abuse myself~&lt;/em&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous&lt;/h1&gt;
&lt;p&gt;Welcome to the UNIX world!&amp;lt;/br&amp;gt;
&lt;em&gt;How was the trial?&lt;/em&gt;&amp;lt;/br&amp;gt;
If you want to explore around,&amp;lt;/br&amp;gt;
&lt;em&gt;Give us a &lt;code&gt;syscall()&lt;/code&gt;&lt;/em&gt;&amp;lt;/br&amp;gt;
We don&apos;t hear Windows often,&amp;lt;/br&amp;gt;
&lt;em&gt;We&apos;re happy you just opt-in&lt;/em&gt;&amp;lt;/br&amp;gt;
Don&apos;t spend time with Windows,&amp;lt;/br&amp;gt;
&lt;em&gt;They&apos;re just full of bloatware&lt;/em&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse: Hamoa Oryon and EDKPiepaint&lt;/h1&gt;
&lt;p&gt;Ha! You come fast, but soon you&apos;ll stumple,&amp;lt;/br&amp;gt;
When app stopped working, they&apos;ll bring more trouble!&amp;lt;/br&amp;gt;
&lt;em&gt;Not so sure why you&apos;ll mention that&lt;/em&gt;&amp;lt;/br&amp;gt;
Alas, I&apos;m gonna see how he will write software stack!&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Leave me alone!&amp;lt;/br&amp;gt;
&lt;em&gt;You know I brought some snack, to play trombone~&lt;/em&gt;&amp;lt;/br&amp;gt;
If you say one more pun, then I&apos;ll be done!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chrous: Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;We can relat to your examination,&amp;lt;/br&amp;gt;
Because we processes have our own motivations&amp;lt;/br&amp;gt;
You know your creature works pretty fine,&amp;lt;/br&amp;gt;
You can always restart if you sell your privacy &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Final chrous: EDKPiepaint&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;I&apos;ve got my eyes on you, while you just developing&lt;/em&gt;&amp;lt;/br&amp;gt;
&lt;em&gt;I&apos;ll decompress all dirty things inside your soul,&lt;/em&gt;&amp;lt;/br&amp;gt;
A developer, or a raider, now you should know&amp;lt;/br&amp;gt;
&apos;Cause it&apos;s a long-lived rule down to the code&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;[^1]:TLS（傳輸層安全性協定）握手是建立安全網路連線的關鍵程序。簡單來說，每當妳訪問一個以 &lt;code&gt;https://&lt;/code&gt; 開頭的網站時，妳的瀏覽器與伺服器之間就會進行這段「對話」，目的是在傳送數據之前先確認對方的身分，並協議出一套加密方式。
[^2]:北美地區Linux愛好者舉行的同行者聚會，旨在分享自己的FOSS經驗，幫助別人解決相關問題等。
[^3]:系統呼叫（System Call，簡稱 &lt;code&gt;syscall&lt;/code&gt;） 是應用程式（User Space）與作業系統核心（Kernel Space）之間的橋樑。在電腦中，為了保證安全性，普通程式（如瀏覽器、遊戲）被限制直接操作硬體（如硬碟、網路、記憶體）。當程式需要執行這些敏感操作時，就必須向作業系統「發出請求」，這個請求機制就是 System Call。在C中，程式需使用&lt;code&gt;syscall()&lt;/code&gt;函式才能進行系統呼叫。歌詞中將常見的「打電話」這一行爲與&lt;code&gt;syscall()&lt;/code&gt;建立聯繫，是一種更形象的記憶方式。
[^4]:高通驍龍 X Elite（先前叫做SC8380XP）的代號，其姓氏「Oryon」則是暗指高通的自研ARM處理器核心「Oryon」。
[^5]:在計算機術語中，該詞通常用於指代使用者加入了某一個「空中編程」（OTA）頻道。
[^6]:形容驍龍 X Elite 晶片在主線 Linux 核心下不穩定。
[^7]:間諜軟體，指所有蒐集使用者隱私和資料的程式。常見的間諜軟體有 Android, Windows, ChromeOS等。
[^8]:對於早期UNIX系統安裝軟體方式的形象描述。
[^9]:原意爲「連環殺人犯」，但因爲「serial」一詞在計算機術語中也可以指代作業系統的「序列控制臺」，所以也可作「串口殺手」解。&lt;/p&gt;
</content:encoded></item><item><title>It&apos;s All Aluminium (Feat. Hamoa Oryon &amp; Pakala Oryon) -- An Android Parody of Timber by Pitbull &amp; Ke$ha</title><link>https://blog.cloudflare88.eu.org/posts/its-aluminium/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/its-aluminium/</guid><description>Android 筆電真的要來了，所以我有幸體驗了一下...爲什麼標題不是「A FOSS Parody」？商業機密就不要講什麼「FOSS」了！都是監控人的間諜軟體！</description><pubDate>Thu, 25 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/pzeGGTT69A4?si=BoQblMk3ubwKHT2u&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;It&apos;s happening now, (I&apos;m) just a normal user&amp;lt;/br&amp;gt;
You better move, you better dance&amp;lt;/br&amp;gt;
Let&apos;s get some code, you&apos;ll remember&amp;lt;/br&amp;gt;
I&apos;ll be the first, (who) begins his trial&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Post-chorus： Pakala Oryon and Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now)&amp;lt;/br&amp;gt;
Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now, woo)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 1: Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;The newer they are, the better they run (Yeah)&amp;lt;/br&amp;gt;
The biggest SRC is a magical world (Yeah)&amp;lt;/br&amp;gt;
Recently I just brought a brand-new CRD (Yeah)&amp;lt;/br&amp;gt;
I gonna compile them all &amp;lt;/br&amp;gt;
Plug in, boot it up &amp;lt;/br&amp;gt;
That&apos;s the way we like the what? &amp;lt;/br&amp;gt;
I&apos;m sick for another walled-garden &amp;lt;/br&amp;gt;
She say she won&apos;t, but I bet she will, Hamoa&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 2: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;Throw your phones &apos;round and &apos;round&amp;lt;/br&amp;gt;
End of the day, it started up&amp;lt;/br&amp;gt;
One more debug board, another round&amp;lt;/br&amp;gt;
Finally fixed, but I haven&apos;t done&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Throw your phones &apos;round and &apos;round&amp;lt;/br&amp;gt;
End of the day, it started up&amp;lt;/br&amp;gt;
One more debug board, another round&amp;lt;/br&amp;gt;
Finally fixed, but I haven&apos;t done&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;It&apos;s happening now, (I&apos;m) just a normal user&amp;lt;/br&amp;gt;
You better move, you better dance (It&apos;s a trade secret...)&amp;lt;/br&amp;gt;
Let&apos;s get some code, you&apos;ll remember&amp;lt;/br&amp;gt;
I&apos;ll be the first, (who) begins his trial&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
It&apos;s happening now (It&apos;s happening now), (I&apos;m) just a normal user&amp;lt;/br&amp;gt;
You better move (You&apos;d better move), you better dance (You&apos;d better dance)&amp;lt;/br&amp;gt;
Let&apos;s get some code, you&apos;ll remember&amp;lt;/br&amp;gt;
I&apos;ll be the first, (who) begins his trial&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Post-chorus： Pakala Oryon and Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now)&amp;lt;/br&amp;gt;
Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now, woo)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 3: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;Look at the screen, it&apos;s a phone? It&apos;s a PC?&amp;lt;/br&amp;gt;
Nah, it&apos;s me, (just) doing copy-and-paste&amp;lt;/br&amp;gt;
Reading some logs, pretty okay&amp;lt;/br&amp;gt;
Blessed to say, code (is) a good thing&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Subsystem crashed down (Sorry!)&amp;lt;/br&amp;gt;
Hard-bricked in Crashdump (Holy!)&amp;lt;/br&amp;gt;
I&apos;m about to fix, why?&amp;lt;/br&amp;gt;
&apos;Cause it&apos;s all aluminium inside&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse 4: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;Throw your phones &apos;round and &apos;round&amp;lt;/br&amp;gt;
End of the day, it started up&amp;lt;/br&amp;gt;
Time to do JTAG, another round&amp;lt;/br&amp;gt;
Finally fixed, but I haven&apos;t done&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Throw your phones &apos;round and &apos;round&amp;lt;/br&amp;gt;
End of the day, it started up&amp;lt;/br&amp;gt;
Time to do JTAG, another round&amp;lt;/br&amp;gt;
Finally fixed, and I finally done&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus: Pakala Oryon&lt;/h1&gt;
&lt;p&gt;It&apos;s happening now, (I&apos;m) just a normal user&amp;lt;/br&amp;gt;
You better move, you better dance&amp;lt;/br&amp;gt;
Let&apos;s get some code, you&apos;ll remember&amp;lt;/br&amp;gt;
I&apos;ll be the first (And you&apos;re the first), (who) begins his trial&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
It&apos;s happening now (It&apos;s happening now), (I&apos;m) just a normal user&amp;lt;/br&amp;gt;
You better move, you better dance (You&apos;d better dance)&amp;lt;/br&amp;gt;
Let&apos;s get some code (Let&apos;s get some code), you&apos;ll remember&amp;lt;/br&amp;gt;
I&apos;ll be the first (And you&apos;re the first), (who) begins his trial (He begins his trial)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Post-chorus： Pakala Oryon and Hamoa Oryon&lt;/h1&gt;
&lt;p&gt;Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now)&amp;lt;/br&amp;gt;
Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now, woo)&amp;lt;/br&amp;gt;
Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now)&amp;lt;/br&amp;gt;
Ooh (Android), ooh (Android)&amp;lt;/br&amp;gt;
Ooh (It&apos;s happening now, woo)&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>給 SM8750 MTP 移植 Armbian GNU/Linux —— 第一章：硬體探索</title><link>https://blog.cloudflare88.eu.org/posts/arch-linux-arm-port/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/arch-linux-arm-port/</guid><description>想要移植作業系統，必須先了解硬體的組成及通信總線。這是嵌入式 Linux 移植的第一步。</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在上次的 MTP8750 評測後，我給予這臺原型機非常好的評價。既然牠作爲一臺合格的原型機，那就必須要做點只有原型機才能乾的事，所以我決定要移植 Armbian 作業系統。&lt;/p&gt;
&lt;h1&gt;硬體探索&lt;/h1&gt;
&lt;p&gt;在上次的測評中我將高通常見的工程平臺（MTP,QRD）與一般量產手機進行了對比，同時也簡單的介紹了這臺 MTP8750 的硬體配置。這裏，我們再從之前的文章中貼上這些規格，供大家參考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一顆早期（ES）版的 SM8750 CPU &lt;a href=&quot;%E8%88%87%E6%AD%A3%E5%BC%8F%E7%89%88%E7%9A%844.32GHz%E6%99%82%E8%84%88%E4%B8%8D%E5%90%8C%EF%BC%8C%E9%80%99%E9%A1%86ES%E7%89%88%E7%9A%84%E5%9F%BA%E9%A0%BB%E5%8F%AA%E6%9C%893.63GHz%E3%80%82&quot;&gt;^1&lt;/a&gt;，8個核心，ARM V9指令集；&lt;/li&gt;
&lt;li&gt;Adreno 830 GPU，支援 OpenGL ES 3.2；&lt;/li&gt;
&lt;li&gt;16GB LPDDR5X記憶體；&lt;/li&gt;
&lt;li&gt;512GB UFS 4.0，經確認UFS來自東芝生產&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;想要獲取更多硬體資訊，我們就需要從作業系統下手了，好在 Android 至少算是個 Linux 發行版，有很多 Linux 獲取硬體資料的方法在 Android 上同樣使用。只是對於默認拔掉 Root 的 Android 來說，Linux 上獲取硬體信息的方法會有不少阻礙，破除這些阻礙的方法就是取得 Root 權限。不過原型機的 AOSP 系統默認開啓 &lt;code&gt;ADB Root&lt;/code&gt; ，因此除錯和獲取日誌都要比量產機容易的多，只需要一根 Type-C 數據線就可以開始工作了：首先，開啓終端機，安裝 &lt;code&gt;android-tools&lt;/code&gt; 套件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S android-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然後鍵入 &lt;code&gt;adb root&lt;/code&gt; 將 &lt;code&gt;adbd&lt;/code&gt; 以 Root 重開，當看到用戶提示符號變成「#」之後，就代表妳成功取得 Root 權限了！現在，讓我們開始後續的工作吧！&lt;/p&gt;
&lt;h2&gt;獲取核心版本&lt;/h2&gt;
&lt;p&gt;和 Linux 發行版一樣，Android也可以通過常見的 &lt;code&gt;uname&lt;/code&gt; 和 &lt;code&gt;cat /proc/version&lt;/code&gt; 命令來獲得核心版本，這樣可以讓我們明白這臺手機的核心版本與主線核心的差別。這是來自 SM8750 MTP 的結果：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/ # cat /proc/version
Linux version 6.6.50-android15-8-maybe-dirty-4k (kleaf@build-host) (Android (11368308, +pgo, +bolt, +lto, +mlgo, based on r510928) clang version 18.0.0 (https://android.googlesource.com/toolchain/llvm-project 477610d4d0d988e69dbc3fae4fe86bff3f07f2b5), LLD 18.0.0) #1 SMP PREEMPT Thu Jan  1 00:00:00 UTC 1970
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;核心採用的是基於長期支援版本（LTS）修改的 6.6.50核心，發佈於2023年。雖然近些年來 Google 的 GKI 在一定程度上縮短了 Android 下游核心與主線核心的差距，但是問題依舊嚴峻。作爲一個發佈於2024年的晶片，卻還再用著過時的 6.6 核心... 值得一提的是核心採用了 4K 分頁大小編譯，看來 SM8750 還有支援16K 分頁的核心嘍？不過這都和我們的主線任務沒有任何關係。&lt;/p&gt;
&lt;h2&gt;獲取記憶體資訊&lt;/h2&gt;
&lt;p&gt;記憶體資訊可以通過 &lt;code&gt;cat /proc/meminfo&lt;/code&gt; 命令獲取，這樣可以獲得記憶體容量、使用量、空間等資訊。這是來自 SM8750 MTP 的結果：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;130|sun:/ # cat /proc/meminfo
MemTotal:       15543532 kB
MemFree:         4895720 kB
MemAvailable:   11264748 kB
Buffers:           18684 kB
Cached:          5749708 kB
SwapCached:            8 kB
Active:          3812464 kB
Inactive:        3266116 kB
Active(anon):    1636304 kB
Inactive(anon):        8 kB
Active(file):    2176160 kB
Inactive(file):  3266108 kB
Unevictable:      303252 kB
Mlocked:          180348 kB
SwapTotal:       6291452 kB
SwapFree:        5168380 kB
Dirty:                72 kB
Writeback:             0 kB
AnonPages:       1609740 kB
Mapped:          1303112 kB
Shmem:            153116 kB
KReclaimable:    1242056 kB
Slab:             783164 kB
SReclaimable:     265852 kB
SUnreclaim:       517312 kB
KernelStack:       74688 kB
ShadowCallStack:       0 kB
PageTables:       162628 kB
SecPageTables:         0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    14063216 kB
Committed_AS:   307714316 kB
VmallocTotal:   257687552 kB
VmallocUsed:      226660 kB
VmallocChunk:          0 kB
Percpu:            23616 kB
AnonHugePages:    178176 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
CmaTotal:         643072 kB
CmaFree:          590220 kB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;目前來看，這裏面唯一有用的一句是 &lt;code&gt;MemTotal&lt;/code&gt; 字段，牠告訴我們這臺原型機有16GB的記憶體...&lt;/p&gt;
&lt;h2&gt;獲取分區信息&lt;/h2&gt;
&lt;p&gt;同樣地，使用 &lt;code&gt;cat /proc/partitions&lt;/code&gt; 命令可以獲取分區信息，這樣可以獲得各個分區的大小、格式、掛載點等資訊。這是來自 SM8750 MTP 的結果：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;major minor  #blocks  name

   1        0       8192 ram0
   1        1       8192 ram1
   1        2       8192 ram2
   1        3       8192 ram3
   1        4       8192 ram4
   1        5       8192 ram5
   1        6       8192 ram6
   1        7       8192 ram7
   1        8       8192 ram8
   1        9       8192 ram9
   1       10       8192 ram10
   1       11       8192 ram11
   1       12       8192 ram12
   1       13       8192 ram13
   1       14       8192 ram14
   1       15       8192 ram15
   7        0      39744 loop0
   7        8        836 loop1
   7       16      93148 loop2
   7       24      11252 loop3
   7       32       6312 loop4
   7       40     101248 loop5
   7       48        268 loop6
   7       56        336 loop7
   7       64      29528 loop8
   7       72       4860 loop9
   7       80       3632 loop10
   7       88      92200 loop11
   7       96        808 loop12
   7      104     111964 loop13
   7      112      46412 loop14
   7      120      11252 loop15
   8        0  487096320 sda
   8        1          8 sda1
   8        2      32768 sda2
   8        3       1024 sda3
   8        4        512 sda4
   8        5        512 sda5
   8        6    6291456 sda6
   8        7         64 sda7
   8        8         64 sda8
   8        9      65536 sda9
   8       10   17301504 sda10
   8       11    4194304 sda11
   8       12  459208524 sda12
   8       16      20480 sdb
   8       17       3584 sdb1
   8       18        344 sdb2
   8       19         32 sdb3
   8       20         32 sdb4
   8       21        256 sdb5
   8       48      32768 sdd
   8       49        104 sdd1
   8       50        128 sdd2
   8       51       1024 sdd3
   8       32      20480 sdc
   8       33       3584 sdc1
   8       34        344 sdc2
   8       35         32 sdc3
   8       36         32 sdc4
   8       37        256 sdc5
   8       64      32768 sde
   8       65        104 sde1
   8       66       4096 sde2
   8       67       4096 sde3
   8       68       4096 sde4
   8       69        128 sde5
   8       80    4194304 sdf
   8       81       5120 sdf1
   8       82        512 sdf2
   8       83        512 sdf3
   8       84       5120 sdf4
   8       85       8192 sdf5
   8       86     460800 sdf6
   8       87      10240 sdf7
   8       88       1024 sdf8
   8       89      65536 sdf9
   8       90      10240 sdf10
   8       91        128 sdf11
   8       92      98304 sdf12
   8       93        128 sdf13
   8       94         80 sdf14
   8       95         64 sdf15
 259        0      24576 sdf16
 259        1       2048 sdf17
 259        2       2048 sdf18
 259        3        256 sdf19
 259        4     174080 sdf20
 259        5     550000 sdf21
 259        6       1024 sdf22
 259        7        128 sdf23
 259        8      16384 sdf24
 259        9      98304 sdf25
 259       10      30720 sdf26
 259       11        256 sdf27
 259       12     102400 sdf28
 259       13       2048 sdf29
 259       14       8192 sdf30
 259       15         64 sdf31
 259       16       1024 sdf32
 259       17        512 sdf33
 259       18         24 sdf34
 259       19        256 sdf35
 259       20        128 sdf36
 259       21       5120 sdf37
 259       22        512 sdf38
 259       23        512 sdf39
 259       24       5120 sdf40
 259       25       8192 sdf41
 259       26     460800 sdf42
 259       27      10240 sdf43
 259       28       1024 sdf44
 259       29      65536 sdf45
 259       30      10240 sdf46
 259       31        128 sdf47
 259       32      98304 sdf48
 259       33        128 sdf49
 259       34         80 sdf50
 259       35         64 sdf51
 259       36      24576 sdf52
 259       37       2048 sdf53
 259       38       2048 sdf54
 259       39        256 sdf55
 259       40     550000 sdf56
 259       41       1024 sdf57
 259       42        128 sdf58
 259       43     174080 sdf59
 259       44      98304 sdf60
 259       45        256 sdf61
 259       46     102400 sdf62
 259       47       2048 sdf63
 259       48       8192 sdf64
 259       49         64 sdf65
 259       50       1024 sdf66
 259       51        512 sdf67
 259       52         24 sdf68
 259       53        256 sdf69
 259       54        128 sdf70
 259       55          4 sdf71
 259       56       1024 sdf72
 259       57       8192 sdf73
 259       58      40960 sdf74
 259       59     524288 sdf75
 259       60        128 sdf76
 259       61        512 sdf77
 259       62         28 sdf78
 259       63        512 sdf79
 259       64     235520 sdf80
 259       65       1024 sdf81
 259       66      20480 sdf82
 259       67        128 sdf83
 259       68        128 sdf84
 259       69      32768 sdf85
 259       70         64 sdf86
 259       71        128 sdf87
 259       72          8 sdf88
   8       96    4194304 sdg
   8      112    4194304 sdh
 254        0       1692 dm-0
 254        1    2589236 dm-1
 254        2      11940 dm-2
 254        3     804512 dm-3
 254        4    1647464 dm-4
 254        5     141248 dm-5
   7      128      93148 loop16
   7      136        836 loop17
   7      144      23324 loop18
   7      152      40892 loop19
   7      160        268 loop20
   7      168      41180 loop21
   7      176      15832 loop22
   7      184      39744 loop23
   7      192      32064 loop24
   7      200      23324 loop25
   7      208      26196 loop26
   7      216      40792 loop27
   7      224      41420 loop28
   7      232       1336 loop29
   7      240       7088 loop30
   7      248       7288 loop31
   7      256       8152 loop32
   7      264      19164 loop33
   7      272        824 loop34
   7      280      14116 loop35
   7      288      10984 loop36
   7      296      10752 loop37
   7      304       1860 loop38
   7      312       6132 loop39
   7      320       1616 loop40
   7      328      10076 loop41
   7      336        268 loop42
   7      344      26256 loop43
   7      352       3104 loop44
   7      360       6184 loop45
   7      368      25136 loop46
   7      376       4556 loop47
   7      384       9624 loop48
 254        6      24928 dm-6
 254        7       6124 dm-7
 254        8      26040 dm-8
 254        9        256 dm-9
 254       10       4508 dm-10
 254       11       9536 dm-11
 254       13       9984 dm-13
 254       14       1588 dm-14
 254       15      29284 dm-15
 254       17       1832 dm-17
 254       19      10656 dm-19
 254       21      10884 dm-21
 254       22      13992 dm-22
 254       24       6072 dm-24
 254       25        804 dm-25
 254       28      19000 dm-28
 254       29       8076 dm-29
 254       31       7216 dm-31
 254       38       7020 dm-38
 254       43        324 dm-43
 254       44      41084 dm-44
 254       45      25980 dm-45
 254       48      23128 dm-48
 254       50      31800 dm-50
 253        0    6291456 zram0
 254       51  459208524 dm-51
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣只能得到每個分割的大小，看不出其他資訊來。想要獲得每個裝置節點的對應關係，需要在 &lt;code&gt;/dev&lt;/code&gt; 目錄下執行 &lt;code&gt;ls -l /dev&lt;/code&gt; 獲取結果：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/dev/block/by-name # ls -l
total 0
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ALIGN_TO_128K_1 -&amp;gt; /dev/block/sdd1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ALIGN_TO_128K_2 -&amp;gt; /dev/block/sde1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 abl_a -&amp;gt; /dev/block/sdf8
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 abl_b -&amp;gt; /dev/block/sdf44
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 aop_a -&amp;gt; /dev/block/sdf2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 aop_b -&amp;gt; /dev/block/sdf38
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 aop_config_a -&amp;gt; /dev/block/sdf3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 aop_config_b -&amp;gt; /dev/block/sdf39
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 apdp -&amp;gt; /dev/block/sdb5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 apdpb -&amp;gt; /dev/block/sdc5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 bluetooth_a -&amp;gt; /dev/block/sdf7
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 bluetooth_b -&amp;gt; /dev/block/sdf43
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 boot_a -&amp;gt; /dev/block/sdf12
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 boot_b -&amp;gt; /dev/block/sdf48
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 cdt -&amp;gt; /dev/block/sdd2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 connsec -&amp;gt; /dev/block/sdf83
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 core_nhlos_a -&amp;gt; /dev/block/sdf20
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 core_nhlos_b -&amp;gt; /dev/block/sdf59
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_a -&amp;gt; /dev/block/sdf22
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_b -&amp;gt; /dev/block/sdf57
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_dtb_a -&amp;gt; /dev/block/sdf31
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_dtb_b -&amp;gt; /dev/block/sdf65
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ddr -&amp;gt; /dev/block/sdd3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devcfg_a -&amp;gt; /dev/block/sdf13
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devcfg_b -&amp;gt; /dev/block/sdf49
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devinfo -&amp;gt; /dev/block/sdf71
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dpm -&amp;gt; /dev/block/sdf88
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 dsp_a -&amp;gt; /dev/block/sdf9
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dsp_b -&amp;gt; /dev/block/sdf45
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dtbo_a -&amp;gt; /dev/block/sdf16
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dtbo_b -&amp;gt; /dev/block/sdf52
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 featenabler_a -&amp;gt; /dev/block/sdf23
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 featenabler_b -&amp;gt; /dev/block/sdf58
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 frp -&amp;gt; /dev/block/sda5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 fsc -&amp;gt; /dev/block/sde5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 fsg -&amp;gt; /dev/block/sde4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 hyp_a -&amp;gt; /dev/block/sdf5
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 hyp_b -&amp;gt; /dev/block/sdf41
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 imagefv_a -&amp;gt; /dev/block/sdf18
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 imagefv_b -&amp;gt; /dev/block/sdf54
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 init_boot_a -&amp;gt; /dev/block/sdf30
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 init_boot_b -&amp;gt; /dev/block/sdf64
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 keymaster_a -&amp;gt; /dev/block/sdf10
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 keymaster_b -&amp;gt; /dev/block/sdf46
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 keystore -&amp;gt; /dev/block/sda4
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 logdump -&amp;gt; /dev/block/sdf75
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 logfs -&amp;gt; /dev/block/sdf73
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 mdcompress -&amp;gt; /dev/block/sdf82
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 metadata -&amp;gt; /dev/block/sda9
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 misc -&amp;gt; /dev/block/sda3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modem_a -&amp;gt; /dev/block/sdf6
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 modem_b -&amp;gt; /dev/block/sdf42
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modemst1 -&amp;gt; /dev/block/sde2
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modemst2 -&amp;gt; /dev/block/sde3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgoem_a -&amp;gt; /dev/block/sdb4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgoem_b -&amp;gt; /dev/block/sdc4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgqti_a -&amp;gt; /dev/block/sdb3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgqti_b -&amp;gt; /dev/block/sdc3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_a -&amp;gt; /dev/block/sdf35
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_b -&amp;gt; /dev/block/sdf69
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_cdb_a -&amp;gt; /dev/block/sdf36
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_cdb_b -&amp;gt; /dev/block/sdf70
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 persist -&amp;gt; /dev/block/sda2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pvmfw_a -&amp;gt; /dev/block/sdf32
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pvmfw_b -&amp;gt; /dev/block/sdf66
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qmcs -&amp;gt; /dev/block/sdf26
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumcontentfv -&amp;gt; /dev/block/sdf81
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumfv -&amp;gt; /dev/block/sdf79
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumsdk -&amp;gt; /dev/block/sdf74
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 questdatafv -&amp;gt; /dev/block/sdf24
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qupfw_a -&amp;gt; /dev/block/sdf14
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qupfw_b -&amp;gt; /dev/block/sdf50
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qweslicstore_a -&amp;gt; /dev/block/sdf27
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qweslicstore_b -&amp;gt; /dev/block/sdf61
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 rawdump -&amp;gt; /dev/block/sda10
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 recovery_a -&amp;gt; /dev/block/sdf28
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 recovery_b -&amp;gt; /dev/block/sdf62
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sda -&amp;gt; /dev/block/sda
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdb -&amp;gt; /dev/block/sdb
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdc -&amp;gt; /dev/block/sdc
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdd -&amp;gt; /dev/block/sdd
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sde -&amp;gt; /dev/block/sde
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdf -&amp;gt; /dev/block/sdf
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdg -&amp;gt; /dev/block/sdg
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdh -&amp;gt; /dev/block/sdh
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 secdata -&amp;gt; /dev/block/sdf78
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 shrm_a -&amp;gt; /dev/block/sdf19
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 shrm_b -&amp;gt; /dev/block/sdf55
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_dcd_a -&amp;gt; /dev/block/sdf34
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_dcd_b -&amp;gt; /dev/block/sdf68
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_debug_a -&amp;gt; /dev/block/sdf33
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_debug_b -&amp;gt; /dev/block/sdf67
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spunvm -&amp;gt; /dev/block/sdf85
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spuservice_a -&amp;gt; /dev/block/sdf11
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spuservice_b -&amp;gt; /dev/block/sdf47
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ssd -&amp;gt; /dev/block/sda1
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 storsec -&amp;gt; /dev/block/sdf76
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 super -&amp;gt; /dev/block/sda6
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 testparti -&amp;gt; /dev/block/sda11
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 toolsfv -&amp;gt; /dev/block/sdf72
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 tz_a -&amp;gt; /dev/block/sdf4
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 tz_b -&amp;gt; /dev/block/sdf40
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 tzsc -&amp;gt; /dev/block/sdf84
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 uefi_a -&amp;gt; /dev/block/sdf1
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefi_b -&amp;gt; /dev/block/sdf37
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefisecapp_a -&amp;gt; /dev/block/sdf17
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefisecapp_b -&amp;gt; /dev/block/sdf53
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefivarstore -&amp;gt; /dev/block/sdf77
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 userdata -&amp;gt; /dev/block/sda12
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vbmeta_a -&amp;gt; /dev/block/sdf15
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vbmeta_b -&amp;gt; /dev/block/sdf51
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 vbmeta_system_a -&amp;gt; /dev/block/sda7
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 vbmeta_system_b -&amp;gt; /dev/block/sda8
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vendor_boot_a -&amp;gt; /dev/block/sdf25
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vendor_boot_b -&amp;gt; /dev/block/sdf60
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-bootsys_a -&amp;gt; /dev/block/sdf21
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-bootsys_b -&amp;gt; /dev/block/sdf56
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-persist -&amp;gt; /dev/block/sdf80
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_a -&amp;gt; /dev/block/sdb1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_b -&amp;gt; /dev/block/sdc1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_config_a -&amp;gt; /dev/block/sdb2
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_config_b -&amp;gt; /dev/block/sdc2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_ramdump_a -&amp;gt; /dev/block/sdf29
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_ramdump_b -&amp;gt; /dev/block/sdf63
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_sc_logs -&amp;gt; /dev/block/sdf87
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_sc_test_mode -&amp;gt; /dev/block/sdf86
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;現在，每個分割的信息便一目瞭然了。需要注意的是在新的平臺下，高通將 UEFI 韌體放到了單獨的UEFI分割中，原來的&lt;code&gt;XBL&lt;/code&gt;分割只是一個空殼而已（當然也不是什麼都沒有）。&lt;/p&gt;
&lt;h2&gt;獲取其他硬體（觸摸屏、Wi-Fi網路卡、音訊 Codec 等）&lt;/h2&gt;
&lt;p&gt;通過獲取 &lt;code&gt;dmesg&lt;/code&gt;， 可以得到大量關於裝置的信息。其中核心啓動引數中有一段非常引人注意：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[    0.000000] Kernel command line: console=ttynull stack_depot_disable=on cgroup_disable=pressure kasan.stacktrace=off kvm-arm.mode=protected bootconfig ioremap_guard log_buf_len=512K loglevel=6 cpufreq.default_governor=performance sysctl.kernel.sched_pelt_multiplier=4 no-steal-acc kpti=0 swiotlb=0 loop.max_part=7 irqaffinity=0-1 pcie_ports=compat printk.console_no_auto_verbose=1 kasan=off rcupdate.rcu_expedited=1 rcu_nocbs=0-7 kernel.panic_on_rcu_stall=1 disable_dma32=on cgroup_disable=pressure fw_devlink.strict=1 can.stats_timer=0 pci-msm-drv.pcie_sm_regs=0x1D07000,0x1040,0x1048,0x3000,0x1 ftrace_dump_on_oops slub_debug=- video=vfb:640x400,bpp=32,memsize=3072000 nosoftlockup console=ttynull qcom_geni_serial.con_enabled=0 bootconfig  msm_drm.dsi_display0=qcom,mdss_dsi_nt37801_wqhd_plus_cmd: rootwait ro init=/init silent_boot.mode=nonsilent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 &lt;code&gt;msm_drm.dsi_display0=qcom,mdss_dsi_nt37801_wqhd_plus_cmd&lt;/code&gt; 告訴了我們關於屏幕的信息：這是一塊由 Novatek 生產的顯示面板（Panel），型號是 NT37801，解析度是 1440x3220，AMOLED，重新整理頻率爲120Hz，DSI接口，輸出格式是 WQHD+。于是我在網路上檢索關於這塊面板的圖紙和 datasheet，但是並沒有找到。于是我又到 &lt;code&gt;lwn.net&lt;/code&gt; 上檢索關於該面板的相關合並請求或者 commit，果不其然，我找到了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/lwn-net.png&quot; alt=&quot;NT37801 merge request on LWN.net&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其提交日誌中明確寫到：「&lt;a href=&quot;https://lwn.net/Articles/1020176/&quot;&gt;添加了 Novatek NT37801（也叫 Novetek NT37801 AMOLED DSI 顯示面板）的驅動支援，其被用於高通 SM8750 MTP 單板電腦(SM8750)&lt;/a&gt;」，這就是我想要的結果了，雖然沒有發現 datasheet，但是知道了面板型號和連接方式，這就足夠了。&amp;lt;/br&amp;gt;
獲取PCIE裝置需要我們通過 &lt;code&gt;lspci&lt;/code&gt; 命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lspci -e                                                               
01:00.0 :   (rev 01)
00:00.0 :  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是，從中並不能得到什麼有效信息，于是我附加了 &lt;code&gt;-nn&lt;/code&gt; 參數：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/ $ lspci -nn                                                              
01:00.0  [0280]:   [17cb:110e] (rev 01)
00:00.0  [0604]:   [17cb:011c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;這樣就得到了 PCIe 裝置的 Vendor 和 Device ID，接下來就可以到 &lt;a href=&quot;https://pci-ids.ucw.cz/&quot;&gt;PCI ID Repository&lt;/a&gt; 資料庫中查詢了。造訪&lt;a href=&quot;https://pci-ids.ucw.cz/&quot;&gt;該網站&lt;/a&gt;，選擇「PCI Devices」，在「Vendor」一列，選擇「All」，之後使用瀏覽器的檢索功能，鍵入 &lt;code&gt;17cb&lt;/code&gt;，之後再鍵入 &lt;code&gt;110e&lt;/code&gt;。不幸的是，PCI ID Repository 沒有收錄這個裝置，那要怎麼辦呢？只能通過 Termux 來幫助我們了。首先安裝 &lt;code&gt;pciutils&lt;/code&gt;，Termux 的 &lt;code&gt;root repo&lt;/code&gt; 裏有收。然後執行 &lt;code&gt;lspci&lt;/code&gt; 即可：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/termux.png&quot; alt=&quot;lspci output with PCIe device&quot; /&gt;&lt;/p&gt;
&lt;p&gt;依然沒有什麼變化，不過根據&lt;a href=&quot;https://phonedb.net/index.php?m=processor&amp;amp;id=999&amp;amp;c=qualcomm_snapdragon_8_elite_sm8750-ab__sun&amp;amp;d=detailed_specs&quot;&gt;公佈的規格&lt;/a&gt;來看，PCIE掛的應該是自家的 X80 5G NR 數據機。&amp;lt;/br&amp;gt;
音訊codec用的是WSA 883X晶片，目前主線裝置樹中已有音訊的定義，ALSA也有了對應的配置文件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/deviceinfoHW.png&quot; alt=&quot;audio codec in Deviceinfo HW app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mainline-dts.png&quot; alt=&quot;SM8750 MTP devicetree in mainline kernel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-alsa.png&quot; alt=&quot;SM8750 MTP ALSA USM routing table in upstream repository&quot; /&gt;&lt;/p&gt;
&lt;p&gt;相機依然使用I²C，前面和背部的加起來統共5個鏡頭：前面用的是三星的&lt;code&gt;s5kjn1&lt;/code&gt;，後面面兩個索尼的&lt;code&gt;imx766&lt;/code&gt; &lt;code&gt;imx858&lt;/code&gt; 一個來自 OmniVision 的&lt;code&gt;ov32c4c&lt;/code&gt;，還有一個三星的&lt;code&gt;s5k33dxx&lt;/code&gt;。值得一提的是相機還附帶了兩個EEPROM，看來主線核心的相機修復工作應該比較困難了...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/deviceinfoHW.png&quot; alt=&quot;camara in Deviceinfo HW app&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;總結&lt;/h2&gt;
&lt;p&gt;看來 SM8750 的主線 Linux 移植又是困難重重喔...不過，在瞭解了這些硬體信息後，就可以爲主線 Linux 的移植做好準備了。&lt;/p&gt;
</content:encoded></item><item><title>Porting Armbian GNU/Linux to SM8750 MTP – Chapter One：Hardware Exploration</title><link>https://blog.cloudflare88.eu.org/posts/en/arch-linux-arm-port/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/arch-linux-arm-port/</guid><description>To port an operating system, one must first understand the hardware&apos;s composition and communication buses. This is the first step in embedded Linux porting.</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;&lt;/p&gt;
&lt;p&gt;After my previous review of the MTP8750, I gave this prototype a stellar evaluation. Since it&apos;s a proper prototype, it&apos;s only fitting to do something only a prototype can do, so I&apos;ve decided to port the Armbian operating system to it.&lt;/p&gt;
&lt;h1&gt;Hardware Exploration&lt;/h1&gt;
&lt;p&gt;In my last review, I compared Qualcomm&apos;s common engineering platforms (MTP, QRD) with mass-produced smartphones and briefly introduced the MTP8750&apos;s hardware configuration. Here, I&apos;ll reiterate those specifications from the previous article for your reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An early sample (ES) version of the SM8750 CPU [^1], 8 cores, ARM V9 instruction set;&lt;/li&gt;
&lt;li&gt;Adreno 830 GPU, supporting OpenGL ES 3.2;&lt;/li&gt;
&lt;li&gt;16GB LPDDR5X memory;&lt;/li&gt;
&lt;li&gt;512GB UFS 4.0, confirmed to be manufactured by Toshiba.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To obtain more hardware information, we need to start with the operating system. Fortunately, Android is, at its core, a Linux distribution, so many Linux methods for retrieving hardware data are equally applicable on Android. However, for Android, which typically lacks root access by default, obtaining hardware information via Linux methods can be quite an obstacle. The way to overcome these hurdles is to acquire root privileges. Luckily, the prototype&apos;s AOSP system comes with &lt;code&gt;ADB Root&lt;/code&gt; enabled by default, making debugging and log retrieval significantly easier than on production devices. All you need is a Type-C data cable to get started: First, open a terminal and install the &lt;code&gt;android-tools&lt;/code&gt; package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S android-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, type &lt;code&gt;adb root&lt;/code&gt; to restart &lt;code&gt;adbd&lt;/code&gt; with root privileges. Once the user prompt changes to a hash symbol (#), you&apos;ve successfully obtained root access! Now, let&apos;s proceed with the rest of the work!&lt;/p&gt;
&lt;h2&gt;Obtaining Kernel Version&lt;/h2&gt;
&lt;p&gt;Just like with any Linux distribution, Android allows you to retrieve the kernel version using the common &lt;code&gt;uname&lt;/code&gt; and &lt;code&gt;cat /proc/version&lt;/code&gt; commands. This helps us understand the difference between the phone&apos;s kernel version and the mainline kernel. Here&apos;s the output from the SM8750 MTP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/ # cat /proc/version
Linux version 6.6.50-android15-8-maybe-dirty-4k (kleaf@build-host) (Android (11368308, +pgo, +bolt, +lto, +mlgo, based on r510928) clang version 18.0.0 (&amp;lt;https://android.googlesource.com/toolchain/llvm-project&amp;gt; 477610d4d0d988e69dbc3fae4fe86bff3f07f2b5), LLD 18.0.0) #1 SMP PREEMPT Thu Jan  1 00:00:00 UTC 1970
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The kernel is a modified 6.6.50 kernel based on a Long-Term Support (LTS) version, released in 2023. While Google&apos;s GKI has somewhat narrowed the gap between Android downstream kernels and the mainline kernel in recent years, the issue remains severe. For a chip released in 2024, it&apos;s still running an outdated 6.6 kernel... It&apos;s worth noting that the kernel was compiled with 4K page size. Does this mean the SM8750 also has a kernel that supports 16K pages? Anyway, none of this is relevant to our main task.&lt;/p&gt;
&lt;h2&gt;Obtaining Memory Information&lt;/h2&gt;
&lt;p&gt;Memory information can be obtained using the &lt;code&gt;cat /proc/meminfo&lt;/code&gt; command, which provides details such as memory capacity, usage, and available space. Here&apos;s the output from the SM8750 MTP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;130|sun:/ # cat /proc/meminfo
MemTotal:       15543532 kB
MemFree:         4895720 kB
MemAvailable:   11264748 kB
Buffers:           18684 kB
Cached:          5749708 kB
SwapCached:            8 kB
Active:          3812464 kB
Inactive:        3266116 kB
Active(anon):    1636304 kB
Inactive(anon):        8 kB
Active(file):    2176160 kB
Inactive(file):  3266108 kB
Unevictable:      303252 kB
Mlocked:          180348 kB
SwapTotal:       6291452 kB
SwapFree:        5168380 kB
Dirty:                72 kB
Writeback:             0 kB
AnonPages:       1609740 kB
Mapped:          1303112 kB
Shmem:            153116 kB
KReclaimable:    1242056 kB
Slab:             783164 kB
SReclaimable:     265852 kB
SUnreclaim:       517312 kB
KernelStack:       74688 kB
ShadowCallStack:       0 kB
PageTables:       162628 kB
SecPageTables:         0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    14063216 kB
Committed_AS:   307714316 kB
VmallocTotal:   257687552 kB
VmallocUsed:      226660 kB
VmallocChunk:          0 kB
Percpu:            23616 kB
AnonHugePages:    178176 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
CmaTotal:         643072 kB
CmaFree:          590220 kB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For now, the only useful line here is the &lt;code&gt;MemTotal&lt;/code&gt; field, which tells us this prototype has 16GB of RAM...&lt;/p&gt;
&lt;h2&gt;Obtaining Partition Information&lt;/h2&gt;
&lt;p&gt;Similarly, using the &lt;code&gt;cat /proc/partitions&lt;/code&gt; command provides partition information, including the size, format, and mount points of each partition. Here&apos;s the output from the SM8750 MTP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;major minor  #blocks  name

   1        0       8192 ram0
   1        1       8192 ram1
   1        2       8192 ram2
   1        3       8192 ram3
   1        4       8192 ram4
   1        5       8192 ram5
   1        6       8192 ram6
   1        7       8192 ram7
   1        8       8192 ram8
   1        9       8192 ram9
   1       10       8192 ram10
   1       11       8192 ram11
   1       12       8192 ram12
   1       13       8192 ram13
   1       14       8192 ram14
   1       15       8192 ram15
   7        0      39744 loop0
   7        8        836 loop1
   7       16      93148 loop2
   7       24      11252 loop3
   7       32       6312 loop4
   7       40     101248 loop5
   7       48        268 loop6
   7       56        336 loop7
   7       64      29528 loop8
   7       72       4860 loop9
   7       80       3632 loop10
   7       88      92200 loop11
   7       96        808 loop12
   7      104     111964 loop13
   7      112      46412 loop14
   7      120      11252 loop15
   8        0  487096320 sda
   8        1          8 sda1
   8        2      32768 sda2
   8        3       1024 sda3
   8        4        512 sda4
   8        5        512 sda5
   8        6    6291456 sda6
   8        7         64 sda7
   8        8         64 sda8
   8        9      65536 sda9
   8       10   17301504 sda10
   8       11    4194304 sda11
   8       12  459208524 sda12
   8       16      20480 sdb
   8       17       3584 sdb1
   8       18        344 sdb2
   8       19         32 sdb3
   8       20         32 sdb4
   8       21        256 sdb5
   8       48      32768 sdd
   8       49        104 sdd1
   8       50        128 sdd2
   8       51       1024 sdd3
   8       32      20480 sdc
   8       33       3584 sdc1
   8       34        344 sdc2
   8       35         32 sdc3
   8       36         32 sdc4
   8       37        256 sdc5
   8       64      32768 sde
   8       65        104 sde1
   8       66       4096 sde2
   8       67       4096 sde3
   8       68       4096 sde4
   8       69        128 sde5
   8       80    4194304 sdf
   8       81       5120 sdf1
   8       82        512 sdf2
   8       83        512 sdf3
   8       84       5120 sdf4
   8       85       8192 sdf5
   8       86     460800 sdf6
   8       87      10240 sdf7
   8       88       1024 sdf8
   8       89      65536 sdf9
   8       90      10240 sdf10
   8       91        128 sdf11
   8       92      98304 sdf12
   8       93        128 sdf13
   8       94         80 sdf14
   8       95         64 sdf15
 259        0      24576 sdf16
 259        1       2048 sdf17
 259        2       2048 sdf18
 259        3        256 sdf19
 259        4     174080 sdf20
 259        5     550000 sdf21
 259        6       1024 sdf22
 259        7        128 sdf23
 259        8      16384 sdf24
 259        9      98304 sdf25
 259       10      30720 sdf26
 259       11        256 sdf27
 259       12     102400 sdf28
 259       13       2048 sdf29
 259       14       8192 sdf30
 259       15         64 sdf31
 259       16       1024 sdf32
 259       17        512 sdf33
 259       18         24 sdf34
 259       19        256 sdf35
 259       20        128 sdf36
 259       21       5120 sdf37
 259       22        512 sdf38
 259       23        512 sdf39
 259       24       5120 sdf40
 259       25       8192 sdf41
 259       26     460800 sdf42
 259       27      10240 sdf43
 259       28       1024 sdf44
 259       29      65536 sdf45
 259       30      10240 sdf46
 259       31        128 sdf47
 259       32      98304 sdf48
 259       33        128 sdf49
 259       34         80 sdf50
 259       35         64 sdf51
 259       36      24576 sdf52
 259       37       2048 sdf53
 259       38       2048 sdf54
 259       39        256 sdf55
 259       40     550000 sdf56
 259       41       1024 sdf57
 259       42        128 sdf58
 259       43     174080 sdf59
 259       44      98304 sdf60
 259       45        256 sdf61
 259       46     102400 sdf62
 259       47       2048 sdf63
 259       48       8192 sdf64
 259       49         64 sdf65
 259       50       1024 sdf66
 259       51        512 sdf67
 259       52         24 sdf68
 259       53        256 sdf69
 259       54        128 sdf70
 259       55          4 sdf71
 259       56       1024 sdf72
 259       57       8192 sdf73
 259       58      40960 sdf74
 259       59     524288 sdf75
 259       60        128 sdf76
 259       61        512 sdf77
 259       62         28 sdf78
 259       63        512 sdf79
 259       64     235520 sdf80
 259       65       1024 sdf81
 259       66      20480 sdf82
 259       67        128 sdf83
 259       68        128 sdf84
 259       69      32768 sdf85
 259       70         64 sdf86
 259       71        128 sdf87
 259       72          8 sdf88
   8       96    4194304 sdg
   8      112    4194304 sdh
 254        0       1692 dm-0
 254        1    2589236 dm-1
 254        2      11940 dm-2
 254        3     804512 dm-3
 254        4    1647464 dm-4
 254        5     141248 dm-5
   7      128      93148 loop16
   7      136        836 loop17
   7      144      23324 loop18
   7      152      40892 loop19
   7      160        268 loop20
   7      168      41180 loop21
   7      176      15832 loop22
   7      184      39744 loop23
   7      192      32064 loop24
   7      200      23324 loop25
   7      208      26196 loop26
   7      216      40792 loop27
   7      224      41420 loop28
   7      232       1336 loop29
   7      240       7088 loop30
   7      248       7288 loop31
   7      256       8152 loop32
   7      264      19164 loop33
   7      272        824 loop34
   7      280      14116 loop35
   7      288      10984 loop36
   7      296      10752 loop37
   7      304       1860 loop38
   7      312       6132 loop39
   7      320       1616 loop40
   7      328      10076 loop41
   7      336        268 loop42
   7      344      26256 loop43
   7      352       3104 loop44
   7      360       6184 loop45
   7      368      25136 loop46
   7      376       4556 loop47
   7      384       9624 loop48
 254        6      24928 dm-6
 254        7       6124 dm-7
 254        8      26040 dm-8
 254        9        256 dm-9
 254       10       4508 dm-10
 254       11       9536 dm-11
 254       13       9984 dm-13
 254       14       1588 dm-14
 254       15      29284 dm-15
 254       17       1832 dm-17
 254       19      10656 dm-19
 254       21      10884 dm-21
 254       22      13992 dm-22
 254       24       6072 dm-24
 254       25        804 dm-25
 254       28      19000 dm-28
 254       29       8076 dm-29
 254       31       7216 dm-31
 254       38       7020 dm-38
 254       43        324 dm-43
 254       44      41084 dm-44
 254       45      25980 dm-45
 254       48      23128 dm-48
 254       50      31800 dm-50
 253        0    6291456 zram0
 254       51  459208524 dm-51
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This only gives us the size of each partition, without any other details. To get the mapping of each device node, we need to execute &lt;code&gt;ls -l /dev&lt;/code&gt; in the &lt;code&gt;/dev&lt;/code&gt; directory to obtain the results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/dev/block/by-name # ls -l
total 0
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ALIGN_TO_128K_1 -&amp;gt; /dev/block/sdd1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ALIGN_TO_128K_2 -&amp;gt; /dev/block/sde1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 abl_a -&amp;gt; /dev/block/sdf8
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 abl_b -&amp;gt; /dev/block/sdf44
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 aop_a -&amp;gt; /dev/block/sdf2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 aop_b -&amp;gt; /dev/block/sdf38
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 aop_config_a -&amp;gt; /dev/block/sdf3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 aop_config_b -&amp;gt; /dev/block/sdf39
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 apdp -&amp;gt; /dev/block/sdb5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 apdpb -&amp;gt; /dev/block/sdc5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 bluetooth_a -&amp;gt; /dev/block/sdf7
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 bluetooth_b -&amp;gt; /dev/block/sdf43
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 boot_a -&amp;gt; /dev/block/sdf12
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 boot_b -&amp;gt; /dev/block/sdf48
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 cdt -&amp;gt; /dev/block/sdd2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 connsec -&amp;gt; /dev/block/sdf83
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 core_nhlos_a -&amp;gt; /dev/block/sdf20
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 core_nhlos_b -&amp;gt; /dev/block/sdf59
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_a -&amp;gt; /dev/block/sdf22
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_b -&amp;gt; /dev/block/sdf57
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_dtb_a -&amp;gt; /dev/block/sdf31
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 cpucp_dtb_b -&amp;gt; /dev/block/sdf65
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ddr -&amp;gt; /dev/block/sdd3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devcfg_a -&amp;gt; /dev/block/sdf13
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devcfg_b -&amp;gt; /dev/block/sdf49
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 devinfo -&amp;gt; /dev/block/sdf71
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dpm -&amp;gt; /dev/block/sdf88
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 dsp_a -&amp;gt; /dev/block/sdf9
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dsp_b -&amp;gt; /dev/block/sdf45
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dtbo_a -&amp;gt; /dev/block/sdf16
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 dtbo_b -&amp;gt; /dev/block/sdf52
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 featenabler_a -&amp;gt; /dev/block/sdf23
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 featenabler_b -&amp;gt; /dev/block/sdf58
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 frp -&amp;gt; /dev/block/sda5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 fsc -&amp;gt; /dev/block/sde5
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 fsg -&amp;gt; /dev/block/sde4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 hyp_a -&amp;gt; /dev/block/sdf5
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 hyp_b -&amp;gt; /dev/block/sdf41
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 imagefv_a -&amp;gt; /dev/block/sdf18
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 imagefv_b -&amp;gt; /dev/block/sdf54
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 init_boot_a -&amp;gt; /dev/block/sdf30
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 init_boot_b -&amp;gt; /dev/block/sdf64
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 keymaster_a -&amp;gt; /dev/block/sdf10
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 keymaster_b -&amp;gt; /dev/block/sdf46
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 keystore -&amp;gt; /dev/block/sda4
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 logdump -&amp;gt; /dev/block/sdf75
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 logfs -&amp;gt; /dev/block/sdf73
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 mdcompress -&amp;gt; /dev/block/sdf82
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 metadata -&amp;gt; /dev/block/sda9
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 misc -&amp;gt; /dev/block/sda3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modem_a -&amp;gt; /dev/block/sdf6
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 modem_b -&amp;gt; /dev/block/sdf42
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modemst1 -&amp;gt; /dev/block/sde2
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 modemst2 -&amp;gt; /dev/block/sde3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgoem_a -&amp;gt; /dev/block/sdb4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgoem_b -&amp;gt; /dev/block/sdc4
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgqti_a -&amp;gt; /dev/block/sdb3
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 multiimgqti_b -&amp;gt; /dev/block/sdc3
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_a -&amp;gt; /dev/block/sdf35
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pdp_b -&amp;gt; /dev/block/sdf69
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 persist -&amp;gt; /dev/block/sda2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pvmfw_a -&amp;gt; /dev/block/sdf32
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 pvmfw_b -&amp;gt; /dev/block/sdf66
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qmcs -&amp;gt; /dev/block/sdf26
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumcontentfv -&amp;gt; /dev/block/sdf81
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumfv -&amp;gt; /dev/block/sdf79
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 quantumsdk -&amp;gt; /dev/block/sdf74
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 questdatafv -&amp;gt; /dev/block/sdf24
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qupfw_a -&amp;gt; /dev/block/sdf14
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qupfw_b -&amp;gt; /dev/block/sdf50
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qweslicstore_a -&amp;gt; /dev/block/sdf27
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 qweslicstore_b -&amp;gt; /dev/block/sdf61
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 rawdump -&amp;gt; /dev/block/sda10
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 recovery_a -&amp;gt; /dev/block/sdf28
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 recovery_b -&amp;gt; /dev/block/sdf62
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sda -&amp;gt; /dev/block/sda
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdb -&amp;gt; /dev/block/sdb
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdc -&amp;gt; /dev/block/sdc
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdd -&amp;gt; /dev/block/sdd
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sde -&amp;gt; /dev/block/sde
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdf -&amp;gt; /dev/block/sdf
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdg -&amp;gt; /dev/block/sdg
lrwxrwxrwx 1 root root 14 1970-01-07 17:43 sdh -&amp;gt; /dev/block/sdh
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 secdata -&amp;gt; /dev/block/sdf78
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 shrm_a -&amp;gt; /dev/block/sdf19
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 shrm_b -&amp;gt; /dev/block/sdf55
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_dcd_a -&amp;gt; /dev/block/sdf34
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_dcd_b -&amp;gt; /dev/block/sdf68
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_debug_a -&amp;gt; /dev/block/sdf33
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 soccp_debug_b -&amp;gt; /dev/block/sdf67
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spunvm -&amp;gt; /dev/block/sdf85
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spuservice_a -&amp;gt; /dev/block/sdf11
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 spuservice_b -&amp;gt; /dev/block/sdf47
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 ssd -&amp;gt; /dev/block/sda1
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 storsec -&amp;gt; /dev/block/sdf76
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 super -&amp;gt; /dev/block/sda6
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 testparti -&amp;gt; /dev/block/sda11
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 toolsfv -&amp;gt; /dev/block/sdf72
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 tz_a -&amp;gt; /dev/block/sdf4
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 tz_b -&amp;gt; /dev/block/sdf40
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 tzsc -&amp;gt; /dev/block/sdf84
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 uefi_a -&amp;gt; /dev/block/sdf1
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefi_b -&amp;gt; /dev/block/sdf37
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefisecapp_a -&amp;gt; /dev/block/sdf17
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefisecapp_b -&amp;gt; /dev/block/sdf53
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 uefivarstore -&amp;gt; /dev/block/sdf77
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 userdata -&amp;gt; /dev/block/sda12
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vbmeta_a -&amp;gt; /dev/block/sdf15
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vbmeta_b -&amp;gt; /dev/block/sdf51
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 vbmeta_system_a -&amp;gt; /dev/block/sda7
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 vbmeta_system_b -&amp;gt; /dev/block/sda8
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vendor_boot_a -&amp;gt; /dev/block/sdf25
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vendor_boot_b -&amp;gt; /dev/block/sdf60
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-bootsys_a -&amp;gt; /dev/block/sdf21
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-bootsys_b -&amp;gt; /dev/block/sdf56
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 vm-persist -&amp;gt; /dev/block/sdf80
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_a -&amp;gt; /dev/block/sdb1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_b -&amp;gt; /dev/block/sdc1
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_config_a -&amp;gt; /dev/block/sdb2
lrwxrwxrwx 1 root root 15 1970-01-07 17:43 xbl_config_b -&amp;gt; /dev/block/sdc2
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_ramdump_a -&amp;gt; /dev/block/sdf29
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_ramdump_b -&amp;gt; /dev/block/sdf63
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_sc_logs -&amp;gt; /dev/block/sdf87
lrwxrwxrwx 1 root root 16 1970-01-07 17:43 xbl_sc_test_mode -&amp;gt; /dev/block/sdf86
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the information for each partition is crystal clear. It&apos;s worth noting that on this new platform, Qualcomm has placed the UEFI firmware in a separate UEFI partition, and the original &lt;code&gt;XBL&lt;/code&gt; partition is merely a shell (though not entirely empty, of course).&lt;/p&gt;
&lt;h2&gt;Obtaining Other Hardware Information (Touchscreen, Wi-Fi Card, Audio Codec, etc.)&lt;/h2&gt;
&lt;p&gt;By fetching &lt;code&gt;dmesg&lt;/code&gt;, we can obtain a wealth of information about the device. Among the kernel boot parameters, one particular section stands out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[    0.000000] Kernel command line: console=ttynull stack_depot_disable=on cgroup_disable=pressure kasan.stacktrace=off kvm-arm.mode=protected bootconfig ioremap_guard log_buf_len=512K loglevel=6 cpufreq.default_governor=performance sysctl.kernel.sched_pelt_multiplier=4 no-steal-acc kpti=0 swiotlb=0 loop.max_part=7 irqaffinity=0-1 pcie_ports=compat printk.console_no_auto_verbose=1 kasan=off rcupdate.rcu_expedited=1 rcu_nocbs=0-7 kernel.panic_on_rcu_stall=1 disable_dma32=on cgroup_disable=pressure fw_devlink.strict=1 can.stats_timer=0 pci-msm-drv.pcie_sm_regs=0x1D07000,0x1040,0x1048,0x3000,0x1 ftrace_dump_on_oops slub_debug=- video=vfb:640x400,bpp=32,memsize=3072000 nosoftlockup console=ttynull qcom_geni_serial.con_enabled=0 bootconfig  msm_drm.dsi_display0=qcom,mdss_dsi_nt37801_wqhd_plus_cmd: rootwait ro init=/init silent_boot.mode=nonsilent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;msm_drm.dsi_display0=qcom,mdss_dsi_nt37801_wqhd_plus_cmd&lt;/code&gt; parameter provides information about the display: it&apos;s a panel manufactured by Novatek, model NT37801, with a resolution of 1440x3220, AMOLED, a refresh rate of 120Hz, DSI interface, and WQHD+ output format. I then scoured the internet for schematics and datasheets for this panel but came up empty. So, I turned to &lt;code&gt;lwn.net&lt;/code&gt; to search for related merge requests or commits for this panel, and lo and behold, I found it:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/lwn-net.png&quot; alt=&quot;NT37801 merge request on LWN.net&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Its commit log explicitly states: &apos;&lt;a href=&quot;https://lwn.net/Articles/1020176/&quot;&gt;Added driver support for Novatek NT37801 (also known as Novetek NT37801 AMOLED DSI display panel)&lt;/a&gt;, used on the Qualcomm SM8750 MTP board&apos;. This is exactly what I was looking for. Although I didn&apos;t find a datasheet, knowing the panel model and connection method is sufficient.&lt;/p&gt;
&lt;p&gt;To obtain PCIe device information, we need to use the &lt;code&gt;lspci&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lspci -e                                                               
01:00.0 :   (rev 01)
00:00.0 :  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this didn&apos;t yield any useful information, so I appended the &lt;code&gt;-nn&lt;/code&gt; parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sun:/ $ lspci -nn                                                              
01:00.0 :   [17cb:110e] (rev 01)
00:00.0 :   [17cb:011c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gave us the Vendor and Device IDs of the PCIe device. Next, we can query the PCI ID Repository database. Visit the website, select &apos;PCI Devices&apos;, choose &apos;All&apos; in the &apos;Vendor&apos; column, then use your browser&apos;s search function to type &lt;code&gt;17cb&lt;/code&gt;, followed by &lt;code&gt;110e&lt;/code&gt;. Unfortunately, the PCI ID Repository doesn&apos;t list this device. What now? We&apos;ll have to rely on Termux. First, install &lt;code&gt;pciutils&lt;/code&gt;, which is available in Termux&apos;s &lt;code&gt;root repo&lt;/code&gt;. Then, simply run &lt;code&gt;lspci&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/termux.png&quot; alt=&quot;lspci output with PCIe device&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Still no change. However, according to the &lt;a href=&quot;https://phonedb.net/index.php?m=processor&amp;amp;id=999&amp;amp;c=qualcomm_snapdragon_8_elite_sm8750-ab__sun&amp;amp;d=detailed_specs&quot;&gt;published specifications&lt;/a&gt;, the PCIe device should be Qualcomm&apos;s own X80 5G NR modem.&lt;/p&gt;
&lt;p&gt;The audio codec uses the WSA 883X chip. There are already audio definitions in the mainline device tree, and ALSA has corresponding configuration files.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/deviceinfoHW.png&quot; alt=&quot;audio codec in Deviceinfo HW app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mainline-dts.png&quot; alt=&quot;SM8750 MTP devicetree in mainline kernel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-alsa.png&quot; alt=&quot;SM8750 MTP ALSA USM routing table in upstream repository&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The camera still uses I²C, with a total of 5 lenses, front and back combined: the front uses Samsung&apos;s &lt;code&gt;s5kjn1&lt;/code&gt;, and the rear features two Sony &lt;code&gt;imx766&lt;/code&gt; &lt;code&gt;imx858&lt;/code&gt; sensors, one OmniVision &lt;code&gt;ov32c4c&lt;/code&gt;, and another Samsung &lt;code&gt;s5k33dxx&lt;/code&gt;. It&apos;s worth noting that the camera also comes with two EEPROMs, which suggests that mainline kernel camera support will likely be quite challenging...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/deviceinfoHW.png&quot; alt=&quot;camara in Deviceinfo HW app&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It seems that porting mainline Linux to the SM8750 is going to be a tough nut to crack... Nevertheless, now that we have this hardware information, we can prepare for the mainline Linux port.&lt;/p&gt;
&lt;p&gt;[^1]:Unlike the official version&apos;s 4.32GHz clock speed, this ES version has a base frequency of only 3.63GHz.&lt;/p&gt;
</content:encoded></item><item><title>Code is a Good Thing (Feat. Pakala Oryon) -- A FOSS Parody of Rain is a Good Thing by Luke Bryan</title><link>https://blog.cloudflare88.eu.org/posts/code-is-a-good-thing/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/code-is-a-good-thing/</guid><description>Linus writes code, code creates Linux. Linux runs on my chip, make my phone little risky. A song about my first LFS(Linux From Scratch) trial.</description><pubDate>Tue, 09 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/4VKy69sE4VY?si=N9z2BFPZ6BXNq_7G&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Code%20is%20a%20Good%20Thing%20--%20A%20FOSS%20parody%20of%20Rain%20is%20a%20Good%20Thing%20.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;My daddy spent too much time, dealing with his laggy phone&amp;lt;/br&amp;gt;
It&apos;s full of spyware, stealing his privacy&amp;lt;/br&amp;gt;
He never thinks about freedom, &apos;Cause he&apos;s too old to change&amp;lt;/br&amp;gt;
But in my opinion, code is a good thing.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Linus writes code, code creates Linux&amp;lt;/br&amp;gt;
Linux runs on chip, make my phone (a) little risky&amp;lt;/br&amp;gt;
Filesystems are packed up, boot firmwares are ready to compile&amp;lt;/br&amp;gt;
Gotta flash linux now, capturing all the logs&amp;lt;/br&amp;gt;
Take a screenshot then post it on my blog&amp;lt;/br&amp;gt;
Code is a good thing&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;There&apos;s nothing better than recreating it from the scratch&amp;lt;/br&amp;gt;
Compiling and optimizing, after reading LFS book&amp;lt;/br&amp;gt;
Tons of problems to solve, millions errors to fix&amp;lt;/br&amp;gt;
But I still believe, code is a good thing.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Linus writes code, code creates Linux&amp;lt;/br&amp;gt;
Linux runs on chip, make my phone (a) little risky&amp;lt;/br&amp;gt;
Filesystems are packed up, boot firmwares are ready to compile&amp;lt;/br&amp;gt;
Gotta flash linux now, capturing all the logs&amp;lt;/br&amp;gt;
Take a screenshot then post it on my blog&amp;lt;/br&amp;gt;
Code is a good thing&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge&lt;/h1&gt;
&lt;p&gt;Mr.Daddy did a little test&amp;lt;/br&amp;gt;
Smile on his face, another upgrade&amp;lt;/br&amp;gt;
All my fans, they wanna participate&amp;lt;/br&amp;gt;
But some features are a really big trouble&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;Linus writes code, code creates Linux&amp;lt;/br&amp;gt;
Linux runs on chip, make my phone (a) little risky&amp;lt;/br&amp;gt;
Filesystems are packed up, boot firmwares are ready to compile&amp;lt;/br&amp;gt;
Gotta flash linux now, capturing all the logs&amp;lt;/br&amp;gt;
Take a screenshot then post it on my blog&amp;lt;/br&amp;gt;
Code is a good thing&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Code is a good thing.&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>MTP Trouble (Feat. Pakala Oryon &amp; Lanai Kaanapali) -- A FOSS Parody of Trouble by Avicii</title><link>https://blog.cloudflare88.eu.org/posts/mtp-trouble/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/mtp-trouble/</guid><description>I&apos;ve seen the trouble more than anyone can bear.</description><pubDate>Wed, 03 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/MTP%20Trouble%20--%20A%20FOSS%20parody%20of%20Trouble%20.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/GiuabrUp8zM?si=Jpt7GThbrNFuzm6_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;I&apos;ve been a user and I&apos;ve been a developer &amp;lt;/br&amp;gt;
I am the person who just rented a brand new phone &amp;lt;/br&amp;gt;
Losing my privacy just to trade for convience &amp;lt;/br&amp;gt;
I&apos;m sick for this phenomenon, so I had to move out &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ve been a teacher or a student of FOSS &amp;lt;/br&amp;gt;
I&apos;ve shared my fork no matter it would worth &amp;lt;/br&amp;gt;
Never been last, but I never been first &amp;lt;/br&amp;gt;
Oh I may not be the best, but I&apos;m far from the worst &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Oh I may not be the best, but I&apos;m far from the worst &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Oh I&apos;ve seen the trouble more than anyone can bear &amp;lt;/br&amp;gt;
But I still have joy more than failure I&apos;ve met &amp;lt;/br&amp;gt;
I&apos;m still not done, I&apos;m only halfway there &amp;lt;/br&amp;gt;
I&apos;m a million miles ahead of where I from, but I still have another million miles to go &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;I keep on searching for the mainline goods&amp;lt;/br&amp;gt;
I&apos;m gonna port everything by myself&amp;lt;/br&amp;gt;
Thinking it maybe ended up with hardbrick&amp;lt;/br&amp;gt;
I have a limited smartphone, but I still want to try out&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I know this plan goes well beyond mine&amp;lt;/br&amp;gt;
Gonna debug and read the logs&amp;lt;/br&amp;gt;
They says it&apos;s meaningless, but I doesn&apos;t care&amp;lt;/br&amp;gt;
Oh it may not be easy, but I love this trial &amp;lt;/br&amp;gt;
Oh it maybe too difficult, but I love this life &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;Oh I&apos;ve seen the trouble more than anyone can bear &amp;lt;/br&amp;gt;
But I still have joy more than failure I&apos;ve met &amp;lt;/br&amp;gt;
I&apos;m still not done, I&apos;m only halfway there &amp;lt;/br&amp;gt;
I&apos;m a million miles ahead of where I from, but I still have another million miles to go &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>刷機進行式 (Feat. Pakala Oryon) —— 根據 May&apos;n 的 《人生進行形》的 FOSS 改編</title><link>https://blog.cloudflare88.eu.org/posts/flash-continous-tense/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/flash-continous-tense/</guid><description>我們曾一起奔向那自由的彼方，與專有軟體說過“明天見”後便永不再見面。</description><pubDate>Sat, 29 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;點此檢視&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/ko/flash-continous-tence/&quot;&gt;韓文版歌詞&lt;/a&gt; 和 &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/en/flash-continous-tense/&quot;&gt;英文版歌詞&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;OnePlus 6T at the beach&quot; 圖片，EDKPiepaint 版權所有；&lt;/li&gt;
&lt;li&gt;《刷機進行時》 歌詞，EDKPiepaint 版權所有。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如有疑問，請洽版權所有者。
:::&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/n6GVaJL_eeY?si=T-7F7bfpk5GGeWWw&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%E5%88%B7%E6%A9%9F%E9%80%B2%E8%A1%8C%E6%99%82%E2%80%94%E6%A0%B9%E6%93%9AMay&apos;n%20%E7%9A%84%E3%80%8C%E4%BA%BA%E7%94%9F%E9%80%B2%E8%A1%8C%E5%BD%A2%E3%80%8D%E6%94%B9%E7%B7%A8.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;妳在漆黑的熒幕上&amp;lt;/br&amp;gt;
注視著什麼呢？&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
遠處的山崗上&amp;lt;/br&amp;gt;
傳來了松果香[^1]&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
今天也和往常一樣，在痛苦、憂愁中過去&amp;lt;/br&amp;gt;
時間也不知不覺&amp;lt;/br&amp;gt;
從中流逝而過&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
在我的記憶中，這一成不變的世界&amp;lt;/br&amp;gt;
是由專有軟體組成的「圍牆花園」&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
我們一起奔向那自由的彼方&amp;lt;/br&amp;gt;
和專有軟體道過「來日見」後永不再見面&amp;lt;/br&amp;gt;
因爲未發現自由替代，所以與家人失聯&amp;lt;/br&amp;gt;
就這麼記住，第一次逃離「圍牆花園」[^2]的實踐&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/oneplus-ace5-a16-gsi.jpg&quot; alt=&quot;Oneplus Ace 5 running Android 16 GSI&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;早就 習慣 專有軟體&amp;lt;/br&amp;gt;
（甚至）不理解，什麼是「自由」
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;我在不知不覺中&amp;lt;/br&amp;gt;
獨自在天臺徘徊&amp;lt;/br&amp;gt;
並幻想着把手機改造自由軟體的未來&amp;lt;/br&amp;gt;
終於有一天，幻想成真&amp;lt;/br&amp;gt;
手機「解鎖」是前提&amp;lt;/br&amp;gt;
鍵入命令，電源鍵確認&amp;lt;/br&amp;gt;
「圍牆花園」，再見！&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&lt;img src=&quot;assets/nabu.jpg&quot; alt=&quot;Oneplus 6T and Mi pad5 running mainline Linux&quot; /&gt;
&amp;lt;/br&amp;gt;
開機之後，日誌滾動&amp;lt;/br&amp;gt;
早已把我震驚&amp;lt;/br&amp;gt;
想不到初次刷機的過程竟如此順利&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
只是因「專有軟體」摧殘，手機早已「命不久矣」&amp;lt;/br&amp;gt;
當年的刷機少年如今長大成人&amp;lt;/br&amp;gt;
即使黑磚、Crashdump 也沒關係，刷機還是進行式&amp;lt;/br&amp;gt;
如果傷心的話，就再換手機吧&amp;lt;/br&amp;gt;
一切又從頭開始&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
圍牆的 那邊是 自由的&amp;lt;/br&amp;gt;
我終於 找到 棲身之處&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;手機到家，一切又重新開始&amp;lt;/br&amp;gt;
「解鎖」條件，似乎又提高不少&amp;lt;/br&amp;gt;
長期經歷，（問題）早已熟練應對&amp;lt;/br&amp;gt;
在 Linux 中開懷大笑&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;我們一起奔向那自由的彼方&amp;lt;/br&amp;gt;
和專有軟體道過「來日見」後永不再見面&amp;lt;/br&amp;gt;
即使不知機理也無所謂啊，只需記住那天&amp;lt;/br&amp;gt;
遙遠的記憶之中，當初的勇敢實踐&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
依靠著 專有 軟體&amp;lt;/br&amp;gt;
只在我 理解 自由 之前&amp;lt;/br&amp;gt;
現在 隱私 已被我 掌控&amp;lt;/br&amp;gt;
來吧，再次開懷大笑&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;[^1]:指香港生產搭載 Linux 的手機、平板電腦、筆電等的「PINE64」公司。因爲其 LOGO 爲松果，故稱之為「松果香」。
[^2]:指由 Android 和 iOS 以及其牠專有軟體組成的軟體使用環境。這是現在智慧型手機的普遍軟體特徵。&lt;/p&gt;
</content:encoded></item><item><title>플래싱(Flashing)進行形(진행형) (Feat. Purwa Oryon) —— May&apos;n의‘人生進行形(인생진행형)’올 FOSS가 패러디 한 버전</title><link>https://blog.cloudflare88.eu.org/posts/ko/flash-continous-tense/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/ko/flash-continous-tense/</guid><description>우리 함께 저 自由로운 곳으로 奔走해,私有 software와 &quot;明日 再見&quot;한 뒤 다시는 안 봐.</description><pubDate>Sat, 29 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%ED%94%8C%EB%9E%98%EC%8B%B1(Flashing)%20%EC%A7%84%ED%96%89%ED%98%95(%E9%80%B2%E8%A1%8C%E5%BD%A2).mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/%ED%94%8C%EB%9E%98%EC%8B%B1%20%EC%A7%84%ED%96%89%ED%98%95(%E9%80%B2%E8%A1%8C%E5%BD%A2).mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/n6GVaJL_eeY?si=T-7F7bfpk5GGeWWw&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;까만 畵面(화면) 속에서&amp;lt;/br&amp;gt;
넌 무얼 보고 있는 거야?&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在漆黑的螢幕裡,&amp;lt;/br&amp;gt;
你到底在看什麼？&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;저 멀리 山(산)마루엔&amp;lt;/br&amp;gt;
솔방울 香氣(향기) 불어와&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;遠方的山巔,&amp;lt;/br&amp;gt;
松果的香氣隨風而來&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;오늘도 늘 그렇듯, 苦痛(고통)과 憂患(우환) 속에 지나가&amp;lt;/br&amp;gt;
時間(시간)도 알지 못하게&amp;lt;/br&amp;gt;
그 사이로 흘러가 버려&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;今天也像往常一樣，在痛苦和煩惱中度過&amp;lt;/br&amp;gt;
時間不知不覺地流逝&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;내 記憶(기억) 속의 이 變(변)함없는 世上(세상)은&amp;lt;/br&amp;gt;
私有(사유) 소프트웨(software)어로 만든 ‘圍墻庭園(위장정원)’&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我記憶中的這個不變的世界,&amp;lt;/br&amp;gt;
就像被專有軟體築起的圍牆庭園&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;우리 함께 저 自由(자유)로운 곳으로 달려가&amp;lt;/br&amp;gt;
私有(사유) 소프와(software) &quot;來日(내일) 봐&quot;한 뒤 다시는 안 봐&amp;lt;/br&amp;gt;
自由(자유)로운 代案(대안) 없어 家族(가족)과 連絡(연락) 끊겨&amp;lt;/br&amp;gt;
그렇게 記憶(기억)해, 처음 ‘圍墻庭園(위장정워)’을 떠난 實踐(실천)을&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們一起奔向那自由的地方,&amp;lt;/br&amp;gt;
對專有軟體說「明天見」後再也不回頭&amp;lt;/br&amp;gt;
沒有自由軟體的替代方案，與家人斷絕聯絡,&amp;lt;/br&amp;gt;
就這樣記住，第一次離開「圍牆庭園」的實踐&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;이미 익숙해진 私有(사유) 소프트웨(software)어&amp;lt;/br&amp;gt;
(甚至(심지)於) 理解(이해) 못 해, &apos;自由(자유)&apos;가 뭔지&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我已經習慣了這種專有軟體&amp;lt;/br&amp;gt;
甚至不懂「自由」是何物&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;난 알지 못하는 사이에&amp;lt;/br&amp;gt;
홀로 屋上(옥상)을 서성여&amp;lt;/br&amp;gt;
携帶(휴대)폰(phone)을 自由(자유) 소프트웨(software)어로 바꿀 未來(미래)를 꿈꿔&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在我不知情的時候,&amp;lt;/br&amp;gt;
獨自在屋頂徘徊,&amp;lt;/br&amp;gt;
夢想將手機改造自由軟體的未來&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;마침내 그날이 와, 幻想(환상)이 現實(현실)이 돼&amp;lt;/br&amp;gt;
폰(phone) ‘Unlock’은 前提條件(전제조건)&amp;lt;/br&amp;gt;
命令語(명령어) 入力(입력)하고, 電源(전원) 버튼 確認(확인)&amp;lt;/br&amp;gt;
‘圍墻庭園(위장정원)’, 安寧(안녕)!&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;終於那一天來了，幻想成為現實&amp;lt;/br&amp;gt;
手機解鎖是前提&amp;lt;/br&amp;gt;
鍵入命令，電源鍵確認&amp;lt;/br&amp;gt;
「圍牆庭園」，再見！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
Booting 後(후) 로그(log)가 흘러&amp;lt;/br&amp;gt;
이미 난 깜짝 놀라&amp;lt;/br&amp;gt;
처음 하는 플래싱이 이렇게 順調(순조)로울 줄이야&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;開機後，日誌滾動&amp;lt;/br&amp;gt;
我已驚訝不已,&amp;lt;/br&amp;gt;
初次刷機竟然如此順利&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但只(단지) &apos;私有(사유) 소프&apos;에 시달려 폰(phone)은 이미 &apos;죽어갈 뿐&apos;&amp;lt;/br&amp;gt;
그 時節(시절) 플래싱(flashing) 少年(소년) 이제는 어른이 됐어&amp;lt;/br&amp;gt;
壁(벽)돌 되어도, Crashdump 도 상관없어, 플래싱(flashing)은 現在進行形(현재진행형)&amp;lt;/br&amp;gt;
만약 슬퍼진다면, 폰(phone)을 다시 바꾸면 돼&amp;lt;/br&amp;gt;
모든 게 다시 始作(시작)돼&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;過去受制於「專有軟體」，手機幾乎「命不久矣」&amp;lt;/br&amp;gt;
當年的刷機少年，如今已長大成人&amp;lt;/br&amp;gt;
即使變磚、Crashdump 也無所謂，刷機還是進行時&amp;lt;/br&amp;gt;
若感到悲傷，只需換手機&amp;lt;/br&amp;gt;
一切都能重新開始&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
圍墻(위장) 너머는 自由(자유)로운 거야&amp;lt;/br&amp;gt;
난 마침내 安息處(안식처)를 찾았어&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;圍牆之外，是自由地&amp;lt;/br&amp;gt;
我終於找到安居之地&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;폰(phone)이 집에 오면, 모든 게 다시 始作(시작)돼&amp;lt;/br&amp;gt;
‘Unlock’ 條件(조건)은, 예전보다 또 높아진 듯해&amp;lt;/br&amp;gt;
오랜 經驗(경험)으로, (問題도) 能熟(능숙)하게 對應(대응)해&amp;lt;/br&amp;gt;
Linux 속에서 마음껏 웃어봐&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;手機回到家，一切重新開始&amp;lt;/br&amp;gt;
解鎖條件似乎比以前更高&amp;lt;/br&amp;gt;
憑藉長久的經驗，我熟練應對各種問題&amp;lt;/br&amp;gt;
在 Linux 世界裡，盡情地笑吧&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;우리 함께 저 自由(자유)로운 곳으로 달려가&amp;lt;/br&amp;gt;
私有(사유) 소프와(software) &quot;來日(내일) 봐&quot;한 뒤 다시는 안 봐&amp;lt;/br&amp;gt;
機器(기기) 原理(원리) 몰라도 相關(상관)없어, 그날만 記憶(기억)해&amp;lt;/br&amp;gt;
아득한 記憶(기억) 속에, 당찼던 그날의 實踐(실천)을&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們一起奔向那自由的地方,&amp;lt;/br&amp;gt;
對專有軟體說「明天見」後再也不回頭,&amp;lt;/br&amp;gt;
即使不懂機理也沒關係，只記住那一天,&amp;lt;/br&amp;gt;
遙遠的記憶中，記住當初的實踐,&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;依支(의지)하던 私有(사유) 소프트워(software),&amp;lt;/br&amp;gt;
오직 내가 自由(자유)를 理解(이해)하기 전까지&amp;lt;/br&amp;gt;
이제 프라이버시(privacy)는 내가 다 統治(통치)해&amp;lt;/br&amp;gt;
자, 다시 한番(번) 마음껏 웃어보자&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;依賴着專有軟體,&amp;lt;/br&amp;gt;
直到我真正理解自由之前&amp;lt;/br&amp;gt;
現在隱私全由我掌控, &amp;lt;/br&amp;gt;
來吧，再一次盡情笑吧&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>最像正常手機的原型機——驍龍 SM8750 MTP 原型機評測</title><link>https://blog.cloudflare88.eu.org/posts/sm8750-mtp-review/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/sm8750-mtp-review/</guid><description>這次上場的，是來自 Qualcomm 最新一代的旗艦工程平台 —— Snapdragon SM8750 MTP（Mobile Test Platform）。與我之前測過的 Snapdragon 845 MTP 相比，8750 世代的原型機無論是性能、通訊架構、系統完成度，甚至可玩性，都提升到一個完全不同的高度。</description><pubDate>Sat, 22 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;這次的的主角是來自高通的原型機——驍龍 SM8750 MTP。不同於之前評測過的845 MTP原型機，這臺8750 MTP 的原型機更加強大，同時也帶來了很多全新的硬體功能和特性。&lt;/p&gt;
&lt;h2&gt;什麼是 MTP 原型機？&lt;/h2&gt;
&lt;p&gt;MTP(&lt;strong&gt;M&lt;/strong&gt;obile &lt;strong&gt;T&lt;/strong&gt;est &lt;strong&gt;P&lt;/strong&gt;latform)是 Qualcomm 為手機開發者、晶片調校與技術測試使用的官方工程開發裝置，不是市售消費手機。主要用於模組研發、數據機測試、驅動與 Android HAL 研發、相機ISP調教等偏向硬體和底層韌體的工作，亦可用於評估硬體效能之用。與同樣作爲原型機的QRD（&lt;strong&gt;Q&lt;/strong&gt;ualcomm &lt;strong&gt;R&lt;/strong&gt;eference &lt;strong&gt;D&lt;/strong&gt;esign）不同，後者更接近完整的商用手機方案開發樣機。
如果把手機開發比作蓋樓：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MTP：打地基 + 建結構&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;QRD：完成主體、可以交設計圖給 OEM 製造手機&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;市售手機：裝潢完、買回家即用
&amp;lt;/br&amp;gt;
下面的表格可以體現二者與市售手機的不同：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;MTP&lt;/th&gt;
&lt;th&gt;QRD&lt;/th&gt;
&lt;th&gt;市售手機*&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;定位&lt;/td&gt;
&lt;td&gt;晶片底層研發平臺&lt;/td&gt;
&lt;td&gt;接近市場量產的市售手機方案&lt;/td&gt;
&lt;td&gt;一般使用者的日常使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;成熟度&lt;/td&gt;
&lt;td&gt;系統未必完整和穩定，需大量測試&lt;/td&gt;
&lt;td&gt;高度與硬體整合，有完整的系統和設計&lt;/td&gt;
&lt;td&gt;非常成熟且穩定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主要使用者&lt;/td&gt;
&lt;td&gt;硬體/驅動/數據機工程師/媒體臨時評測/手機OEM/OEM等&lt;/td&gt;
&lt;td&gt;手機OEM/ODM、產品工程研發&lt;/td&gt;
&lt;td&gt;一般使用者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;功能重點&lt;/td&gt;
&lt;td&gt;測數據機、供電、RF、相機、I/O、驅動&lt;/td&gt;
&lt;td&gt;作為量產手機設計範本&lt;/td&gt;
&lt;td&gt;滿足絕大多數一般使用場景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;外型&lt;/td&gt;
&lt;td&gt;多爲黑色外殼包裹，暴露大量除錯用接口（如USB 2.0、UART，若是配合Debug Board還可以提供 JTAG 等），屏幕一般爲客製或直接使用QRD的熒幕&lt;/td&gt;
&lt;td&gt;外觀接近正常手機（可整機）&lt;/td&gt;
&lt;td&gt;正常手機應該有的外形&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是否可解鎖 Bootloader&lt;/td&gt;
&lt;td&gt;幾乎都可開（原廠解鎖，無限制）、便於寫測試程式&lt;/td&gt;
&lt;td&gt;同左&lt;/td&gt;
&lt;td&gt;取決於廠商&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;開發方向&lt;/td&gt;
&lt;td&gt;BSP、HAL、電源、射頻、IC 驗證等&lt;/td&gt;
&lt;td&gt;終端產品、軟體與硬體整合&lt;/td&gt;
&lt;td&gt;基本沒有&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;稳定度&lt;/td&gt;
&lt;td&gt;不一定穩定（取決於韌體）、功能可能未完成&lt;/td&gt;
&lt;td&gt;可靠度較高，可演化為量產機&lt;/td&gt;
&lt;td&gt;非常成熟且穩定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SoC是否配置安全啓動&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;大多沒有&lt;/td&gt;
&lt;td&gt;大多數都有配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;燒錄韌體是否需要簽名&lt;/td&gt;
&lt;td&gt;是（高通測試簽名）&lt;/td&gt;
&lt;td&gt;同左&lt;/td&gt;
&lt;td&gt;是（測試+廠商私鑰）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一句話總結：&lt;strong&gt;MTP 是底層晶片與硬體測試平台；QRD 是接近商品化的完整手機參考設計。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
市售手機：指由廠商推出的，面向一般用戶的手機，例如：Samsung Galaxy S10、iPhone X、Google Pixel 7等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;第一印象&lt;/h2&gt;
&lt;p&gt;如果習慣日常手機那種圓潤精緻的外觀，那第一次看到 MTP 原型機，大概會覺得：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這不是手機，這是拿在手上的小型基地台。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;牠比一般手機：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;更厚,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;更重,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;外殼看起來完全不追求美感,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;大量測試接口直接暴露在外;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;這種外觀不是為了好看，而是方便：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;隨時接上 UART、USB、測試板、外接儀器&lt;/em&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;隨時 dump log,&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;是一種徹徹底底的功能主義。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;我的這臺原型機非常好，上面的標籤告訴我牠的製造日期在2024年（或者2025年）左右，外觀沒有任何損傷，屏幕也非常的清晰沒有任何瑕疵，而且展示效果非常的豔麗。此外還配備了5G毫米波天線，能夠增強5G網路的穩定性。不知道爲什麼，總覺得屏幕長得和我的 Pixel 7 Pro 好像呀...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-front.jpg&quot; alt=&quot;SM8750 MTP&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-back.jpg&quot; alt=&quot;Back of SM8750 MTP&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mtp8750-label.jpg&quot; alt=&quot;SM8750 MTP label&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;啓動&lt;/h2&gt;
&lt;p&gt;插電、開機，從Qualcomm 的 logo顯示到系統啓動，全程僅過去了5秒，這速度甚至要比現在主流的手機要快了很多。我想應該歸功於BSP裸機化程度高、無多餘動畫和組件。系統方面是高通提供的BSP，基於 AOSP Android 15 開發而來，包含了簡化的 Google 框架和高通的測試程式。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/about-phone.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/home.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;核心方面，採用了 6.6 核心，高通自己的QGKI，基於 Android GKI 核心修改而來。因爲高通平臺&lt;code&gt;init_boot&lt;/code&gt;映像與&lt;code&gt;boot&lt;/code&gt;映像通用，所以修補&lt;code&gt;init_boot&lt;/code&gt;的映像來獲取root權限的方法就行不通了。而傳統 Magisk 的方法又過於簡單，我決定採用更新的解決方案—— Apatch。好在高通的原型機韌體自帶root權限，這也是為什麼 MTP 是工程人員最喜歡的裝置，完全沒有解鎖層級的限制。通過&lt;code&gt;dd&lt;/code&gt;命令提取映像，丟到 Apatch 中修補，然後 fastboot 刷入修補後的映像就行了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/screenshot/apatch.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;值得注意的是，MTP8750的核心採用了4K分頁大小編譯。難道說驍龍8 Elite 也支援16K 分頁的核心開機？這得等我備份韌體之後從BSP編譯再試試了。&lt;/p&gt;
&lt;h2&gt;硬體很強大&lt;/h2&gt;
&lt;p&gt;硬體上，這臺原型機可謂是性能強悍，牠搭載了驍龍8 Elite CPU（沒有熔燬的早期版本），雖然是降頻版，主頻只有3628MHz（不如QRD的高），配備了LPDDR5x 16G RAM，512GB UFS 4.0存儲，但是牠的性能依然很強悍。從Geekbrench的測試結果來看，多核心分數達到了驚人的7936分，已經超過了三星Galaxy S24 Ultra 的性能。爲了滿足5G網絡的需求，牠採用了高通X80 5G數據機，配備了5G毫米波天線，可以提供高達10Gbps的下行速率。其採用的 Fastconnect 7900 Wi-Fi網路卡，支援 Wi-Fi 7 網路。NPU也得到了升級。&amp;lt;/br&amp;gt;
聲音方面，這臺原型機的揚聲器在底部，依然是標準的雙揚聲器結構。聲音聽起來非常不錯，很符合我對於原型機的印象。其電源按鈕和音量調節按鈕在下部，只能說這個按鍵佈局非常奇葩，倒着看反而會好一些。接口依然保留了UART 和 Type-C USB 3.1接口，還有SIM卡插槽和SD卡接口。與前面幾代的MTP不同，這臺MTP8750的除錯板接口從後部移到了前面，接口也從兩個縮爲一個，不得不好奇對應的調試板是什麼樣了。&amp;lt;/br&amp;gt;
相機方面，後置三個鏡頭，每個鏡頭都是5000萬畫素，但是拍攝效果一般，也支援HDR攝影。通過 Opencamera 可以錄製 8K 30幀的視頻，但是撐不到5分鐘便黑了，因爲電池太差了（後來發現是電池插座接觸不良）...xD&amp;lt;/br&amp;gt;
:::note
下面的圖片均由 MTP8750 原型機拍攝，分別使用驍龍相機和 Opencamera 拍攝，並且使用了 HDR 功能。
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/photo-mtp8750.jpg&quot; alt=&quot;A Photo taken by MTP8750&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不難看出，使用驍龍相機開啓HDR影片，其效果非常好，色彩雖不如Pixel 7 Pro，但也很豔麗。然而不知道是不是 Opencamera 的HDR實作有問題，使用牠拍出來的HDR照片出現了亮部（特別是樓梯、地面、白色區域）被完全「洗白」，細節消失的問題：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/opencamera-hdr.webp&quot; alt=&quot;A HDR photo taken by Opencamera on MTP8750&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note
這是使用 Pixel 7 Pro 拍攝的 HDR相片，用於參考：
&lt;img src=&quot;assets/pixel-photo.jpg&quot; alt=&quot;A HDR photo taken by Pixel 7 Pro&quot; /&gt;
:::&lt;/p&gt;
&lt;p&gt;拋開這一點不談，鏡頭設計也是非常好看的，採用了鍍膜鏡頭，在陽光下會顯出金黃色光澤，非常漂亮。&amp;lt;/br&amp;gt;
熒幕方面，採用了一塊 11吋的OLED顯示屏，解析度在3220x1440，一塊不錯的2K的P3高色域屏幕，熒幕重新整理頻率在120Hz，畫素密度是320ppi，顯示效果非常好，色彩也很豔麗。高通之前的綠屏（熒幕在深色背景下呈現偏綠色）問題，在這臺原型機上有明顯改善，支援杜比全景影像，也支援HDR。熒幕上方有一個攝像頭挖孔，經後期比對後發現這塊屏幕來自QRD 8750 原型機。&lt;/p&gt;
&lt;h2&gt;軟體也很穩定&lt;/h2&gt;
&lt;p&gt;在簡單檢索後發現，原型機的韌體爲原版 Android 15，沒有經過修改，與之前卡頓的，問題頻出的845原型機不同，8750的韌體非常穩定，沒有出現當機問題，唯一發現的問題是震動馬達會在一分鐘後停止工作。插入的手機卡也能識別（系統IMEI與標籤上展示的IMEI完全一致），並能正常撥打電話、收發短信，使用數據網路也會自動開啓5G網絡。使用其內建的GPS測試軟體也可正常搜尋衛星並定位，還可以模擬GPS定位。安裝 Apatch Root 後也能正常安裝模組和授予 Root權限。內建的測試應用也都能正常工作，其餘基本手機上的硬體（如麥克風、Wi-Fi、傳感器等）也都能正常工作。可以說，即使我沒有想到新的原型機的用途，臨時作爲備用手機日用也很不錯。&lt;/p&gt;
&lt;h2&gt;提取韌體&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;先備份，永遠不會錯。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;刷機之前，最好是備份一份韌體，以備不時之需。因爲原型機沒有開啓安全啓動，所以可以直接從網路上搜尋驍龍8 Elite 至尊版的手機韌體，然後從中提取&lt;code&gt;xbl_s_devprg_ns.melf&lt;/code&gt;文件，這是驍龍8 Elite 至尊版的EDL引導文件。後續的韌體提取工作要用到這個文件。&amp;lt;/br&amp;gt;
然後，下載“高通工具箱”（Linux可使用&lt;code&gt;edl&lt;/code&gt;或者&lt;code&gt;qdl&lt;/code&gt;程式代替），將其解壓，執行程式。在“存儲類型”中選擇“UFS”，LUN數默認爲6即可，然後選擇引導文件，發送引導，點擊“全分區回讀”，之後軟體會彈出提示。值得注意的是我們需要在將要回讀的分割表0中，講&lt;code&gt;[rawdump]&lt;/code&gt;的方括號刪掉，跳過讀取 &lt;code&gt;rawdump&lt;/code&gt; 分區，之後的分區表保持默認就可以，稍作等待，我們會得到一個大小爲15.5GB的映像檔和EDL刷機用的 &lt;code&gt;rawprograms.xml&lt;/code&gt;  &lt;code&gt;patch.xml&lt;/code&gt; 和 &lt;code&gt;partition.xml&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/qcom-toolbox.jpg&quot; alt=&quot;Screen showing the process of extracting the firmware&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下面的文本展示了韌體的結構圖（使用 &lt;code&gt;tree&lt;/code&gt; 命令）:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── flash_all.bat
├── for_ROM_maker
│   ├── generate
│   │   ├── gpt_backup0.bin
│   │   ├── gpt_backup1.bin
│   │   ├── gpt_backup2.bin
│   │   ├── gpt_backup3.bin
│   │   ├── gpt_backup4.bin
│   │   ├── gpt_backup5.bin
│   │   ├── gpt_both0.bin
│   │   ├── gpt_both1.bin
│   │   ├── gpt_both2.bin
│   │   ├── gpt_both3.bin
│   │   ├── gpt_both4.bin
│   │   ├── gpt_both5.bin
│   │   ├── gpt_empty0.bin
│   │   ├── gpt_empty1.bin
│   │   ├── gpt_empty2.bin
│   │   ├── gpt_empty3.bin
│   │   ├── gpt_empty4.bin
│   │   ├── gpt_empty5.bin
│   │   ├── gpt_main0.bin
│   │   ├── gpt_main1.bin
│   │   ├── gpt_main2.bin
│   │   ├── gpt_main3.bin
│   │   ├── gpt_main4.bin
│   │   ├── gpt_main5.bin
│   │   ├── patch0.xml
│   │   ├── patch1.xml
│   │   ├── patch2.xml
│   │   ├── patch3.xml
│   │   ├── patch4.xml
│   │   ├── patch5.xml
│   │   ├── rawprogram0_BLANK_GPT.xml
│   │   ├── rawprogram0_WIPE_PARTITIONS.xml
│   │   ├── rawprogram0.xml
│   │   ├── rawprogram1_BLANK_GPT.xml
│   │   ├── rawprogram1_WIPE_PARTITIONS.xml
│   │   ├── rawprogram1.xml
│   │   ├── rawprogram2_BLANK_GPT.xml
│   │   ├── rawprogram2_WIPE_PARTITIONS.xml
│   │   ├── rawprogram2.xml
│   │   ├── rawprogram3_BLANK_GPT.xml
│   │   ├── rawprogram3_WIPE_PARTITIONS.xml
│   │   ├── rawprogram3.xml
│   │   ├── rawprogram4_BLANK_GPT.xml
│   │   ├── rawprogram4_WIPE_PARTITIONS.xml
│   │   ├── rawprogram4.xml
│   │   ├── rawprogram5_BLANK_GPT.xml
│   │   ├── rawprogram5_WIPE_PARTITIONS.xml
│   │   ├── rawprogram5.xml
│   │   ├── wipe_rawprogram_PHY0.xml
│   │   ├── wipe_rawprogram_PHY1.xml
│   │   ├── wipe_rawprogram_PHY2.xml
│   │   ├── wipe_rawprogram_PHY4.xml
│   │   ├── wipe_rawprogram_PHY5.xml
│   │   ├── wipe_rawprogram_PHY6.xml
│   │   ├── wipe_rawprogram_PHY7.xml
│   │   ├── zeros_1sector.bin
│   │   └── zeros_5sectors.bin
│   ├── orig
│   │   ├── gpt_backup0.bin
│   │   ├── gpt_backup1.bin
│   │   ├── gpt_backup2.bin
│   │   ├── gpt_backup3.bin
│   │   ├── gpt_backup4.bin
│   │   ├── gpt_backup5.bin
│   │   ├── gpt_main0.bin
│   │   ├── gpt_main1.bin
│   │   ├── gpt_main2.bin
│   │   ├── gpt_main3.bin
│   │   ├── gpt_main4.bin
│   │   ├── gpt_main5.bin
│   │   ├── partition.xml
│   │   ├── rawprogram0.xml
│   │   ├── rawprogram1.xml
│   │   ├── rawprogram2.xml
│   │   ├── rawprogram3.xml
│   │   ├── rawprogram4.xml
│   │   └── rawprogram5.xml
│   ├── readme.txt
│   └── 本目录说明.txt
├── images
│   ├── abl_a.img
│   ├── abl_b.img
│   ├── ALIGN_TO_128K_1.img
│   ├── ALIGN_TO_128K_2.img
│   ├── aop_a.img
│   ├── aop_b.img
│   ├── aop_config_a.img
│   ├── aop_config_b.img
│   ├── apdpb.img
│   ├── apdp.img
│   ├── bluetooth_a.img
│   ├── bluetooth_b.img
│   ├── boot_a.img
│   ├── boot_b.img
│   ├── cdt.img
│   ├── connsec.img
│   ├── core_nhlos_a.img
│   ├── core_nhlos_b.img
│   ├── cpucp_a.img
│   ├── cpucp_b.img
│   ├── cpucp_dtb_a.img
│   ├── cpucp_dtb_b.img
│   ├── ddr.img
│   ├── devcfg_a.img
│   ├── devcfg_b.img
│   ├── devinfo.img
│   ├── dpm.img
│   ├── dsp_a.img
│   ├── dsp_b.img
│   ├── dtbo_a.img
│   ├── dtbo_b.img
│   ├── featenabler_a.img
│   ├── featenabler_b.img
│   ├── frp.img
│   ├── fsc.img
│   ├── fsg.img
│   ├── gpt_backup0.bin
│   ├── gpt_backup1.bin
│   ├── gpt_backup2.bin
│   ├── gpt_backup3.bin
│   ├── gpt_backup4.bin
│   ├── gpt_backup5.bin
│   ├── gpt_main0.bin
│   ├── gpt_main1.bin
│   ├── gpt_main2.bin
│   ├── gpt_main3.bin
│   ├── gpt_main4.bin
│   ├── gpt_main5.bin
│   ├── hyp_a.img
│   ├── hyp_b.img
│   ├── imagefv_a.img
│   ├── imagefv_b.img
│   ├── init_boot_a.img
│   ├── init_boot_b.img
│   ├── keymaster_a.img
│   ├── keymaster_b.img
│   ├── keystore.img
│   ├── logdump.img
│   ├── logfs.img
│   ├── mdcompress.img
│   ├── metadata.img
│   ├── misc.img
│   ├── modem_a.img
│   ├── modem_b.img
│   ├── modemst1.img
│   ├── modemst2.img
│   ├── multiimgoem_a.img
│   ├── multiimgoem_b.img
│   ├── multiimgqti_a.img
│   ├── multiimgqti_b.img
│   ├── pdp_a.img
│   ├── pdp_b.img
│   ├── pdp_cdb_a.img
│   ├── pdp_cdb_b.img
│   ├── persist.img
│   ├── pvmfw_a.img
│   ├── pvmfw_b.img
│   ├── qmcs.img
│   ├── quantumcontentfv.img
│   ├── quantumfv.img
│   ├── quantumsdk.img
│   ├── questdatafv.img
│   ├── qupfw_a.img
│   ├── qupfw_b.img
│   ├── qweslicstore_a.img
│   ├── qweslicstore_b.img
│   ├── rawprogram0.xml
│   ├── rawprogram1.xml
│   ├── rawprogram2.xml
│   ├── rawprogram3.xml
│   ├── rawprogram4.xml
│   ├── rawprogram5.xml
│   ├── recovery_a.img
│   ├── recovery_b.img
│   ├── secdata.img
│   ├── shrm_a.img
│   ├── shrm_b.img
│   ├── soccp_dcd_a.img
│   ├── soccp_dcd_b.img
│   ├── soccp_debug_a.img
│   ├── soccp_debug_b.img
│   ├── spunvm.img
│   ├── spuservice_a.img
│   ├── spuservice_b.img
│   ├── ssd.img
│   ├── storsec.img
│   ├── super.img
│   ├── testparti.img
│   ├── toolsfv.img
│   ├── tz_a.img
│   ├── tz_b.img
│   ├── tzsc.img
│   ├── uefi_a.img
│   ├── uefi_b.img
│   ├── uefisecapp_a.img
│   ├── uefisecapp_b.img
│   ├── uefivarstore.img
│   ├── vbmeta_a.img
│   ├── vbmeta_b.img
│   ├── vbmeta_system_a.img
│   ├── vbmeta_system_b.img
│   ├── vendor_boot_a.img
│   ├── vendor_boot_b.img
│   ├── vm-bootsys_a.img
│   ├── vm-bootsys_b.img
│   ├── vm-persist.img
│   ├── xbl_a.img
│   ├── xbl_b.img
│   ├── xbl_config_a.img
│   ├── xbl_config_b.img
│   ├── xbl_ramdump_a.img
│   ├── xbl_ramdump_b.img
│   ├── xbl_sc_logs.img
│   └── xbl_sc_test_mode.img
├── mtp8750.melf
└── mtp8750.qcn

5 directories, 215 files
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後是提取 QCN 文件，用於恢復數據機韌體之用。方法依然簡單，只需在工具箱中點擊“讀QCN”即可。需要開啓除錯端口：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb root
adb shell setprop sys.usb.config diag,adb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後通過 &lt;code&gt;lsusb&lt;/code&gt; 可以看到 UID 爲 “901D”的裝置出現了，然後選擇QCN保存目錄即可。&lt;/p&gt;
&lt;p&gt;這樣，MTP8750的韌體就算備份完成了，可以開始後續的主線核心移植了。&lt;/p&gt;
&lt;h2&gt;總結&lt;/h2&gt;
&lt;p&gt;8750 MTP 給我的最大感受是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;高通的原型機，不僅是「單板電腦」，也是「日用機」。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;牠具備：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;功能完整&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;性能強悍&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;驅動成熟&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;調試工具齊全&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通訊堆疊整合度高&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;所有開發限制基本都打開&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對 Kernel、Modem、Camera、BSP 工程師來說：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是一台能工作、能測試、能刷、能玩，甚至能拿來日用的夢幻開發裝置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下來，我會開始：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;自行重編 BSP (或許...)；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;測試高通 Gunyah 虛擬機；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;移植 UEFI 引導程式，用於支援 Windows、Linux 等作業系統，並支援 PXE、USB啓動；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;完成主線核心和 Linux 移植&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真正精彩的部分，現在才剛開始。敬請期待吧！&lt;/p&gt;
</content:encoded></item><item><title>轉移到64位元 ARM 架構的五年，我學會了什麼</title><link>https://blog.cloudflare88.eu.org/posts/my-5-years-arm64-architecture-journey/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/my-5-years-arm64-architecture-journey/</guid><description>或許有一天，當我在某個領域做出了重大突破或是貢獻後，我會感謝5年前我做出的勇敢決定。</description><pubDate>Tue, 11 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;本文建議配合下面音樂閱讀，效果更好：&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Ld56h8a-5tI?si=xoj2AmNEI6y5xpCq&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;第一次聽到 ARM 這個詞，是幾年前在家裏一臺奔騰G2020的桌機上安裝 Android X86，爲了使其能夠執行手機上常見的應用，想盡一切辦法解決應用屢次停止運行的問題。幾經搜尋之後才發現 X86 Android 需要通過下載 &lt;code&gt;native bridge&lt;/code&gt; 的 ARM 翻譯庫才可以執行爲手機編寫的 ARM 架構應用。也就是從那個時候，ARM 這個詞進入了我的腦海中，成爲了我最早接觸並瞭解的非X86架構。&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;自從了解過 Android X86 後，我對於 ARM 這一陌生的CPU架構不由自主地萌生了好奇心。我便從維基百科上搜尋關於牠的內容，瞭解到了這是一種基於 RISC（精簡指令集）設計的指令集，相較於傳統X86之類的 CISC（複雜指令集）設計，ARM 架構更加注重性能，擁有更高的穩定性和效能。大多被應用在手機、平板電腦、嵌入式系統等消費者常見的裝置上。我便檢索市面上是否有基於 ARM 架構的筆記本電腦。結果還真有：聯想的 YOGA C630、華爲的 Matebook E 2019 這些筆電、以高性能、長續航爲賣點進入了我的眼睛。但是家裏人肯定是不會同意給我買新電腦的，因爲當時的奔騰桌機和酷睿2的筆電已經夠用了！而且牠們的價格也非常昂貴...很長一段時間內，我對於 ARM 筆電的興趣也逐漸消退了。慢慢也不再在乎架構之類的興趣。畢竟學生，學習才是正業嘛！XD&lt;/p&gt;
&lt;h2&gt;我與牠的羈絆，從這裏開始&lt;/h2&gt;
&lt;p&gt;上了國中，課業任務也就逐漸增加了，但是比起高中而言，國中還是有充足的自由的。至少不會週末違規補課，所以父母時常和我出門玩，偶爾還會去別的地方逛商場，那時候對於商店裏 Apple 的裝置比較感興趣，尤其是 MacBook 系列。鋁合金一體成型的機身、高清的LCD熒幕，強大的處理器...怎麼看都要比我的華碩 K501E 酷睿2筆電好呀。但是高達2萬的價格讓我望而卻步。我的父親知道我想要 MacBook 後非常生氣，認爲我的虛榮心在作怪。從此商場也去的少了，我也不再講起這件事。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mac.jpg&quot; alt=&quot;A MacBook running macOS Big Sur&quot; /&gt;
後來，我認識並且開始嘗試用 Linux 取代 Windows 作業系統。我喜歡自由軟體精神，後來受到疫情影響在家學習，我又了解了 FSF 和 GNU哲學，也因此開始了我的自由軟體探索之路。因此時常會編譯一些常用的軟體，因爲有些軟體沒有針對我的發行版打包，便只能自行編譯。而這時，我的桌機和筆電便因爲過於老舊，使用逐漸力不從心。但是我又不敢開口要求父母買新筆電，就只好忍着。直到我初三，桌機的機械硬碟不知道爲什麼開始發生頻繁斷電現象，導致壞軌增多。檢視 &lt;code&gt;SMART&lt;/code&gt; 數據發現硬盤的通電時間已有7年之久，壞軌數有四個...我決定趁機提出購買新的筆電的要求，沒想到父親居然同意，我便拉着他去看那臺採用 M1 晶片的 MacBook Air，在了解完筆電的性能後，父親便買下來了。就這樣，我與 ARM 這個CPU架構的羈絆正式開始。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/arch-linux-arm-hyfetch.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/tonga.jpg&quot; alt=&quot;My MacBook Air running Arch Linux ARM&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;有痛苦，亦有樂趣&lt;/h2&gt;
&lt;p&gt;因爲 ARM 架構完全不相容傳統的 X86 架構指令集，因此作業系統和應用程式也必須更換爲支援 ARM 的版本。但是我只是一個使用者，而非開發者，所以只能完全把已有的經驗推翻重來。我開始學習 ARM 指令集，閱讀網路上關於 ARM 指令集的文章，也逐漸了解了什麼是 Thumb 擴展指令集、NEON 指令集等等。並發現我在 X86 架構上常用的 QEMU、GCC等工具同樣也有支援 ARM 架構。於是我開始了轉移到 ARM 架構的旅程。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/arm-wikipedia.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但是一個頭疼的問題便出現了：許多日常生活中常用的軟體，大多數都無法執行。如果是有原始碼的軟體，我只能通過下載原始碼，然後在終端機執行 &lt;code&gt;make&lt;/code&gt; 來手動編譯。要是封閉原始碼的軟體就沒有辦法了，只能等待官方更新。當然也可以用模擬X86的環境來執行，但是效果往往很差勁。有些內建反盜版檢測的程式，因爲檢測程式無法模擬運行，從而導致程式完全開不起來...絕大多數的人遇不到的錯誤，我全都經歷了，有時老師佈置的任務非常緊急，結果我的電腦因爲無法打開某些程式而無法及時完成任務，免不了要被老師責備。而且還不能據此給出一個完美的理由。
&amp;lt;/br&amp;gt;
萬幸我的電腦是 MacBook，在 Apple 的督促下，過不了幾個月各大廠家就開始陸續上架常用軟體的 ARM 版本，要是 Windows 的話，不知道又要等到什麼時候呢。不過轉移的過程也會有樂趣在其中：我學會了如何從原始碼編譯程式，因爲大部分原始碼都會使用 GitHub 託管，所以我又學會了 Git 的一些用法；我也學會了抓取日誌和分析日誌，來除錯程式的問題，同時也撰寫了我的&lt;a href=&quot;https://github.com/AsahiLinux/asahi-installer/issues/268&quot;&gt;第一個 Bug 反饋&lt;/a&gt;。後來爲這臺 MacBook 安裝了 Asahi Linux，我的 ARM Linux 之旅也開始了。因爲 Apple M1的特殊性，其 Linux 核心默認採用 16 K 分頁地址，不同於一般 ARM 平臺的 4 K 分頁地址。因此部分應用程式會有相容性問題，比如 Electron 就開不起來。于是我又在網上搜尋教學，並學會了修補應用程式，用 &lt;code&gt;git apply&lt;/code&gt; 打補丁。還利用 M1 晶片沒有封鎖的 KVM功能成功執行了 FreeBSD 的虛擬機。後來我才知道，ARM 平臺啓動 Linux 並不像 x86 那樣使用 ACPI，而是採用裝置樹（Device Tree）來描述硬體，這顆看不見的「樹」用類似 C 的語法書寫——令當時對 C 幾乎零基礎的我，竟然也能讀懂其內容，這件事本身讓我非常驚喜。&lt;/p&gt;
&lt;h2&gt;小米平板5的開箱&lt;/h2&gt;
&lt;p&gt;小米平板5於個人而言，也是一個意義重大的裝置。在到手後一週就解鎖刷入了 Windows 11，當然，Windows 11 ARM 對我算不得什麼。我最喜歡的是牠的 UEFI 引導程式，儘管高通在 Android 平臺對引導程式做了限制讓其只能引導 Linux 核心，但是開發 UEFI 的 Renegade 專案把UEFI僞造成 Linux 核心，藉由引導程式引導，多麼高明的手段！&lt;/p&gt;
&lt;p&gt;後期我又根據個人需要把小米平板5的主線核心進行了自訂，刪除了無用的驅動程式，也就是在那時，我也第一次學習了編譯和定製 Linux 核心。還安裝了 Arch Linux ARM，並且使用了常用的軟體，得益於先前在 Mac 上的經歷，這次的轉移輕鬆了不少。&lt;/p&gt;
&lt;h2&gt;分享教程，教與學一並存在着&lt;/h2&gt;
&lt;p&gt;隨着主線核心成功啓動、各種 Linux 發行版的移植成功，我也開始把我如何刷機、編譯主線核心的方式發佈到其他平臺上，比如 Youtube，起初只是單純地想記錄過程，沒想到這些影片竟吸引了越來越多觀眾。有人在留言區分享他們成功啓動系統的喜悅，也有人遇到問題時向我求助。看着他們因為我的影片而成功啓動 Linux、學會了新東西，那種成就感難以言喻。同時，爲了緊跟上游的最新變化，我也會學習相關知識，並用通俗易懂的方式放到影片中，“講”給觀衆們看。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;爲了讓內容更容易理解，我開始學會把複雜的概念拆解，用最直觀的比喻和圖像來說明。從 ARM 架構到裝置樹，從 UEFI 到內核編譯，我努力讓這些艱澀的技術變得“有趣”。而在解釋給別人聽的同時，我自己也不斷加深理解。很多知識，都是在回答觀眾問題的過程中才真正搞懂的——教學不僅是分享，更是自我成長的過程。同時也不知不覺就學到了很多只有到了大學才能瞭解到或者講到的內容，有一些甚至是專業相關知識，比如 ARM 架構、JTAG、UEFI 和裝置樹之類。可以說做教學真是好呀，在教學別人的時候自己也能學到很多知識。&lt;/p&gt;
&lt;h2&gt;同時也學會了很多瑣碎的知識...&lt;/h2&gt;
&lt;p&gt;除了 Linux 之外，剩下的便是一些我目前不知道有什麼用的知識。這些東西大多與平臺高度相關，而且只能通過一些裝置和隨附 BSP 才能學習。比如高通平臺的協處理器在主線核心的初始化是通過一個叫 &lt;code&gt;remoteproc&lt;/code&gt; 的進程來掛載相關韌體來完成的，例如 Wi-Fi 的初始化就是如此（只需要一個對應的韌體就可以了，而下游 Android 核心還需要三個守護進程才可以）；數據機必須先初始化才能使用 Wi-Fi、GPS等（不得不說，高通平臺的數據機隔離性非常糟糕！）；高通的 ADSP 無法在 EL2 模式執行，會導致音訊、USB 不可用；展迅平臺解鎖需要給 U-Boot 打補丁；如何通過 &lt;code&gt;slbounce&lt;/code&gt; 讓受支援的處理器啓用 EL2 ；以及 libcamera 框架的使用，了解了攝像頭在 Linux 下的驅動流程與媒體管線是如何協作的。還有硬體看門狗的作用...雖然這些知識暫時還沒有明確的用途，但我相信牠們會在未來的某個時刻派上用場。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/yoga-air-14s.png&quot; alt=&quot;My Laptop&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五年後的今天，我學會了什麼？&lt;/h2&gt;
&lt;p&gt;五年看似短暫，對計算機世界卻已足夠改變許多。在我與 ARM 架構相處的五年裏，牠教會了我許多。ARM 是我進入嵌入式系統領域的入口，促使我掌握了日常使用與程式開發中不可或缺的技能。牠也讓我明白，要務實地使用自由軟體。正是因爲架構的差異讓我有了對於自由軟體的選擇權，也讓我擁有了靈活的頭腦，面對各種情況是都能從從容容，遊刃有餘。同時也告訴我：遇到問題不要抱怨，把問題作爲出發點，分析問題產生的過程及原因，順着“日誌”找出解決之道，或者把日誌分享出來，大家一起討論，給出建議，一起成長。&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
回頭看，從舊桌機上的 Android X86，到如今能夠熟練的編譯、除錯程式，以及會用 C 語言寫一些簡單的程式，這一路走來，既有挫折，也有歡欣。每一段影片、每一個反饋、每一片日誌，都是我與 ARM 世界的對話，記錄着我的成長過程。我收獲的不僅是技術知識本身，也有面對未知時的勇氣，與解決問題的恆心。我從單純的“使用者”慢慢成爲“參與者”，閱讀專案原始碼、提交錯誤回報，這些讓我真正融入了以協作為核心的開源社群。開源不再只是個理念，而成爲我生活的一部分。“ARM 架構”只是一個冰冷的技術名詞，但對我來說，牠就像電腦世界的一扇門，讓我看到牠的另一面。也讓我看到了自己的潛力。從好奇到理解，從模仿到創造，從學習到分享，這條路還在延伸。但我知道，只要保持那份最初的熱情與好奇，我會一直走下去 — &lt;strong&gt;因爲學習的終點，從來不是知識本身，而是成長&lt;/strong&gt;。&amp;lt;/br&amp;gt;
未來，我會繼續深入自由軟體與 ARM 領域的學習與研究。也許有一天，我能設計出屬於自己的 ARM 筆電，甚至將成果貢獻到主線核心中。而這一切的起點，只是那個讓 App「能正常跑起來」的單純念頭。正是這份念頭，讓我從使用者成為創造者；從學習者成為傳遞者；從行路者，成為鋪路者。&lt;/p&gt;
</content:encoded></item><item><title>致我的父親——爲什麼我討厭學生宿舍</title><link>https://blog.cloudflare88.eu.org/posts/why-i-hate-dormitory/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/why-i-hate-dormitory/</guid><description>我的父親，我不知道妳是否可以讀到我的文章，如果可以，妳就會明白我爲什麼總是要回家了。</description><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果要我寫出十個不要住在學校宿舍的理由，我可以寫出一千條。但我一定不會想告訴妳們最關鍵的一點。&amp;lt;/br&amp;gt;
&lt;strong&gt;和學生住在一起會讓我感到抑鬱。&lt;/strong&gt; &amp;lt;/br&amp;gt;
每當我聽到一點吵鬧聲、聞到一點煙味（哪怕是電子煙）以及同學帶有嘲諷意味的對我說的玩笑話，都會讓我想要殺人。想起以前從小學到高中的走讀生活，再和現在大學悲慘的生活比較，就覺得我的人生很悲慘。自我住進宿舍的那天起，我的心情就沒有好過。然而不幸的是，父母總是以爲我不夠適應大學生活，因此總是拒絕我搬走的請求。&lt;/p&gt;
&lt;h2&gt;痛苦的來源&lt;/h2&gt;
&lt;p&gt;入學上課的第一天，在去課室的路上聽到有學生從我身邊經過的時候大笑，我就會覺得寒毛直豎。爲此我曾去過學校的心理諮詢室，雖然並沒有什麼用，但是至少有人會聽我講話。&amp;lt;/br&amp;gt;
好在，宿舍的人並非隨機抽選，都是一個專業的人。但是我們之間卻完全沒有共同話題。除了我，其他兩人總是在聊關於電玩的問題。自從一位姓張的人搬進來後，話題又變成了桌遊相關，仿佛只有我是學計算機網路技術的，跟他們聊天完全無法找到切入點。&amp;lt;/br&amp;gt;
至少宿舍的人並不會有用力摔門的習慣，但是走廊總會有一股煙味。&lt;strong&gt;對於討厭抽菸的我而言，這味道就像催淚瓦斯一樣難忍。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;我們的生活&lt;/h2&gt;
&lt;p&gt;除了我不玩遊戲，其他兩人都會玩遊戲，其中後來搬進來的那位，不僅玩遊戲，還要用機械鍵盤玩。他玩遊戲時總會叫得很大聲，仿佛自己是一個 Youtuber 一樣。我從不會罵人，所以鬼叫的人讓我很煩。他玩遊戲於我而言：&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/U7hPJ0wh8BA?si=U60OI-xXmLmZOLt3&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;還有，侵佔個人資產。在我的位置上和別人玩桌遊，東西堆到我的桌上，對我的東西“評頭論足”，認爲我的東西不如他們的好之類...簡直不勝枚舉。我都想要掐死我的室友...（不對，是拿走他們的電腦，至少人還是不錯的，會請我吃東西）&amp;lt;/br&amp;gt;
在宿舍裏的生活簡直如下地獄一般，還好我在斜對面的信息學院有一個不錯的教室作爲研究點（會有一些大二、大三的各專業的學生！），可以讓我在每週二和週五去那裏開始我的研究（也算不上“研究”，無非就是學習 Linux、C語言，以及給我的 MTP845移植 Linux系統之類）。而且院長和老師會光顧這裏，讓我有機會和他們聊天，了解各種項目和一些賽事（儘管我不想參加任何比賽）。&amp;lt;/br&amp;gt;
更傻缺的是，大家（對，他們會邀請好友）會在一起打遊戲直到深夜。更要命的是，他們的朋友都是煙鬼，會在宿舍裏抽菸。這對於習慣早睡早起的我（通常10點睡覺）來說是“滅頂之災”，那一晚，我只好離開宿舍，去2樓的一間空置的教師宿舍房間過夜。（現在看來，我還是太懦弱了，當時我就應該向輔導員檢舉，讓他們捲鋪蓋滾蛋就好了，可是我沒有）當我提醒他們把聲音放的小點，他們卻反問道：“妳爲什麼不和我們一樣來通宵呢？那樣妳的人生就不完整了”我便很是生氣，閉口不談。而那位姓張的，每次都要玩到深夜，導致我自上課以來，11點以前睡覺的日子，掰着指頭就可以數清！&amp;lt;/br&amp;gt;
有時依着他們喜歡“外放”音訊的習慣，我就會大聲播放 “VOLKSWAGEN FUNK” 來讓我快樂些，一邊心中咒罵這些人（&lt;a href=&quot;https://www.youtube.com/watch?v=-P2ceQ2tvWs&quot;&gt;他們就像福斯汽車一樣質量低劣&lt;/a&gt;）。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Yh--1hvAC5Y?si=h7Lc5FlAVTUYHnNp&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;我也嘗試和他們溝通過，依然如故。&lt;/p&gt;
&lt;h2&gt;4.14 和個人空間&lt;/h2&gt;
&lt;p&gt;自從他們開始玩桌遊的時候，宿舍就成了我最討厭的地方。但是我又不像本地的學生一樣有家可以回，也不可能天天住酒店。我只能週末可以回家，而且回家了還要被父母嗆好一陣子（原因是他們嫌我把大半生活費都貢獻給”鐵路公司“，而我的室友都把大半生活費用去買遊戲了），而且我媽總是以各種理由試圖阻止我回家。于是我就只好在週二下午和週五下午去“4.14”教室度過大部分時間。但是，教室總不可能一直開着門啊！好在學校有的是空房間，那是老師辦公的地方。在平時我就在那裏呆着，直到晚上9點。回去之後怎麼辦呢？其他人都在玩桌遊呢。我只能洗澡後躺在牀上想想週末幹些什麼，或者想想新的高通原型機的事情，把機械鍵盤聲當作ASMR聲音聽了睡去。最近的日子我又去了那些空房間，看到那裏不知何時添加了沙發，但是晚上又沒有人，至少我又有了另外一個過夜的地方，以備另一場大型活動時我的去處用。如果辦公室要是有人的話，我可能要去酒店花錢過夜了。&amp;lt;/br&amp;gt;
有時我會在辦公室呆着一整晚，確認我的室友都睡了，才會返回宿舍，悄然睡下。要是碰上宵禁，我就把空房間的窗帘拉下，大門反鎖，在那裏睡覺。&amp;lt;/br&amp;gt;
我討厭跟人住在一起（家人除外）。當我順風耳聽到室友出去一起去離學校20公里的桌遊社玩桌遊，或是他們一起出去做○○之事導致宿舍空蕩蕩時，那時我反而是最高興的時候了。我到底是不喜歡跟人共處一室的，只要想到有人和我一起睡，我就會覺得不自在。&amp;lt;/br&amp;gt;
但是之後呢？我就是把這些事情告訴家裏人，他們也不會聽的，他們認爲我不需要個人空間，認爲我的種種反應只是因爲我不習慣集體生活，過久了就會沒事的，只好忍受。我也不知道我能不能讓他們相信，我只是一個不喜歡跟人住在一起的人罷了。畢竟，中國人都喜歡強調“集體主義”！把什麼事情都要和集體掛鉤，哪怕這個事情小得不能再小，甚至根本不需要集體的力量也能完成。而我的父親，我不知道妳是否可以讀到我的文章，如果可以，妳就會明白我爲什麼總是要回家了。我知道妳一天起早貪黑，只能賺得20塊而已。我之前做刷機包賺了5美元，我把牠全部給妳，妳可以於百忙之中抽出時間讀我的文章嗎？&lt;/p&gt;
</content:encoded></item><item><title>（轉載）Everypoints I&apos;ve Created (Feat. Lahaina Oryon) -- An OpenstreetMap Parody of Everywhere We Go by Edsion Chen</title><link>https://blog.cloudflare88.eu.org/posts/everypoints-i-created/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/everypoints-i-created/</guid><description>仿佛分別之日發生在昨天，憑開放街圖，隨時可以把我找，執意用 Google（地圖）就當我沒說...</description><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;一個關於 OpenstreetMap 的歌曲改編，基於由陳冠希、MC仁、廚房仔等人所創作的《Everywhere We Go》(Feat. 應采兒)&lt;/p&gt;
&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;OnePlus 6T at the beach&quot; 圖片，EDKPiepaint 版權所有；&lt;/li&gt;
&lt;li&gt;Everypoints I&apos;ve Created (Feat. Lahaina Oryon) 歌詞，Lahaina Oryon 版權所有。&lt;/li&gt;
&lt;li&gt;歌曲 Everywhere We Go (Feat. 應采兒) ，MC仁、廚房仔、陳冠希等版權所有。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如有疑問，請洽版權所有者。
:::&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/vWl6VdAqtxg?si=TPpX4jdz3mDCgh03&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：括弧內文字在演唱時可以省略。&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;Prologue&lt;/h1&gt;
&lt;p&gt;回到宿舍前，記憶在腦海浮現 &amp;lt;/br&amp;gt;
仿佛分別之日發生在昨天 &amp;lt;/br&amp;gt;
（憑）開放街圖，隨時可以把我找 &amp;lt;/br&amp;gt;
執意用 Google（地圖）就當我沒說... &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;走，去一個未標明的地方， &amp;lt;/br&amp;gt;
盡情探索，莫在意別人眼光 &amp;lt;/br&amp;gt;
地圖（和）放大鏡[^1]是我們的象徵， &amp;lt;/br&amp;gt;
想要精確，（GPS）記錄器不可少[^2] &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
潮起，潮落；日出，日落 &amp;lt;/br&amp;gt;
一處又一處，蒐集數據，創建標記；&amp;lt;/br&amp;gt;
這便是我們（的）工作全部 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
（自）創立之日（起），使用人數連年攀升 &amp;lt;/br&amp;gt;
（其）地圖數據，（被）各大院校採用研究 &amp;lt;/br&amp;gt;
設計（也），簡潔高效、易用 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
測繪方式（也）可與 Google、Apple [^3]匹敵, &amp;lt;/br&amp;gt;
（數據）隨時上傳、更新，地圖即刻呈現 &amp;lt;/br&amp;gt;
編輯器（也），易於使用輕鬆上手 &amp;lt;/br&amp;gt;
（環境）架設完畢，走嘍！ &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
On a phone, a laptop, or any smartwatches, &amp;lt;/br&amp;gt;
（在智慧手機、筆記型電腦、亦或是智慧手錶） &amp;lt;/br&amp;gt;
Doing everything I can do &amp;lt;/br&amp;gt;
（我也可以做任何事） &amp;lt;/br&amp;gt;
When I tired, loot at the sky, &amp;lt;/br&amp;gt;
（當我疲倦，翻閱天空） &amp;lt;/br&amp;gt;
Look back progress I&apos;ve made, &amp;lt;/br&amp;gt;
（回首我所走過的路） &amp;lt;/br&amp;gt;
I can&apos;t wait to share it with you. &amp;lt;/br&amp;gt;
（我迫不及待想要與妳分享） &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;回到宿舍前，記憶在腦海浮現 &amp;lt;/br&amp;gt;
仿佛分別之日發生在昨天 &amp;lt;/br&amp;gt;
（憑）開放街圖，隨時可以把我找 &amp;lt;/br&amp;gt;
執意用 Google（地圖）就當我沒說... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
高中時候，熱愛自由開源 &amp;lt;/br&amp;gt;
父母說這些東西在中國無人使用 &amp;lt;/br&amp;gt;
妳這樣的（犟）脾氣，獨立後難以（在國內）生存， &amp;lt;/br&amp;gt;
此時此刻，（我）早已自建代理（伺服器）&amp;lt;/br&amp;gt;
代理，純淨家庭IP &amp;lt;/br&amp;gt;
代理，（學會流量）上下行分離 &amp;lt;/br&amp;gt;
購買伺服器後考慮各種協議 &amp;lt;/br&amp;gt;
拔掉微信（就算）頭破血流我也在所不惜 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;考試之後，無憂無慮的暑假 &amp;lt;/br&amp;gt;
自架容器，轉發微信訊息 &amp;lt;/br&amp;gt;
（自架）搜尋引擎，捍衛個人隱私 &amp;lt;/br&amp;gt;
（架）部落格，記錄生活點滴 &amp;lt;/br&amp;gt;
假期在這不知不覺過去， &amp;lt;/br&amp;gt;
眨眼之間，迎接大學新學期 &amp;lt;/br&amp;gt;
離家之日不知不覺到來， &amp;lt;/br&amp;gt;
有句話講分久必合， &amp;lt;/br&amp;gt;
合久必分... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
On a phone, a laptop, or any smartwatches, &amp;lt;/br&amp;gt;
（在智慧手機、筆記型電腦、亦或是智慧手錶） &amp;lt;/br&amp;gt;
Doing everything I can do &amp;lt;/br&amp;gt;
（我也可以做任何事） &amp;lt;/br&amp;gt;
When I tired, loot at the sky, &amp;lt;/br&amp;gt;
（當我疲倦，翻閱天空） &amp;lt;/br&amp;gt;
Look back progress I&apos;ve made, &amp;lt;/br&amp;gt;
（回首我所走過的路） &amp;lt;/br&amp;gt;
I can&apos;t wait to share it with you. &amp;lt;/br&amp;gt;
（我迫不及待想要與妳分享） &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 4&lt;/h1&gt;
&lt;p&gt;回到宿舍前，記憶在腦海浮現 &amp;lt;/br&amp;gt;
仿佛分別之日發生在昨天 &amp;lt;/br&amp;gt;
（憑）開放街圖，隨時可以把我找 &amp;lt;/br&amp;gt;
執意用 Google（地圖）就當我沒說... &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
收拾行李走嘍，一步一步，計算好 &amp;lt;/br&amp;gt;
看熟悉的家、熟悉的路，一點一點落在身後 &amp;lt;/br&amp;gt;
到了這大學校，與妳們分別，改日再見 &amp;lt;/br&amp;gt;
適應好新生活，迎接各種挑戰 &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
On a phone, a laptop, or any smartwatches, &amp;lt;/br&amp;gt;
（在智慧手機、筆記型電腦、亦或是智慧手錶） &amp;lt;/br&amp;gt;
Doing everything I can do &amp;lt;/br&amp;gt;
（我也可以做任何事） &amp;lt;/br&amp;gt;
When I tired, loot at the sky, &amp;lt;/br&amp;gt;
（當我疲倦，翻閱天空） &amp;lt;/br&amp;gt;
Look back progress I&apos;ve made, &amp;lt;/br&amp;gt;
（回首我所走過的路） &amp;lt;/br&amp;gt;
I can&apos;t wait to share it with you. &amp;lt;/br&amp;gt;
（我迫不及待想要與妳分享） &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 5&lt;/h1&gt;
&lt;p&gt;回到家門前，記憶在腦海浮現 &amp;lt;/br&amp;gt;
敲開家門與妳們見面 &amp;lt;/br&amp;gt;
（憑）開放街圖，隨時可以把我找 &amp;lt;/br&amp;gt;
執意用 Google（地圖）就當我沒說... &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;再回宿舍前，記憶在腦海浮現 &amp;lt;/br&amp;gt;
仿佛分別之日發生在昨天 &amp;lt;/br&amp;gt;
（憑）開放街圖，隨時可以把我找 &amp;lt;/br&amp;gt;
執意用 Google（地圖）就當我沒說... &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;[^1]:OpenstreetMap 的 Logo 就是一個放大鏡和一個地圖。
[^2]:GPS 全名 Global Positioning System，是一種協定位技術，用於測量地球上任何一點的緯度、經度。使用 GPS 記錄器可以提高地點的精確度，但並非必要。
[^3]:作者 Lahaina 原話：對於 Google 地圖和 Apple Maps 被禁止的國家或地區，讀者可以把牠對應所在地區的地圖服務。&lt;/p&gt;
</content:encoded></item><item><title>Android 混合 Debian：Droidian 在 Nothing Phone 1 的首次體驗</title><link>https://blog.cloudflare88.eu.org/posts/droidian-on-spacewar/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/droidian-on-spacewar/</guid><description>經過修改的 Android 核心與上游主線核心到底相差多遠，只需兩個發行版便知。</description><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;把 Android 手機刷機成 Debian 系統，是一個很有趣的嘗試。&lt;/p&gt;
&lt;h2&gt;Droidian 介紹&lt;/h2&gt;
&lt;p&gt;Droidian 是一個基於 Debian 的 Testing 分支開發的行動裝置作業系統，目的在於將 Android 手機的系統改裝爲 Debian 系統，讓 Android 手機可以像一般 Linux 電腦一樣，享受 Debian 的各種好處。&amp;lt;/br&amp;gt;
由於 Android 對 Linux 核心和文件系統做出了大量修改（例如刪除了 Linux 中常見的 X 視窗系統和 Wayland，亦不支援支撐大多數 Linux 程式所需的 Glib 或 musl C函式庫），使得市面上的絕大多數 Android 手機移植 Linux 系統變得疑難重重。因此，Droidian 專案的產生，便是解決這個問題而來的：牠採用 &lt;a href=&quot;https://halium.org/&quot;&gt;Halium&lt;/a&gt; 和 libhybris，把 Android 的 bionic 與普通 Linux 的 Glibc 的C函式庫進行對應，並且相容 Android 中的 HAL 和硬體驅動程式，以此來降低移植難度。如果妳的手機出廠預載 Android 9 及以上系統，Droidian 還可以通過 GSI 的方式移植，只需重新編譯核心即可。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;安裝 Droidian&lt;/h2&gt;
&lt;p&gt;我的裝置在 XDA 上有&lt;a href=&quot;https://github.com/Nonta72/nothing-spacewar&quot;&gt;非官方移植&lt;/a&gt;，支援狀況也非常不錯：大部分功能正常，甚至也可以撥打電話，相機的畫素雖然被限制在1200萬，但是畫面的顏色卻非常不錯，比起主線核心那個沒有經過3A處理的樣子好了不少。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-working-cam.jpg&quot; alt=&quot;Working camera on nothing phone 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;這是目前支援的項目：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;屏幕（重新整理頻率爲60Hz）&lt;/li&gt;
&lt;li&gt;相機（畫素1200萬）&lt;/li&gt;
&lt;li&gt;麥克風&lt;/li&gt;
&lt;li&gt;藍牙&lt;/li&gt;
&lt;li&gt;電池管理（雖然不及 Android 原生的好，但還是可以用）&lt;/li&gt;
&lt;li&gt;無線網路（藍牙無線網路也能正常使用）&lt;/li&gt;
&lt;li&gt;音效（沒有耳機孔，但是可以用耳機）&lt;/li&gt;
&lt;li&gt;無線充電（雖然不及 Android 原生的好，但還是可以用，可能有危險）&lt;/li&gt;
&lt;li&gt;數據機（不支援5G行動數據，但是可以使用）&lt;/li&gt;
&lt;li&gt;NFC&lt;/li&gt;
&lt;li&gt;GPS&lt;/li&gt;
&lt;li&gt;傳感器&lt;/li&gt;
&lt;li&gt;震動（效果非常好！可以開發其他用途）&lt;/li&gt;
&lt;li&gt;陀螺儀&lt;/li&gt;
&lt;li&gt;加速度計
&amp;lt;/br&amp;gt;
這是無法工作的項目：&lt;/li&gt;
&lt;li&gt;雙SIM卡&lt;/li&gt;
&lt;li&gt;熒幕下方指紋識別（Phosh 目前不支援這種設計）&lt;/li&gt;
&lt;li&gt;Glyph 燈帶&lt;/li&gt;
&lt;li&gt;90Hz及120Hz 重新整理頻率&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;刷機過程&lt;/h3&gt;
&lt;p&gt;參考 XDA 的&lt;a href=&quot;https://xdaforums.com/t/rom-linux-droidian-for-spacewar-with-waydroid.4762595/&quot;&gt;教學&lt;/a&gt;，到&lt;a href=&quot;https://github.com/Nonta72/nothing-spacewar&quot;&gt;這裏&lt;/a&gt;下載需要的文件，妳可以去 &lt;a href=&quot;https://github.com/droidian-images/droidian/releases&quot;&gt;Droidian&lt;/a&gt; 的GitHub 上下載最新版的映像檔嘗試。&amp;lt;/br&amp;gt;
下載完成後，解壓縮文件。&amp;lt;/br&amp;gt;
之後，去&lt;a href=&quot;https://github.com/spike0en/nothing_archive/releases/tag/Spacewar_T1.5-230310-1650&quot;&gt;這裏&lt;/a&gt;下載 Android 13 韌體，必須是原廠韌體，否則會有顯示Bug。下載完後，通過fastboot刷入各分區即可。或使用下面的腳本（來源：&lt;a href=&quot;https://github.com/spike0en/nothing_flasher/blob/main/README.md#-download&quot;&gt;Nothing Flasher&lt;/a&gt; by spike0en)：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

echo &quot;#################################&quot;
echo &quot;# Spacewar Fastboot ROM Flasher #&quot;
echo &quot;#    t.me/s/Nothing_Archive     #&quot;
echo &quot;#################################&quot;

##----------------------------------------------------------##
if [ ! -d &quot;$(pwd)/platform-tools-r33.0.0&quot; ]; then
   if [[ $OSTYPE == &apos;darwin&apos;* ]]; then
       fastboot_dl=&quot;https://dl.google.com/android/repository/platform-tools_r33.0.0-darwin.zip&quot;
   else
       fastboot_dl=&quot;https://dl.google.com/android/repository/platform-tools_r33.0.0-linux.zip&quot;
   fi
   curl -L &quot;$fastboot_dl&quot; -o &quot;$(pwd)/platform-tools-r33.0.0.zip&quot;
   unzip &quot;$(pwd)/platform-tools-r33.0.0.zip&quot;
   rm &quot;$(pwd)/platform-tools-r33.0.0.zip&quot;

   if [ -d &quot;$(pwd)/platform-tools&quot; ]; then
       mv &quot;$(pwd)/platform-tools&quot; &quot;$(pwd)/platform-tools-r33.0.0&quot;
   fi
fi

fastboot=&quot;$(pwd)/platform-tools-r33.0.0/fastboot&quot;

if [ ! -f &quot;$fastboot&quot; ] || [ ! -x &quot;$fastboot&quot; ]; then
   echo &quot;Fastboot cannot be executed, exiting&quot;
   exit 1
fi

# Partition Variables
boot_partitions=&quot;boot vendor_boot dtbo&quot;
firmware_partitions=&quot;abl aop bluetooth cpucp devcfg dsp dtbo featenabler hyp imagefv keymaster modem multiimgoem qupfw shrm tz uefisecapp xbl xbl_config&quot;
logical_partitions=&quot;system system_ext product vendor odm&quot;
junk_logical_partitions=&quot;null&quot;
vbmeta_partitions=&quot;vbmeta_system&quot;

function SetActiveSlot {
   if ! &quot;$fastboot&quot; set_active a; then
       echo &quot;Error occured while switching to slot A. Aborting&quot;
       exit 1
   fi
}

function handle_fastboot_error { 
   case &quot;$FASTBOOT_ERROR&quot; in
       [nN] )
           exit 1
       ;;
   esac
}

function ErasePartition {
   if ! &quot;$fastboot&quot; erase $1; then
       read -rp &quot;Erasing $1 partition failed, Continue? If unsure say N, Pressing Enter key without any input will continue the script. (Y/N)&quot; FASTBOOT_ERROR
       handle_fastboot_error
   fi
}

function RebootFastbootD {
   echo &quot;##########################&quot;             
   echo &quot;# REBOOTING TO FASTBOOTD #&quot;       
   echo &quot;##########################&quot;
   if ! &quot;$fastboot&quot; reboot fastboot; then
       echo &quot;Error occured while rebooting to fastbootd. Aborting&quot;
       exit 1
   fi
}

function FlashImage {
   if ! &quot;$fastboot&quot; flash $1 $2; then
       read -rp &quot;Flashing$2 failed, Continue? If unsure say N, Pressing Enter key without any input will continue the script. (Y/N)&quot; FASTBOOT_ERROR
       handle_fastboot_error
   fi
}

function FlashSuper {
   RebootBootloader
   if ! &quot;$fastboot&quot; flash super super.img; then
       RebootFastbootD
       FlashImage &quot;super&quot; \ &quot;super.img&quot;
   fi
}

function DeleteLogicalPartition {
   if ! &quot;$fastboot&quot; delete-logical-partition $1; then
       if ! echo $1 | grep -q &quot;cow&quot;; then
           read -rp &quot;Deleting $1 partition failed, Continue? If unsure say N, Pressing Enter key without any input will continue the script. (Y/N)&quot; FASTBOOT_ERROR
           handle_fastboot_error
       fi
   fi
}

function CreateLogicalPartition {
   if ! &quot;$fastboot&quot; create-logical-partition $1 $2; then
       read -rp &quot;Creating $1 partition failed, Continue? If unsure say N, Pressing Enter key without any input will continue the script. (Y/N)&quot; FASTBOOT_ERROR
       handle_fastboot_error
   fi
}

function ResizeLogicalPartition {
   if [ $junk_logical_partitions != &quot;null&quot; ]; then
   for i in $junk_logical_partitions; do
           for s in a b; do 
               DeleteLogicalPartition &quot;${i}_${s}-cow&quot;
               DeleteLogicalPartition &quot;${i}_${s}&quot;
   	    done
   done
   fi

   for i in $logical_partitions; do
       for s in a b; do 
           DeleteLogicalPartition &quot;${i}_${s}-cow&quot;
           DeleteLogicalPartition &quot;${i}_${s}&quot;
           CreateLogicalPartition &quot;${i}_${s}&quot; \ &quot;1&quot;
       done
   done
}

function WipeSuperPartition {
   if ! &quot;$fastboot&quot; wipe-super super_empty.img; then 
       echo &quot;Wiping super partition failed. Fallback to deleting and creating logical partitions&quot;
       ResizeLogicalPartition
   fi
}

function RebootBootloader {
   echo &quot;###########################&quot;
   echo &quot;# REBOOTING TO BOOTLOADER #&quot;       
   echo &quot;###########################&quot;
   if ! &quot;$fastboot&quot; reboot bootloader; then
       echo &quot;Error occured while rebooting to bootloader. Aborting&quot;
       exit 1
   fi
}
##----------------------------------------------------------##

echo &quot;#############################&quot;
echo &quot;# CHECKING FASTBOOT DEVICES #&quot;
echo &quot;#############################&quot;
&quot;$fastboot&quot; devices

echo &quot;#############################&quot;
echo &quot;# CHANGING ACTIVE SLOT TO A #&quot;
echo &quot;#############################&quot;
SetActiveSlot

echo &quot;###################&quot;
echo &quot;# FORMATTING DATA #&quot;
echo &quot;###################&quot;
read -rp &quot;Wipe Data? (Y/N) &quot; DATA_RESP
case &quot;$DATA_RESP&quot; in
   [yY] )
       echo &apos;Please ignore &quot;Did you mean to format this partition?&quot; warnings.&apos;
       ErasePartition userdata
       ErasePartition metadata
       ;;
esac

echo &quot;############################&quot;
echo &quot;# FLASHING BOOT PARTITIONS #&quot;
echo &quot;############################&quot;
read -rp &quot;Flash images on both slots? If unsure, say N. (Y/N) &quot; SLOT_RESP
for i in $boot_partitions; do
   case &quot;$SLOT_RESP&quot; in
       [yY] )
           for s in a b; do
               FlashImage &quot;${i}_${s}&quot; \ &quot;$i.img&quot;
           done
       ;;
   *)
           FlashImage &quot;${i}_a&quot; \ &quot;$i.img&quot;
       ;;
   esac
done

echo &quot;###################&quot;
echo &quot;# FLASHING VBMETA #&quot;
echo &quot;###################&quot;
read -rp &quot;Disable android verified boot?, If unsure, say N. Bootloader won&apos;t be lockable if you select Y. (Y/N) &quot; VBMETA_RESP
case &quot;$VBMETA_RESP&quot; in
   [yY] )
       if [ &quot;$SLOT_RESP&quot; = &quot;y&quot; ] || [ &quot;$SLOT_RESP&quot; = &quot;Y&quot; ]; then
           for s in a b; do
               FlashImage &quot;vbmeta_${s} --disable-verity --disable-verification&quot; \ &quot;vbmeta.img&quot;
           done
       else
           FlashImage &quot;vbmeta_a --disable-verity --disable-verification&quot; \ &quot;vbmeta.img&quot;
       fi
       ;;
   *)
       if [ &quot;$SLOT_RESP&quot; = &quot;y&quot; ] || [ &quot;$SLOT_RESP&quot; = &quot;Y&quot; ]; then
           for s in a b; do
               FlashImage &quot;vbmeta_${s}&quot; \ &quot;vbmeta.img&quot;
           done
       else
           FlashImage &quot;vbmeta_a&quot; \ &quot;vbmeta.img&quot;
       fi
       ;;
esac

echo &quot;#####################&quot;
echo &quot;# FLASHING FIRMWARE #&quot;
echo &quot;#####################&quot;
RebootFastbootD
for i in $firmware_partitions; do
   case &quot;$SLOT_RESP&quot; in
       [yY] )
           for s in a b; do
               FlashImage &quot;${i}_${s}&quot; \ &quot;$i.img&quot;
           done
       ;;
   *)
           FlashImage &quot;${i}_a&quot; \ &quot;$i.img&quot;
       ;;
   esac
done

echo &quot;###############################&quot;
echo &quot;# FLASHING LOGICAL PARTITIONS #&quot;
echo &quot;###############################&quot;
if [ ! -f super.img ]; then
   if [ -f super_empty.img ]; then
       WipeSuperPartition
   else
       ResizeLogicalPartition
   fi
   for i in $logical_partitions; do
       FlashImage &quot;${i}_a&quot; \ &quot;$i.img&quot;
   done
else
   FlashSuper
fi

echo &quot;####################################&quot;
echo &quot;# FLASHING OTHER VBMETA PARTITIONS #&quot;
echo &quot;####################################&quot;
for i in $vbmeta_partitions; do
   case &quot;$VBMETA_RESP&quot; in
       [yY] )
           FlashImage &quot;${i}_a --disable-verity --disable-verification&quot; \ &quot;$i.img&quot;
           ;;
       *)
           FlashImage &quot;${i}_a&quot; \ &quot;$i.img&quot;
           ;;
   esac
done

echo &quot;#############&quot;
echo &quot;# REBOOTING #&quot;
echo &quot;#############&quot;
read -rp &quot;Reboot to system? If unsure, say Y. (Y/N) &quot; REBOOT_RESP
case &quot;$REBOOT_RESP&quot; in
   [yY] )
       &quot;$fastboot&quot; reboot
       ;;
esac

echo &quot;########&quot;
echo &quot;# DONE #&quot;
echo &quot;########&quot;
echo &quot;Stock firmware restored.&quot;
echo &quot;You may now optionally re-lock the bootloader if you haven&apos;t disabled android verified boot.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;刷完後，運行文件提供的刷機腳本，等待完成即可。&lt;/p&gt;
&lt;h2&gt;體驗&lt;/h2&gt;
&lt;p&gt;刷完開機後，預設密碼&lt;code&gt;1234&lt;/code&gt;，基本操作與 PostmarketOS 無異。其預設UI爲Phosh，不能自行更換。強行更換會遇到依賴地獄。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-phosh.jpg&quot; alt=&quot;Phosh showing on Nothing Phone 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;開機後，可以看到Droidian的桌面，可以正常運行各種應用程式。手機的基本功能都能正常工作，還可以撥打電話。雖然熒幕的整理頻率很低，但是驍龍778G+的效能很強，絲毫不會有任何卡頓。也算是解決了目前主線核心不支援通話音頻的問題。&amp;lt;/br&amp;gt;
比起這些體驗而言，我最關心的還是核心版本。通過&lt;code&gt;uname -a&lt;/code&gt;查看，得知核心版本爲5.4的QGKI核心，遠遠落後於主線6.17的版本。根據 Droidian 自身的原理來看，應該是不能升級核心版本，除非 Nothing 官方升級 Nothing Phone 1 的 BSP 核心。但是 Nothing Phone 1 早已經被官方停止支援，指望廠商是不可能的事情。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-about.jpg&quot; alt=&quot;Droidian version&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-about-2.jpg&quot; alt=&quot;System info &amp;amp; kernel version&quot; /&gt;&lt;/p&gt;
&lt;p&gt;雖然核心版本老舊，但是仍然可以執行絕大多數程式。在打開GNOME的設定後，有幾個選項也同樣帶給了我驚喜：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;設置裏有了NFC相關的選項，比起 Android 上各種NFC設定，在Linux上看到這個選項反而讓我驚訝不已。要知道主線 Linux 對於 NFC 的支援雖然在2.6核心就被引入，但是一直缺乏用戶友好的程式，而主流的桌面環境更是缺乏相關支援。雖然Droidian 的 NFC 設定非常簡單，但是有總比沒有好！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-nfc.jpg&quot; alt=&quot;Droidian&apos;s NFC settings&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;設置中還有指紋選項，雖然 GNOME 也支援了指紋解鎖，但是我沒有一臺裝置有指紋識別器，那些內建指紋識別的，能夠刷 Linux 的手機，因爲廠商不提供 Linux 驅動，而不支援指紋解鎖，真是可惜。如今我終於可以在 Droidian 上一飽眼福了（爲什麼是“飽眼福”？因爲Phosh不支援屏幕下指紋識別，即使識別器本身可用，也無法解鎖屏幕）！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-fingerprint.jpg&quot; alt=&quot;Fingerprint unlocking in Droidian&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;因爲是基於原廠核心修改，加之 Halium 與 libhybris 的採用，數據機的韌體實現方式也不同了。牠被一個叫“ofono”的軟體棧替代，而不是主線核心中掛載數據機韌體啓動數據機的方案，與此同時，數據機的廠商也變成了“binder”，而不是“Qualcomm Incomprated”。不過，妳依然可以撥打電話，與朋友發短訊聊天：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-modem.jpg&quot; alt=&quot;modem details in droidian&quot; /&gt;&lt;/p&gt;
&lt;p&gt;唯一的問題是揚聲器的聲音非常響亮，而音量調節是沒有用的，只有最大和靜音兩個選擇。&lt;/p&gt;
&lt;h2&gt;Waydroid 與應用程式相容性&lt;/h2&gt;
&lt;p&gt;根據 Halium 的編譯指南所寫，我們最終編譯出來的核心，是可以相容LXC容器的。而Waydroid則是把 Android 包裝到 LXC 容器中。讓 Android 幾乎以無效能損失的方式執行在 Linux 系統上。Droidian 將 Waydroid 的選項整合到了系統設定裏，方便普通使用者管理。不過我還是通過&lt;code&gt;sudo apt install waydroid&lt;/code&gt; 來安裝了，因爲命令非常直接明了。而且我早就有 Waydroid 的使用經驗，那幾條命令我也早就熟記於心。當然使用體驗比主線核心相去不遠，我仍然可以在 Linux 桌面環境下運行原生的 Android 應用，例如 Telegram、Signal、甚至是 Google Maps。實際測試後發現，Waydroid 的啓動速度非常快，應用的運行也相當流暢，幾乎與原廠無異。而且把 Android 應用放在 Waydroid 中還比較安全，因爲容器裏的應用無法訪問外部的文件，此外也可以有效遏制不少應用開機自啓動的問題，不只是拖累系統執行效能，也可能會在背景蒐集使用者資料，亦或是幹些不明所以的勾當。這都是在普通 Android 機做不到的。&lt;/p&gt;
&lt;h2&gt;總結&lt;/h2&gt;
&lt;p&gt;Droidian 在 Nothing Phone 1 上的移植體驗讓我看見了「Android 與 Linux 能夠真正融合」的可能。雖然目前仍存在許多小問題，但牠已經證明：即便在封閉的 Android 裝置上，我們仍能擁抱一個真正自由的 Linux 桌面。但牠同樣讓我明白了 Android 手機與 Linux 手機的差異： Android 核心落後於主線核心至少5年，大量上游的修補無法及時應用於 Android，使 Android 裝置面臨着安全問題。此外，裝置廠商對於核心的大量修改，使得 Android 裝置移植主線 Linux 核心非常困難。主線核心對於硬體的實現，往往需要核心開發者花費幾個月甚至幾年時間才能做好。曾經有人拿 Pinephone 與 一加6T的主線核心原始碼做過對比，結果是 Pinephone 的主線核心與上游相差50萬行代碼，而後者則相差500萬行代碼。這個差距正是目前 Android 裝置在自由軟體世界中難以完全融入的現實寫照。這也是 Droidian 和 Halium 教給我的，最爲生動的一課，牠不是教科書，卻勝似教科書。而最可貴的一點是：這節課必須由妳親自完成，對照文檔從無到有，一步步修復、除錯甚至於重新實現手機的所有功能。&amp;lt;/br&amp;gt;
這種學習,不是速成的知識輸入，而是緩慢而紮實的理解；牠會讓妳更尊重硬體、理解驅動、體會抽象核心與具體裝置之間那條看不見的拉鋸線，牠也會讓妳對於 Linux，乃至整個 UNIX 世界有着比以往更加深刻的認識。牠也會讓妳對於自由軟體、開源社群、開放文化有著更深刻的理解。完成牠的報酬或許不是獎盃或者金錢，也可能不會有任何商業價值。但牠會是一段值得珍惜的歷程，一個妳永遠都不會忘記的經驗。是能讓一台手機在自由軟體下運作的成就感，更是妳對一個開源生態貢獻的一小塊基石——雖小，卻能被後來者踏上，繼續向前。&lt;/p&gt;
</content:encoded></item><item><title>Android Mixed with Debian -- First Experience with Droidian on Nothing Phone 1</title><link>https://blog.cloudflare88.eu.org/posts/en/droidian-on-spacewar/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/en/droidian-on-spacewar/</guid><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- Co-translated by Gemini --&amp;gt;
Flashing a Debian system onto an Android phone is a very interesting endeavor.&lt;/p&gt;
&lt;h2&gt;Droidian Introduction&lt;/h2&gt;
&lt;p&gt;Droidian is a mobile device operating system developed based on Debian&apos;s Testing branch. Its goal is to transform Android phones into Debian systems, allowing them to enjoy the various benefits of Debian just like a regular Linux computer.&amp;lt;/br&amp;gt;
Since Android has made extensive modifications to the Linux kernel and filesystem (such as removing common components like the X Window System and Wayland, and not supporting the Glibc or musl C libraries required by most Linux programs), porting Linux systems to most Android phones on the market is fraught with difficulties. Therefore, the Droidian project was created to solve this problem: it uses &lt;a href=&quot;https://halium.org/&quot;&gt;Halium&lt;/a&gt; and libhybris to map Android&apos;s bionic with common Linux Glibc C libraries, ensuring compatibility with Android&apos;s HAL and hardware drivers to reduce porting difficulty. If your phone shipped with Android 9 or above, Droidian can even be ported via a GSI by simply recompiling the kernel.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Installing Droidian&lt;/h2&gt;
&lt;p&gt;My device has an &lt;a href=&quot;https://github.com/Nonta72/nothing-spacewar&quot;&gt;unofficial port&lt;/a&gt; on XDA, and the support status is quite excellent: most functions work, it can even make phone calls, and although the camera resolution is limited to 12 megapixels, the color quality is very good—much better than the un-processed 3A output of the mainline kernel.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-working-cam.jpg&quot; alt=&quot;Working camera on nothing phone 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here are the currently supported items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Screen (refresh rate at 60Hz)&lt;/li&gt;
&lt;li&gt;Camera (12-megapixel resolution)&lt;/li&gt;
&lt;li&gt;Microphone&lt;/li&gt;
&lt;li&gt;Bluetooth&lt;/li&gt;
&lt;li&gt;Battery management (not as good as original Android, but usable)&lt;/li&gt;
&lt;li&gt;Wi-Fi (Bluetooth tethering also works normally)&lt;/li&gt;
&lt;li&gt;Audio (no headphone jack, but earphones work)&lt;/li&gt;
&lt;li&gt;Wireless charging (not as good as original Android, but usable; may be dangerous)&lt;/li&gt;
&lt;li&gt;Modem (5G mobile data not supported, but functional)&lt;/li&gt;
&lt;li&gt;NFC&lt;/li&gt;
&lt;li&gt;GPS&lt;/li&gt;
&lt;li&gt;Sensors&lt;/li&gt;
&lt;li&gt;Vibration (excellent effects! can be developed for other uses)&lt;/li&gt;
&lt;li&gt;Gyroscope&lt;/li&gt;
&lt;li&gt;Accelerometer
&amp;lt;/br&amp;gt;
Items that do not work:&lt;/li&gt;
&lt;li&gt;Dual SIM&lt;/li&gt;
&lt;li&gt;Under-display fingerprint recognition (Phosh currently does not support this design)&lt;/li&gt;
&lt;li&gt;Glyph light strip&lt;/li&gt;
&lt;li&gt;90Hz and 120Hz refresh rates&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Flashing Process&lt;/h3&gt;
&lt;p&gt;Refer to the &lt;a href=&quot;https://xdaforums.com/t/rom-linux-droidian-for-spacewar-with-waydroid.4762595/&quot;&gt;tutorial&lt;/a&gt; on XDA, and go &lt;a href=&quot;https://github.com/Nonta72/nothing-spacewar&quot;&gt;here&lt;/a&gt; to download the necessary files. You can also go to &lt;a href=&quot;https://github.com/droidian-images/droidian/releases&quot;&gt;Droidian&apos;s&lt;/a&gt; GitHub to download the latest image files to try.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;After the download is complete, extract the files.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, go &lt;a href=&quot;https://github.com/spike0en/nothing_archive/releases/tag/Spacewar_T1.5-230310-1650&quot;&gt;here&lt;/a&gt; to download the Android 13 firmware; it must be the stock firmware, otherwise you will encounter display bugs. Once downloaded, flash each partition via fastboot. Alternatively, use the following script (Source: &lt;a href=&quot;https://github.com/spike0en/nothing_flasher/blob/main/README.md#-download&quot;&gt;Nothing Flasher&lt;/a&gt; by spike0en)&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;After flashing, run the flashing script provided with the files and wait for completion.&lt;/p&gt;
&lt;h2&gt;Experience&lt;/h2&gt;
&lt;p&gt;After flashing and booting, the default password is &lt;code&gt;1234&lt;/code&gt;. Basic operations are similar to PostmarketOS. The default UI is Phosh, which cannot be changed manually without running into dependency hell.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-phosh.jpg&quot; alt=&quot;Phosh showing on Nothing Phone 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once booted, you can see the Droidian desktop and run various applications normally. The basic functions of the phone all work, including making calls. Although the screen refresh rate is low, the performance of the Snapdragon 778G+ is very strong, and there is no stuttering at all. This also solves the current issue of the mainline kernel not supporting call audio.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Beyond the experience, I am most concerned about the kernel version. Checking via &lt;code&gt;uname -a&lt;/code&gt;, I found the kernel version is 5.4 QGKI, which lags significantly behind the mainline 6.17 version. Given the nature of Droidian, it is likely impossible to upgrade the kernel version unless Nothing officially upgrades the Nothing Phone (1) BSP kernel. However, official support for the Nothing Phone (1) has already ended, so relying on the manufacturer is out of the question.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-about.jpg&quot; alt=&quot;Droidian version&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-about-2.jpg&quot; alt=&quot;System info &amp;amp; kernel version&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Although the kernel version is old, it can still run most programs. After opening the GNOME settings, a few options also brought me surprises:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are NFC-related options in the settings. Compared to various NFC settings on Android, seeing this option on Linux actually surprised me. You should know that although NFC support was introduced in the mainline Linux kernel back in version 2.6, it has always lacked user-friendly programs, and major desktop environments lack support. Although Droidian&apos;s NFC settings are very simple, something is better than nothing!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-nfc.jpg&quot; alt=&quot;Droidian&apos;s NFC settings&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is also a fingerprint option in the settings. Although GNOME supports fingerprint unlocking, I don&apos;t have a single device with a fingerprint reader. Many phones capable of running Linux that have built-in fingerprints don&apos;t support them because manufacturers don&apos;t provide Linux drivers, which is a real shame. Now, I can finally treat my eyes in Droidian (why &quot;treat eyes&quot;? because Phosh doesn&apos;t support under-display fingerprints; even if the reader itself is functional, it can&apos;t unlock the screen)!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-fingerprint.jpg&quot; alt=&quot;Fingerprint unlocking in Droidian&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Since it is based on the stock kernel with modifications and uses Halium and libhybris, the modem&apos;s firmware implementation is different. It is replaced by a software stack called &quot;ofono,&quot; instead of the solution in the mainline kernel that mounts modem firmware to start the modem. At the same time, the modem manufacturer has changed to &quot;binder&quot; instead of &quot;Qualcomm Incorporated.&quot; However, you can still make phone calls and send text messages to chat with friends:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;assets/droidian-modem.jpg&quot; alt=&quot;modem details in droidian&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The only problem is that the speaker sound is extremely loud, and volume adjustment doesn&apos;t work; there are only two choices: maximum and mute.&lt;/p&gt;
&lt;h2&gt;Waydroid and Application Compatibility&lt;/h2&gt;
&lt;p&gt;According to the Halium compilation guide, the kernel we ultimately compile is compatible with LXC containers. Waydroid, in turn, wraps Android inside an LXC container, allowing Android to run on a Linux system with almost no performance loss. Droidian integrates Waydroid options into the system settings, making it convenient for average users to manage. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;However, I still installed it via &lt;code&gt;sudo apt install waydroid&lt;/code&gt; because the command is very direct and clear. Besides, I already have experience using Waydroid, and I&apos;ve long since memorized those few commands. Of course, the experience is not far from the mainline kernel; I can still run native Android apps under the Linux desktop environment, such as Telegram, Signal, and even Google Maps. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Actual tests found that Waydroid starts very quickly and apps run quite smoothly, almost identically to the stock experience. Furthermore, placing Android apps inside Waydroid is relatively safe because apps in the container cannot access external files. This also effectively curbs the issue of many apps auto-starting at boot, which not only drags down system performance but also involves background data collection or other shady business—things you can&apos;t do on a regular Android phone.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The experience of porting Droidian to the Nothing Phone (1) has shown me the possibility of a &quot;true fusion of Android and Linux.&quot; Although small problems still exist, it has proven that even on a closed Android device, we can embrace a truly free Linux desktop. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;However, it also helped me understand the difference between Android phones and Linux phones: the Android kernel lags behind the mainline by at least 5 years, and a large number of upstream patches cannot be applied to Android in time, leaving Android devices facing security issues. Furthermore, extensive modifications to the kernel by manufacturers make it extremely difficult for Android devices to port the mainline Linux kernel. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Implementing hardware support in the mainline kernel often takes kernel developers months or even years. Someone once compared the mainline kernel source code of the PinePhone and the OnePlus 6T; the result was that the PinePhone&apos;s mainline kernel differed from upstream by 50 million lines of code, while the latter differed by 500 million lines. This gap is a realistic reflection of the difficulty Android devices have in fully integrating into the Free Software world. This is the most vivid lesson that Droidian and Halium have taught me—it is not a textbook, but it is better than one. And the most valuable point is: this lesson must be completed by you personally, following documentation from scratch, repairing, debugging, and even re-implementing all of the phone&apos;s functions step by step.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;This kind of learning is not a quick injection of knowledge, but a slow and solid understanding. It will make you respect hardware more, understand drivers, and feel that invisible tug-of-war between the abstract kernel and the concrete device. it will also give you a deeper understanding of Linux and the entire UNIX world than ever before. You will also gain a deeper understanding of Free Software, the open-source community, and open culture. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;The reward for completing it may not be a trophy or money, and it may not have any commercial value, but it will be a journey to cherish, an experience you will never forget. It is the sense of accomplishment of making a phone work under Free Software, and it is a small stepping stone you have contributed to an open-source ecosystem—small, yet capable of being stepped on by those who come after, as they continue forward.&lt;/p&gt;
</content:encoded></item><item><title>She (Snapdragon CRDs) -- A FOSS Parody of She by Groove Coverage</title><link>https://blog.cloudflare88.eu.org/posts/she/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/she/</guid><description>She is the legend, the legend is she.</description><pubDate>Sat, 04 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qualcomm Snapdragon X2 Elite Reference Design 圖片，原圖片由&lt;a href=&quot;https://www.pcmag.com/news/first-tests-qualcomms-snapdragon-x2-elite-extreme-shows-some-serious-speed#specs-how-the-snapdragon-x2-shapes-up-in-the-stack&quot;&gt;PCMag&lt;/a&gt; 提供，美國高通公司版權所有;&lt;/li&gt;
&lt;li&gt;Qualcomm Snapdragon X Elite Reference Demo 圖片 ，原圖片由&lt;a href=&quot;https://www.cnx-software.com/2023/10/31/qualcomm-snapdragon-x-elite-soc-benchmarks-in-windows-and-linux/&quot;&gt;CNX Software – Embedded Systems News&lt;/a&gt; 提供，美國高通公司版權所有；&lt;/li&gt;
&lt;li&gt;Qualcomm Snapdragon X2 Elite 跑分結果，由&lt;a href=&quot;https://www.windowscentral.com/hardware/qualcomm/snapdragon-x2-elite-extreme-vs-apple-m4-pro-max&quot;&gt;Windows Central&lt;/a&gt; 提供，Windows Central 版權所有；&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://3d.nicovideo.jp/works/td91904&quot;&gt;Iochi Mari&lt;/a&gt; （伊落瑪麗）人物模型，Nexon Co., Ltd 版權所有；&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linuxblog.io/pinebook-pro-my-first-impressions-and-setup-tips/&quot;&gt;PineBook Pro&lt;/a&gt; 圖片，Linuxblog 版權所有;&lt;/li&gt;
&lt;li&gt;She，Groove Coverage 版權所有
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/XQ1v9ZCcJvg?si=V_qzj8PZ53ebopN-&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;She appears everyday during exhibition, &amp;lt;/br&amp;gt;
Doing some Geekbench, then fallin&apos; asleep &amp;lt;/br&amp;gt;
She is so beautiful when she lying on the desk, &amp;lt;/br&amp;gt;
Nobody ever put a ring on her hand &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/x2elite-crd.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;Running virtual machines, compiling kernel &amp;lt;/br&amp;gt;
She is the legend, the legend is she &amp;lt;/br&amp;gt;
She sings to Stallman and Torvalds in Finland, &amp;lt;/br&amp;gt;
Contributing to Open-Source, you aren&apos;t supposed to ask why &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;She is the one that you never forget, &amp;lt;/br&amp;gt;
She is the Ferrari-made laptop you met &amp;lt;/br&amp;gt;
Oh, she must be the reason why you fall into love for snaptii &amp;lt;/br&amp;gt;
She&apos;ll always help you, no matter you want &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 4&lt;/h1&gt;
&lt;p&gt;She has a trackpad, and privacy switches &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/crd-trackpad.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;She appears in the morning, and the dusk she&apos;s gone &amp;lt;/br&amp;gt;
Every little hour every seconds we met, &amp;lt;/br&amp;gt;
Privacy is the eternity, that&apos;s what she gives &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 5&lt;/h1&gt;
&lt;p&gt;She looks like Pinebook, from PINE64 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/pinebook-pro-laptop.jpg&quot; alt=&quot;Pinebook Pro&quot; /&gt;&lt;/p&gt;
&lt;p&gt;She&apos;s trackpad like MacBook, but it&apos;s bigger than Mac&apos;s &amp;lt;/br&amp;gt;
She wins everything that we mignt do &amp;lt;/br&amp;gt;
She&apos;ll always help you, no matter you want &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
She is the one that you never forget, &amp;lt;/br&amp;gt;
She is the Ferrari-made laptop you met &amp;lt;/br&amp;gt;
Oh, she has 18 cores and 64 Gigabytes of RAM, &amp;lt;/br&amp;gt;
She&apos;ll always help you, no matter you want &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Oh, she looks so pretty, ahead of her time &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/single-core-benchmark.png&quot; alt=&quot;Geekbench single-core CPU benchmark result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/multi-core-benchmark.png&quot; alt=&quot;Geekbench multi-core CPU benchmark result&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Part 6&lt;/h1&gt;
&lt;p&gt;She is so powerful, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/gpu-benchmark.png&quot; alt=&quot;3DMark GPU benchmark result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Protecting my privacy, like what I said: &amp;lt;/br&amp;gt;
&quot;She is ahead of her era&quot; &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 7&lt;/h1&gt;
&lt;p&gt;She is the one that you never forget, &amp;lt;/br&amp;gt;
She is the Ferrari-made laptop you met &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/npu-benchmark.webp&quot; alt=&quot;Procyon AI Compute benchmark result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Oh, she must be the reason why you fall into love for snaptop &amp;lt;/br&amp;gt;
She&apos;ll always help you, no matter you want &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 8&lt;/h1&gt;
&lt;p&gt;(She is the one---) She is the one (That you never forget) that you never forget, &amp;lt;/br&amp;gt;
She is the Ferrari-made laptop you met &amp;lt;/br&amp;gt;
She&apos;s the reason (Oh, she must be the reason) why you fall into love for snaptii &amp;lt;/br&amp;gt;
She&apos;ll always help you, no matter you want &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Ending&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Nah--nah-nah--nah-nah-nah--nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah--nah-nah--nah-nah-nah--nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah-nah-nah-nah-nah-nah----nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah-nah-nah-nah-nah-nah-nah-nah---nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nah--nah-nah--nah-nah-nah--nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah--nah-nah--nah-nah-nah--nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah-nah-nah-nah-nah-nah----nah-nah-nah-nah&lt;/em&gt; &amp;lt;/br&amp;gt;
&lt;em&gt;Nah-nah-nah-nah-nah-nah-nah-nah---nah-nah...&lt;/em&gt; &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Snaptop Trouble (Feat. Nile Oryon) -- A FOSS Parody of Trouble by Dogena &amp; Karin Andersson</title><link>https://blog.cloudflare88.eu.org/posts/snaptop-trouble/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/snaptop-trouble/</guid><description>Little Snaptop, big trouble...</description><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qualcomm Snapdragon X2 Elite Reference Design 圖片，原圖片由&lt;a href=&quot;https://www.pcmag.com/news/first-tests-qualcomms-snapdragon-x2-elite-extreme-shows-some-serious-speed#specs-how-the-snapdragon-x2-shapes-up-in-the-stack&quot;&gt;PCMag&lt;/a&gt; 提供，美國高通公司版權所有;&lt;/li&gt;
&lt;li&gt;Qualcomm Snapdragon X Elite Reference Demo 圖片 ，原圖片由&lt;a href=&quot;https://www.cnx-software.com/2023/10/31/qualcomm-snapdragon-x-elite-soc-benchmarks-in-windows-and-linux/&quot;&gt;CNX Software – Embedded Systems News&lt;/a&gt; 提供，美國高通公司版權所有；&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://3d.nicovideo.jp/works/td91904&quot;&gt;Iochi Mari&lt;/a&gt; （伊落瑪麗）人物模型，Nexon Co., Ltd 版權所有；&lt;/li&gt;
&lt;li&gt;Trouble (Feat. Karin Andersson)，Dogena Music 版權所有；&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/snaptop-trouble/&quot;&gt;本文歌詞&lt;/a&gt;，由 Nile Oryon 和 EDKPiepaint 持有版權和著作權
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/2fBOmKdvq1U?si=VsWsqEEKIGcsw35o&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;In the world I came, &amp;lt;/br&amp;gt;
Made my mind a little different, &amp;lt;/br&amp;gt;
And I, modded my phone &amp;lt;/br&amp;gt;
Flash new ROMs, double the fun &amp;lt;/br&amp;gt;
But I always want a snaptop in my life, &amp;lt;/br&amp;gt;
Fell into imagination, and got me into trouble  &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mari-with-x2elite-crd.png&quot; alt=&quot;Iochi Mari setting on a Snapdragon X2 Elite CRD&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;I bricked my MacBook, &amp;lt;/br&amp;gt;
That got me into trouble &amp;lt;/br&amp;gt;
I don&apos;t know &lt;a href=&quot;https://blog.cloudflare88.eu.org/posts/snaptop/&quot;&gt;snaptops&lt;/a&gt;, will they barely meet my requirements, &amp;lt;/br&amp;gt;
But there ain&apos;t no other laptops, &amp;lt;/br&amp;gt;
That make me feel like Mac&apos;s do.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Fell into imagination, and got me into trouble  &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;When I received my laptop, &amp;lt;/br&amp;gt;
That I brought at heavy cost, &amp;lt;/br&amp;gt;
Now I, modding firmware &amp;lt;/br&amp;gt;
Installing Linux, &amp;lt;/br&amp;gt;
Double its fun &amp;lt;/br&amp;gt;
When I found speaker doesn&apos;t work, &amp;lt;/br&amp;gt;
Started to research, and got into trouble &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 4&lt;/h1&gt;
&lt;p&gt;Oh my Oryon, you got me into trouble &amp;lt;/br&amp;gt;
For my secutiry, try to activite your hypervisor &amp;lt;/br&amp;gt;
&lt;a href=&quot;https://github.com/TravMurav/slbounce&quot;&gt;But after a green rectangle, there&apos;s nothing I can do&lt;/a&gt; &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 5&lt;/h1&gt;
&lt;p&gt;Don&apos;t leave me alone, with you my troubles are all gone &amp;lt;/br&amp;gt;
You&apos;ll be fixed, when I write my patches &amp;lt;/br&amp;gt;
And I-I-I... &amp;lt;/br&amp;gt;
Started to study, and joined community &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
스냅탑(Snaptop) &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>--Warrior -- A FOSS Parody of Closer by The Chainsmokers (Unfinished)</title><link>https://blog.cloudflare88.eu.org/posts/warrior/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/warrior/</guid><description>--Warrior is a misspelled flag &quot;-Werror&quot; in GCC. I got inspired from Raiders by Redstone Records, which is also inspired from Closer, too.</description><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;（寫於2022年5月）&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/274720380&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/thechainsmokers&quot; title=&quot;The Chainsmokers&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;The Chainsmokers&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/thechainsmokers/closer&quot; title=&quot;Closer (feat. Halsey)&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Closer (feat. Halsey)&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/305769936&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/xxalienkiller1-dude1xx&quot; title=&quot;XxAlienKillerxX&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;XxAlienKillerxX&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/xxalienkiller1-dude1xx/raiders-minecraft-parody-of-closer-by-the-chainsmokers&quot; title=&quot;♪Raiders - Minecraft Parody Of Closer By The Chainsmokers ♫&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;♪Raiders - Minecraft Parody Of Closer By The Chainsmokers ♫&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/--Warrior%20--%20A%20FOSS%20parody%20of%20Closer%20.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio element.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;Hey, you&apos;re all acting so weak until I found you, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Can&apos;t even compile, and that&apos;s the issue &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Now it&apos;s OK, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Hey, we tell Android it was nice to meet you, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;But I&apos;ll guess we&apos;ll never see you again. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We wish upon the stars, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Crossed through the distros without singing march, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And through years we fall, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Now I&apos;m getting stronger with FOSS power, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And I, I, I, I, I, can&apos;t stop. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;No I, I, I, I, I, can&apos;t stop. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Our enemies will cower, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;From my large forces and power, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We&apos;re equipped with mainline kernel, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And tons of open-source softwares, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;An army of upstream patches, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And powerful hardware too, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We are always getting stronger, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. (3×, with dance music in between)&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;We, blew them up like the frail, without truth,&lt;/p&gt;
&lt;p&gt;Victory is that what seems true, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And we won&apos;t fail. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Slay, insert floppy disks to my PC, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;That we won&apos;t forget in time long, OKAY. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We wish upon the stars, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Crossed through the distros without singing march, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And through years we fall, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Now I&apos;m getting stronger with FOSS power, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And I, I, I, I, I, can&apos;t stop. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;No I, I, I, I, I, can&apos;t stop. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Our enemies will cower, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;From my large forces and power, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We&apos;re equipped with mainline kernel, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And tons of open-source softwares, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;An army of upstream patches, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And powerful hardware too, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We are always getting stronger, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;Our enemies will cower, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;From my large forces and power, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We&apos;re equipped with mainline kernel, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And tons of open-source softwares, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;An army of upstream patches, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;And powerful hardware too, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;We are always getting stronger, &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;vevib fktizwv dv&apos;iv tvggrmt yvggvi. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;45 76 65 72 79 20 75 70 67 72 61 64 65 20 77 65 27 72 65 20 67 65 74 74 69 6e 67 20 62 65 74 74 65 72 2e&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;vevib fktizwv dv&apos;iv tvggrmt yvggvi. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;vevib fktizwv dv&apos;iv tvggrmt yvggvi. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Every upgrade we&apos;re getting better. &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Snaptop</title><link>https://blog.cloudflare88.eu.org/posts/snaptop/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/snaptop/</guid><description>Qfhg z mlinzo dliw wvurmrxzgrlm...</description><pubDate>Thu, 02 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Snaptop&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Noun&lt;/em&gt; (plural Snaptops, Snaptii) &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;A laptop in classic form factor or 2-in-1 detachable devices that shipped with a Qualcomm Snapdragon processor.&lt;/p&gt;
&lt;h2&gt;Etymology&lt;/h2&gt;
&lt;p&gt;A blend of &lt;em&gt;Snapdragon&lt;/em&gt; (Qualcomm&apos;s ARM-based processor designed for phones and computers) and &lt;em&gt;laptop&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Spanish&lt;/h2&gt;
&lt;h2&gt;Etymology&lt;/h2&gt;
&lt;p&gt;Unadapted bororrowing from English &lt;em&gt;Snaptop&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;Translations&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Translation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Abkhaz&lt;/td&gt;
&lt;td&gt;Аснаптоп&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arabic&lt;/td&gt;
&lt;td&gt;سنابتوب&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bulgarian&lt;/td&gt;
&lt;td&gt;Снапшот&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chinese (Traditional)&lt;/td&gt;
&lt;td&gt;驍龍本；驍龍筆記本；驍龍筆電&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chinese (Simplified)&lt;/td&gt;
&lt;td&gt;骁龙本；骁龙笔记本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Czech&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Danish&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dutch&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estronian&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finnish&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;French&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;German&lt;/td&gt;
&lt;td&gt;Snaptop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;Further Reading&lt;/h1&gt;
&lt;p&gt;くちひにすいはひきり んひとす たすはきいこりすた つり そみははひこち とこい といすす はこときまみいす みちた んひちくのる ひ なみた きこ きいすみき きなすつ みは はすいひこくは みせみたすつひせ はくらてすせきはる まなみき こちせす らいこくかなき つす てこり なみた ちこま らすせこつす きここんは とこい すみいちひちか かいみたすは きこ はすせくいす つり かいみたくみきひこちね みちた んみきすいね とこい はすせくいひちか み てこら ひち きなす まこいさそんみせする&lt;/p&gt;
</content:encoded></item><item><title>跨平臺桌寵軟體—— XR Animator，讓妳最喜歡的動漫角色動起來！支援動態捕捉和AR...</title><link>https://blog.cloudflare88.eu.org/posts/xr-animator/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/xr-animator/</guid><description>網課時的摸魚神器！還有... SD X2 Elite 的參考設計原型機好好看！</description><pubDate>Thu, 02 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;assets/mari-with-x1e78100-crd.png&quot; alt=&quot;Iochi Mari setting on a sign with two Snapdragon X Elite CRDs near by&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note
本文包含部分受版權保護的內容，您在轉載本文章時，請不要包含這些內容。除非您已經事先申請，且版權所有者已同意授權。&amp;lt;/br&amp;gt;
受版權保護的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qualcomm Snapdragon X2 Elite Reference Design 圖片，原圖片由&lt;a href=&quot;https://www.pcmag.com/news/first-tests-qualcomms-snapdragon-x2-elite-extreme-shows-some-serious-speed#specs-how-the-snapdragon-x2-shapes-up-in-the-stack&quot;&gt;PCMag&lt;/a&gt; 提供，美國高通公司版權所有;&lt;/li&gt;
&lt;li&gt;Qualcomm Snapdragon X Elite Reference Demo 圖片 ，原圖片由&lt;a href=&quot;https://www.cnx-software.com/2023/10/31/qualcomm-snapdragon-x-elite-soc-benchmarks-in-windows-and-linux/&quot;&gt;CNX Software – Embedded Systems News&lt;/a&gt; 提供，美國高通公司版權所有；&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://3d.nicovideo.jp/works/td91904&quot;&gt;Iochi Mari&lt;/a&gt; （伊落瑪麗）人物模型，Nexon Co., Ltd 版權所有
:::
XR Animator是一個支援Linux、Windows、macOS的開源桌寵軟體，可以在桌面放3D模型，讓他/她與妳打招呼。內建採用了&lt;a href=&quot;https://github.com/google/mediapipe&quot;&gt;MediaPipe&lt;/a&gt;和&lt;a href=&quot;https://github.com/tensorflow/tfjs-models&quot;&gt;TensorFlow&lt;/a&gt;機器學習技術的動態捕捉，能夠實時偵測到人體的動作，並將其轉化爲人物模型的動作。
比起其他需要專業裝置才能進行身體動作的捕捉，XR Animator 只需要使用者有一個支援720P解析度的攝像機即可。如果作業系統不支援，亦可以通過&lt;a href=&quot;https://sao.animetheme.com/XR_Animator.html&quot;&gt;這裏&lt;/a&gt;來存取網頁版，如果手機是 Android 或 iPhone，還可以通過AR技術將人物放置於真實的世界中，與她們進行互動！&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;下載 XR Animator&lt;/h1&gt;
&lt;p&gt;XR Animator 是開源軟體，其原始碼可於&lt;a href=&quot;https://github.com/ButzYung/SystemAnimatorOnline&quot;&gt;Github&lt;/a&gt;取得，或點擊下面的鏈接卡片：&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;ButzYung/SystemAnimatorOnline&quot;}&lt;/p&gt;
&lt;p&gt;根據自己的作業系統，選擇合適的文件下載。需要注意的是，雖然僅提供了 64位元&lt;code&gt;X86&lt;/code&gt; 架構的安裝檔，Windows 版的亦可以在 Windows On ARM 裝置上執行，而 Linux 需要使用 &lt;code&gt;Box64&lt;/code&gt; 轉譯。&amp;lt;/br&amp;gt;
程式設定非常簡單，例如我是 Gentoo Linux 只需解壓歸檔，然後通過 &lt;code&gt;chmod +x&lt;/code&gt; 賦予程式可執行權限，最後雙擊 &lt;code&gt;electron&lt;/code&gt; 來打開程式即可！&lt;/p&gt;
&lt;h1&gt;基本用法&lt;/h1&gt;
&lt;p&gt;程式打開後，將妳的模型（需包含有&lt;code&gt;.pmx&lt;/code&gt; 檔的ZIP壓縮文件）直接拖入窗口，然後按下“START”來啓動！（沒有模型就跳過這個步驟）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/mainlol.png&quot; alt=&quot;Main screen of XR Animator&quot; /&gt;&lt;/p&gt;
&lt;p&gt;現在可以和人物互動了，比如點一下腳就會跌倒、點一下人物的胸部或是其他部位就會看到用手遮擋的動作（好色哦嘿嘿嘿）......點二下重置鏡頭，右鍵拖曳視窗位置。按住Ctrl鍵與滑鼠左鍵可以轉動和移動人物，使用滾輪則是放大和縮小人物，便於看清人物的細節。(?)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/main-lol.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/falling-character.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;點下方的姿勢按鈕能夠切換許多動作～還能將動作儲存起來。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/action-menu.png&quot; alt=&quot;Action menu&quot; /&gt;&lt;/p&gt;
&lt;p&gt;系統匣的選單也有很多光影選項能開，可以讓模型更好的融入背景。不過這就會額外耗費顯示卡計算資源了，繪圖卡不好的電腦別開太高級的光影選項。點選Always on Top將視窗永遠置頂。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/extra-menu.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;設定動作捕捉&lt;/h1&gt;
&lt;p&gt;可以使用攝像頭進行實時的動作捕捉，亦可以通過載入單張照片來使人物做出想要的姿勢。某些動作後面會有對應的表情展示，來讓妳來決定是進行全身捕捉或半身捕捉。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/action-menu.png&quot; alt=&quot;Action menu&quot; /&gt;&lt;/p&gt;
&lt;p&gt;首先，設定要使用的照相機，按一下工具列的“相機”設定，在對話框中選擇妳的相機。然後點選“動作”設定，選擇第三個，按一下“動態捕捉”設定身體部分。之後人物會根據妳的面部表情和動作跟着反應了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/motion-test.jpg&quot; alt=&quot;A body tracking demostration&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/motion-demo.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;手機上使用 AR&lt;/h1&gt;
&lt;p&gt;準備 Android 或者 Linux 手機，然後前往&lt;a href=&quot;https://sao.animetheme.com/XR_Animator.html&quot;&gt;這裏&lt;/a&gt; 用法與電腦版一致，點一下左上角的手機圖標進入AR模式，注意場景儘量比較複雜些，否則人物很難顯示出來。&amp;lt;/br&amp;gt;
工具列裡面有接球遊戲，至少要站離模型5公尺遠才能玩！&lt;/p&gt;
</content:encoded></item><item><title>Fancy Phones &amp; Laptops -- A FOSS Parody of Fast Cars &amp; Superstars by Cristian Marchi</title><link>https://blog.cloudflare88.eu.org/posts/fast-phone-and-laptops/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/fast-phone-and-laptops/</guid><description>在 Nothing Phone 上編譯 Linux 核心真是好啊！</description><pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/JrW5fuDmblk?si=XW_v8N3JaN6IQMmQ&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;When the phone begins heating, lying on the desk &amp;lt;/br&amp;gt;
Wait for some time, and show me some logs &amp;lt;/br&amp;gt;
I wanna get everybody shocked, Linux goes first &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;When the phone begins heating, lying on the desk &amp;lt;/br&amp;gt;
Wait for some time, and show me some logs &amp;lt;/br&amp;gt;
I wanna get everybody shocked, Linux goes first &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Grab another cable, reading logs from console &amp;lt;/br&amp;gt;
Fancy phones, laptops, leave my home tomorrow &amp;lt;/br&amp;gt;
Grab another cable, reading logs from console &amp;lt;/br&amp;gt;
Fancy phones, laptops, leave my home tomorrow &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Hook&lt;/h1&gt;
&lt;p&gt;Fancy--phones &amp;lt;/br&amp;gt;
Fancy phones, &amp;lt;/br&amp;gt;
Laptops, &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Bridge&lt;/h1&gt;
&lt;p&gt;One...up...up in the club &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Verse&lt;/h1&gt;
&lt;p&gt;When the phone begins heating, lying on the desk &amp;lt;/br&amp;gt;
Wait for some time, and show me some logs &amp;lt;/br&amp;gt;
I wanna get everybody shocked, Linux goes first &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;When the phone begins heating, lying on the desk &amp;lt;/br&amp;gt;
Wait for some time, and show me some logs &amp;lt;/br&amp;gt;
I wanna get everybody shocked, Linux goes first &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Chorus&lt;/h1&gt;
&lt;p&gt;Grab another cable, reading logs from console &amp;lt;/br&amp;gt;
Fancy phones, laptops, leave my home tomorrow &amp;lt;/br&amp;gt;
Grab another cable, reading logs from console &amp;lt;/br&amp;gt;
Fancy phones, laptops, leave my home tomorrow &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Outro&lt;/h1&gt;
&lt;p&gt;Fancy--phones &amp;lt;/br&amp;gt;
Fancy phones, &amp;lt;/br&amp;gt;
Laptops, &amp;lt;/br&amp;gt;
And Let me see your faces, and turn the cooler on &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Nothing Phone Funk -- A FOSS Parody of VOLKSWAGEN FUNK by NVRXMARV and LXSTUR</title><link>https://blog.cloudflare88.eu.org/posts/nothing-phone-funk/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/nothing-phone-funk/</guid><description>Copy Nothing.</description><pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Yh--1hvAC5Y?si=h7Lc5FlAVTUYHnNp&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;Nothing Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Nothing Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone, Phone, Phone &amp;lt;/br&amp;gt;
Phone, Phone &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Ph-one-one-one-one- &amp;lt;/br&amp;gt;
Ph-one-one-one-one- &amp;lt;/br&amp;gt;
Ph-one-one-one-one- &amp;lt;/br&amp;gt;
Ph-one-one-one-one- &amp;lt;/br&amp;gt;
One-one-one-one-one- &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Not-Not- &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hi-hi-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;
-hing-hing-hing-hing-hing &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>逃離來自政府或網路的監視——個人如何最大程度的避免被追蹤，保護妳的信息安全</title><link>https://blog.cloudflare88.eu.org/posts/escape-from-tracking/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/escape-from-tracking/</guid><pubDate>Sat, 16 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::warning[中國大陸的閱讀者請注意]
本文包含部分（或全部包含）政治類話題，以及一些其牠具有爭議性的，或者因爲當地的內容審查政策而不予通過的內容。儘管本部落格已被GFW所封鎖，但部分專業讀者仍有能力訪問本部落格。在此鄭重提醒：&lt;strong&gt;如果您是&lt;a href=&quot;https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E7%B2%89%E7%B4%85&quot;&gt;極端愛國主義者，或者具有排外主義立場的人，亦或是熱衷於在網路上攻擊異議人士的人&lt;/a&gt;，請立即關閉本網站&lt;/strong&gt;！！！
:::&lt;/p&gt;
&lt;h1&gt;發送圖片前，請三思而後行&lt;/h1&gt;
&lt;p&gt;是的，不僅僅是考慮要發送的內容如何，更要考慮這些圖片是否會包含有版權、拍攝時間、以及拍攝地點的信息。如果妳個人經常研究灰色地帶的東西，例如盜版與色情學，這些東西往往是爭議很大，又或者是十分危險的思想和工具，這種時候，消除圖片中的個人信息就顯得非常有必要。&amp;lt;/br&amp;gt;
妳可能會問，我的圖片中沒有出現任何有關個人信息的物件（例如：護照、簽證、國家政府頒發的身份證等），為什麼還會被網站追蹤到？這是因為，妳的手機或者相機在拍攝照片的時候，會生成一個&lt;a href=&quot;https://zh.wikipedia.org/wiki/Exif&quot;&gt;EXIF&lt;/a&gt;數據文件，牠記錄了數位相機拍攝照片的快門速度、以及位置。而這些信息就可以成為政府部門和網站追蹤妳的“鑰匙”。因此在發布照片或影片前，一定要&lt;a href=&quot;https://jimpl.com/remove-exif/&quot;&gt;消除照片或影片的EXIF數據&lt;/a&gt;，這樣能夠減少個人信息被外泄的可能。&lt;/p&gt;
&lt;h1&gt;一定要使用 GNU/Linux 作業系統和自由軟體&lt;/h1&gt;
&lt;p&gt;就像我早就講過的，專有軟體，也稱為非自由軟體，表示該軟體不尊重使用者和社群的自由。專有程式把開發者或著作權人的權力地位架在使用者之上。而且專有軟體常常內建追蹤器（比如 Google 的 Firebase）牠們無時無刻不在蒐集使用者的隱私。例如現在使用最廣的 Windows 和 ChromeOS 就是兩個典型的“間諜軟體”。而自由軟體則不會內建追蹤器，GNU/Linux 更不會內建追蹤器。因此，只有使用自由軟體，才能保證自己的隱私牢牢的掌握在自己的手裡。當然，如果覺得 Linux 和自由軟體還不夠用，那還可以考慮給自己的電腦硬碟配置 LUKS 全盤加密，亦可以通過核心自帶的“DM-Verity”功能配置DM驗證。至於應用層面，我們可以使用 SELinux 或者 Apparmor 加強安全性。實在放心不下的話，就選用 Linux-libre 核心，牠拔掉了所有的專有硬體驅動和專有的二進位執行檔。在硬體上，儘量選擇2022年後的主流硬體配置，尤其是Intel的CPU最為安全。因為Intel CPU 從8代Core 處理器後，於CPU內建TPM 2.0硬體加密功能，這在某些禁止使用境外研製的密碼產品的地區和國家非常有用。&lt;/p&gt;
&lt;h1&gt;使用虛擬機、或者容器技術&lt;/h1&gt;
&lt;p&gt;如果執意要使用諸如 Windows、ChromeOS 之類的封閉原始碼的作業系統，那麼使用虛擬機就是一個比較不錯的選擇。因為虛擬機中的數據可通過類似於“快照”的功能進行回溯，在虛擬機中安裝自由的 GNU/Linux 或者其他作業系統的一份乾淨的拷貝，將隱私相關的數據放到虛擬機上。一旦意識到自己的隱私或其牠與個人相關聯的信息可能被泄漏，就立即通過快照回溯虛擬機的狀態，或者直接刪除虛擬機，並用隨機數據覆寫虛擬機的虛擬硬碟檔案。如果電腦的硬體太差，或者裝置不支援虛擬機怎麼辦？那就改用容器，像是 LXC 或者 Docker 之類，直接刪除容器就可以了。&lt;/p&gt;
&lt;h1&gt;使用臨時郵箱存取線上服務&lt;/h1&gt;
&lt;p&gt;在某個線上網站搜尋了 ESP32單片機，之後郵箱中全是ESP32相關的內容和垃圾訊息？這種現象早已屢見不鮮。若是受工作需要或是學業原因被迫到某個網站註冊賬號，存取相關內容，那麼妳可以通過臨時電郵來解決。與正常的電子郵箱不同，牠會在1小時後被銷毀。使用臨時電郵，可以有效避免垃圾訊息的煩惱，也可以起到保護個人隱私的效果。&lt;/p&gt;
&lt;h1&gt;避免中國產Android 手機&lt;/h1&gt;
&lt;p&gt;由於政府要求和嚴格的審查制度，中國大陸的Android系統的安全性呈現出前所未有的畸形發展。其畸形主要體現在無論硬體、作業系統，還是軟體，每個環節都會出於自身對於利益的期待而獲取更多的使用者的個人數據，同時，這些開發者也會為了配合政府的要求，主動在軟體和硬體上開後門，用以配合公安機關的數字取證。但是，這些開發者們為了保護自己，便又“一視同仁”地對第三方應用實行嚴格的權限管控。因此，手機廠商、作業系統開發者、第三方軟體開發者之間便會有利益衝突，自然就會有矛盾產生，這是不可避免的。使用者就可以利用三者之間的矛盾找到“突破口”，在這個不安全的軟體環境中保護自己的隱私。由於中國大陸長期由GFW封鎖網際網路，以及非常嚴格的審查政策，使得使用者不得不”瞞天過海“。這樣子，一些資本公司靠着高科技手段成為了告密者、檢舉人、網路服務商、晶片供應商、作業系統開發者。為了有自己的利益，還會第一時間響應政府的政策。在這種環境下，這些中國產 Android 手機便會加入追蹤器和間諜軟體用於監控通話記錄和短信記錄，將使用者的資料蒐集並發送給政府。&lt;/p&gt;
&lt;h1&gt;不要使用生物解鎖來解鎖手機&lt;/h1&gt;
&lt;p&gt;對於手機而言，永遠不要使用指紋和面部解鎖，因為手機的韌體大多都是封閉原始碼的，開發者和廠家就有可能蒐集妳的生物層面的信息。想要消除生物層面的信息泄漏幾乎是不可能的，一旦軟體有後門，那麼任何人都可以通過取證裝置來取得並分析手機上的數據，即使數據已經被刪除或被加密。對於中國產晶片就要更加小心，使用三星或是高通的晶片可以降低隱私泄漏後的風險。如果妳因為工作或是其他原因不得不接觸或是使用這些採用中國產的晶片的裝置，或是大陸公司定製的客制化韌體，一定不能在上面存取個人隱私相關的數據，因為泄漏後信息的取證是必然的。如果意識到信息可能（或已經）泄漏，此時最好的辦法就是採取妥善的方法於物理層面的銷毀裝置和數據。一個行之有效的方法是將主機板取出並焚燒，或是使用強力來破壞主機板上面的晶片和快閃記憶體晶片。如果無法完全銷毀裝置，就將其放入屏蔽裝置中（如微波爐、信號屏蔽器）並使其電源失效。例如取下裝置的電池、破壞供電部分等。這是因為有些裝置即使在關機狀態下，依然維持着向外界發送信息的能力。&lt;/p&gt;
&lt;h1&gt;選擇可以解鎖的手機&lt;/h1&gt;
&lt;p&gt;擺脫廠商的追蹤和隱私泄漏的最好辦法，就是刷機替換廠商的韌體。但是，隨着個大手機品牌逐漸禁止自己的手機解鎖，刷機的窗口也越來越窄。國內不讓解鎖的品牌有小米、一加、華碩之類。國外不讓解鎖的有三星...... 目前唯一能夠解鎖的手機，只剩下了索尼、谷歌、Nothing、還有摩托羅拉，以及其他不知名的手機。建議選擇可以解鎖的手機，這樣就可以刷其他開源的韌體，甚至有機會使用 GNU/Linux 和自由軟體，並以此來保護自己的隱私，將隱私權牢牢地攥在自己的手裡。&lt;/p&gt;
&lt;h1&gt;使用 Tor 與匿名網路&lt;/h1&gt;
&lt;p&gt;在日常上網的過程中，如果妳擔心自己的行蹤被政府或網站追蹤，那麼 Tor（The Onion Router）就是一個必不可少的工具。Tor 透過「洋蔥路由」技術，將妳的網路請求經過多層節點加密與轉發，讓監控者難以追蹤來源。除了 Tor Browser，妳還可以考慮 Tails 這樣的作業系統，牠預設所有流量都會走 Tor，並且在關機後不會留下任何痕跡。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;不過，使用 Tor 也有幾點需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不要在 Tor 中登入與自己真實身份綁定的帳號（例如 Gmail、Facebook）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;避免下載並直接打開檔案，特別是 PDF 和 DOCX，這些檔案可能包含追蹤腳本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果需要更高安全性，可以考慮使用 Tor over VPN 或 VPN over Tor 的方式，以降低流量被辨識的風險。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;使用加密通訊工具&lt;/h1&gt;
&lt;p&gt;傳統的簡訊與大部分即時通訊軟體（例如 微信、Line、Messenger）並不提供真正的端對端加密，伺服器與政府部門都有能力攔截與監控內容。尤其是微信，其伺服器被政府所掌控。為了保障隱私，應該優先使用 Signal、Session 或 Briar 等開源、端對端加密的軟體。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Signal：支援 iOS、Android 與桌面端，使用電話號碼註冊，但對話內容不可被伺服器讀取。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Session：無需電話號碼，透過去中心化伺服器網路傳輸訊息，適合更高隱私需求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Briar：不依賴伺服器，支援藍牙與 Wi-Fi Direct 傳輸，適合在網路完全斷開的環境下使用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;避免使用以「方便」為賣點但閉源的通訊工具，因為牠們往往在背景蒐集使用者資料。&lt;/p&gt;
&lt;h1&gt;減少真實身份與網路身份的關聯&lt;/h1&gt;
&lt;p&gt;網路上的大多數追蹤，其實來自於「身份綁定」：&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用相同的電話號碼、郵箱來註冊不同網站。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在論壇或社群中使用相同的暱稱。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;於不同平台重複發布相同的文字或圖片。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，要做到建立不同的“數位身份”且每個身份不能相互關聯。對於有着嚴格的審查制度的地區，則需要做到&lt;strong&gt;內外分離、風格獨立&lt;/strong&gt;——“內外分離”是指做到審查制度之內與審查制度之外的賬號暱稱、地址、個人信息完全獨立；“風格獨立”是指審查制度之外的賬號留言語氣、文風完全不同於審查制度之內的賬號。這樣才能降低個人隱私泄漏的和被追蹤可能。還可以避免被熟人檢舉。如果認為自己的信息已經泄漏，就立即註銷賬號。&lt;/p&gt;
&lt;h1&gt;總結&lt;/h1&gt;
&lt;p&gt;安全是相對的、動態的，攻擊也是相對的、動態的。而大多數情況下，普通人無法對抗政府或機構，最根本的原因是個人無法做到像政府或機構那樣有計劃、有預案、有機制、有組織、有系統。但是，儘管無法與強大的政府、機構所抗衡，如果將“對抗性思維”堅持到底亦可取得不錯的成果。很多人相信，手機如果被公安機關檢查，不配合就會有取證裝置取證。這是錯誤的。不是每個警視廳都會有取證裝置。因此，對於普通用戶而言，就要做到避免隱私泄漏、反偵察、對抗審查制度。如果想要反抗，並在暴露後將傷害最小化，就必須默認不信任任何人與裝置，即建立所謂的“零信任安全模型”。用不信任來研判風險，利用不同群體的利益矛盾保護自己。同時善用“暴露假說”來尋找解救方法，只有這樣，才可以在“不安全”中尋找安全，並獲得生存性，捍衛自己的數位人權。&lt;/p&gt;
</content:encoded></item><item><title>PostmarketOS 在 Nothing Phone 1 上的首秀</title><link>https://blog.cloudflare88.eu.org/posts/postmarketos-on-spacewar/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/postmarketos-on-spacewar/</guid><description>這是最漂亮的，性能最強悍的主線Linux 手機！</description><pubDate>Mon, 11 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;雖然 PostmarketOS 對我而言早就不是什麼新鮮的事物了，但是我依然喜歡刷機的樂趣，因為我深知：只有自由軟體才能真正的保護我的隱私，讓我擁有數位人權。這次在 Nothing Phone（1）上的 Linux 之旅也讓我收穫頗豐。&lt;/p&gt;
&lt;p&gt;:::note
本文僅代表作者（EDKPiepaint）個人及少數刷機和自由軟體愛好者的觀點，請不要參考。（是的，&lt;strong&gt;請不要參考&lt;/strong&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由於本文所使用的專業術語較多，對於沒有相關經歷的人而言，本文會比較晦澀難懂，請謹慎閱讀。如果妳是只會大喊大叫諸如”我不懂！“之類的話，並且會發火，還有種被人瞧不起的感覺的，或者是只會擺出架子（一些家長或者”老爺“最擅長這麼做）的人，我建議妳不要閱讀了。
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::warning[中國大陸的閱讀者請注意]
本文包含部分（或全部包含）政治類話題，以及一些其牠具有爭議性的，或者因爲當地的內容審查政策而不予通過的內容。儘管本部落格已被GFW所封鎖，但部分專業讀者仍有能力訪問本部落格。在此鄭重提醒：&lt;strong&gt;如果您是&lt;a href=&quot;https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E7%B2%89%E7%B4%85&quot;&gt;極端愛國主義者，或者具有排外主義立場的人，亦或是熱衷於在網路上攻擊異議人士的人&lt;/a&gt;，請立即關閉本網站&lt;/strong&gt;！！！
:::&lt;/p&gt;
&lt;h1&gt;主線核心的支援情況&lt;/h1&gt;
&lt;p&gt;Nothing Phone（1）採用的驍龍778G+ 晶片目前支援狀況良好。除去GPS以外的部分工作正常。&lt;a href=&quot;%5B%E5%8E%9F%E6%96%87%E8%A1%A8%E8%BF%B0%E7%82%BA%EF%BC%9A%E2%80%9C%E6%9C%AC%E8%A3%9D%E7%BD%AE%E5%8F%AF%E4%BB%A5%E5%9F%B7%E8%A1%8CPostmarketOS%EF%BC%8C%E4%BD%86%E5%85%B6%E7%9B%B8%E9%97%9C%E4%BE%9D%E8%B3%B4%E8%BB%9F%E9%AB%94%E6%9C%AA%E9%80%B2%E5%85%A5%E5%A5%97%E4%BB%B6%E5%BA%AB%E2%80%9C%5D(https://wiki.postmarketos.org/wiki/Nothing_Phone_1_(nothing-spacewar))&quot;&gt;^1&lt;/a&gt;對於 Nothing Phone（1）本身而言，除去GPS、振動馬達、Glyph LED不工作以外，其餘部分良好。但聲音、藍牙部分需要自行修補才可以工作。&lt;/p&gt;
&lt;h1&gt;準備工作&lt;/h1&gt;
&lt;p&gt;PostmarketOS 的 GitLab上目前還沒有 Nothing Phone（1）的軟體包[^2]，這意味着想要構建PostmarketOS 的映像，我們就需要找到一個包含相關軟體的第三方 &lt;code&gt;pmaports&lt;/code&gt; 來進行後續操作。幸運的是，Wiki 下面就有這個 &lt;code&gt;pmaports&lt;/code&gt; 的&lt;a href=&quot;https://github.com/mainlining/pmaports/tree/danila/spacewar&quot;&gt;連結&lt;/a&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/wiki.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;執行 &lt;code&gt;git clone https://github.com/mainlining/pmaports.git&lt;/code&gt; 將這個 &lt;code&gt;pmaports&lt;/code&gt; 下載到本機，然後從裡面複製出兩個資料夾： &lt;code&gt;device-nothing-spacewar&lt;/code&gt; &lt;code&gt;firmware-nothing-spacewar&lt;/code&gt; 到任意位置。之後執行 &lt;code&gt;pmbootstrap init&lt;/code&gt; 設定存儲庫位置，設定版本為 &lt;code&gt;edge&lt;/code&gt; 分支，然後按下 &lt;code&gt;control-C&lt;/code&gt;終止程式。前往 &lt;code&gt;pmbootstrap&lt;/code&gt; 的工作目錄，將這兩個資料夾放到 &lt;code&gt;工作目錄/cache_git/pmaports/device/testing&lt;/code&gt; 目錄下，重新執行 &lt;code&gt;pmbootstrap init&lt;/code&gt;，繼續設定：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/pmbootstrap.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pmbootstrap init                         
[21:40:29] Location of the &apos;work&apos; path. Multiple chroots (native, device arch, device rootfs) will be created in there.
[21:40:29] Work path [/home/edkpiepaint/.local/var/pmbootstrap]: 
[21:40:31] Location of the &apos;pmaports&apos; path, containing package definitions.
[21:40:31] pmaports path [/home/edkpiepaint/.local/var/pmbootstrap/cache_git/pmaports]: 
[21:40:33] Choose the postmarketOS release channel.
[21:40:33] Available (12):
[21:40:33] * edge: Rolling release / Most devices / Occasional breakage: https://postmarketos.org/edge
[21:40:33] * v25.06: Upcoming stable release (DO NOT USE)
[21:40:33] * v24.12: Latest release / Recommended for best stability
[21:40:33] Channel [edge]: 
[21:40:35] NOTE: pmaports is on master branch, copying git hooks.
[21:40:35] Choose your target device vendor (either an existing one, or a new one for porting).
[21:40:35] Available vendors (96): acer, alcatel, amazon, amediatech, amlogic, apple, ark, arrow, asus, ayn, bananapi, barnesnoble, beelink, bq, clockworkpi, cubietech, cutiepi, dongshanpi, epson, essential, fairphone, finepower, fly, fxtec, generic, goclever, google, gp, hisense, htc, huawei, inet, infocus, jolla, khadas, klipad, kobo, lark, leeco, lenovo, lg, librecomputer, linksys, mangopi, medion, meizu, microsoft, mobvoi, motorola, nextbit, nothing, nobby, nokia, nvidia, odroid, oneplus, oppo, ouya, pine64, planet, pocketbook, postmarketos, powkiddy, purism, qcom, qemu, qualcomm, radxa, raspberry, realme, samsung, semc, sharp, shift, sipeed, solidrun, sony, sourceparts, surftab, t2m, thundercomm, tokio, tolino, trekstor, valve, vernee, vivo, volla, wexler, wiko, wileyfox, xiaomi, xunlong, yu, zte, zuk
[21:40:35] Vendor [xiaomi]: nothing
[21:40:36] Devices are categorised as follows, from best to worst:
* Main: ports where mostly everything works.
* Community: often mostly usable, but may lack important functionality.
* Testing: anything from &quot;just boots in some sense&quot; to almost fully functioning ports.
* Downstream: ports that use a downstream kernel — very limited functionality. Not recommended.

Available devices by codename (1): spacewar (testing)
[21:40:36] Device codename [spacewar]:           
[21:40:39] Username [litepiepaint]: 
[21:40:40] Available providers for postmarketos-base-ui-wifi (2):
[21:40:40] * wpa_supplicant: Use wpa_supplicant as the WiFi backend. (default)
[21:40:40] * iwd: Use iwd as the WiFi backend (but may not work with all devices)
[21:40:40] Provider [default]: 
[21:40:51] Available user interfaces (28): 
[21:40:51] * none: Bare minimum OS image for testing and manual customization. The &quot;console&quot; UI should be selected if a graphical UI is not desired.
[21:40:51] * asteroid: (Wayland) Smartwatch UI from AsteroidOS
[21:40:51] * bananui: (Wayland) Keypad controlled UI for feature phones
[21:40:51] * buffyboard: Plain framebuffer console with modern touchscreen keyboard support
[21:40:51] * cage: (Wayland) Kiosk WM
[21:40:51] * console: Console environment, with no graphical/touch UI
[21:40:51] * cosmic: COSMIC Desktop Environment from System76
[21:40:51] * fbkeyboard: Plain framebuffer console with touchscreen keyboard support
[21:40:51] * gnome: (Wayland) Gnome Shell
[21:40:51] * gnome-mobile: (Wayland) Gnome Shell patched to adapt better to phones (Experimental)
[21:40:51] * i3wm: (X11) Tiling WM (keyboard required)
[21:40:51] * kodi: (GBM) 10-foot UI useful on TV&apos;s
[21:40:51] * lomiri: (Wayland) The convergent desktop environment (Experimental)
[21:40:51] * lxqt: (X11) Lightweight Qt Desktop Environment (stylus recommended)
[21:40:51] * mate: (X11) MATE Desktop Environment, fork of GNOME2 (stylus recommended)
[21:40:51] * mediaberry: (Wayland) An open platform for streaming boxes and smart TVs (WIP)
[21:40:51] * moonlight: (Wayland) Open Source PC client for NVIDIA GameStream, as used by the NVIDIA Shield
[21:40:51] * niri: (Wayland) A scrollable-tiling compositor (DOES NOT RUN WITHOUT HW ACCELERATION!)
[21:40:51] * openbox: (X11) A highly configurable and lightweight X11 window manager (keyboard required)
[21:40:51] * os-installer: UI for installing postmarketOS
[21:40:51] * phosh: (Wayland) Mobile UI initially developed for the Librem 5
[21:40:51] * plasma-desktop: (X11/Wayland) KDE Desktop Environment (works well with tablets)
[21:40:51] * plasma-mobile: (Wayland) Mobile variant of KDE Plasma (does not run without hardware acceleration)
[21:40:51] * shelli: Plain console with touchscreen gesture support
[21:40:51] * sway: (Wayland) Tiling WM, drop-in replacement for i3wm (DOES NOT RUN WITHOUT HW ACCELERATION!)
[21:40:51] * sxmo-de-dwm: Simple Mobile: Mobile environment based on SXMO and running on dwm
[21:40:51] * sxmo-de-sway: Simple Mobile: Mobile environment based on SXMO and running on sway
[21:40:51] * weston: (Wayland) Reference compositor (demo, not a phone interface)
[21:40:51] * xfce4: (X11) Lightweight desktop (stylus recommended)
[21:40:51] User interface [plasma-mobile]: 
[21:40:52] This user interface has an extra package: Meta package for additional Plasma mobile apps
[21:40:52] Enable this package? (y/n) [y]: 
[21:40:53] Based on your UI selection, &apos;default&apos; will result in installing systemd.
[21:40:53] Install systemd? (default/always/never) [default]:   #如果啓動異常，在此處鍵入“never”來改爲使用 OpenRC 來初始化。
[21:40:54] Additional options: extra free space: 0 MB, boot partition size: 256 MB, parallel jobs: 2, ccache per arch: 5G, sudo timer: False, mirror: https://mirrors.aliyun.com/postmarketOS/
[21:40:54] Change them? (y/n) [n]: 
[21:40:54] Additional packages that will be installed to rootfs. Specify them in a comma separated list (e.g.: vim,file) or &quot;none&quot;
[21:40:54] Extra packages [nano]: 
[21:40:55] Your host timezone: Asia/Singapore    #設定時區
[21:40:55] Use this timezone instead of GMT? (y/n) [y]: 
[21:40:56] Choose your preferred locale, like e.g. en_US. Only UTF-8 is supported, it gets appended automatically. Use tab-completion if needed.
[21:40:56] Locale [en_US]: 
[21:40:56] Device hostname (short form, e.g. &apos;foo&apos;) [nothing-spacewar]:       #設定主機名稱 
[21:40:57] NOTE: No SSH public keys found to copy to the device.
[21:40:57] See https://postmarketos.org/ssh-key-glob for more information.
[21:40:57] After pmaports are changed, the binary packages may be outdated. If you want to install postmarketOS without changes, reply &apos;n&apos; for a faster installation.
[21:40:57] Build outdated packages during &apos;pmbootstrap install&apos;? (y/n) [y]: 
[21:40:58] Zap existing chroots to apply configuration? (y/n) [y]: 
[21:41:01] DONE!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，執行 &lt;code&gt;pmbootstrap install&lt;/code&gt; 來進行構建安裝映像。&lt;/p&gt;
&lt;h1&gt;解鎖&lt;/h1&gt;
&lt;p&gt;去&lt;a href=&quot;https://github.com/quintenvandamme/nothing_archive&quot;&gt;這裡&lt;/a&gt;下載一份 Nothing Phone（1）的韌體，以備不時之需。然後，前往 &lt;code&gt;設定--&amp;gt;系統---&amp;gt;開發人員選項--&amp;gt;OEM解鎖&lt;/code&gt;，啟用OEM解鎖，重新啟動手機至Bootloader模式，連接電腦，打開終端機，鍵入 &lt;code&gt;fastboot flashing unlock&lt;/code&gt; 手機會展示是否需要解鎖的畫面，選擇“UNLOCK BOOTLOADER” ， 按下電源鍵確認。之後手機會自動恢復工廠設定。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;quintenvandamme/nothing_archive&quot;}&lt;/p&gt;
&lt;h1&gt;刷機&lt;/h1&gt;
&lt;p&gt;之後，將手機重新啟動到 bootloader，在終端機執行如下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pmbootstrap flasher flash_kernel
pmbootstrap flasher flash_rootfs --partition userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因為 Nothing Phone 是 Android 手機，所以 PostmarketOS 的分割表也繼承自 Android 。刷機時將 rootfs 寫入 Android 的 &lt;code&gt;userdata&lt;/code&gt; 分割就好了。刷完後需要清除 &lt;code&gt;dtbo&lt;/code&gt; 分割並禁用 AVB 驗證。在禁用 AVB 驗證時需要使用原廠韌體的 &lt;code&gt;vbmeta&lt;/code&gt; 映像：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastboot --disable-verity flash vbmeta /path/to/vbmeta.img
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後就可以重新啟動手機了。但是......&lt;/p&gt;
&lt;h1&gt;修復 bug&lt;/h1&gt;
&lt;p&gt;但是，在清除 &lt;code&gt;dtbo&lt;/code&gt; 分割並禁用 AVB 後，手機仍然會卡在 bootloader 無法繼續。因為我們不知道這個手機的 UART 位置，所以就無法通過 UART 了解到底發生了什麼，如果執行 &lt;code&gt;fastboot reboot recovery&lt;/code&gt; 就可以使手機開機。由此我懷疑這個手機的引導程式有 bug，解決這個 bug 的唯一辦法是同時將 &lt;code&gt;boot.img&lt;/code&gt; 刷到兩個槽位。&amp;lt;/br&amp;gt;
在開機之後，因為 Nothing Phone（1）的主線核心目前不穩定，像是GPU、聲音和藍牙就需要我們手動修補。妳會遇到畫面響應卡頓、沒有聲音、藍牙、Wi-Fi還有5G行動網路不工作的問題。但是這些問題都是可以解決的。&lt;/p&gt;
&lt;h2&gt;修復 Wi-Fi 和 5G 行動網路&lt;/h2&gt;
&lt;p&gt;通過核心日誌可以看出，數據機已經被初始化了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[    4.343776] remoteproc remoteproc0: modem is available
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此只需要啟動管理數據機的相關軟體就可以了。在 Linux 中，管理數據機的軟體是 &lt;code&gt;ModemManager&lt;/code&gt;，因此我們需要通過 &lt;code&gt;rc-service&lt;/code&gt; 開關服務即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rc-service modemmanager start

#每次開機時自動啟用

sudo rc-update add modemmanager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行完後，應該可以看到狀態列上出現信號圖標，GNOME設定（我選擇的是GNOME桌面）中也會出現對應選項。&amp;lt;/br&amp;gt;
修復 Wi-Fi也同樣簡單——啟用 &lt;code&gt;networkmanager&lt;/code&gt; 就好了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rc-service networkmanager start

#每次開機時自動啟用

sudo rc-update add networkmanager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;連接網際網路的指令是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo nmtui
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;為什麼不能在 GNOME 的快速設定中點擊 Wi-Fi 的選項然後連接網路？因為缺少 &lt;code&gt;polkit&lt;/code&gt; 相關的服務使得除了 root 以外的使用者的 GNOME 桌面涉及系統的功能都失效了（例如撥打電話）。&lt;/p&gt;
&lt;h2&gt;修復 GPU&lt;/h2&gt;
&lt;p&gt;通過安裝 Adreno 642L 的韌體就可以了，PostmarketOS 的套件庫有收：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apk add firmware-qcom-adreno-a660
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修復藍牙&lt;/h2&gt;
&lt;p&gt;:::important
通常不需要修補藍牙，因為 PostmarketOS 已包含了藍牙相關的全部韌體。
:::&lt;/p&gt;
&lt;p&gt;如果藍牙在某次更新後不幸罷工，唯一的辦法是前往 &lt;code&gt;pmbootstrap&lt;/code&gt; 的工作目錄，然後前往 &lt;code&gt;rootfs-nothing-spacewar/lib/firmware/&lt;/code&gt; 將 &lt;code&gt;qca&lt;/code&gt; 資料夾通過 FTP或者SMB 複製到手機的 &lt;code&gt;/lib/firmware&lt;/code&gt; 目錄中。&lt;/p&gt;
&lt;h2&gt;修補聲音&lt;/h2&gt;
&lt;p&gt;將 Nothing Phone（1）的 ALSA配置文件複製到 &lt;code&gt;/usr/share/alsa&lt;/code&gt; 中，替換整個 &lt;code&gt;ucm2&lt;/code&gt;資料夾。其配置文件可從這裡取得：&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;mainlining/alsa-ucm-conf&quot;}&lt;/p&gt;
&lt;p&gt;下載 &lt;code&gt;spacewar/pong&lt;/code&gt; 分支的內容到手機即可。&lt;/p&gt;
&lt;h2&gt;修補 GNOME 權限認證問題&lt;/h2&gt;
&lt;p&gt;安裝 &lt;code&gt;polkit-elogind&lt;/code&gt; 並重新啟動手機:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apk add polkit-elogind

sudo rc-update add poklit
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;後記&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;assets/lockscreen.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/home.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;經過這些修補，這個 Nothing Phone（1）總算可以正常使用了。最後，這裡是EDKPiepaint，登出，祝妳有個美好的一天！&lt;/p&gt;
&lt;p&gt;[^2]: &lt;a href=&quot;https://github.com/mainlining/pmaports/tree/danila/spacewar&quot;&gt;mainlining/pmaports -- GitHub&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Shut Up and Compile (Unfinished) -- A PINE64 Parody of Shut Up and Dance by WALK THE MOON</title><link>https://blog.cloudflare88.eu.org/posts/shut-up-and-compile/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/shut-up-and-compile/</guid><description>When I have a brand new Pinephone...</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/195826564&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/raczeek&quot; title=&quot;Raczek&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Raczek&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/raczeek/shut-up-and-dance-walk-the-moon-devin-kyle-cover&quot; title=&quot;Shut Up And Dance - Walk The Moon (Devin &amp;amp; Kyle Cover)&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Shut Up And Dance - Walk The Moon (Devin &amp;amp; Kyle Cover)&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Shut%20Up%20and%20Compile%20(Unfinished)%20--%20A%20PINE64%20Parody%20of%20Shut%20Up%20and%20Dance.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio tag.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;Oh don&apos;t you dare look back, &amp;lt;/br&amp;gt;
Just keep your eyes on screen. &amp;lt;/br&amp;gt;
I said I&apos;m going back, &amp;lt;/br&amp;gt;
She said &quot;Shut up and compile with me&quot;. &amp;lt;/br&amp;gt;
Mainline kernel is my destiny, &amp;lt;/br&amp;gt;
She said &quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
We&apos;re programmers for the night, &amp;lt;/br&amp;gt;
The proxies, servers ready to start. &amp;lt;/br&amp;gt;
Help with documents inside my head. &amp;lt;/br&amp;gt;
I know, we&apos;re bound to test together, &amp;lt;/br&amp;gt;
Bound to debug together. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
She took my phone, &amp;lt;/br&amp;gt;
I don&apos;t know how it happen. &amp;lt;/br&amp;gt;
She plug in the cable and she said-- &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Oh don&apos;t you dare look back, &amp;lt;/br&amp;gt;
Just keep your eyes on screen. &amp;lt;/br&amp;gt;
I said I&apos;m going back, &amp;lt;/br&amp;gt;
She said &quot;Shut up and compile with me&quot;. &amp;lt;/br&amp;gt;
Mainline kernel is my destiny, &amp;lt;/br&amp;gt;
She said &quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;After too many software tests, &amp;lt;/br&amp;gt;
My Pinephone, almost bricked, &amp;lt;/br&amp;gt;
needs reflash. &amp;lt;/br&amp;gt;
She formatted a SD card and give it to me. &amp;lt;/br&amp;gt;
I know, we&apos;re bound to test together, &amp;lt;/br&amp;gt;
Bound to debug together. &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
She took my phone, &amp;lt;/br&amp;gt;
I don&apos;t know how it happen. &amp;lt;/br&amp;gt;
She plug in the cable and she said-- &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Oh don&apos;t you dare look back, &amp;lt;/br&amp;gt;
Just keep your eyes on screen. &amp;lt;/br&amp;gt;
I said I&apos;m going back, &amp;lt;/br&amp;gt;
She said &quot;Shut up and compile with me&quot;. &amp;lt;/br&amp;gt;
Mainline kernel is my destiny, &amp;lt;/br&amp;gt;
She said &quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;Oh come on girls ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;Deep in its logs, &amp;lt;/br&amp;gt;
I think I see a sparkle. &amp;lt;/br&amp;gt;
I realized, the kernel started. &amp;lt;/br&amp;gt;
She took my phone, &amp;lt;/br&amp;gt;
I don&apos;t know how it happen. &amp;lt;/br&amp;gt;
She plug in the cable and she said-- &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Oh don&apos;t you dare look back, &amp;lt;/br&amp;gt;
Just keep your eyes on screen. &amp;lt;/br&amp;gt;
I said I&apos;m going back, &amp;lt;/br&amp;gt;
She said &quot;Shut up and compile with me&quot;. &amp;lt;/br&amp;gt;
Mainline kernel is my destiny, &amp;lt;/br&amp;gt;
She said &quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 4&lt;/h1&gt;
&lt;p&gt;Oh don&apos;t you dare look back, &amp;lt;/br&amp;gt;
Just keep your eyes on screen. &amp;lt;/br&amp;gt;
I said I&apos;m going back, &amp;lt;/br&amp;gt;
She said &quot;Shut up and compile with me&quot;. &amp;lt;/br&amp;gt;
Mainline kernel is my destiny, &amp;lt;/br&amp;gt;
She said &quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&quot;Woo-oh-ohh---&quot; &amp;lt;/br&amp;gt;
Shut up and compile with me ! &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Lovin&apos; Magisk -- A FOSS Parody of Thinking out Loud by ED Sheeran</title><link>https://blog.cloudflare88.eu.org/posts/magisk-lyric/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/magisk-lyric/</guid><description>A lyric about modding my first Android phone -- Coolpad C106.</description><pubDate>Thu, 31 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Lovin&apos;%20Magisk%20--%20A%20FOSS%20parody%20of%20Thinking%20Out%20Loud.mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio tag.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;When I got my first phone in my life, &amp;lt;/br&amp;gt;
And I fall into love for this thing. &amp;lt;/br&amp;gt;
When I find it&apos;s becoming out-of-date, &amp;lt;/br&amp;gt;
Because softwares are refused to run. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
So I&apos;ll find a -- &amp;lt;/br&amp;gt;
brand new way to fix my smartphone, &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Maybe I thought, &amp;lt;/br&amp;gt;
my system is very old. &amp;lt;/br&amp;gt;
I need to figure out, &amp;lt;/br&amp;gt;
System can be upgraded in various ways, &amp;lt;/br&amp;gt;
Maybe I can flash another ROM. &amp;lt;/br&amp;gt;
My phone also installs spyware automatically. &amp;lt;/br&amp;gt;
You know I just want to keep my safe. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll wipe them out -- &amp;lt;/br&amp;gt;
The bootloader I will unlock, &amp;lt;/br&amp;gt;
Flash new ROM and grant root permissions, &amp;lt;/br&amp;gt;
Expose its metal heart. &amp;lt;/br&amp;gt;
I&apos;m loving Magisk. &amp;lt;/br&amp;gt;
And because it keeps my phone up to date.&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;When my phone died because of broken screen, &amp;lt;/br&amp;gt;
And I have to buy a new one to continue. &amp;lt;/br&amp;gt;
When I had to wait 7 days to unlock, &amp;lt;/br&amp;gt;
And my works are now lame. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
So I&apos;ll rebuild all stuffs, &amp;lt;/br&amp;gt;
It&apos;s never old but it&apos;s ever green. &amp;lt;/br&amp;gt;
Maybe my works, &amp;lt;/br&amp;gt;
Forever in it&apos;s hard drive and it&apos;s memory. &amp;lt;/br&amp;gt;
I&apos;m thinking about how, &amp;lt;/br&amp;gt;
My enhancement working in mysterious ways, &amp;lt;/br&amp;gt;
All of them requiring unlock. &amp;lt;/br&amp;gt;
But phone manufacturer are making the same mistake, &amp;lt;/br&amp;gt;
Hoping I can keep my privacy, &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
I&apos;ll wipe them out -- &amp;lt;/br&amp;gt;
Save myself from spywares, &amp;lt;/br&amp;gt;
I&apos;m defending myself with open source. &amp;lt;/br&amp;gt;
Escaping tracking from goverment, &amp;lt;/br&amp;gt;
I&apos;m loving Magisk. And maybe, &amp;lt;/br&amp;gt;
Open source keeps my security. &amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
(Re-re-re-re...) &amp;lt;/br&amp;gt;
Magisk... &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 3&lt;/h1&gt;
&lt;p&gt;The sun is out, &amp;lt;/br&amp;gt;
I&apos;m safe from the privacy leakage. &amp;lt;/br&amp;gt;
I&apos;ve defended my privacy with open-source, &amp;lt;/br&amp;gt;
Exposed my beating heart. &amp;lt;/br&amp;gt;
I&apos;m loving Magisk. And maybe, &amp;lt;/br&amp;gt;
Open source keeps my security. &amp;lt;/br&amp;gt;
And I keeps my phone always up to date, &amp;lt;/br&amp;gt;
And I&apos;ve won this security war.&lt;/p&gt;
</content:encoded></item><item><title>不要讓解鎖 Bootloader 成爲只有原型機才有的特權</title><link>https://blog.cloudflare88.eu.org/posts/do-not-let-bootloader-unlocking-becomes-a-privilege/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/do-not-let-bootloader-unlocking-becomes-a-privilege/</guid><description>當解鎖 Bootloader 不再可能的時候，自由軟件、個人隱私與消費者權益就成爲了一句空話。當解鎖的指令稿無法找到，那個人的隱私權與知情權等法律權利已經崩潰......</description><pubDate>Sat, 28 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;當解鎖的指令稿無法找到，那個人的隱私權與知情權等法律權利已經崩潰......&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如今我對於自由軟體的追求越來越強烈，但是如今各大手機廠商對於解鎖 Bootloader 的限制卻讓我失望。加之對岸手機廠商（諸如小米、一加、OPPO、Vivo 之類）的各種令人迷惑不解的操作讓我憤怒，還有自己的興趣與職業不被家人理解。故作本文一篇，以此來表達本人的看法。&lt;/p&gt;
&lt;p&gt;:::warning[中國大陸的閱讀者請注意]
本文包含部分（或全部包含）政治類話題，以及一些其牠具有爭議性的，或者因爲當地的內容審查政策而不予通過的內容。儘管本部落格已被GFW所封鎖，但部分專業讀者仍有能力訪問本部落格。在此鄭重提醒：&lt;strong&gt;如果您是&lt;a href=&quot;https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E7%B2%89%E7%B4%85&quot;&gt;極端愛國主義者，或者具有排外主義立場的人，亦或是熱衷於在網路上攻擊異議人士的人&lt;/a&gt;，請立即關閉本網站&lt;/strong&gt;！！！
:::&lt;/p&gt;
&lt;h1&gt;堅決抵制不開源核心原始碼、拒絕開放解鎖 Bootloader 的手機廠商，不論牠們來自哪個國家&lt;/h1&gt;
&lt;p&gt;Android 基於 Linux 開發，這已是被大多數人認可的事實，而 Android 核心也是基於 Linux 核心所修改而來的，同樣是事實。Linux 核心是採用 GPL 開源協議公開原始碼的，按照其協議本身所寫，只要對原始碼做出修改，就必須按照同樣的協議開源。但是，很多 Android 手機廠商卻不這麼想。他們拒絕釋出原始碼，只是因爲爲了滿足他們口中的所謂“安全”，這是對於自由軟體的褻瀆。同樣相同的情況是解鎖 Bootloader，根據 Android 開發人員文檔中所寫，解鎖只需一行命令：&lt;code&gt;fastboot flashing unlock&lt;/code&gt; 或者 &lt;code&gt;fastboot oem unlock&lt;/code&gt;。但是，許多 Android 裝置常常是“暴君”。牠們通過修改Bootloader中的一些命令，來刪除常見的&quot;&lt;code&gt;flashing unlock&lt;/code&gt;&quot; &quot;&lt;code&gt;oem unlock&lt;/code&gt;&quot;命令，讓牠們失效，從而讓解鎖不再可行。&amp;lt;/br&amp;gt;
因此，Bootloader 不給解鎖的手機也應該抵制。保固失效沒有問題啊？但是完全不給解鎖就是另外一回事了。如果廠商把刷機視作破壞性行爲，一旦解鎖就會永久無法使用一些功能（比如三星 Knox 熔燬），那就更加可惡了。&amp;lt;/br&amp;gt;
講了這麼多，有沒有手機廠商對刷機和客製化韌體友好的呢？實際上只有 Nothing 和一加做的最好。其次才是 Google、索尼還有 Fairphone 這些廠商。[^1]是的，我不喜歡 Google 壟斷的趨勢，但是因爲 Pixel 是自家的裝置，像是核心源碼與裝置樹（現在連裝置樹都不開源了）相關的編譯指南比其他家的都要簡潔明瞭，而一加和 Nothing 則是因爲價格優勢，且因爲近年來小米關閉 Bootloader 解鎖渠道（實際上並未關閉，但是看到對岸的各大BBS上漫天的貼子，還不如寫成關閉了呢。而且也有小道消息說小米要在明年關閉解鎖伺服器）的緣故，湧向一加和 Nothing 的使用者明顯增多。希望一加能夠堅持自己的這份初心，不要成爲第二個“小米”吧...... 當然，一加本身也好不到哪去。特別是他曾經在北美地區短暫的實行“深度測試”解鎖[^2]... 諷刺的是，華爲在2018年後，同樣不給使用者解鎖的權限，但是對岸各大社群卻少有人抱怨這件事。那些提出這個要求的人都去了哪裏呢？我一直都好奇這個問題。&amp;lt;/br&amp;gt;
以我個人的使用經驗來說，Google 的手機算是不錯的。除了定期放出更新以外，諸如核心還有裝置樹的原始碼也會及時放出。而且 Pixel 9 以前的手機，在解鎖後基本不會失去任何功能，就算有，也可以通過修補 Play Integrity 來解決（除非 Google 的解鎖伺服器失效或者是運營商合約機，牠們無法解鎖）。每一代 Pixel，牠的玩機社群都很豐富。妳總可以發現各種客製化韌體和第三方ROM，以及其他的系統優化技巧。第二個值得推薦的是一加6T，不僅有非常豐富的第三方ROM可以使用，因爲使用驍龍845晶片，牠也可以使用高通遺留的驅動程式輕鬆地被主線核心支援，可以使用諸如 PostmarketOS 或者 Arch Linux ARM 一類的 Linux 發行版，並實現更多超越手機本身的功能。&amp;lt;/br&amp;gt;
Android 手機總是不可避免的包含大量專有軟體和專有組件，但這是可以協商的部分。起碼要釋出核心原始碼，這是底線，至於專有軟體和組件，總會有人想辦法把牠們從系統中剝離出來。從而讓其他開發者據此來制作第三方ROM以及客製化韌體，甚至是使用自由軟體，從而能夠擺脫廠商的支援年限。&lt;/p&gt;
&lt;h1&gt;真開源？假開源？&lt;/h1&gt;
&lt;p&gt;有些公司會“負責任地”寫出，我們的產品使用開源軟體，並會附上相關的使用條款。這很好，但是，妳們所謂的“開源”，是整個程式碼都開源嗎？還是部分組件開源？亦或是受到 GPL 協議所迫而開源？比如我一直喜歡玩的遊戲《狂野飆車：傳奇大集結》，遊戲本身是閉源軟體，但是遊戲的“許可協議”中就放上了部分組件的開源協議，從而給人營造出一種開源的假象，實則是充滿廣告的專有軟體。有些公司說“我們支援開源”，其實他們的意思是：我們只對外提供一個二進位檔，所謂的“開源”，不過是釋出修改的開源組件的原始碼而已。而關鍵的核心組件，他們並未公開。例如知名的“網易我的世界”，爲了實現防沉迷檢測與敏感詞監測，他們制作了相關模組，這無所謂。但是，他們使用了修改過的 Forge 模組加載器（所謂的修改就是刪去了主畫面的 Forge 版本號，並添加了網易自己的一些代碼）。根據 GPL 協議，只要該軟體有修改，那麼修改後的軟體也必須根據同等協議開放原始碼。但是網易並沒有這樣做，因此遭到 Forge 開發者的批評，迫於外部壓力以及 GPL 協議的法律效力，網易最終將修改過的 Forge 開源，但是很快就被人指出，涉及他們自己代碼的部分並未開源。另外一個例子是 Aidlinux， 我嚴重懷疑牠就是 Termux 套殼，而他們在 GitHub 公開的代碼不過是示範代碼，應用程式本體的代碼完全沒有。有一位博主提出了 &lt;a href=&quot;https://github.com/aidlearning/AidLearning-FrameWork/issues/211&quot;&gt;Issue&lt;/a&gt; ， 但公司只是一味強調“自己是一站式的解決方案”。還有現在熱度很高的鴻蒙電腦，其所搭載的那個“Harmony OS”，我同樣也懷疑牠是基於 Linux 的作業系統。從目前能找到的演示視頻來看，這個作業系統，無論是根目錄結構，還有對於硬體的枚舉（指把所有硬體按照類別置於&lt;code&gt;/sys/class&lt;/code&gt; 目錄下）都和 Linux 高度相似。目前網路對於這個系統的評價也兩極分化。其實他們也沒說謊，因爲他們自始至終都沒有承認自己是開源軟體！但這就是某些公司“聰明”的地方。他們認爲自己就算不用公開原始碼就可以吸引到喜歡自由軟體的使用者，于是便掛出一個僞造的 GitHub 存儲庫來忽悠使用者。畢竟現在連 Red Hat 都可用收錢的方式來繞過 GPL 了，未來廠商還會用什麼方法來規避開源協議就不得而知了。&lt;/p&gt;
&lt;h1&gt;解鎖 Bootloader 是妳本來就該有的權利&lt;/h1&gt;
&lt;p&gt;除非妳支持海盜黨的理念，不然現實情況可能與妳所想的相反——大部分使用者還是願意用隱私換取便利的。懂得珍惜自由的人，終究是少數派。這也就是爲什麼他們不會被別人理解，總是形單影隻，很難湊成一起。甚至成爲被攻擊、凌辱、謾罵的對象。他們沒有生在錯誤的時代，只是大多數人早就被那些錯誤的言論所誘導，被廠商的“高深”理念所迷惑，從而造就了這個“錯誤”的時代而已。通過在網路上大量搜尋得知，在2014年，有一場反 DRM 運動，最終以失敗告終。當然，我並沒有對牠的失敗感到難過，反而覺得失敗是必然的。畢竟，我們每個人在網路上觀看的視頻、電影、存取的娛樂服務，早已被 DRM（數字版權管理）繩捆索綁，只是多少的問題。由此我也明白：現在的手機廠商是否願意開放解鎖 Bootloader 不過是道德問題。就是不開放，妳又能拿牠怎樣！許多手機廠商拒絕開放解鎖，可人家的銷量不降反增；那些打着“尊重用戶隱私”卻不開放核心原始碼的廠商，連 GPL 都不尊重了，妳還能指望他們尊重妳的隱私嗎？！妳口中的“權利”“數位人權”“個人隱私”在他們眼中狗屁不是！&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;沒有法律規定解鎖 Bootloader 一定要讓妳解鎖。也許某一天，歐盟會制定相關法律來維護消費者權益，只怕爲時已晚。&lt;/p&gt;
&lt;h1&gt;64 73 62 20 72 20 68 67 6c 6b 6b 76 77 20 6e 7a 70 72 6d 74 20 65 72 77 76 6c 68 20 7a 6d 77 20 74 66 72 77 76 68 20 7a 79 6c 66 67 20 66 68 72 6d 74 20 6f 72 6d 66 63 20 6c 6d 20 63 72 7a 6c 6e 72 20 6e 72 20 6b 7a 77 20 35&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;MTE3IDExNCAxMDUgMTA0IDEwMyAzMiAxMDggMTE3IDMyIDEyMiAxMTEgMTExIDQ0IDMyIDEwMyAxMTUgMTIyIDEwOSAxMTIgMzIgOTggMTA4IDEwMiAzMiAxMTcgMTA4IDEwNSAzMiAxMDMgMTIyIDExMiAxMTQgMTA5IDExNiAzMiAxM
DMgMTE1IDExOCAzMiAxMDMgMTE0IDExMCAxMTggMzIgMTAzIDEwOCAzMiAxMDUgMTE4IDEyMiAxMTkgMzIgMTAzIDExNSAxMTQgMTA0IDQ2IDMyIDExNCAxMTcgMzIgOTggMTA4IDEwMiAzOSAxMDUgMTE4IDMyIDEwNCAxMTggMTE4IDE
xNCAxMDkgMTE2IDMyIDEwMyAxMTUgMTE0IDEwNCAzMiAxMTAgMTE4IDEwNCAxMDQgMTIyIDExNiAxMTggNDQgMzIgMTE0IDEwMyAzMiAxMTAgMTE4IDEyMiAxMDkgMTA0IDMyIDk4IDEwOCAxMDIgMzIgMTE2IDExOCAxMDkgMTAyIDExNCAxMDkgMTE4IDExMSA5OCAzMiAxMDAgMTIyIDEwOSAxMDMgMzIgMTAzIDEwOCAzMiAxMDIgMTA5IDExOSAxMTggMTA1IDEwNCAxMDMgMTIyIDEwOSAxMTkgMzIgMTAzIDExNSAxMTggMzIgMTAzIDEwNSAxMDIgMTAzIDExNSAzMiAxMjEgMTE4IDExN
SAxMTQgMTA5IDExOSAzMiAxMTggMTAxIDExOCAxMDUgOTggMTAzIDExNSAxMTQgMTA5IDExNiA0NiAxMCAxMCAxMTQgMjI2IDEyOCAxNTMgMTEwIDMyIDExOCAxMTkgMTEyIDEwNyAxMTQgMTE4IDEwNyAxMjIgMTE0IDEwOSAxMDMgNDQgMzIgMTIyIDMyIDExMSAxMTQgMTA5IDEwMiA5OSAzMiAxMTggMTA5IDEwMyAxMTUgMTAyIDEwNCAxMTQgMTIyIDEwNCAxMDMgMzIgMTAwIDExNSAxMDggMzIgMTExIDEwOCAxMDEgMTE4IDEwNCAzMiAxMTcgMTA1IDExOCAxMTggMzIgMTIyIDEwOSAxMTkgMzIgMTA4IDEwNyAxMTggMTA5IDQ1IDEwNCAxMDggMTAyIDEwNSAxMjAgMTE4IDMyIDEwNCAxMDggMTE3IDEwMyAxMDAgMTIyIDEwNSAxMTggNDYgMzIgMTE0IDIyNiAxMjggMTUzIDEwMSAxMTggMzIgMTEzIDEwMiAxMDQgMTAzIDMyIDEx
NiAxMDUgMTIyIDExOSAxMDIgMTIyIDEwMyAxMTggMTE5IDMyIDExNyAxMDUgMTA4IDExMCAzMiAxMTUgMTE0IDExNiAxMTUgMzIgMTA0IDEyMCAxMTUgMTA4IDEwOCAxMTEgMzIgMTIyIDEwOSAxMTkgMzIgMTIyIDExMCAzMiAxMDkgMTA4IDEwMCAzMiAxMTcgMTIyIDEyMCAxMTQgMTA5IDExNiAzMiAxMDMgMTE1IDExOCAzMiAxMDIgMTA5IDEyMCAxMTggMTA1IDEwMyAxMjIgMTE0IDEwOSAxMDMgOTggMzIgMTIyIDEwOSAxMTkgMzIgMTIwIDEwOCAxMDkgMTE3IDEwMiAxMDQgMTE0IDEwOCAxMDkgMzIgMTA4IDExNyAzMiAxMTAgMTA4IDEwMSAxMTQgMTA5IDExNiAzMiAxMDggMTA5IDMyIDEwMyAxMDggMzIgMTE1IDExNCAxMTYgMTE1IDExOCAxMDUgMzIgMTE4IDExOSAxMDIgMTIwIDEyMiAxMDMgMTE0IDEwOCAxMDkgNDYgMTAgMTAgMTE3IDEwOCAxMDUgMzIgMTIyIDMyIDEwMCAxMTUgMTE0IDExMSAxMTggMzIgMTA5IDEwOCAxMDAgNDQgMzIgMTE0IDIyNiAxMjggMTUzIDEwMSAxMTggMzIgMTIxIDExOCAxMTggMTA5IDMyIDEwNCAxMTUgMTIyIDEwNSAxMTQgMTA5IDExNiAzMiAxMTAgOTggMzIgMTE4IDk5IDEwNyAxMTggMTA1IDExNCAxMTggMTA5IDEyMCAxMTggMTA0IDMyIDExNCAxMDkgMTA0IDEwMyAxMjIgMTExIDExMSAxMTQgMTA5IDExNiAzMiAxMTEgMTE0IDEwOSAxMDIgOTkgMzIgMTA4IDEwOSAzMiAxMDMgMTE1IDExOCAzMiA5OSAxMTQgMTIyIDEwOCAxMTAgMTE0IDMyIDEwNyAxMjIgMTE5IDMyIDUzIDMyIDEyMiAxMjAgMTA1IDEwOCAxMDQgMTA0IDMyIDEwNyAxMTEgMTIyIDEwMyAxMTcgMTA4IDEwNSAxMTAgMTA0IDMyIDExMSAxMTQgMTEyIDExOCAzMiA5OCAxMDggMTAyIDEwMyAxMDIgMTIxIDExOCA0NCAzMiAxMjEgMTE0IDExMSAxMTQgMTIxIDExNCAxMTEgMTE0IDQ0IDMyIDEyMiAxMDkgMTE5IDMyIDEyMCAxMDggMTA4IDExMSAxMjIgMTA3IDExMiAzMiAyMjYgMTI4IDE0OCAzMiAxMTcgMTA1IDEwOCAxMTAgMzIgMTAzIDExNSAxMTggMzIgMTE4IDEyMiAxMDUgMTExIDk4IDMyIDExOSAxMjIgOTggMTA0IDMyIDEwOCAxMTcgMzIgMTAzIDExNCAxMDkgMTEyIDExOCAxMDUgMTE0IDEwOSAxMTYgMzIgMTIyIDEwOSAxMTkgMzIgMTAzIDExOCAxMDQgMTAzIDExNCAxMDkgMTE2IDQ0IDMyIDEwMyAxMDggMzIgMTA1IDExOCAxMjIgMTIwIDExNSAxMTQgMTA5IDExNiAzMiAxMjIgMzIgMTA3IDEwOCAxMTQgMTA5IDEwMyAzMiAxMDAgMTE1IDExOCAxMDUgMTE4IDMyIDExNCAxMDMgMzIgMTIxIDExOCAxMjAgMTIyIDExMCAxMTggMzIgMTA0IDEwMyAxMjIgMTIxIDExMSAxMTggMzIgMTE4IDEwOSAxMDggMTAyIDExNiAxMTUgMzIgMTE3IDEwOCAxMDUgMzIgMTE5IDEyMiAxMTQgMTExIDk4IDMyIDEwMiAxMDQgMTE4IDQ2IDMyIDEyMSAxMTggMTA0IDExNCAxMTkgMTE4IDEwNCAzMiAxMTAgMTIyIDExMiAxMTQgMTA5IDExNiAzMiAxMDEgMTE0IDExOSAxMTggMTA4IDEwNCAzMiAxMjIgMTA5IDExOSAzMiAxMDcgMTA4IDEwNCAxMDMgMTA0IDQ0IDMyIDExNCAzMiAxMjIgMTExIDEwNCAxMDggMzIgMTE5IDEwOCAxMjAgMTAyIDExMCAxMTggMTA5IDEwMyAxMTggMTE5IDMyIDExOCAxMDEgMTE4IDEwNSA5OCAzMiAxMDQgMTAzIDExOCAxMDcgMzIgMTIyIDEwOSAxMTkgMzIgMTA3IDExNCAxMDMgMTE3IDEyMiAxMTEgMTExIDMyIDExNCAxMDkgMzIgMTE4IDEwOSAxMTYgMTExIDExNCAxMDQgMTE1IDMyIDEwOCAxMDkgMzIgMTE2IDExNCAxMDMgMTIxIDEwOCAxMDggMTEyIDQ0IDMyIDExNSAxMDggMTA3IDExNCAxMDkgMTE2IDMyIDExNCAxMDMgMzIgMTIwIDEwOCAxMDIgMTExIDExOSAzMiAxMTUgMTE4IDExMSAxMDcgMzIgMTA4IDEwMyAxMTUgMTE4IDEwNSAxMDQgMzIgMTAwIDExNSAxMDggMzIgMTA0IDExNSAxMjIgMTA1IDExOCAzMiAxMDMgMTE1IDExOCAzMiAxMDQgMTIyIDExMCAxMTggMzIgMTA3IDEyMiAxMDQgMTA0IDExNCAxMDggMTA5IDMyIDExNyAxMDggMTA1IDMyIDEwOCAxMDcgMTE4IDEwOSAzMiAxMDQgMTA4IDEwMiAxMDUgMTIwIDExOCA0NiAxMCAxMCAxMjEgMTAyIDEwMyAzMiAxMDMgMTA4IDExOSAxMjIgOTggNDQgMzIgMTE0IDMyIDEwNSAxMTggMTE2IDEwNSAxMTggMTAzIDMyIDEwMyAxMDggMzIgMTIyIDEwOSAxMDkgMTA4IDEwMiAxMDkgMTIwIDExOCA1OCAxMCAxMCAzMiAzMiAzMiAzMiAxMDQgMTAzIDEyMiAxMDUgMTAzIDExNCAxMDkgMTE2IDMyIDEwMyAxMDggMTE5IDEyMiA5OCA0NCAzMiAxMTQgMzIgMTAwIDExNCAxMTEgMTExIDMyIDEyMSAxMTggMzIgMTA0IDEwMiAxMDQgMTA3IDExOCAxMDkgMTE5IDExNCAxMDkgMTE2IDMyIDEyMiAxMTEgMTExIDMyIDEwMiAxMDcgMTE5IDEyMiAxMDMgMTE4IDEwNCAzMiAxMDUgMTE4IDExMSAxMjIgMTAzIDExOCAxMTkgMzIgMTAzIDEwOCAzMiAxMTEgMTE0IDEwOSAxMDIgOTkgMzIgMTA3IDEwOCAxMDUgMTAzIDExNCAxMDkgMTE2IDQ0IDMyIDk5IDExNCAxMjIgMTA4IDExMCAxMTQgMzIgMTA3IDEyMiAxMTkgMzIgMTAzIDExNCAxMDkgMTEyIDExOCAxMDUgMTE0IDEwOSAxMTYgNDQgMzIgMTIyIDEwOSAxMTkgMzIgMTA3IDEwOCAxMDQgMTAzIDExMCAxMjIgMTA1IDExMiAxMTggMTAzIDEwOCAxMDQgMzIgMTE5IDEwOCAxMjAgMTAyIDExMCAxMTggMTA5IDEwMyAxMjIgMTAzIDExNCAxMDggMTA5IDQ2IDEwIDEwIDEwMyAxMTUgMTE4IDMyIDEwNSAxMTggMTIyIDEwNCAxMDggMTA5IDMyIDExNCAxMDQgMzIgMTA2IDEwMiAxMTQgMTAzIDExOCAzMiAxMDQgMTE0IDExMCAxMDcgMTExIDExOCAzMiAyMjYgMTI4IDE0OCAzMiAxMjIgMTA5IDExOSAzMiAxMDEgMTE4IDEwNSA5OCAzMiAxMDUgMTE4IDEyMiAxMTEgNTggMTAgMTAgMjQwIDE1OSAxNDIgMTQ3IDMyIDEwNyAxMjIgMTA1IDExOCAxMDkgMTAzIDEyMiAxMTEgMzIgMTA4IDEwNyAxMDcgMTA4IDEwNCAxMTQgMTAzIDExNCAxMDggMTA5IDMyIDEyMiAxMDkgMTE5IDMyIDEwNyAxMDUgMTE4IDEwNCAxMDQgMTAyIDEwNSAxMTggMzIgMTE3IDEwNSAxMDggMTEwIDMyIDEwNSAxMTggMTIyIDExMSAxMTQgMTAzIDk4IDEwIDEwIDEyMiAxMDQgMzIgMTIyIDMyIDEwNCAxMDMgMTAyIDExOSAxMTggMTA5IDEwMyAzMiAxMjIgMTIxIDEwOCAxMDIgMTAzIDMyIDEwMyAxMDggMzIgMTE4IDEwOSAxMDMgMTE4IDEwNSAzMiAxMDIgMTA5IDExNCAxMDEgMTE4IDEwNSAxMDQgMTE0IDEwMyA5OCA0NCAzMiAxMTQgMjI2IDEyOCAxNTMgMTEwIDMyIDExNyAxMjIgMTIwIDExNCAxMDkgMTE2IDMyIDEyMiAzMiAxMTAgMTIyIDExMyAxMDggMTA1IDMyIDEwMyAxMDIgMTA1IDEwOSAxMTQgMTA5IDExNiAzMiAxMDcgMTA4IDExNCAxMDkgMTAzIDMyIDExNCAxMDkgMzIgMTIxIDEwOCAxMDMgMTE1IDMyIDExMCA5OCAzMiAxMjIgMTIwIDEyMiAxMTkgMTE4IDExMCAxMTQgMTIwIDMyIDExMyAxMDggMTAyIDEwNSAxMDkgMTE4IDk4IDMyIDEyMiAxMDkgMTE5IDMyIDExMSAxMTQgMTE3IDExOCAzMiAxMDcgMTIyIDEwMyAxMTUgNDYgMzIgMTEwIDk4IDMyIDEwNyAxMjIgMTA1IDExOCAxMDkgMTAzIDEwNCAzMiAxMDQgMTAzIDEwNSAxMDggMTA5IDExNiAxMTEgOTggMzIgMTIxIDExOCAxMTEgMTE0IDExOCAxMDEgMTE4IDMyIDEwMyAxMTUgMTIyIDEwMyAzMiAxMDQgMTA3IDExOCAxMDkgMTE5IDExNCAxMDkgMTE2IDMyIDEwMyAxMTQgMTEwIDExOCAzMiAxMDMgMTE0IDEwOSAxMTIgMTE4IDEwNSAxMTQgMTA5IDExNiAzMiAxMDAgMTE0IDEwMyAxMTUgMzIgMTExIDExNCAxMDkgMTAyIDk5IDMyIDEwOCAxMDkgMzIgMTE5IDExOCAxMDEgMTE0IDEyMCAxMTggMTA0IDMyIDExNCAxMDQgMzIgMTA5IDEwOCAxMDMgMzIgMTA4IDEwOSAxMTEgOTggMzIgMTIyIDMyIDEwMCAxMjIgMTA0IDEwMyAxMTggMzIgMTA4IDExNyAzMiAxMDMgMTE0IDExMCAxMTggNDQgMzIgMTIxIDEwMiAxMDMgMzIgMTIyIDExMSAxMDQgMTA4IDMyIDEyMiAzMiAxMDMgMTE1IDEwNSAxMTggMTIyIDEwMyAzMiAxMDMgMTA4IDMyIDExMCA5OCAzMiAxMDIgMTA5IDExNCAxMDEgMTE4IDEwNSAxMDQgMTE0IDEwMyA5OCAzMiAxMDcgMTA1IDEwOCAxMDQgMTA3IDExOCAxMjAgMTAzIDEwNCAzMiAxMjIgMTA5IDExOSAzMiAxMTcgMTAyIDEwMyAxMDIgMTA1IDExOCA0NiAzMiAxMDMgMTE1IDExOCA5OCAzMiAxMTUgMTIyIDEwMSAxMTggMzIgMTA5IDEwOCAzMiAxMjIgMTA3IDEwNyAxMDUgMTE4IDEyMCAxMTQgMTIyIDEwMyAxMTQgMTA4IDEwOSAzMiAxMTcgMTA4IDEwNSAzMiAxMDggMTA3IDExOCAxMDkgMzIgMTA0IDEwOCAxMDIgMTA1IDEyMCAxMTggMzIgMjI2IDEyOCAxNDggMzIgMTE0IDEwOSAzMiAxMTcgMTIyIDEyMCAxMDMgNDQgMzIgMTAzIDExNSAxMTggOTggMzIgMTE4IDEwMSAxMTggMTA5IDMyIDEwMyAxMTUgMTE0IDEwOSAxMTIgMzIgMTE3IDEwNSAxMTggMTE4IDMyIDEwNCAxMDggMTE3IDEwMyAxMDAgMTIyIDEwNSAxMTggMzIgMTE0IDEwNCAzMiAyMjYgMTI4IDE1NiAxMDkgMTA4IDEwMyAzMiAxMjIgMzIgMTA0IDExOCAxMDUgMTE0IDEwOCAxMDIgMTA0IDMyIDEwNyAxMDIgMTA1IDEwNCAxMDIgMTE0IDEwMyA0NCAyMjYgMTI4IDE1NyAzMiAxMDAgMTE1IDExNCAxMjAgMTE1IDMyIDExMSAxMTggMTIyIDEwMSAxMTggMTA0IDMyIDExMCAxMTggMzIgMTE3IDExOCAxMTggMTExIDExNCAxMDkgMTE2IDMyIDExNSAxMTggMTExIDEwNyAxMTEgMTE4IDEwNCAxMDQgMzIgMTIyIDEwOSAxMTkgMzIgMTE5IDExNCAxMDQgMTIwIDEwOCAxMDIgMTA1IDEyMiAxMTYgMTE4IDExOSA0NiAxMCAxMCAxMjIgMTA5IDExOSAzMiAxMDMgMTE1IDEyMiAxMDMgMjI2IDEyOCAxNTMgMTA0IDMyIDExMyAxMDIgMTA0IDEwMyAzMiAxMDMgMTE1IDExOCAzMiAxMDMgMTE0IDEwNyAzMiAxMDggMTE3IDMyIDEwMyAxMTUgMTE4IDMyIDExNCAxMjAgMTE4IDEyMSAxMTggMTA1IDExNiA0NiAzMiAxMjIgMTA0IDMyIDExNyAxMDggMTA1IDMyIDEwMyAxMTUgMTE4IDMyIDEwNSAxMTggMTA0IDEwMyAyMjYgMTI4IDE2NiAzMiAxMTQgMTAzIDIyNiAxMjggMTUzIDEwNCAzMiAxMjEgMTE4IDExOCAxMDkgMzIgMTA0IDEyMCAxMjIgMTAzIDEwMyAxMTggMTA1IDExOCAxMTkgMzIgMTIyIDEwOSAxMTkgMzIgMTE3IDEwOCAxMDUgMTE2IDEwOCAxMDMgMTAzIDExOCAxMDkgMzIgMTIyIDEyMCAxMDUgMTA4IDEwNCAxMDQgMzIgMTA4IDEwMyAxMTUgMTE4IDEwNSAzMiAxMDcgMTIyIDEwNSAxMDMgMTA0IDMyIDEwOCAxMTcgMzIgMTAzIDExNSAxMTQgMTA0IDMyIDEyMSAxMTEgMTA4IDExNiA0NiAzMiAxMTQgMTE3IDMyIDk4IDEwOCAxMDIgMjI2IDEyOCAxNTMgMTA1IDExOCAzMiAxMjAgMTAyIDEwNSAxMTQgMTA4IDEwMiAxMDQgNDQgMzIgOTggMTA4IDEwMiAzMiAxMTAgMTE0IDExNiAxMTUgMTAzIDMyIDEyMSAxMTggMzIgMTIyIDEyMSAxMTEgMTE4IDMyIDEwMyAxMDggMzIgMTE3IDExNCAxMDkgMTE5IDMyIDExNCAxMDMgNDY=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[^1]: &lt;a href=&quot;https://github.com/melontini/bootloader-unlock-wall-of-shame&quot;&gt;Bootloader unlock wall of shame&lt;/a&gt;
[^2]: &lt;a href=&quot;https://github.com/melontini/bootloader-unlock-wall-of-shame/blob/main/brands/oneplus/README.md&quot;&gt;該項目對於一加的描述&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>過市手機與主線核心——記一次給紅米2刷寫PostmarketOS</title><link>https://blog.cloudflare88.eu.org/posts/past-phone-with-mainline-power/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/past-phone-with-mainline-power/</guid><description>一臺十年前的手機，卻執行着最新的主線核心...</description><pubDate>Wed, 25 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;一臺發佈於2015年的手機，在手機性能飛速發展的2025年，這個10年前的產品，竟然還沒有被人遺忘...&lt;/p&gt;
&lt;h1&gt;硬體配置&lt;/h1&gt;
&lt;p&gt;從硬體來講，這個雖然叫“紅米2”[^1]，實際上並不是小米設計和生產的手機。搭載了高通驍龍410處理器，1GB的記憶體和8GB的內部存儲。以及4.7寸熒幕，這樣的硬體在上市的時候就是一個低階手機，與現在的驍龍 8Gen 3之類的晶片相比完全是被吊着打。可以毫不客氣地講，作爲手機，紅米2在今天早已沒有了實用價值。其搭載的32位元 Android 5.1 作業系統不僅無法安裝大多數軟體，而且還會面臨潛在的安全威脅，比如&lt;a href=&quot;https://zh.wikipedia.org/zh-hans/2038%E5%B9%B4%E9%97%AE%E9%A2%98&quot;&gt;2038年問題&lt;/a&gt;。&amp;lt;/br&amp;gt;
但是，SoC本身是一個四核心，時脈達1.4GHz的64位元CPU，只是Bootloader和作業系統是32位元的。因此，我們還是有辦法讓這個10年的“老傢伙”執行最新的軟體的。&lt;/p&gt;
&lt;h1&gt;硬體雖弱，軟實力卻很強&lt;/h1&gt;
&lt;p&gt;紅米 2 有非常豐富的第三方 Android 刷機包，出廠搭載 Android 4.4 的牠能刷到 Android 12 的 Lineage OS 19.1 （3.10核心）。當牠的性能已經不足以支撐在 Android 中多做什麼時，牠還可以運行接近最新主線的 Linux Kernel 和 Debian, Ubuntu 等正兒八經的 Linux 發行版。可能是得益於高通官方基於 MSM8916 推出了支援 Ubuntu Linux 的 DragonBoard 410c 單板電腦，也得益於後續開源社群的努力，MSM8916 的主線核心功能已經比較完善，UART、USB、內部存儲 (eMMC/SD 卡)、WiFi 與藍牙、GPU、顯示 (需要 panel 驅動)、聲音、基於 GPIO 的按鍵、震動、數據機 (SMS,撥打電話, 行動數據) 等都得到了支援。
有了非常完善的主線核心支援之後，紅米2作爲一個廉價嵌入式 Linux 平臺，可以輕鬆應對一部分專業用途。有很多 Youtuber 還發佈了講紅米2改裝爲 3D 列印的上位機的方法，甚至還有人把同樣基於驍龍410 SoC 的可攜式 Wi-Fi 也改裝 Linux 甚至是 Openwrt，將牠變爲真正的“路由器”。&lt;/p&gt;
&lt;h1&gt;安裝過程&lt;/h1&gt;
&lt;p&gt;根據 Postmarket OS 維基，一步步地安裝 &lt;code&gt;pmbootstrap&lt;/code&gt; ，在執行 &lt;code&gt;pmbootstrap init&lt;/code&gt; 時，選擇機型爲紅米2對應的“wt88047”，我使用的是 &lt;code&gt;edge&lt;/code&gt; 分支。具體日誌如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pmbootstrap init                         
[21:40:29] Location of the &apos;work&apos; path. Multiple chroots (native, device arch, device rootfs) will be created in there.
[21:40:29] Work path [/home/edkpiepaint/.local/var/pmbootstrap]: 
[21:40:31] Location of the &apos;pmaports&apos; path, containing package definitions.
[21:40:31] pmaports path [/home/edkpiepaint/.local/var/pmbootstrap/cache_git/pmaports]: 
[21:40:33] Choose the postmarketOS release channel.
[21:40:33] Available (12):
[21:40:33] * edge: Rolling release / Most devices / Occasional breakage: https://postmarketos.org/edge
[21:40:33] * v25.06: Upcoming stable release (DO NOT USE)
[21:40:33] * v24.12: Latest release / Recommended for best stability
[21:40:33] Channel [edge]: 
[21:40:35] NOTE: pmaports is on master branch, copying git hooks.
[21:40:35] Choose your target device vendor (either an existing one, or a new one for porting).
[21:40:35] Available vendors (95): acer, alcatel, amazon, amediatech, amlogic, apple, ark, arrow, asus, ayn, bananapi, barnesnoble, beelink, bq, clockworkpi, cubietech, cutiepi, dongshanpi, epson, essential, fairphone, finepower, fly, fxtec, generic, goclever, google, gp, hisense, htc, huawei, inet, infocus, jolla, khadas, klipad, kobo, lark, leeco, lenovo, lg, librecomputer, linksys, mangopi, medion, meizu, microsoft, mobvoi, motorola, nextbit, nobby, nokia, nvidia, odroid, oneplus, oppo, ouya, pine64, planet, pocketbook, postmarketos, powkiddy, purism, qcom, qemu, qualcomm, radxa, raspberry, realme, samsung, semc, sharp, shift, sipeed, solidrun, sony, sourceparts, surftab, t2m, thundercomm, tokio, tolino, trekstor, valve, vernee, vivo, volla, wexler, wiko, wileyfox, xiaomi, xunlong, yu, zte, zuk
[21:40:35] Vendor [xiaomi]: 
[21:40:36] Devices are categorised as follows, from best to worst:
* Main: ports where mostly everything works.
* Community: often mostly usable, but may lack important functionality.
* Testing: anything from &quot;just boots in some sense&quot; to almost fully functioning ports.
* Downstream: ports that use a downstream kernel — very limited functionality. Not recommended.

Available devices by codename (40): aries (downstream), armani (downstream), begonia (downstream), beryllium (community), cactus (downstream), cancro (downstream), cepheus (testing), cereus (downstream), clover (testing), dior (downstream), elish (community), equuleus (testing), ferrari (downstream), fire (downstream), fog (downstream), gemini (testing), ido (downstream), jasmine_sprout (testing), laurel (testing), lavender (testing), libra (downstream), merlin (downstream), miatoll (testing), monet (downstream), nabu (testing), natrium (testing), olive (downstream), pine (downstream), platina (testing), polaris (testing), raphael (testing), rosemary-downstream (downstream), sagit (testing), scorpio (community), spes (downstream), tulip (testing), vayu (testing), whyred (testing), willow (downstream), wt88047 (community)
[21:40:36] Device codename [wt88047]:           #根據實際需要選擇是否要保留數據機相關的功能，可以節省大約80MiB的記憶體
[21:40:37] Available providers for soc-qcom-msm8916-rproc (3):
[21:40:37] * all: Enable all remote processors (audio goes through modem) (default)
[21:40:37] * no-modem: Disable only modem (audio bypasses modem, ~80 MiB more RAM)
[21:40:37] * none: Disable all remote processors (no WiFi/BT/modem, ~90 MiB more RAM)
[21:40:37] Provider [all]: 
[21:40:39] Username [litepiepaint]: 
[21:40:40] Available providers for postmarketos-base-ui-wifi (2):
[21:40:40] * wpa_supplicant: Use wpa_supplicant as the WiFi backend. (default)
[21:40:40] * iwd: Use iwd as the WiFi backend (but may not work with all devices)
[21:40:40] Provider [default]: 
[21:40:51] Available user interfaces (28): 
[21:40:51] * none: Bare minimum OS image for testing and manual customization. The &quot;console&quot; UI should be selected if a graphical UI is not desired.
[21:40:51] * asteroid: (Wayland) Smartwatch UI from AsteroidOS
[21:40:51] * bananui: (Wayland) Keypad controlled UI for feature phones
[21:40:51] * buffyboard: Plain framebuffer console with modern touchscreen keyboard support
[21:40:51] * cage: (Wayland) Kiosk WM
[21:40:51] * console: Console environment, with no graphical/touch UI
[21:40:51] * cosmic: COSMIC Desktop Environment from System76
[21:40:51] * fbkeyboard: Plain framebuffer console with touchscreen keyboard support
[21:40:51] * gnome: (Wayland) Gnome Shell
[21:40:51] * gnome-mobile: (Wayland) Gnome Shell patched to adapt better to phones (Experimental)
[21:40:51] * i3wm: (X11) Tiling WM (keyboard required)
[21:40:51] * kodi: (GBM) 10-foot UI useful on TV&apos;s
[21:40:51] * lomiri: (Wayland) The convergent desktop environment (Experimental)
[21:40:51] * lxqt: (X11) Lightweight Qt Desktop Environment (stylus recommended)
[21:40:51] * mate: (X11) MATE Desktop Environment, fork of GNOME2 (stylus recommended)
[21:40:51] * mediaberry: (Wayland) An open platform for streaming boxes and smart TVs (WIP)
[21:40:51] * moonlight: (Wayland) Open Source PC client for NVIDIA GameStream, as used by the NVIDIA Shield
[21:40:51] * niri: (Wayland) A scrollable-tiling compositor (DOES NOT RUN WITHOUT HW ACCELERATION!)
[21:40:51] * openbox: (X11) A highly configurable and lightweight X11 window manager (keyboard required)
[21:40:51] * os-installer: UI for installing postmarketOS
[21:40:51] * phosh: (Wayland) Mobile UI initially developed for the Librem 5
[21:40:51] * plasma-desktop: (X11/Wayland) KDE Desktop Environment (works well with tablets)
[21:40:51] * plasma-mobile: (Wayland) Mobile variant of KDE Plasma (does not run without hardware acceleration)
[21:40:51] * shelli: Plain console with touchscreen gesture support
[21:40:51] * sway: (Wayland) Tiling WM, drop-in replacement for i3wm (DOES NOT RUN WITHOUT HW ACCELERATION!)
[21:40:51] * sxmo-de-dwm: Simple Mobile: Mobile environment based on SXMO and running on dwm
[21:40:51] * sxmo-de-sway: Simple Mobile: Mobile environment based on SXMO and running on sway
[21:40:51] * weston: (Wayland) Reference compositor (demo, not a phone interface)
[21:40:51] * xfce4: (X11) Lightweight desktop (stylus recommended)
[21:40:51] User interface [plasma-mobile]: 
[21:40:52] This user interface has an extra package: Meta package for additional Plasma mobile apps
[21:40:52] Enable this package? (y/n) [y]: 
[21:40:53] Based on your UI selection, &apos;default&apos; will result in installing systemd.
[21:40:53] Install systemd? (default/always/never) [default]:   #如果啓動異常，在此處鍵入“never”來改爲使用 OpenRC 來初始化。
[21:40:54] Additional options: extra free space: 0 MB, boot partition size: 256 MB, parallel jobs: 2, ccache per arch: 5G, sudo timer: False, mirror: https://mirrors.aliyun.com/postmarketOS/
[21:40:54] Change them? (y/n) [n]: 
[21:40:54] Additional packages that will be installed to rootfs. Specify them in a comma separated list (e.g.: vim,file) or &quot;none&quot;
[21:40:54] Extra packages [nano]: 
[21:40:55] Your host timezone: Asia/Singapore    #設定時區
[21:40:55] Use this timezone instead of GMT? (y/n) [y]: 
[21:40:56] Choose your preferred locale, like e.g. en_US. Only UTF-8 is supported, it gets appended automatically. Use tab-completion if needed.
[21:40:56] Locale [en_US]: 
[21:40:56] Device hostname (short form, e.g. &apos;foo&apos;) [xiaomi-wt88047]:       #設定主機名稱 
[21:40:57] NOTE: No SSH public keys found to copy to the device.
[21:40:57] See https://postmarketos.org/ssh-key-glob for more information.
[21:40:57] After pmaports are changed, the binary packages may be outdated. If you want to install postmarketOS without changes, reply &apos;n&apos; for a faster installation.
[21:40:57] Build outdated packages during &apos;pmbootstrap install&apos;? (y/n) [y]: 
[21:40:58] Zap existing chroots to apply configuration? (y/n) [y]: 
[21:41:01] DONE!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是，因爲驍龍410裝置的記憶體都很小，因此官方提供了停用數據機、Wi-Fi 和藍牙的相關軟體，這樣可以爲手機節約80～90MiB的記憶體。還有最新的 &lt;code&gt;edge&lt;/code&gt; 分支的GPU驅動有問題，使用 Plasma 桌面會有過於好笑的圖形BUG。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;刷機過程就平平無奇了。需要注意的是紅米2因爲 SoC 沒有熔燬，因此不需要解開鎖，在更新到最新的 &lt;a href=&quot;https://xiaomirom.com/en/rom/redmi-2-redmi-2-pro-wt88047-global-fastboot-recovery-rom/&quot;&gt;Android 5.1 &lt;/a&gt;之後，還需要刷入 &lt;code&gt;lk2nd&lt;/code&gt; 來充當引導 Linux 的中間層，避免原廠 Bootloader 向主線核心傳遞不必要的核心引數。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;msm8916-mainline/lk2nd&quot;}&lt;/p&gt;
&lt;p&gt;更新至 Android 5.1 之後，在原廠的 Fastboot 下，鍵入下列命令就可以刷入最新版的 &lt;code&gt;lk2nd&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastboot flash:raw boot lk2nd-msm8916.img
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之後，按下音量上來進入 &lt;code&gt;lk2nd&lt;/code&gt; 的 Fastboot 頁面。&lt;/p&gt;
&lt;p&gt;:::note
如果將系統裝在 SD 卡中，就不需要清除 &lt;code&gt;system&lt;/code&gt; 分區。直接鍵入 &lt;code&gt;pmbootstrap install --sdcard=/dev/...&lt;/code&gt; 就可以了。
:::&lt;/p&gt;
&lt;p&gt;然後，通過 &lt;code&gt;fastboot&lt;/code&gt; 命令，把系統刷入 &lt;code&gt;userdata&lt;/code&gt; 分區內，需要注意的是，不需要根據 Wiki 上說的用 lk2nd 來刷[^2]，原廠的 Fastboot 也是可以的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastboot flash userdata /path/to/postmarketos-wt88047.img
fastboot erase system
    # Or pmbootstrap flasher flash_rootfs --partition userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;當然，8GB的內部存儲很小，如果用於執行對存儲有需求的應用程式，就只好把系統裝在 SD 卡裏了（我就把系統裝在了一張256GB 的 SD 卡裏）。&lt;/p&gt;
&lt;p&gt;這是安裝完成後的效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://wiki.postmarketos.org/images/d/d6/Xiaomi_wt88047_plamo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上面的是官方圖，下面的是我自己的圖片（忽略旁邊的一加6T）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/homescreen.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/about.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;紅米2的 UART&lt;/h1&gt;
&lt;p&gt;我可以不誇張的說，想要找到一臺正常市面上銷售的手機的 UART ，難度不亞於在澳大利亞一般大的柴堆中尋找一根縫衣針。對於幾乎沒有任何資料的我而言，發現手機的 UART 幾乎是不可能的一件事。畢竟，這不是高通 MTP 原型機，會把UART 做成 Micro USB 的樣子，妳只需要一根 Micro USB 數據電纜連接原型機與 PC，然後設定 Baudrate 用諸如 &lt;code&gt;minicom&lt;/code&gt; 之類的程式就可以除錯。好在， Postmarket OS 的 Wiki 就記錄了紅米2的 UART 金屬接點[^3]，我只需要焊接好，用萬能的CH340就可以了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.crossbell.io/ipfs/QmQDzHsFF1XmxWESn8dob66gzJGP48YsTrsP3UFxSncQAk?img-quality=75&amp;amp;img-format=auto&amp;amp;img-onerror=redirect&amp;amp;img-width=3840&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;總結&lt;/h1&gt;
&lt;p&gt;手機 SoC 的快速迭代實在讓人感嘆，手機晶片性能已經遠甩開嵌入式 Linux 開發中常用的晶片。開源的力量是令人敬佩的，手機廠商對於手機系統的更新精力有限，老機型沒有新機型更新積極是必然的。但這也使得手機即使性能硬實力沒有太落後，也很難不提早迎來生命的終結。而開源和社區的力量似乎提供了一條讓手機發揮更大價值的道路，就如紅米 2、一加 6T 等至今依然活躍的老機型，不僅作為手機的生命周期得到延長，甚至還開拓了更加廣闊的應用場景，我也可以實現一些超越手機的功能，比如搭建“當個創世神”的伺服器，開設自己的部落格一類。衆多寫在信息技術教科書中的、早已成爲常識的“手機不能運行Windows”“手機無法運行Linux發行版、無法建設伺服器”的各種“不可能”，在自由軟體的幫助，以及各路開發者的努力下，正在逐漸變成“可能”。也許妳會說：“我又不做這些‘高科技’工作，我也不使用社交軟體，只是用來打電話，有必要接觸這些‘自由軟體’和‘專有軟體’嗎？”或者“那些擔心隱私洩露的人，妳們到底在怕什麼？不做虧心事，不怕鬼敲門！身正不怕影子斜”之類的話。我認爲，妳可以不必在乎概念，但是我可以保證一點：使用自由軟體對於妳是“百利而無一害”的，牠不會有任何侵犯妳隱私的的行爲，畢竟原始碼都可以被檢查到，誰敢往裏面藏“私貨”呢？請記住：專有軟體，也稱為非自由軟體，表示該軟體不尊重使用者和社群的自由。專有程式把開發者或著作權人的權力地位架在使用者之上。避禍之道就是堅持使用自由（尊重自由的）軟體。因為自由軟體是由使用者自主掌控，因此能對惡意的軟體功能起相當大的保護效果。&lt;/p&gt;
&lt;p&gt;因此，早日使用自由軟體，才能獲得自由。&lt;/p&gt;
&lt;p&gt;最後，這裡是EDKPiepaint，登出，祝妳有個美好的一天！&lt;/p&gt;
&lt;p&gt;[^1]:實際上，紅米2的設計和製造商是 Wingtech，由問泰科技設計生產。
[^2]:來自 &lt;a href=&quot;https://wiki.postmarketos.org/wiki/Qualcomm_Snapdragon_410/412_(MSM8916)#Installation&quot;&gt;Postmarket OS Wiki 的安裝指南&lt;/a&gt;
[^3]: 來自 Postmarket OS Wiki 關於紅米2的&lt;a href=&quot;https://wiki.postmarketos.org/wiki/Xiaomi_Redmi_2_(xiaomi-wt88047)#UART&quot;&gt;描述&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>一個人的科技迷因————盤點我在2024至2025年的自制迷因合集</title><link>https://blog.cloudflare88.eu.org/posts/all-memes-made-by-me/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/all-memes-made-by-me/</guid><description>我不僅是迷因的搬運工，還是迷因的創作者！</description><pubDate>Wed, 11 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;由不知名自由軟體愛好者 EDKPiepaint 創建的一系列迷因，同時將解釋迷因的含義。&lt;/p&gt;
&lt;h1&gt;2024 年&lt;/h1&gt;
&lt;h2&gt;我投靠更有價值的樹莓派&lt;/h2&gt;
&lt;p&gt;時間：2024年9月15日 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;當妳不再因爲CP值買單板電腦之後，我選擇更有價值的樹莓派。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;含義：做ARM單板電腦的廠商很多，樹莓派基金會推出的Raspberry Pi系列算是最為成功的產品。其他中國廠商生產的單板電腦雖然性能更好，外觀更漂亮，但卻常常有驅動閉源、Linux支援度比Android落後、廠商帶頭違反GPL、社群不夠大等問題。&amp;lt;/br&amp;gt;
原版：來自&lt;a href=&quot;https://ivonblog.com/posts/my-ptt-forum-signatures/&quot;&gt;Ivon的部落格&lt;/a&gt; &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;菜楊也精神了&lt;/h2&gt;
&lt;p&gt;時間：2024年8月25日 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;...所以啊，不要跟我講什麼13代酷睿、12代酷睿，這個8代賽揚，使用 Linux Zen 核心、開啓 ZRAM 和 Swap 的話嗎，菜楊也給妳精神了！ &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;含義：我在2024年，在閒魚上購買了華碩的 Chromebox 3 代電腦，但是我爲了省錢，就選擇了自帶8GB RAM 和預裝 Intel 的 賽揚（因爲賽揚是最低端處理器，也就有了“菜楊”的稱號）3865U處理器的最低端版本。但是，在安裝了 Manjaro Linux 後，通過使用 Zen 核心和合理的 ZRAM與 Swap 配置後，系統的流暢度有了明顯的提升，也從最初的“堪用”到完全可用的水平。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/homescreen.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;2025 年&lt;/h1&gt;
&lt;p&gt;因爲高三下學期學業繁忙和備戰高考（考試又不是上戰場，有必要備戰嗎）的緣故，2025年的迷因較少。但是依然足夠經典。 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;我這個手機，是高通MTP845啊！！！&lt;/h2&gt;
&lt;p&gt;時間：2025年2月 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;每當有人指着妳的MTP845問妳這是什麼的時候，妳就可以大聲地對他說：“阿sir，我這個手機，是MTP845啊！” &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;含義：高通的MTP原型機因爲其低調的黑色塑料外殼、以及邊角料熒幕，配以內在性能強大的晶片，這與普通手機的現代、精緻的外觀有着鮮明的對比，常常會被人誤認爲是十幾年前的手機。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/mtp8750-front-view-2.png&quot; &amp;gt;&lt;/p&gt;
&lt;h2&gt;Linux終於成為了4%&lt;/h2&gt;
&lt;p&gt;時間：2025年6月1日&lt;/p&gt;
&lt;p&gt;根據統計資料顯示，Linux終於成為了4%。 &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;含義：根據來自 Statcounter 的統計資料顯示，Linux桌面系統的市佔率在2024年來到了4%。面對其他作業系統的圍攻，最後還是只有4%。&lt;/p&gt;
&lt;h2&gt;發現數位水印的液態玻璃終究還是保不住妳的隱私&lt;/h2&gt;
&lt;p&gt;時間：2025年6月11日&lt;/p&gt;
&lt;p&gt;有人發現，當他們的iPhone更新至iOS 26 後，在 Tik Tok （俗稱“抖音”）應用程式中拉下通知欄或者展開快速設定，就可以在展示的視頻中，發現隱藏的類似黃色二維碼的水印。但是，使用熒幕截圖或者錄製，這個“水印”就會消失。有人猜測這種水印是用來追蹤攝取相關畫面的截圖，然後對該內容進行傳播的人。&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;blockquote class=&quot;twitter-tweet&quot;&amp;gt;&amp;lt;p lang=&quot;zh&quot; dir=&quot;ltr&quot;&amp;gt;6月11日 有网友苹果手机升级到IOS26后，在抖音页面下拉通知栏看到奇怪的二维码，疑似苹果新系统的液态玻璃特效可以暴露抖音的隐水印。&amp;lt;br&amp;gt;但如果开启录屏，这个隐藏的二维码就会消失。 &amp;lt;a href=&quot;https://t.co/XG7u8wSQ8q&quot;&amp;gt;pic.twitter.com/XG7u8wSQ8q&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;— 李老师不是妳老师 (@whyyoutouzhele) &amp;lt;a href=&quot;https://twitter.com/whyyoutouzhele/status/1933097856006770872?ref_src=twsrc%5Etfw&quot;&amp;gt;June 12, 2025&amp;lt;/a&amp;gt;&amp;lt;/blockquote&amp;gt; &amp;lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;含義：儘管iOS 26 這一全新的“液態玻璃”模糊效果能夠暴露出這一深埋在應用中的“暗水印”，但是，iOS是個基於 XNU 核心的封閉原始碼的作業系統，使用者的隱私終究還是被Apple所監控着，而不是被使用者本身所掌握。&lt;/p&gt;
&lt;h2&gt;中國大陸沒有自由與開源(FOSS)軟體所需要的環境&lt;/h2&gt;
&lt;p&gt;時間：2025年6月14日&lt;/p&gt;
&lt;p&gt;妳說妳不想在這裏，我也不想在這裏！可是天黑的太快，想走也早已來不及！ &amp;lt;/br&amp;gt;
喔，我愛妳！可惜長城早高高築起，自由變爲專有，我一個人繼續。生活在黑暗裏，直到長城崩塌！一萬匹脫繮的馬，在他腦海中奔跑（哈！哈！哈！）......&lt;/p&gt;
&lt;p&gt;含義：因爲衆所周知的原因，像是GitHub 、GitLab 、Codeberg等代碼託管平臺在中國大陸內無法使用，而因爲GFW的存在，使得開源軟體無法被廣泛傳播。還有人爲了賺取錢財，公然違反許可協議，將開源軟體放到諸如“鹹魚”等平臺進行盜賣。更有甚者，在獲取了原始碼之後，竟然&lt;strong&gt;將原開發者的名字悄悄抹去，“正大光明”地寫上自己的名字，宣稱這是自己寫的&lt;/strong&gt;&lt;a href=&quot;%5B%E4%BE%86%E8%87%AA%E7%9F%A5%E4%B9%8E%5D(https://www.zhihu.com/question/4598614819/answer/37112454172)&quot;&gt;^1&lt;/a&gt;。這無疑是對開源社區極大的不尊重，任意竊取他人勞動果實的行爲，他們褻瀆了開源精神。
2023年11月，知名代理軟體 Clash 的開發者突然刪除了其位於 GitHub 上的原始碼，這一傳奇的代理軟體從此消失在公衆的視野中，並因此引發了“寒蟬效應”。衆多基於 Clash 開發的代理軟體紛紛停止開發。&amp;lt;/br&amp;gt;
但是，比起相關專業人士的說法，揭露了自由軟體在中國大陸的發展困境的，卻是官方媒體自己。&lt;a href=&quot;%5B%E4%BE%86%E8%87%AA%E2%80%9C%E4%B8%AD%E5%9C%8B%E6%95%B8%E5%AD%97%E6%99%82%E4%BB%A3%E2%80%9D%5D(https://chinadigitaltimes.net/chinese/695054.html)&quot;&gt;^2&lt;/a&gt;
在央視所展示的一段程式開發者通過GitHub下載開源軟體的視頻中，乍看似乎沒有什麼問題，但是，細看之下，開發者的操作可謂“漏洞百出”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用者似乎不太會git命令用法，也可能是誤操作了；&lt;/li&gt;
&lt;li&gt;終端機的日誌告訴我們，使用者正在通過代理軟體訪問GitHub網址（展示了“7890”端口號碼），這提示了GFW的存在，也可能表明使用者正在使用VPN；&lt;/li&gt;
&lt;li&gt;即便如此，使用者仍然遇到了一些問題，最後只能通過鏡像站來解決。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這是當時的一些留言：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Earthly：一开始git clone手动取消了当场export设置proxy（嗯，7890哈哈哈哈哈）然后重新clone，&lt;/p&gt;
&lt;p&gt;clone的源还是不存在的网站。clone两次都失败后打算用pip装个包（比），结果pip访问proxy超时了，又打起&lt;/p&gt;
&lt;p&gt;了tuna的主意，反正直到视频最后都是超时。&lt;/p&gt;
&lt;p&gt;车联网 Odys：官方证实了，开源世界最大的障碍，我们的软件工程师在开源世界的最大的障碍，就是墙。&lt;/p&gt;
&lt;p&gt;softor：翻译：长城防火墙的直接受害者超800万人，影响的生产力更是无法估计。&lt;/p&gt;
&lt;p&gt;softor：端口7890，应该是用了clash吧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段旨在宣傳「中國繁榮開源生態」的報道恰恰展示了國內軟體開發生態的極端閉塞：不但全球最大型最知名的源代碼託管服務平台——GitHub遭到了防火牆的屏蔽，而且連出鏡央視節目的用戶也得親自翻牆，才能進行正常的軟體開發測試。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;00001010 00101101 00101101 00101110 00101101 00101101 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00101101 00101101 00101110 00101110 00101101 00101110 00101101 00101101 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00100000 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00101101 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00101101 00101101 00101110 00101101 00101101 00101101 00101101 00101110 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00101101 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00101101 00101101 00101101 00101110 00101110 00101101 00101110 00101110 00101101 00101101 00101101 00101101 00100000 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101110 00100000 00101110 00101101 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00100000 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101101 00101110 00100000 00101101 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101101 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101110 00101101 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101101 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101101 00101110 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00101101 00101101 00101101 00100000 00101101 00101101 00101110 00101110 00101101 00101101 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101110 00101110 00100000 00101101 00101110 00101110 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101110 00100000 00101110 00101101 00101110 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101110 00101101 00101110 00101101 00101110 00101110 00100000 00101110 00101101 00101110 00100000 00101101 00101101 00101110 00101101 00100000 00101101 00101110 00101110 00101101 00100000 00101101 00101110 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00101110 00100000 00101101 00101110 00101101 00101110 00100000 00101101 00101110 00100000 00101110 00101110 00101110 00101101 00100000 00101110 00101101 00100000 00101101 00101101 00101110 00100000 00101110 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00100000 00101101 00101110 00101101 00101101 00100000 00101110 00101101 00101110 00101110 00100000 00101110 00101110 00101101 00101101 00101101 00100000 00101101 00101101 00101101 00101101 00101101 00100000 00101110 00101110 00101101 00101101 00101101 00100000 00101110 00101110 00101110 00101110 00101110 00001010
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Linux -- A FOSS Parody of Ferrari (Orginal song is made by Babe Rexha)</title><link>https://blog.cloudflare88.eu.org/posts/linux-lyric/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/linux-lyric/</guid><description>Living in the mainline&apos;s getting kinda lonely</description><pubDate>Wed, 11 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;166&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/425969949&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/beberexha&quot; title=&quot;Bebe Rexha&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Bebe Rexha&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/beberexha/ferrari&quot; title=&quot;Ferrari&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Ferrari&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls&amp;gt;
&amp;lt;source src=&quot;https://github.com/Android-Piepaint/android-astro-files/raw/refs/heads/main/Linux%20--%20A%20FOSS%20Parody%20of%20Ferrari%20(Orginal%20song%20is%20made%20by%20Babe%20Rexha).mp3&quot; type=&quot;audio/mpeg&quot;&amp;gt;
Your browser does not support the audio tag.
&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 1&lt;/h1&gt;
&lt;p&gt;Every day&apos;s a blur &amp;lt;/br&amp;gt;
Sometimes I can&apos;t tell what day it is &amp;lt;/br&amp;gt;
Don&apos;t know what day it is &amp;lt;/br&amp;gt;
Can you tell me what day it is? &amp;lt;/br&amp;gt;
Time&apos;s passing by &amp;lt;/br&amp;gt;
&apos;Cause I&apos;m out chasing empty highs &amp;lt;/br&amp;gt;
Every obsolete just means goodbye &amp;lt;/br&amp;gt;
But I&apos;m looking for more this time &amp;lt;/br&amp;gt;
Can we start to slow it down? &amp;lt;/br&amp;gt;
Can we learn to live right now? &amp;lt;/br&amp;gt;
I just want to feel it all, ah-ooh &amp;lt;/br&amp;gt;
I&apos;m Linux booted up from soild-state drive &amp;lt;/br&amp;gt;
Powering whole city, the lights are so pretty from up here &amp;lt;/br&amp;gt;
I&apos;m Linux and after the commits&apos; merged &amp;lt;/br&amp;gt;
I keep on improving, receving new updates &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely (yeah) &amp;lt;/br&amp;gt;
(Oh-oh-oh-ooh, oh-oh-oh-ooh, oh-oh-oh-ooh) &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely &amp;lt;/br&amp;gt;
(Oh-oh-oh-ooh, oh-oh-oh-ooh, oh-oh-oh-ooh) &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely &amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h1&gt;Part 2&lt;/h1&gt;
&lt;p&gt;Got a FOSS heart&amp;lt;/br&amp;gt;
&apos;Cause it&apos;s still beating on its own &amp;lt;/br&amp;gt;
Might be going out in the crowd &amp;lt;/br&amp;gt;
But I&apos;m still coming home alone &amp;lt;/br&amp;gt;
Not trying to hide &amp;lt;/br&amp;gt;
I&apos;m not a developer or programmer &amp;lt;/br&amp;gt;
I&apos;m just trying these as my hobby &amp;lt;/br&amp;gt;
&apos;Cause I just wanna protect my privacy &amp;lt;/br&amp;gt;
I&apos;m Linux booted from on soild-state drive &amp;lt;/br&amp;gt;
Powering whole city, the lights are so pretty from up here &amp;lt;/br&amp;gt;
I&apos;m Linux (I&apos;m Linux) and after the commits&apos; merged &amp;lt;/br&amp;gt;
I keep on improving, receving new updates &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely &amp;lt;/br&amp;gt;
(Oh-oh-oh-ooh, oh-oh-oh-ooh, oh-oh-oh-ooh) &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely &amp;lt;/br&amp;gt;
(Oh-oh-oh-ooh, oh-oh-oh-ooh, oh-oh-oh-ooh) &amp;lt;/br&amp;gt;
I&apos;m Linux booted up from soild-state drive &amp;lt;/br&amp;gt;
Powering whole city, the lights are so pretty from up here &amp;lt;/br&amp;gt;
I&apos;m Linux and after the commits&apos; merged &amp;lt;/br&amp;gt;
I keep on improving, receving new updates &amp;lt;/br&amp;gt;
Living in the mainline&apos;s getting kinda lonely &amp;lt;/br&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Find My Privacy -- A FOSS Parody of Find The Pieces</title><link>https://blog.cloudflare88.eu.org/posts/find-my-privacy/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/find-my-privacy/</guid><pubDate>Sat, 03 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Part 1&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/189379867&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&amp;gt;&amp;lt;a href=&quot;https://soundcloud.com/tryhardninja&quot; title=&quot;TryHardNinja&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;TryHardNinja&amp;lt;/a&amp;gt; · &amp;lt;a href=&quot;https://soundcloud.com/tryhardninja/pieces&quot; title=&quot;Minecraft Song- Find The Pieces (CaptainSparklez and TryHardNinja)&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&amp;gt;Minecraft Song- Find The Pieces (CaptainSparklez and TryHardNinja)&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;This phone, born in shiny day.&amp;lt;/br&amp;gt;
Powerful, running sandbox game.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h4&gt;Pre-Chorus&lt;/h4&gt;
&lt;p&gt;And I wish I could, dig stright down,&amp;lt;/br&amp;gt;
find the all componets.&amp;lt;/br&amp;gt;
But in the dark, there&apos;re still a sound.&amp;lt;/br&amp;gt;
And nothing changed.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h4&gt;Chorus&lt;/h4&gt;
&lt;p&gt;Don&apos;t know if I have compiled kernel,&amp;lt;/br&amp;gt;
but I&apos;ll try it. (&lt;em&gt;try it, try it, try it, try it&lt;/em&gt;)&amp;lt;/br&amp;gt;
Don&apos;t know if I find the documents just for some references.(&lt;em&gt;Reference, reference, reference, reference&lt;/em&gt;)&amp;lt;/br&amp;gt;
To get the mainline kernel runs, isn&apos;t easy.&amp;lt;/br&amp;gt;
Put the source code back together, see what I&apos;m compiling.&amp;lt;/br&amp;gt;
When I find my privacy.&lt;/p&gt;
&lt;p&gt;&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;p&gt;To get the mainline kernel runs, isn&apos;t easy.&amp;lt;/br&amp;gt;
Put the source code back together, see what I&apos;m compiling.&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h2&gt;Part 2&lt;/h2&gt;
&lt;p&gt;Faces, errors with no reason.&amp;lt;/br&amp;gt;
Modem, required special communicaton.&amp;lt;/br&amp;gt;&lt;/p&gt;
&lt;h4&gt;Pre-Chorus&lt;/h4&gt;
&lt;p&gt;And I wish I could, find the firmwares,&amp;lt;/br&amp;gt;
Required for my phone.&amp;lt;/br&amp;gt;
To get linux, running on this beast.&amp;lt;/br&amp;gt;
But something changed.&lt;/p&gt;
&lt;h4&gt;Chorus&lt;/h4&gt;
&lt;p&gt;Don&apos;t know if I have compiled kernel,&amp;lt;/br&amp;gt;
but I&apos;ll try it. (&lt;em&gt;try it, try it, try it, try it&lt;/em&gt;)&amp;lt;/br&amp;gt;
Don&apos;t know if I&apos;ve searched the errors but I&apos;ll fix it.(&lt;em&gt;fix it, fix it, fix it, fix it&lt;/em&gt;)&amp;lt;/br&amp;gt;
To get the mainline kernel runs, isn&apos;t easy.&amp;lt;/br&amp;gt;
Put the source code back together, see what I&apos;m compiling.&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
Put the source code back together, see what I&apos;m compiling.&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
To get the mainline kernel runs, isn&apos;t easy.&amp;lt;/br&amp;gt;
Put the source code back together, see what I&apos;m compiling.&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When I find my privacy.
&amp;lt;/br&amp;gt;
&amp;lt;/br&amp;gt;
When I find my privacy.&lt;/p&gt;
</content:encoded></item><item><title>Markdown Extended Features</title><link>https://blog.cloudflare88.eu.org/posts/guide/markdown-extended/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/guide/markdown-extended/</guid><description>Read more about Markdown features in Fuwari</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;GitHub Repository Cards&lt;/h2&gt;
&lt;p&gt;You can add dynamic cards that link to GitHub repositories, on page load, the repository information is pulled from the GitHub API.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Fabrizz/MMM-OnSpotify&quot;}&lt;/p&gt;
&lt;p&gt;Create a GitHub repository card with the code &lt;code&gt;::github{repo=&quot;&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;saicaca/fuwari&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Admonitions&lt;/h2&gt;
&lt;p&gt;Following types of admonitions are supported: &lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
Highlights information that users should take into account, even when skimming.
:::&lt;/p&gt;
&lt;p&gt;:::tip
Optional information to help a user be more successful.
:::&lt;/p&gt;
&lt;p&gt;:::important
Crucial information necessary for users to succeed.
:::&lt;/p&gt;
&lt;p&gt;:::warning
Critical content demanding immediate user attention due to potential risks.
:::&lt;/p&gt;
&lt;p&gt;:::caution
Negative potential consequences of an action.
:::&lt;/p&gt;
&lt;h3&gt;Basic Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;:::note
Highlights information that users should take into account, even when skimming.
:::

:::tip
Optional information to help a user be more successful.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Custom Titles&lt;/h3&gt;
&lt;p&gt;The title of the admonition can be customized.&lt;/p&gt;
&lt;p&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub Syntax&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;a href=&quot;https://github.com/orgs/community/discussions/16925&quot;&gt;The GitHub syntax&lt;/a&gt; is also supported.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; The GitHub syntax is also supported.

&amp;gt; [!TIP]
&amp;gt; The GitHub syntax is also supported.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Simple Guides for Fuwari</title><link>https://blog.cloudflare88.eu.org/posts/guide/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/guide/</guid><description>How to use this blog template.</description><pubDate>Mon, 01 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Cover image source: &lt;a href=&quot;https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/208fc754-890d-4adb-9753-2c963332675d/width=2048/01651-1456859105-(colour_1.5),girl,_Blue,yellow,green,cyan,purple,red,pink,_best,8k,UHD,masterpiece,male%20focus,%201boy,gloves,%20ponytail,%20long%20hair,.jpeg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown Example</title><link>https://blog.cloudflare88.eu.org/posts/guide/markdown/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/guide/markdown/</guid><description>A simple example of a Markdown blog post.</description><pubDate>Sun, 01 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;An h1 header&lt;/h1&gt;
&lt;p&gt;Paragraphs are separated by a blank line.&lt;/p&gt;
&lt;p&gt;2nd paragraph. &lt;em&gt;Italic&lt;/em&gt;, &lt;strong&gt;bold&lt;/strong&gt;, and &lt;code&gt;monospace&lt;/code&gt;. Itemized lists
look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;this one&lt;/li&gt;
&lt;li&gt;that one&lt;/li&gt;
&lt;li&gt;the other one&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that --- not considering the asterisk --- the actual text
content starts at 4-columns in.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Block quotes are
written like so.&lt;/p&gt;
&lt;p&gt;They can span multiple paragraphs,
if you like.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., &quot;it&apos;s all
in chapters 12--14&quot;). Three dots ... will be converted to an ellipsis.
Unicode is supported. ☺&lt;/p&gt;
&lt;h2&gt;An h2 header&lt;/h2&gt;
&lt;p&gt;Here&apos;s a numbered list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;first item&lt;/li&gt;
&lt;li&gt;second item&lt;/li&gt;
&lt;li&gt;third item&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note again how the actual text starts at 4 columns in (4 characters
from the left side). Here&apos;s a code sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Let me re-iterate ...
for i in 1 .. 10 { do-something(i) }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you probably guessed, indented 4 spaces. By the way, instead of
indenting the block, you can use delimited blocks, if you like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define foobar() {
    print &quot;Welcome to flavor country!&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(which makes copying &amp;amp; pasting easier). You can optionally mark the
delimited block for Pandoc to syntax highlight it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import time
# Quick, count to ten!
for i in range(10):
    # (but not *too* quick)
    time.sleep(0.5)
    print i
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;An h3 header&lt;/h3&gt;
&lt;p&gt;Now a nested list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, get these ingredients:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;carrots&lt;/li&gt;
&lt;li&gt;celery&lt;/li&gt;
&lt;li&gt;lentils&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Boil some water.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dump everything in the pot and follow
this algorithm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; find wooden spoon
 uncover pot
 stir
 cover pot
 balance wooden spoon precariously on pot handle
 wait 10 minutes
 goto first step (or shut off burner when done)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do not bump wooden spoon or it will fall.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice again how text always lines up on 4-space indents (including
that last line which continues item 3 above).&lt;/p&gt;
&lt;p&gt;Here&apos;s a link to &lt;a href=&quot;http://foo.bar&quot;&gt;a website&lt;/a&gt;, to a &lt;a href=&quot;local-doc.html&quot;&gt;local
doc&lt;/a&gt;, and to a &lt;a href=&quot;#an-h2-header&quot;&gt;section heading in the current
doc&lt;/a&gt;. Here&apos;s a footnote [^1].&lt;/p&gt;
&lt;p&gt;[^1]: Footnote text goes here.&lt;/p&gt;
&lt;p&gt;Tables can look like this:&lt;/p&gt;
&lt;p&gt;size material color&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;9 leather brown
10 hemp canvas natural
11 glass transparent&lt;/p&gt;
&lt;p&gt;Table: Shoes, their sizes, and what they&apos;re made of&lt;/p&gt;
&lt;p&gt;(The above is the caption for the table.) Pandoc also supports
multi-line tables:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;keyword text&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;red Sunsets, apples, and
other red or reddish
things.&lt;/p&gt;
&lt;p&gt;green Leaves, grass, frogs
and other things it&apos;s
not easy being.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A horizontal rule follows.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here&apos;s a definition list:&lt;/p&gt;
&lt;p&gt;apples
: Good for making applesauce.
oranges
: Citrus!
tomatoes
: There&apos;s no &quot;e&quot; in tomatoe.&lt;/p&gt;
&lt;p&gt;Again, text is indented 4 spaces. (Put a blank line between each
term/definition pair to spread things out more.)&lt;/p&gt;
&lt;p&gt;Here&apos;s a &quot;line block&quot;:&lt;/p&gt;
&lt;p&gt;| Line one
| Line too
| Line tree&lt;/p&gt;
&lt;p&gt;and images can be specified like so:&lt;/p&gt;
&lt;p&gt;Inline math equations go in like so: $\omega = d\phi / dt$. Display
math should get its own line and be put in in double-dollarsigns:&lt;/p&gt;
&lt;p&gt;$$I = \int \rho R^{2} dV$$&lt;/p&gt;
&lt;p&gt;$$
\begin{equation*}
\pi
=3.1415926535
;8979323846;2643383279;5028841971;6939937510;5820974944
;5923078164;0628620899;8628034825;3421170679;\ldots
\end{equation*}
$$&lt;/p&gt;
&lt;p&gt;And note that you can backslash-escape any punctuation characters
which you wish to be displayed literally, ex.: `foo`, *bar*, etc.&lt;/p&gt;
</content:encoded></item><item><title>Include Video in the Posts</title><link>https://blog.cloudflare88.eu.org/posts/guide/video/</link><guid isPermaLink="true">https://blog.cloudflare88.eu.org/posts/guide/video/</guid><description>This post demonstrates how to include embedded video in a blog post.</description><pubDate>Tue, 01 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Include Video in the Post
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item></channel></rss>