<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Wely</title><description>Wely | 博客</description><link>https://blog.wely.fun/</link><language>zh_CN</language><item><title>sunxi_d1 设备树文件定位报告</title><link>https://blog.wely.fun/posts/sunxi_d1-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%AE%9A%E4%BD%8D%E6%8A%A5%E5%91%8A/</link><guid isPermaLink="true">https://blog.wely.fun/posts/sunxi_d1-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%AE%9A%E4%BD%8D%E6%8A%A5%E5%91%8A/</guid><description>为哪吒 D1 开发板适配的开源鸿蒙系统定位构建依赖的内核设备树源文件。</description><pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;sunxi_d1 设备树文件定位报告&lt;/h1&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;在开源鸿蒙系统源码的根目录 &lt;code&gt;OpenHarmony&lt;/code&gt; 中，使用以下命令构建内核时：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./build.sh --product-name sunxi_d1 --ccache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要修改的 Linux 内核设备树源文件是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;device/sunxi/config/chips/d1/configs/nezha/linux-5.4/board.dts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该文件会被构建脚本复制到内核源码树并参与设备树编译。请修改此文件，不要直接修改 &lt;code&gt;out/&lt;/code&gt; 目录中生成的 DTS/DTB 中间产物。&lt;/p&gt;
&lt;p&gt;若硬件改动还影响 U-Boot 阶段（例如启动介质、早期供电、启动显示），还应检查并按需修改：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;device/sunxi/config/chips/d1/configs/nezha/uboot-board.dts&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;确认依据&lt;/h2&gt;
&lt;h3&gt;1. 产品选择了 sunxi 的 D1 设备包&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;productdefine/common/products/sunxi_d1.json&lt;/code&gt; 定义产品 &lt;code&gt;sunxi_d1&lt;/code&gt;，并在 &lt;code&gt;parts&lt;/code&gt; 中引入 &lt;code&gt;sunxi_products:sunxi_products&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;随后，&lt;code&gt;device/sunxi/build/BUILD.gn&lt;/code&gt; 的 &lt;code&gt;products_group&lt;/code&gt; 在设备类型为 &lt;code&gt;sunxi_d1&lt;/code&gt; 时，依赖 &lt;code&gt;//device/sunxi/sunxi_d1:sunxi_d1_group&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;2. D1 设备包构建内核目标&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;device/sunxi/sunxi_d1/BUILD.gn&lt;/code&gt; 的 &lt;code&gt;sunxi_d1_group&lt;/code&gt; 依赖 &lt;code&gt;kernel:kernel&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;device/sunxi/sunxi_d1/kernel/BUILD.gn&lt;/code&gt; 将内核源码设为 &lt;code&gt;//kernel/linux-5.4&lt;/code&gt;，并通过 &lt;code&gt;build_kernel.sh&lt;/code&gt; 调用内核构建流程，设备类型参数为 &lt;code&gt;sunxi_d1&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;3. D1 内核构建流程选用 kernel-5.4.mk&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kernel/linux/patches/kernel_module_build.sh&lt;/code&gt; 对 &lt;code&gt;sunxi_d1&lt;/code&gt; 设置 &lt;code&gt;TARGET_PRODUCT=sunxi_d1&lt;/code&gt; 和 Linux 5.4 输出目录；随后执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make -f kernel-5.4.mk
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 构建规则明确复制并编译 nezha 的 board.dts&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kernel/linux/patches/kernel-5.4.mk&lt;/code&gt; 第 98 行包含以下复制规则：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp $(OHOS_BUILD_HOME)/device/sunxi/config/chips/d1/configs/nezha/linux-5.4/board.dts \
   $(KERNEL_SRC_TMP_PATH)/arch/riscv/boot/dts/sunxi/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这说明项目源目录中的 &lt;code&gt;device/sunxi/config/chips/d1/configs/nezha/linux-5.4/board.dts&lt;/code&gt; 会进入内核的 RISC-V sunxi DTS 编译目录，因此它是上述构建命令所使用的 Linux 内核板级设备树源文件。&lt;/p&gt;
&lt;h2&gt;为什么不是其他 board.dts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;其他芯片或板型目录下的 &lt;code&gt;board.dts&lt;/code&gt; 不在 &lt;code&gt;sunxi_d1&lt;/code&gt; 的上述复制规则中。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out/&lt;/code&gt; 中的文件是构建生成的中间产物，下一次构建可能被覆盖，不能作为源文件修改。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uboot-board.dts&lt;/code&gt; 属于 U-Boot 板级配置；只有在执行 &lt;code&gt;device/sunxi/build/pack&lt;/code&gt; 打包并需要改变 U-Boot 行为时才需要同步修改。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;相关文件&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;Linux 内核设备树（本次构建应修改）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;device/sunxi/config/chips/d1/configs/nezha/linux-5.4/board.dts&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;U-Boot 设备树（按硬件改动需要同步）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;device/sunxi/config/chips/d1/configs/nezha/uboot-board.dts&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux 设备树复制规则&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kernel/linux/patches/kernel-5.4.mk&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内核构建入口&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kernel/linux/patches/kernel_module_build.sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>开源鸿蒙系统配置 USB 转网口驱动</title><link>https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AEusb%E8%BD%AC%E7%BD%91%E5%8F%A3%E9%A9%B1%E5%8A%A8/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AEusb%E8%BD%AC%E7%BD%91%E5%8F%A3%E9%A9%B1%E5%8A%A8/</guid><description>为哪吒 D1 开发板适配的开源鸿蒙系统配置 USB 转网口驱动。</description><pubDate>Sat, 10 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;哪吒 D1 开发板可通过 USB 转网口模块实现网络连接。但在开源鸿蒙系统中，内核默认并未配置该驱动。本文将介绍如何为开源鸿蒙系统内核添加 USB 转网口驱动支持。&lt;/p&gt;
&lt;h1&gt;修改内核配置&lt;/h1&gt;
&lt;p&gt;内核配置文件位于以下位置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OpenHarmony/device/sunxi/config/chips/d1/configs/nezha/linux-5.4/config-5.4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中 &lt;code&gt;OpenHarmony&lt;/code&gt; 是开源鸿蒙系统源码的根目录。&lt;/p&gt;
&lt;p&gt;打开该文件，在文件末尾添加以下配置选项：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_USBNET=y
CONFIG_USB_RTL8152=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_RNDIS_HOST=y
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_CDC_MBIM=y
CONFIG_USB_NET_CDC_EEM=y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存文件后，重新构建系统。&lt;/p&gt;
&lt;h1&gt;构建系统&lt;/h1&gt;
&lt;p&gt;在开源鸿蒙系统源码根目录 &lt;code&gt;OpenHarmony&lt;/code&gt; 下，首先删除已有的构建内容 &lt;code&gt;out&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rm -rf out
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后执行以下命令进行构建：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./build.sh --product-name sunxi_d1 --ccache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后续参考 &lt;a href=&quot;https://blog.wely.fun/posts/%E6%9E%84%E5%BB%BA%E9%80%82%E7%94%A8%E4%BA%8E%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%9A%84%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F/&quot;&gt;构建适用于哪吒开发板的开源鸿蒙系统&lt;/a&gt; 进行系统构建和生成镜像文件并烧写。参考 &lt;a href=&quot;https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E7%BD%91%E7%BB%9C/&quot;&gt;开源鸿蒙系统配置网络&lt;/a&gt; 进行网络配置。&lt;/p&gt;
</content:encoded></item><item><title>解决 WPS 的 libdbus-1 问题</title><link>https://blog.wely.fun/posts/%E8%A7%A3%E5%86%B3wps%E7%9A%84libdbus-1%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E8%A7%A3%E5%86%B3wps%E7%9A%84libdbus-1%E9%97%AE%E9%A2%98/</guid><description>解决在 arm64 的 Linux 上运行 WPS 出现的 Cannot find libdbus-1 in your system to resolve symbol dbus_get_local_machine_id.</description><pubDate>Wed, 03 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在给树莓派 5 上 &lt;code&gt;arm64&lt;/code&gt; 架构的 &lt;code&gt;Debian 13&lt;/code&gt; 系统安装 &lt;code&gt;WPS 365&lt;/code&gt; 后，会出现打不开的问题，运行 &lt;code&gt;wps&lt;/code&gt; 命令后终端输出如下错误信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wely@pi500:/opt/kingsoft/wps-office/office6 $ ./wps
qt.qpa.plugin: Could not find the Qt platform plugin &quot;wayland&quot; in &quot;&quot;
QFont::fromString: Invalid description &apos;苹方-简,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,常规体&apos;
QFont::fromString: Invalid description &apos;Consolas,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1&apos;
QFont::fromString: Invalid description &apos;苹方-简,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,常规体&apos;
QFont::fromString: Invalid description &apos;苹方-简,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,常规体&apos;
Cannot find libdbus-1 in your system to resolve symbol &apos;dbus_get_local_machine_id&apos;.
段错误（核心已转储）
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;解决方案&lt;/h1&gt;
&lt;p&gt;在四处搜寻解决方案无果后，&lt;code&gt;GPT-5.1&lt;/code&gt; 给出了一个可行的解决方案（不得不说还得是 &lt;code&gt;ChatGPT&lt;/code&gt; 厉害）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /opt/kingsoft/wps-office/office6/addons/cef
sudo mv libm.so.6 libm.so.6.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行完上述命令后，再次运行 &lt;code&gt;wps&lt;/code&gt;，WPS 成功启动。&lt;/p&gt;
&lt;h1&gt;原因&lt;/h1&gt;
&lt;p&gt;从报错来看，貌似是 &lt;code&gt;WPS&lt;/code&gt; 找不到 &lt;code&gt;libdbus-1&lt;/code&gt; 库，但此时系统里是有安装 &lt;code&gt;libdbus-1&lt;/code&gt; 库的，运行以下命令可以看到：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wely@pi500:~ $ ls -l /usr/lib/*/libdbus-1.so*
lrwxrwxrwx 1 root root     19 2025年 3月 9日 /usr/lib/aarch64-linux-gnu/libdbus-1.so.3 -&amp;gt; libdbus-1.so.3.38.3
-rw-r--r-- 1 root root 395416 2025年 3月 9日 /usr/lib/aarch64-linux-gnu/libdbus-1.so.3.38.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;手动抓一份调试日志来查找原因：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /opt/kingsoft/wps-office/office6
./wps 2&amp;gt; /tmp/wps-ld.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看日志内容，发现一行致命错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/opt/kingsoft/wps-office/office6/addons/cef/libm.so.6: error: version lookup error:
version `GLIBC_2.39&apos; not found (required by /lib/aarch64-linux-gnu/libsystemd.so.0) (fatal)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;意思是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WPS 自带了一份旧的 &lt;code&gt;libm.so.6&lt;/code&gt;：&lt;br /&gt;
&lt;code&gt;/opt/kingsoft/wps-office/office6/addons/cef/libm.so.6&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;系统里的 &lt;code&gt;libsystemd.so.0&lt;/code&gt; 是用 &lt;strong&gt;glibc 2.39&lt;/strong&gt; 编译的，需要 &lt;code&gt;GLIBC_2.39&lt;/code&gt; 版本的符号；&lt;/li&gt;
&lt;li&gt;结果动态链接器优先加载了 WPS 目录里的这个旧 &lt;code&gt;libm.so.6&lt;/code&gt;，它没有 &lt;code&gt;GLIBC_2.39&lt;/code&gt; 版本的符号，于是报错 &lt;strong&gt;(fatal)&lt;/strong&gt;，后面一连串找 &lt;code&gt;libdbus-1&lt;/code&gt; 也就全都失败了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以是 &lt;strong&gt;WPS 自带的旧 C 运行库（libm.so.6）跟系统太新（glibc 2.39）的库冲突&lt;/strong&gt;，把整个动态链接过程搞崩了，Qt 最后只能说“找不到 libdbus-1”。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;解决办法：让 WPS 用系统的 libm，而不是自带那份&lt;/h2&gt;
&lt;p&gt;直接把 WPS 自带的 &lt;code&gt;libm.so.6&lt;/code&gt; 改名，让它加载系统的 &lt;code&gt;/lib/aarch64-linux-gnu/libm.so.6&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /opt/kingsoft/wps-office/office6/addons/cef
sudo mv libm.so.6 libm.so.6.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再次运行 &lt;code&gt;wps&lt;/code&gt;，WPS 成功启动。&lt;/p&gt;
</content:encoded></item><item><title>开源鸿蒙哪吒开发板使用gdbserver调试程序</title><link>https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E4%BD%BF%E7%94%A8gdbserver%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E4%BD%BF%E7%94%A8gdbserver%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F/</guid><description>使用 gdb 与 gdbserver 为开源鸿蒙哪吒开发板调试程序，并配置 vscode 进行可视化调试。</description><pubDate>Wed, 29 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;gdb&lt;/code&gt; 与 &lt;code&gt;gdbserver&lt;/code&gt; 是 GNU 提供的远程调试工具，&lt;code&gt;gdb&lt;/code&gt; 运行在主机上，&lt;code&gt;gdbserver&lt;/code&gt; 运行在目标设备上，通过网络连接实现远程调试。本文介绍如何为开源鸿蒙哪吒开发板配置 &lt;code&gt;gdbserver&lt;/code&gt; 进行程序调试，并在 &lt;code&gt;vscode&lt;/code&gt; 中进行可视化调试。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
被调试的程序需要是 &lt;code&gt;debug&lt;/code&gt; 模式编译的可执行文件，以包含调试信息，在编译时需要加入 &lt;code&gt;-g&lt;/code&gt; 参数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;编译 &lt;code&gt;gdbserver&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;首先依照 &lt;a href=&quot;https://blog.wely.fun/posts/%E4%B8%BA%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%BC%96%E5%86%99%E7%A8%8B%E5%BA%8F/&quot;&gt;为开源鸿蒙哪吒开发板编写程序&lt;/a&gt; 中的步骤，下载并解压 &lt;code&gt;剑池开发工具集&lt;/code&gt; 中的 &lt;code&gt;GCC工具链-900系列&lt;/code&gt;。本文以 &lt;code&gt;Linux&lt;/code&gt; 系统为例，使用 &lt;code&gt;Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;打开终端，首先下载并解压 &lt;code&gt;gdb&lt;/code&gt; 源码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://ftp.gnu.org/gnu/gdb/gdb-16.3.tar.xz
tar -xvf gdb-16.3.tar.xz
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
也可以从 &lt;a href=&quot;https://ftp.gnu.org/gnu/gdb/gdb-16.3.tar.xz&quot;&gt;GNU FTP 站点&lt;/a&gt; 直接下载 &lt;code&gt;gdb&lt;/code&gt; 源码。下载速度较慢时，可以使用国内镜像站点，例如 &lt;a href=&quot;https://mirrors.tuna.tsinghua.edu.cn/gnu/gdb/gdb-16.3.tar.xz&quot;&gt;清华大学开源软件镜像站&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因为 &lt;code&gt;gdb&lt;/code&gt; 在之前下载的编译工具链中已经包含，我们只需要编译 &lt;code&gt;gdbserver&lt;/code&gt; 部分。进入解压后的 &lt;code&gt;gdb-16.3&lt;/code&gt; 目录，并新建 &lt;code&gt;build&lt;/code&gt; 文件夹：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd gdb-16.3
mkdir build
cd build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用以下命令进行编译，注意替换 &lt;code&gt;TOOL&lt;/code&gt; 路径为实际的编译器路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export TRIPLE=riscv64-unknown-linux-musl
export TOOL=/home/wely/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.2.0/bin/
export CC=&quot;$TOOL$TRIPLE-gcc&quot;
export CXX=&quot;$TOOL$TRIPLE-g++&quot;
export AR=&quot;$TOOL$TRIPLE-ar&quot;
export RANLIB=&quot;$TOOL$TRIPLE-ranlib&quot;
export CFLAGS=&quot;-O2 -DELF_NFPREG=33&quot;
export CXXFLAGS=&quot;-O2 -DELF_NFPREG=33&quot;
export LDFLAGS=&quot;-static -Wl,--gc-sections -static-libgcc -static-libstdc++&quot;
../configure --host=&quot;$TRIPLE&quot; --disable-gdb --disable-werror --without-python --without-guile --disable-inprocess-agent
make -j&quot;$(nproc)&quot; all-gdbserver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编译完成后，&lt;code&gt;gdbserver&lt;/code&gt; 可执行文件位于 &lt;code&gt;gdb-16.3/build/gdbserver/gdbserver&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;将 &lt;code&gt;gdbserver&lt;/code&gt; 可执行文件传输到开源鸿蒙哪吒开发板上，作为服务端运行。建议复制到 &lt;code&gt;/bin/&lt;/code&gt; 目录下，以便全局使用。&lt;/p&gt;
&lt;h1&gt;使用 &lt;code&gt;gdb&lt;/code&gt; 连接 &lt;code&gt;gdbserver&lt;/code&gt; 进行调试&lt;/h1&gt;
&lt;p&gt;首先在开源鸿蒙哪吒开发板上启动 &lt;code&gt;gdbserver&lt;/code&gt;，监听指定端口（例如 &lt;code&gt;23456&lt;/code&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gdbserver --multi :23456
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在主机上，使用编译工具链中的 &lt;code&gt;riscv64-unknown-linux-musl-gdb&lt;/code&gt;，连接到哪吒开发板上的 &lt;code&gt;gdbserver&lt;/code&gt;，注意将 &lt;code&gt;/host/test-cpp-debug&lt;/code&gt; 替换为主机实际的可执行文件路径，将 &lt;code&gt;x.x.x.x&lt;/code&gt; 替换为哪吒开发板的实际 IP 地址，并设置远程执行文件路径为哪吒开发板上的实际路径 &lt;code&gt;/remote/test-cpp-debug&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./riscv64-unknown-linux-musl-gdb /host/test-cpp-debug
(gdb) target extended-remote x.x.x.x:23456
(gdb) set remote exec-file /remote/test-cpp-debug
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在可以使用 &lt;code&gt;gdb&lt;/code&gt; 命令进行调试，例如设置断点、单步执行等：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(gdb) break main
(gdb) continue
(gdb) step
(gdb) print variable_name
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;在 &lt;code&gt;vscode&lt;/code&gt; 中配置可视化调试&lt;/h1&gt;
&lt;p&gt;首先在开源鸿蒙哪吒开发板上启动 &lt;code&gt;gdbserver&lt;/code&gt;，监听指定端口（例如 &lt;code&gt;23456&lt;/code&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gdbserver --multi :23456
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在主机上，在 &lt;code&gt;vscode&lt;/code&gt; 中安装 &lt;code&gt;C/C++&lt;/code&gt; 扩展，然后创建或修改项目中的 &lt;code&gt;.vscode/launch.json&lt;/code&gt; 文件，添加以下配置，注意替换 &lt;code&gt;program&lt;/code&gt; 为实际的主机可执行文件路径，替换 &lt;code&gt;miDebuggerPath&lt;/code&gt; 为实际的 &lt;code&gt;riscv64-unknown-linux-musl-gdb&lt;/code&gt; 路径，替换 &lt;code&gt;-target-select extended-remote x.x.x.x:23456&lt;/code&gt; 中的 IP 地址和端口号为实际的哪吒开发板地址和端口号，替换 &lt;code&gt;set remote exec-file /remote/test-cpp-debug&lt;/code&gt; 为实际的哪吒开发板可执行文件路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息，请访问: https://go.microsoft.com/fwlink/?linkid=830387
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;(gdb) 远程&quot;,
            &quot;type&quot;: &quot;cppdbg&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${workspaceFolder}/test-cpp-debug&quot;,
            &quot;args&quot;: [],
            &quot;stopAtEntry&quot;: true,
            &quot;cwd&quot;: &quot;${fileDirname}&quot;,
            &quot;environment&quot;: [],
            &quot;externalConsole&quot;: false,
            &quot;MIMode&quot;: &quot;gdb&quot;,
            &quot;miDebuggerPath&quot;: &quot;riscv64-unknown-linux-musl-gdb&quot;,
            &quot;setupCommands&quot;: [
                {
                    &quot;description&quot;: &quot;为 gdb 启用整齐打印&quot;,
                    &quot;text&quot;: &quot;-enable-pretty-printing&quot;,
                    &quot;ignoreFailures&quot;: true
                },
                {
                    &quot;description&quot;: &quot;将反汇编风格设置为 Intel&quot;,
                    &quot;text&quot;: &quot;-gdb-set disassembly-flavor intel&quot;,
                    &quot;ignoreFailures&quot;: true
                },
                { &quot;text&quot;: &quot;-target-select extended-remote x.x.x.x:23456&quot; },
                { &quot;text&quot;: &quot;set remote exec-file /remote/test-cpp-debug&quot; },
                { &quot;text&quot;: &quot;skip file /musl/&quot; },
                { &quot;text&quot;: &quot;skip function exit&quot; },
                { &quot;text&quot;: &quot;skip function _Exit&quot; }
            ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存后，在 &lt;code&gt;vscode&lt;/code&gt; 中启动调试，即可通过图形界面进行断点设置、单步执行和变量查看等操作。&lt;/p&gt;
&lt;h1&gt;进阶：在 &lt;code&gt;vscode&lt;/code&gt; 中一键编译、上传与调试&lt;/h1&gt;
&lt;p&gt;可以在开发板上运行 &lt;code&gt;ssh&lt;/code&gt; 服务，使 &lt;code&gt;vscode&lt;/code&gt; 能够通过 &lt;code&gt;scp&lt;/code&gt; 自动上传编译后的可执行文件，实现一键调试。&lt;/p&gt;
&lt;h2&gt;编译 &lt;code&gt;dropbear&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dropbear&lt;/code&gt; 是一个轻量级的 &lt;code&gt;ssh&lt;/code&gt; 服务器，适合资源受限的嵌入式设备。&lt;/p&gt;
&lt;p&gt;还是依照 &lt;a href=&quot;https://blog.wely.fun/posts/%E4%B8%BA%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%BC%96%E5%86%99%E7%A8%8B%E5%BA%8F/&quot;&gt;为开源鸿蒙哪吒开发板编写程序&lt;/a&gt; 中的步骤，下载并解压 &lt;code&gt;剑池开发工具集&lt;/code&gt; 中的 &lt;code&gt;GCC工具链-900系列&lt;/code&gt;。本文以 &lt;code&gt;Linux&lt;/code&gt; 系统为例，使用 &lt;code&gt;Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;获取 &lt;code&gt;dropbear&lt;/code&gt; 源码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/mkj/dropbear.git
cd dropbear
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建 &lt;code&gt;build&lt;/code&gt; 目录并进入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir build
cd build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用以下命令进行编译，注意替换 &lt;code&gt;TOOL&lt;/code&gt; 路径为实际的编译器路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export TRIPLE=riscv64-unknown-linux-musl
export TOOL=/home/wely/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.2.0/bin/
export CC=&quot;$TOOL$TRIPLE-gcc&quot;
export CXX=&quot;$TOOL$TRIPLE-g++&quot;
export AR=&quot;$TOOL$TRIPLE-ar&quot;
export RANLIB=&quot;$TOOL$TRIPLE-ranlib&quot;
export CFLAGS=&quot;-O2 -DELF_NFPREG=33&quot;
export CXXFLAGS=&quot;-O2 -DELF_NFPREG=33&quot;
export LDFLAGS=&quot;-static -Wl,--gc-sections -static-libgcc -static-libstdc++&quot;
../configure --host=riscv64-linux-musl --disable-pam --disable-zlib --disable-shadow --disable-lastlog --disable-wtmp --disable-utmp
make MULTI=1 PROGRAMS=&quot;dropbear dbclient dropbearkey scp&quot; LDFLAGS=&quot;-static&quot; -j$(nproc)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编译完成后，&lt;code&gt;dropbearmulti&lt;/code&gt; 可执行文件位于 &lt;code&gt;dropbear/build/dropbearmulti&lt;/code&gt;，它是一个多合一可执行文件，包含 &lt;code&gt;dropbear&lt;/code&gt;、&lt;code&gt;dbclient&lt;/code&gt;、&lt;code&gt;dropbearkey&lt;/code&gt; 和 &lt;code&gt;scp&lt;/code&gt; 四个程序。&lt;/p&gt;
&lt;p&gt;将 &lt;code&gt;dropbearmulti&lt;/code&gt; 可执行文件传输到开源鸿蒙哪吒开发板上，作为 &lt;code&gt;ssh&lt;/code&gt; 服务器运行。建议复制到 &lt;code&gt;/bin/&lt;/code&gt; 目录下，以便全局使用。&lt;/p&gt;
&lt;h2&gt;配置 &lt;code&gt;dropbear&lt;/code&gt; 服务器&lt;/h2&gt;
&lt;p&gt;为方便使用，创建符号链接：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ln -s /bin/dropbearmulti /bin/dropbear
ln -s /bin/dropbearmulti /bin/dbclient
ln -s /bin/dropbearmulti /bin/dropbearkey
ln -s /bin/dropbearmulti /bin/scp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成主机密钥：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /etc/dropbear
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;root&lt;/code&gt; 用户配置使其可登录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /etc/passwd /etc/passwd.bak
sed -i &apos;/^root:/c root:x:0:0:root:/root:/bin/sh&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置 &lt;code&gt;root&lt;/code&gt; 用户密码，此时&lt;strong&gt;在本地&lt;/strong&gt;生成密码的哈希值（注意&lt;strong&gt;不是在开发板上&lt;/strong&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;openssl passwd -6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按提示输入两次你想要的密码，得到一串形如 &lt;code&gt;$6$6$xxxxx$yyyy&lt;/code&gt; 的哈希，复制备用。&lt;strong&gt;在开发板上&lt;/strong&gt;将此哈希值设置为变量：&lt;code&gt;HASH=&apos;$6$......&apos;&lt;/code&gt;（以下&lt;strong&gt;回到开发板上&lt;/strong&gt;运行）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;HASH=&apos;$6$......&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将密码写入 &lt;code&gt;/etc/passwd&lt;/code&gt; 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sed -i &quot;s#^root:[^:]*:#root:${HASH}:#&quot; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建 &lt;code&gt;root&lt;/code&gt; 用户的家目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /root &amp;amp;&amp;amp; chmod 700 /root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建 &lt;code&gt;.ssh&lt;/code&gt; 目录并设置权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /root/.ssh &amp;amp;&amp;amp; chmod 700 /root/.ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时可启动 &lt;code&gt;dropbear&lt;/code&gt; 服务器，测试密码登录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dropbear -E -F -R -p 22
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可在主机上使用 &lt;code&gt;ssh&lt;/code&gt; 连接到哪吒开发板，输入密码测试登录。&lt;/p&gt;
&lt;h2&gt;配置密钥登录&lt;/h2&gt;
&lt;p&gt;在&lt;strong&gt;主机上&lt;/strong&gt;生成 &lt;code&gt;ssh&lt;/code&gt; 密钥对（注意&lt;strong&gt;不是在开发板上&lt;/strong&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sh-keygen -t rsa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行后会提示输入文件名和密码，可直接回车使用默认文件名且不设置密码。生成的公钥文件为 &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt;，私钥文件为 &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;ssh-copy-id&lt;/code&gt; 将公钥复制到哪吒开发板的 &lt;code&gt;root&lt;/code&gt; 用户下（注意替换 &lt;code&gt;x.x.x.x&lt;/code&gt; 为实际 IP 地址）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-copy-id -i ~/.ssh/id_rsa.pub root@x.x.x.x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注：也可以手动将公钥内容追加到哪吒开发板的 &lt;code&gt;/root/.ssh/authorized_keys&lt;/code&gt; 文件中。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在客户端查看公钥
cat ~/.ssh/id_rsa.pub

# 在服务器上添加到 authorized_keys
mkdir -p root/.ssh
chmod 700 root/.ssh
echo &quot;粘贴公钥内容&quot; &amp;gt;&amp;gt; root/.ssh/authorized_keys
chmod 600 root/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上传完成后，即可使用密钥登录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -i ~/.ssh/id_rsa root@x.x.x.x
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;在 &lt;code&gt;vscode&lt;/code&gt; 中配置一键上传与调试&lt;/h2&gt;
&lt;p&gt;配置 &lt;code&gt;.vscode/launch.json&lt;/code&gt; 文件，注意修改 &lt;code&gt;miDebuggerPath&lt;/code&gt;、&lt;code&gt;x.x.x.x&lt;/code&gt; 以及 &lt;code&gt;set remote exec-file&lt;/code&gt; 中的 IP 地址和可执行文件路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息，请访问: https://go.microsoft.com/fwlink/?linkid=830387
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;(gdb) 远程&quot;,
            &quot;type&quot;: &quot;cppdbg&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${fileDirname}/${fileBasenameNoExtension}-debug&quot;,
            &quot;args&quot;: [],
            &quot;stopAtEntry&quot;: true,
            &quot;cwd&quot;: &quot;${fileDirname}&quot;,
            &quot;environment&quot;: [],
            &quot;externalConsole&quot;: false,
            &quot;MIMode&quot;: &quot;gdb&quot;,
            &quot;miDebuggerPath&quot;: &quot;riscv64-unknown-linux-musl-gdb&quot;,
            &quot;preLaunchTask&quot;: &quot;build+upload&quot;,
            &quot;setupCommands&quot;: [
                {
                    &quot;description&quot;: &quot;为 gdb 启用整齐打印&quot;,
                    &quot;text&quot;: &quot;-enable-pretty-printing&quot;,
                    &quot;ignoreFailures&quot;: true
                },
                {
                    &quot;description&quot;: &quot;将反汇编风格设置为 Intel&quot;,
                    &quot;text&quot;: &quot;-gdb-set disassembly-flavor intel&quot;,
                    &quot;ignoreFailures&quot;: true
                },
                { &quot;text&quot;: &quot;-target-select extended-remote x.x.x.x:23456&quot; },
                { &quot;text&quot;: &quot;set remote exec-file ${fileBasenameNoExtension}-debug&quot; },
                { &quot;text&quot;: &quot;skip file /musl/&quot; },
                { &quot;text&quot;: &quot;skip function exit&quot; },
                { &quot;text&quot;: &quot;skip function _Exit&quot; }
            ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置 &lt;code&gt;.vscode/tasks.json&lt;/code&gt; 文件，添加编译与上传任务，注意修改 &lt;code&gt;riscv64-unknown-linux-musl-g++&lt;/code&gt; 编译器路径与 &lt;code&gt;scp&lt;/code&gt; 使用的 &lt;code&gt;id_rsa&lt;/code&gt; 私钥、&lt;code&gt;x.x.x.x&lt;/code&gt; IP 和 &lt;code&gt;/&lt;/code&gt; 上传路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;version&quot;: &quot;2.0.0&quot;,
  &quot;tasks&quot;: [
    {
      &quot;label&quot;: &quot;build-static-riscv&quot;,
      &quot;type&quot;: &quot;shell&quot;,
      &quot;command&quot;: &quot;riscv64-unknown-linux-musl-g++&quot;,
      &quot;args&quot;: [
        &quot;${fileBasename}&quot;,
        &quot;-static&quot;,
        &quot;-g&quot;,
        &quot;-o&quot;,
        &quot;${fileBasenameNoExtension}-debug&quot;
      ],
      &quot;options&quot;: {
        &quot;cwd&quot;: &quot;${fileDirname}&quot;
      },
      &quot;group&quot;: &quot;build&quot;,
      &quot;problemMatcher&quot;: [&quot;$gcc&quot;]
    },
    {
      &quot;label&quot;: &quot;upload-to-target&quot;,
      &quot;type&quot;: &quot;shell&quot;,
      &quot;command&quot;: &quot;scp&quot;,
      &quot;args&quot;: [
        &quot;-i&quot;,
        &quot;id_rsa&quot;,
        &quot;-O&quot;,
        &quot;${fileDirname}/${fileBasenameNoExtension}-debug&quot;,
        &quot;root@x.x.x.x:/&quot;
      ]
    },
    {
      &quot;label&quot;: &quot;build+upload&quot;,
      &quot;dependsOrder&quot;: &quot;sequence&quot;,
      &quot;dependsOn&quot;: [
        &quot;build-static-riscv&quot;,
        &quot;upload-to-target&quot;
      ]
    }

    // 可选：调试结束后清理远端文件
    // {
    //   &quot;label&quot;: &quot;cleanup-remote&quot;,
    //   &quot;type&quot;: &quot;shell&quot;,
    //   &quot;command&quot;: &quot;ssh&quot;,
    //   &quot;args&quot;: [&quot;root@192.168.31.200&quot;, &quot;rm -f /test/${fileBasenameNoExtension}-debug&quot;]
    // }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在开发板上启动 &lt;code&gt;dropbear&lt;/code&gt; 和 &lt;code&gt;gdbserver&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dropbear -p 22 -R
gdbserver --multi :23456
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在在 &lt;code&gt;vscode&lt;/code&gt; 中启动调试，选择 &lt;code&gt;(gdb) 远程&lt;/code&gt;，即可实现一键编译、上传与调试功能，大大提升开发效率。&lt;/p&gt;
</content:encoded></item><item><title>为开源鸿蒙哪吒开发板编写程序</title><link>https://blog.wely.fun/posts/%E4%B8%BA%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%BC%96%E5%86%99%E7%A8%8B%E5%BA%8F/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E4%B8%BA%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%BC%96%E5%86%99%E7%A8%8B%E5%BA%8F/</guid><description>使用 C 语言为开源鸿蒙编写程序。</description><pubDate>Sat, 18 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;使用 C 语言为开源鸿蒙编写第一个程序 &lt;code&gt;Hello NeZha&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;下载编译工具链&lt;/h2&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://www.xrvm.cn/community/download&quot;&gt;玄铁资源中心&lt;/a&gt;，在 &lt;code&gt;资源目录&lt;/code&gt; 中选择 &lt;code&gt;剑池开发工具集&lt;/code&gt; - &lt;code&gt;编译工具&lt;/code&gt; - &lt;code&gt;GCC工具链-900系列&lt;/code&gt;。若在 &lt;code&gt;Windows&lt;/code&gt; 系统下进行编译，则下载 &lt;code&gt;Xuantie-900-gcc-linux-6.6.0-musl64-mingw-V3.2.0-20250627.tar.gz&lt;/code&gt;；若在 &lt;code&gt;Linux&lt;/code&gt; 系统下进行编译，则下载 &lt;code&gt;Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.2.0-20250627.tar.gz&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;以 &lt;code&gt;Windows&lt;/code&gt; 系统为例，下载完成后解压，&lt;code&gt;Xuantie-900-gcc-linux-6.6.0-musl64-mingw-V3.2.0\bin\riscv64-unknown-linux-musl-gcc.exe&lt;/code&gt; 即为将要使用的编译器。&lt;/p&gt;
&lt;h2&gt;编写程序&lt;/h2&gt;
&lt;p&gt;创建 &lt;code&gt;hello_word.c&lt;/code&gt; 文件，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int main(int argc, char const *argv[])
{
    printf(&quot;Hello NeZha\n&quot;);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编译程序&lt;/h2&gt;
&lt;p&gt;使用以下命令进行编译，其中 &lt;code&gt;riscv64-unknown-linux-musl-gcc.exe&lt;/code&gt; 替换为实际的编译器路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.\Xuantie-900-gcc-linux-6.6.0-musl64-mingw-V3.2.0\bin\riscv64-unknown-linux-musl-gcc.exe hello_word.c -static -o hello_word
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;code&gt;-static&lt;/code&gt; 参数用于生成静态链接的可执行文件，避免在目标设备上运行时出现缺少动态库的问题。
此处使用 &lt;code&gt;gcc&lt;/code&gt; 编译 &lt;code&gt;C&lt;/code&gt; 语言程序，后续也可以使用 &lt;code&gt;g++&lt;/code&gt; 编译 &lt;code&gt;C++&lt;/code&gt; 语言程序。
默认生成的是 &lt;code&gt;release&lt;/code&gt; 模式的可执行文件，若需要包含调试信息以便调试程序，可以添加 &lt;code&gt;-g&lt;/code&gt; 参数以生成 &lt;code&gt;debug&lt;/code&gt; 模式的可执行文件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;编译成功后会在 &lt;code&gt;hello_word.c&lt;/code&gt; 同目录下生成 &lt;code&gt;hello_word&lt;/code&gt; 可执行文件。&lt;/p&gt;
&lt;h2&gt;传输程序&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
由于哪吒开发板上的开源鸿蒙系统目前不支持通过 &lt;code&gt;hdc&lt;/code&gt; 传输文件，此处使用 U 盘进行传输。为保证兼容性，使用 &lt;code&gt;FAT32&lt;/code&gt; 格式化 U 盘。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;将 U 盘插入电脑，复制 &lt;code&gt;hello_word&lt;/code&gt; 文件到 U 盘根目录。然后将 U 盘插入哪吒开发板的 USB 接口。&lt;/p&gt;
&lt;p&gt;查看哪吒开发板是否识别到 U 盘：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls /dev/block/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;识别到的 U 盘应类似于 &lt;code&gt;sda&lt;/code&gt; 或 &lt;code&gt;sda1&lt;/code&gt; 等。若有多个 &lt;code&gt;sda&lt;/code&gt;，挂载数字最大的那个。&lt;/p&gt;
&lt;p&gt;使用以下命令在哪吒开发板上挂载 U 盘：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /mnt/sda
mount -t vfat /dev/block/sda /mnt/sda
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
后续可以使用 &lt;code&gt;umount /mnt/sda&lt;/code&gt; 命令卸载 U 盘。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;将程序复制到 &lt;code&gt;/bin&lt;/code&gt; 目录下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp -v /mnt/sda/hello_word /bin/
chmod +x /bin/hello_word
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;运行程序&lt;/h2&gt;
&lt;p&gt;输入命令 &lt;code&gt;hello_word&lt;/code&gt; 即可运行程序，程序运行如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# hello_word
Hello NeZha
#
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h1&gt;参考&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.aw-ol.com/d1/study/study_6helloword/&quot;&gt;编译第一个程序：Hello Word&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.xrvm.cn/community/download&quot;&gt;玄铁资源中心&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>开源鸿蒙开发板连接集成开发环境</title><link>https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%BC%80%E5%8F%91%E6%9D%BF%E8%BF%9E%E6%8E%A5%E9%9B%86%E6%88%90%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E5%BC%80%E5%8F%91%E6%9D%BF%E8%BF%9E%E6%8E%A5%E9%9B%86%E6%88%90%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</guid><description>开源鸿蒙系统适配的哪吒开发板通过 hdc 工具连接 DevEco Studio 集成开发环境。</description><pubDate>Fri, 10 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在为哪吒 D1 开发板 &lt;a href=&quot;https://blog.wely.fun/posts/%E6%9E%84%E5%BB%BA%E9%80%82%E7%94%A8%E4%BA%8E%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%9A%84%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F/&quot;&gt;构建开源鸿蒙系统&lt;/a&gt; 并 &lt;a href=&quot;https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E7%BD%91%E7%BB%9C/&quot;&gt;配置网络&lt;/a&gt; 后，可将开发板通过 &lt;code&gt;hdc&lt;/code&gt; 工具连接至华为 &lt;code&gt;DevEco Studio&lt;/code&gt; 集成开发环境进行应用开发与调试。&lt;/p&gt;
&lt;h1&gt;开发板设置&lt;/h1&gt;
&lt;p&gt;首先将开发板连接至有线网络，并与 PC &lt;strong&gt;处于同一局域网内&lt;/strong&gt;。PC 通过 USB 转串口线连接至开发板，为开发板 &lt;a href=&quot;https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E7%BD%91%E7%BB%9C/&quot;&gt;配置网络&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;网络配置好后，通过&lt;strong&gt;串口&lt;/strong&gt;使用以下命令打开开发板的 &lt;code&gt;hdcd&lt;/code&gt; 服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hdcd -t -l4 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
由于开源鸿蒙系统适配尚不完全，&lt;code&gt;hdcd&lt;/code&gt; 服务启动时会有三个报错，但不影响使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开发板的串口输出如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# hdcd -t -l4 &amp;amp;
[1] 343
# 
# Option TCP enabled
[  325.104766] [pid=345][param_request.c:136][Init][ERROR] Can not get param for persist.hdc.root
[[1;36mD[0m][0:5:26] HdcDaemon main run
[[1;36mD[0m][0:5:26] loopMain init
[[1;36mD[0m][0:5:26] HdcDaemon InitMod
[  325.177150] [pid=346][param_request.c:136][Init][ERROR] Can not get param for persist.hdc.port
[[1;36mD[0m][0:5:27] HdcDaemonTCP init
[[1;32mI[0m][0:5:27] TCP listen on port:[44643]
[[1;36mD[0m][0:5:27] JdwpListen begin
[  325.248777] [pid=347][param_request.c:136][Init][ERROR] Can not get param for ro.hdc.secure
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;code&gt;hdcd&lt;/code&gt; 服务启动后，注意查看串口输出中的 &lt;code&gt;TCP listen on port&lt;/code&gt;，记录下端口号，后续在 PC 端连接时需要用到。注意端口号在每次启动 &lt;code&gt;hdcd&lt;/code&gt; 服务时可能会变化。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;PC 设置&lt;/h1&gt;
&lt;p&gt;首先下载 &lt;code&gt;hdc&lt;/code&gt; 工具，访问 &lt;a href=&quot;https://ci.openharmony.cn/workbench/cicd/dailybuild/dailyList&quot;&gt;https://ci.openharmony.cn/workbench/cicd/dailybuild/dailyList&lt;/a&gt;，项目选择 &lt;code&gt;openharmony&lt;/code&gt;，然后在流水线名称中找到 &lt;code&gt;ohos-sdk-public&lt;/code&gt;，点击 &lt;code&gt;下载链接&lt;/code&gt;，选择 &lt;code&gt;全量包&lt;/code&gt; 的 &lt;code&gt;下载链接&lt;/code&gt; 进行下载。&lt;/p&gt;
&lt;p&gt;下载完成后解压，进入解压后文件夹内寻找 &lt;code&gt;windows&lt;/code&gt; 平台对应的 &lt;code&gt;windows&lt;/code&gt; 文件夹，将其中的 &lt;code&gt;toolchains&lt;/code&gt; 文件夹复制到任意目录下，例如 &lt;code&gt;C:\toolchains&lt;/code&gt;，该目录即为 &lt;code&gt;hdc&lt;/code&gt; 工具所在目录，并将其添加到系统 &lt;code&gt;PATH&lt;/code&gt; 环境变量中。&lt;/p&gt;
&lt;p&gt;打开终端，输入 &lt;code&gt;hdc -v&lt;/code&gt; 查看 &lt;code&gt;hdc&lt;/code&gt; 工具版本，验证是否配置成功，若成功则会输出版本信息，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ver: 1.2.0a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来使用 &lt;code&gt;hdc&lt;/code&gt; 工具连接开发板，输入以下命令，注意将 &lt;code&gt;x.x.x.x&lt;/code&gt; 替换为开发板的 IP 地址，&lt;code&gt;port&lt;/code&gt; 替换为前面记录的端口号：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hdc tconn x.x.x.x:port
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时终端中会输出类似如下信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PS C:\Users\wely&amp;gt; hdc tconn 192.168.31.200:44643
Connect OK
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Connect OK&lt;/code&gt; 表示连接成功。&lt;/p&gt;
&lt;p&gt;此时可在终端中输入 &lt;code&gt;hdc shell&lt;/code&gt; 进入开发板的 shell 环境，输入 &lt;code&gt;hdc kill&lt;/code&gt; 可以断开与开发板的连接。&lt;/p&gt;
&lt;p&gt;连接成功后，即可在 &lt;code&gt;DevEco Studio&lt;/code&gt; 中选择该开发板设备，进行应用开发与调试。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
由于开源鸿蒙系统适配尚不完全，&lt;code&gt;hdc&lt;/code&gt; 工具目前仍存在无法传输文件等问题。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>开源鸿蒙系统配置网络</title><link>https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E7%BD%91%E7%BB%9C/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E7%BD%91%E7%BB%9C/</guid><description>为哪吒 D1 开发板适配的开源鸿蒙系统配置网络。</description><pubDate>Tue, 30 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
为哪吒 D1 开发板 &lt;a href=&quot;https://blog.wely.fun/posts/%E6%9E%84%E5%BB%BA%E9%80%82%E7%94%A8%E4%BA%8E%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%9A%84%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F/&quot;&gt;构建适配的开源鸿蒙系统&lt;/a&gt; 后，默认情况下系统不带 &lt;code&gt;dhcp&lt;/code&gt; 服务，连接网线后&lt;strong&gt;无法自动配置 IP 地址&lt;/strong&gt;，需要&lt;strong&gt;手动进行配置&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;查看网口信息&lt;/h1&gt;
&lt;p&gt;输入 &lt;code&gt;ifconfig -a&lt;/code&gt; 命令查看网口信息。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ifconfig -a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eth0      Link encap:Ethernet  HWaddr 56:22:6c:6a:59:9b  Driver sunxi-gmac
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 
          Interrupt:62 

sit0      Link encap:IPv6-in-IPv4  
          NOARP  MTU:1480  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0 
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:1000 
          RX bytes:0 TX bytes:0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从返回的信息可以看到默认有 &lt;code&gt;eth0&lt;/code&gt; 有线网口，下面对其进行配置。&lt;/p&gt;
&lt;h1&gt;配置有线网络&lt;/h1&gt;
&lt;h2&gt;配置 IP 地址&lt;/h2&gt;
&lt;p&gt;使用以下命令配置 IP 地址，注意将 &lt;code&gt;x.x.x.x&lt;/code&gt; 替换为&lt;strong&gt;实际的&lt;/strong&gt; IP 地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ifconfig eth0 x.x.x.x netmask 255.255.255.0 up
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置默认网关&lt;/h2&gt;
&lt;p&gt;使用以下命令配置默认网关，注意将 &lt;code&gt;x.x.x.x&lt;/code&gt; 替换为&lt;strong&gt;实际的&lt;/strong&gt;网关地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;route add default gw x.x.x.x
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置 DNS 服务器&lt;/h2&gt;
&lt;p&gt;编辑 &lt;code&gt;/etc/resolv.conf&lt;/code&gt; 文件，添加 DNS 服务器地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;nameserver 223.5.5.5&quot; &amp;gt; /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;开放 ping 权限&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
默认情况下，系统未开放 &lt;code&gt;ping&lt;/code&gt; 权限，直接使用 &lt;code&gt;ping&lt;/code&gt; 命令会提示 &lt;code&gt;Permission denied&lt;/code&gt; 错误。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;直接使用 &lt;code&gt;ping&lt;/code&gt; 会出现错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ping www.baidu.com
ping: socket SOCK_DGRAM 1: Permission denied
Kernel bug workaround (as root):
echo 0 9999999 &amp;gt; /proc/sys/net/ipv4/ping_group_range
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;报错提示可用以下命令开放 &lt;code&gt;ping&lt;/code&gt; 权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;0 9999999&quot; &amp;gt; /proc/sys/net/ipv4/ping_group_range
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;测试网络连接&lt;/h2&gt;
&lt;p&gt;使用 &lt;code&gt;ping&lt;/code&gt; 命令测试网络连接：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ping www.baidu.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;出现类似输出即表示网络配置成功：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ping www.baidu.com
Ping www.baidu.com (183.2.172.17): 56(84) bytes.
64 bytes from 183.2.172.17: icmp_seq=1 ttl=0 time=27 ms
64 bytes from 183.2.172.17: icmp_seq=2 ttl=0 time=27 ms
64 bytes from 183.2.172.17: icmp_seq=3 ttl=0 time=26 ms

--- 183.2.172.17 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss
round-trip min/avg/max = 0/0/26 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h1&gt;参考&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://xie.infoq.cn/article/31bacd33446185b4a1b73a620&quot;&gt;【OH 干货】给 OpenHarmony 开发板配置网络&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>vim 拟人配置</title><link>https://blog.wely.fun/posts/vim-%E6%8B%9F%E4%BA%BA%E9%85%8D%E7%BD%AE/</link><guid isPermaLink="true">https://blog.wely.fun/posts/vim-%E6%8B%9F%E4%BA%BA%E9%85%8D%E7%BD%AE/</guid><description>修改 vim 配置使方向键和退格键可以正常使用</description><pubDate>Wed, 24 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大部分 Linux 发行版自带的 vim 都是精简版的，无法正常使用方向键和退格键，本文介绍如何配置 vim 使其可以正常使用。&lt;/p&gt;
&lt;h1&gt;修改配置文件&lt;/h1&gt;
&lt;p&gt;首先使用 vim 打开 &lt;code&gt;/etc/vim/vimrc.tiny&lt;/code&gt; 配置文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vi /etc/vim/vimrc.tiny
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开后内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot; Vim configuration file, in effect when invoked as &quot;vi&quot;. The aim of this
&quot; configuration file is to provide a Vim environment as compatible with the
&quot; original vi as possible. Note that ~/.vimrc configuration files as other
&quot; configuration files in the runtimepath are still sourced.
&quot; When Vim is invoked differently (&quot;vim&quot;, &quot;view&quot;, &quot;evim&quot;, ...) this file is
&quot; _not_ sourced; /etc/vim/vimrc and/or /etc/vim/gvimrc are.

&quot; Debian system-wide default configuration Vim
set runtimepath=~/.vim,/var/lib/vim/addons,/usr/share/vim/vimfiles,/usr/share/vim/vim91,/usr/share/vim/vimfiles/after,/var/lib/vim/addons/after,~/.vim/after

set compatible

&quot; vim: set ft=vim:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到 &lt;code&gt;set compatible&lt;/code&gt; 这一行，将其修改为 &lt;code&gt;set nocompatible&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;首先使用方向键下键移动光标到 &lt;code&gt;set compatible&lt;/code&gt; 这一行，然后使用方向键右键移动光标到 &lt;code&gt;c&lt;/code&gt; 字母上，即 set &lt;code&gt;c&lt;/code&gt;ompatible，此时按 &lt;code&gt;i&lt;/code&gt; 进入编辑模式，输入 &lt;code&gt;no&lt;/code&gt;，使这一行变为 &lt;code&gt;set nocompatible&lt;/code&gt;，按 &lt;code&gt;Esc&lt;/code&gt; 退出插入模式，最后输入 &lt;code&gt;:wq&lt;/code&gt; 保存并退出。&lt;/p&gt;
&lt;p&gt;再次打开这个配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vi /etc/vim/vimrc.tiny
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按 &lt;code&gt;i&lt;/code&gt; 进入编辑模式，使用方向键移动光标到&lt;code&gt;set nocompatible&lt;/code&gt; 这一行末尾，按下回车键换行，输入以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set backspace=2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按 &lt;code&gt;Esc&lt;/code&gt; 退出插入模式，输入 &lt;code&gt;:wq&lt;/code&gt; 保存并退出。&lt;/p&gt;
&lt;p&gt;此时 vim 即可正常使用方向键和退格键了。&lt;/p&gt;
&lt;h1&gt;修改后配置文件&lt;/h1&gt;
&lt;p&gt;修改后的 &lt;code&gt;/etc/vim/vimrc.tiny&lt;/code&gt; 文件内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot; Vim configuration file, in effect when invoked as &quot;vi&quot;. The aim of this
&quot; configuration file is to provide a Vim environment as compatible with the
&quot; original vi as possible. Note that ~/.vimrc configuration files as other
&quot; configuration files in the runtimepath are still sourced.
&quot; When Vim is invoked differently (&quot;vim&quot;, &quot;view&quot;, &quot;evim&quot;, ...) this file is
&quot; _not_ sourced; /etc/vim/vimrc and/or /etc/vim/gvimrc are.

&quot; Debian system-wide default configuration Vim
set runtimepath=~/.vim,/var/lib/vim/addons,/usr/share/vim/vimfiles,/usr/share/vim/vim91,/usr/share/vim/vimfiles/after,/var/lib/vim/addons/after,~/.vim/after

set nocompatible
set backspace=2

&quot; vim: set ft=vim:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;简单来说就是修改了如下两行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set nocompatible
set backspace=2
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>构建适用于哪吒开发板的开源鸿蒙系统</title><link>https://blog.wely.fun/posts/%E6%9E%84%E5%BB%BA%E9%80%82%E7%94%A8%E4%BA%8E%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%9A%84%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E6%9E%84%E5%BB%BA%E9%80%82%E7%94%A8%E4%BA%8E%E5%93%AA%E5%90%92%E5%BC%80%E5%8F%91%E6%9D%BF%E7%9A%84%E5%BC%80%E6%BA%90%E9%B8%BF%E8%92%99%E7%B3%BB%E7%BB%9F/</guid><description>为哪吒 D1 开发板构建适配的开源鸿蒙系统。</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
由于官方给出的示例文档写的实在太烂，故在此对构建过程进行逐步记录。所有构建过程均于 Ubuntu 系统中进行，并通过 Docker 获取编译环境，请确保&lt;strong&gt;已提前安装好 Docker&lt;/strong&gt;，参考 &lt;a href=&quot;https://docs.docker.com/engine/install/&quot;&gt;官方文档&lt;/a&gt; 以安装。&lt;/p&gt;
&lt;p&gt;目前的适配进度止步于进入控制台，即可通过串口连接开发板进入命令行，&lt;strong&gt;未适配图形化界面&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
构建时必要的 llvm-riscv 工具链 &lt;code&gt;llvm-riscv-1124.tar.gz&lt;/code&gt; 目前&lt;strong&gt;仅可通过 &lt;a href=&quot;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&quot;&gt;百度网盘&lt;/a&gt; 下载&lt;/strong&gt;，链接为 &lt;a href=&quot;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&quot;&gt;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&lt;/a&gt;，提取码为 &lt;code&gt;chds&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;安装 Repo 工具&lt;/h1&gt;
&lt;p&gt;构建前需要使用 Repo 工具来获取源码和 SDK。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install repo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要设置 git 的用户名和邮箱，将以下命令中的 &lt;code&gt;your_name&lt;/code&gt; 和 &lt;code&gt;your_email&lt;/code&gt; 替换为你的用户名和邮箱。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global user.name &quot;your_name&quot;
git config --global user.email &quot;your_email&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;更换镜像源&lt;/h2&gt;
&lt;p&gt;每次运行时 Repo 会尝试访问官方的 git 源检查更新，更换镜像源可以提高下载速度。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo export REPO_URL=&apos;https://mirrors.bfsu.edu.cn/git/git-repo&apos; &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;创建工作目录&lt;/h1&gt;
&lt;p&gt;为便于进行文件管理，创建工作目录，文件夹关系如下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nezha/                  # 总文件夹
├── OpenHarmony/        # OpenHarmony 源码
└── tina-d1/            # Tina-D1 SDK
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过以下命令创建这些文件夹。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p nezha/OpenHarmony nezha/tina-d1
cd nezha
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;获取 SDK&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
需要&lt;strong&gt;提前注册 &lt;a href=&quot;https://bbs.aw-ol.com/&quot;&gt;全志在线开发者论坛&lt;/a&gt; 账号，并达到 LV2 等级&lt;/strong&gt;，参考 &lt;a href=&quot;https://bbs.aw-ol.com/topic/4008/%E6%B0%B4%E7%BB%8F%E9%AA%8C%E6%B7%B7%E4%B8%8B%E8%BD%BD%E6%9D%83%E9%99%90%E4%B8%93%E7%94%A8%E8%B4%B4-%E5%A6%82%E4%BD%95%E5%8D%87%E7%BA%A7lv2%E6%8B%89%E5%8F%96sdk&quot;&gt;这个链接&lt;/a&gt; 升级。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;初始化仓库&lt;/h2&gt;
&lt;p&gt;进入刚才创建的 &lt;code&gt;tina-d1&lt;/code&gt; 文件夹，使用 Repo 工具初始化仓库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd tina-d1
repo init -u https://sdk.aw-ol.com/git_repo/D1_Tina_Open/manifest.git -b master -m tina-d1-h.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果提示 &lt;code&gt;Username for &apos;https://sdk.aw-ol.com&apos;&lt;/code&gt;， 请输入 &lt;a href=&quot;https://bbs.aw-ol.com/&quot;&gt;全志在线开发者论坛&lt;/a&gt; 的用户名和密码，需要&lt;strong&gt;全志在线开发者论坛 LV2 等级以上&lt;/strong&gt;用户才有权限拉取 SDK。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
如果出现 &lt;code&gt;git requires authentication, but repo cannot perform interactive authentication. Check git credentials.&lt;/code&gt; 错误导致无法拉取，需要手动设置用户名和密码。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;git config --global credential.helper store
git ls-remote https://sdk.aw-ol.com/git_repo/D1_Tina_Open/manifest.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时会触发输入用户名和密码，输入后重新执行 &lt;code&gt;repo init -u https://sdk.aw-ol.com/git_repo/D1_Tina_Open/manifest.git -b master -m tina-d1-h.xml&lt;/code&gt; 即可。&lt;/p&gt;
&lt;h2&gt;拉取 SDK&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;repo sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由于 SDK 体积普遍较大，拉取可能需要一定的时间，此时可同步进行源码的获取。&lt;/p&gt;
&lt;h1&gt;获取源码&lt;/h1&gt;
&lt;p&gt;进入之前创建的 &lt;code&gt;OpenHarmony&lt;/code&gt; 文件夹，使用 Repo 工具拉取源码。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd ../OpenHarmony
repo init -u https://gitee.com/allwinnertech-d1/manifest-sunxi-d1.git -b master -m sunxi_d1.xml --no-repo-verify
repo sync -c
repo forall -c &apos;git lfs pull&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;源码体积较大，拉取时间较长，此时可提前下载编译工具链。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
若报类似于 &lt;code&gt;Syncing: 25% (63/248) 0:44 | 4 jobs | 0:04 update_packaging_tools @ base/update/packaging_toolserror.GitError: Cannot checkout update_packaging_tools: Cannot initialize work tree for update_packaging_tools&lt;/code&gt; 的错误，可能是因为 &lt;code&gt;git-lfs&lt;/code&gt; 未安装，使用 &lt;code&gt;sudo apt install git-lfs &amp;amp;&amp;amp; git lfs install&lt;/code&gt; 安装 &lt;code&gt;git-lfs&lt;/code&gt; 后重新运行 &lt;code&gt;repo sync -c&lt;/code&gt; 即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;获取编译工具链&lt;/h1&gt;
&lt;p&gt;通过 &lt;a href=&quot;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&quot;&gt;百度网盘&lt;/a&gt; 下载 llvm-riscv 工具链 &lt;code&gt;llvm-riscv-1124.tar.gz&lt;/code&gt;，链接为 &lt;a href=&quot;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&quot;&gt;https://pan.baidu.com/s/19JVNwFrl5ISOAsruW_y9hA?pwd=chds&lt;/a&gt;，提取码为 &lt;code&gt;chds&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;可将 &lt;code&gt;llvm-riscv-1124.tar.gz&lt;/code&gt; 文件放入 &lt;code&gt;nezha&lt;/code&gt; 文件夹中，此时文件夹结构如下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nezha/
├── OpenHarmony/
├── tina-d1/
└── llvm-riscv-1124.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;构建系统&lt;/h1&gt;
&lt;h2&gt;构建前准备&lt;/h2&gt;
&lt;p&gt;进入 &lt;code&gt;OpenHarmony&lt;/code&gt; 文件夹，修改 &lt;code&gt;./build/prebuilts_download.sh&lt;/code&gt; 文件中的 npm 镜像源，将所有的 &lt;code&gt;http://registry.npm.taobao.org&lt;/code&gt; 修改为 &lt;code&gt;https://mirrors.huaweicloud.com/repository/npm/&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd OpenHarmony
sed -i &apos;s|http://registry.npm.taobao.org|https://mirrors.huaweicloud.com/repository/npm/|g&apos; build/prebuilts_download.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行 &lt;code&gt;./build/prebuilts_download.sh&lt;/code&gt;，下载相关编译工具链与 host 端工具。注意需要提前安装 &lt;code&gt;bzip2&lt;/code&gt;，使用 &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install bzip2&lt;/code&gt; 命令以安装。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./build/prebuilts_download.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;复制编译工具&lt;/h2&gt;
&lt;p&gt;回到 &lt;code&gt;nezha&lt;/code&gt; 文件夹，将 &lt;code&gt;tina-d1/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702&lt;/code&gt; 复制到 &lt;code&gt;OpenHarmony/prebuilts/gcc/linux-x86/riscv/riscv64-glibc-gcc-thead_20200702&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd nezha
mkdir -p OpenHarmony/prebuilts/gcc/linux-x86/riscv/riscv64-glibc-gcc-thead_20200702
cp -rv tina-d1/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/* OpenHarmony/prebuilts/gcc/linux-x86/riscv/riscv64-glibc-gcc-thead_20200702/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;解压编译工具链&lt;/h2&gt;
&lt;p&gt;还是在 &lt;code&gt;nezha&lt;/code&gt; 文件夹，将之前下载的 &lt;code&gt;llvm-riscv-1124.tar.gz&lt;/code&gt; 工具链解压到 &lt;code&gt;OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm-riscv/&lt;/code&gt; 目录下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tar -xzvf llvm-riscv-1124.tar.gz -C OpenHarmony/prebuilts/clang/ohos/linux-x86_64/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获取 Docker 编译环境&lt;/h2&gt;
&lt;p&gt;使用预搭建好的 Docker 镜像来构建 OpenHarmony 系统，其中 &lt;code&gt;nezha&lt;/code&gt; 文件夹的路径 &lt;code&gt;/path/to/nezha&lt;/code&gt; 根据你的实际路径进行替换。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull welyfun/nezha
docker run -dit --name nezha -v /path/to/nezha:/root welyfun/nezha
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
若报 &lt;code&gt;docker: Error response from daemon: Get &quot;https://registry-1.docker.io/v2/&quot;: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)&lt;/code&gt; 的错误，为网络问题，可自行搜索配置 Docker 代理地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;构建系统&lt;/h2&gt;
&lt;p&gt;进入 Docker 容器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it nezha /bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入 &lt;code&gt;OpenHarmony&lt;/code&gt; 文件夹并构建系统。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /root/OpenHarmony
./build.sh --product-name sunxi_d1 --ccache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;构建过程可能需要较长时间（接近一小时），具体取决于你的计算机性能，此时可以去喝杯茶。&lt;/p&gt;
&lt;p&gt;出现以下信息时，表示构建成功。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=====build sunxi_d1 successful.
2025-08-01 11:08:37
++++++++++++++++++++++++++++++++++++++++
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若报错，大多数错误可通过重复运行 &lt;code&gt;./build.sh --product-name sunxi_d1 --ccache&lt;/code&gt; 来解决。&lt;/p&gt;
&lt;h2&gt;生成镜像文件&lt;/h2&gt;
&lt;p&gt;还是在 Docker 容器的 &lt;code&gt;OpenHarmony&lt;/code&gt; 文件夹中，运行以下命令生成镜像文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./device/sunxi/build/pack
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成的镜像文件位于 &lt;code&gt;./out/d1-nezha/&lt;/code&gt; 目录下，文件名为 &lt;code&gt;tina_d1-nezha_uart0.img&lt;/code&gt;，成功信息如下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dragon execute image.cfg SUCCESS !
----------image is for nand/emmc----------
----------image is at----------

/root/OpenHarmony/out/d1-nezha/tina_d1-nezha_uart0.img

pack finish
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;生成可写镜像文件&lt;/h3&gt;
&lt;p&gt;默认打包的 rootfs 是 squashfs 类型，只读，不可写。执行: &lt;code&gt;./device/sunxi/build/pack -e&lt;/code&gt;，可生成 ext4 格式（可写）的 rootfs，此时固件大小会超过 256M（D1 开发板 flash 总大小），无法直接烧写，需使用 TF 卡烧写方式，并修改 &lt;code&gt;./device/sunxi/config/chips/d1/configs/nezha/sys_partition.fex&lt;/code&gt; 文件，调大对应分区的 size。&lt;/p&gt;
&lt;p&gt;首先打开 &lt;code&gt;./device/sunxi/config/chips/d1/configs/nezha/sys_partition.fex&lt;/code&gt; 文件，找到以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[partition]
    name         = rootfs
    size         = 258048
    downloadfile = &quot;rootfs.fex&quot;
    user_type    = 0x8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将 &lt;code&gt;size&lt;/code&gt; 的值改为 &lt;code&gt;819200&lt;/code&gt;，修改后的内容如下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[partition]
    name         = rootfs
    size         = 819200
    downloadfile = &quot;rootfs.fex&quot;
    user_type    = 0x8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;随后在 &lt;code&gt;OpenHarmony&lt;/code&gt; 文件夹中运行以下命令生成可写镜像文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./device/sunxi/build/pack -e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功后同样显示如下信息。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dragon execute image.cfg SUCCESS !
----------image is for nand/emmc----------
----------image is at----------

/root/OpenHarmony/out/d1-nezha/tina_d1-nezha_uart0.img

pack finish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成的可写镜像文件位于 &lt;code&gt;./out/d1-nezha/&lt;/code&gt; 目录下，文件名为 &lt;code&gt;tina_d1-nezha_uart0.img&lt;/code&gt;。&lt;/p&gt;
&lt;h1&gt;烧写镜像&lt;/h1&gt;
&lt;p&gt;此处记录烧写镜像至 TF 卡的过程，若要烧写至开发板的 flash 中，请参考 &lt;a href=&quot;https://d1.docs.aw-ol.com/study/study_4compile/&quot;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;烧写工具 &lt;code&gt;PhoenixCard&lt;/code&gt; （仅适用于 Windows）于 &lt;a href=&quot;https://www.aw-ol.com/downloads?cat=5&quot;&gt;此处&lt;/a&gt; 下载，注意需要&lt;strong&gt;先登录&lt;/strong&gt;才能下载，下载 &lt;code&gt;PhoenixCardv4.2.7.7z&lt;/code&gt; 文件，解压后运行 &lt;code&gt;PhoenixCard.exe&lt;/code&gt;，以 &lt;code&gt;启动卡&lt;/code&gt; 模式烧写镜像至 TF 卡。&lt;/p&gt;
&lt;h1&gt;启动系统&lt;/h1&gt;
&lt;p&gt;将烧写好的 TF 卡插入 D1 开发板，连接好串口线，使用串口工具连接开发板的串口，波特率设置为 &lt;code&gt;115200&lt;/code&gt;。&lt;strong&gt;最后连接电源线&lt;/strong&gt;，即可通过串口进入命令行界面。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;参考&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://gitee.com/allwinnertech-d1/device_sunxi&quot;&gt;OpenHarmony 构建 d1_nezha (Gitee 仓库)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://gitcode.com/openharmony-sig/riscv/tree/master/docs/openharmony_for_riscv&quot;&gt;OpenHarmony for RISC-V (GitCode 仓库)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://d1.docs.aw-ol.com&quot;&gt;D1-H 官方文档&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>树莓派 Pico 驱动墨水屏显示信息</title><link>https://blog.wely.fun/posts/%E6%A0%91%E8%8E%93%E6%B4%BE-pico-%E9%A9%B1%E5%8A%A8%E5%A2%A8%E6%B0%B4%E5%B1%8F%E6%98%BE%E7%A4%BA%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E6%A0%91%E8%8E%93%E6%B4%BE-pico-%E9%A9%B1%E5%8A%A8%E5%A2%A8%E6%B0%B4%E5%B1%8F%E6%98%BE%E7%A4%BA%E4%BF%A1%E6%81%AF/</guid><description>树莓派 Pico 驱动墨水屏，通过 USB 连接树莓派 5 显示系统信息。</description><pubDate>Sun, 18 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;墨水屏&lt;/h1&gt;
&lt;p&gt;显示屏为 &lt;code&gt;2.13&lt;/code&gt; 寸黑白电子墨水屏，于 &lt;a href=&quot;https://www.waveshare.net/wiki/Pico-ePaper-2.13&quot;&gt;微雪电子&lt;/a&gt; 购买，并利用树莓派 Pico 驱动以显示信息。&lt;/p&gt;
&lt;h1&gt;树莓派 Pico 环境搭建&lt;/h1&gt;
&lt;p&gt;于树莓派 5 上进行环境搭建。&lt;/p&gt;
&lt;p&gt;创建 &lt;code&gt;pico&lt;/code&gt; 文件夹并进入。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir pico
cd pico
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Raspberry Pi Pico SDK&lt;/h2&gt;
&lt;p&gt;参考 &lt;a href=&quot;https://github.com/raspberrypi/pico-sdk&quot;&gt;GitHub&lt;/a&gt; 页面。&lt;/p&gt;
&lt;h3&gt;安装依赖&lt;/h3&gt;
&lt;p&gt;安装 &lt;code&gt;CMake&lt;/code&gt; 和 &lt;code&gt;GCC&lt;/code&gt; 编译器及其相关依赖。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;克隆存储库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/raspberrypi/pico-sdk.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;添加环境变量&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;vi ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加 &lt;code&gt;PICO_SDK_PATH&lt;/code&gt; 路径。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export PICO_SDK_PATH=/home/ubuntu/pico/pico-sdk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使环境变量立即生效。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;picotool&lt;/h2&gt;
&lt;p&gt;参考 &lt;a href=&quot;https://github.com/raspberrypi/picotool&quot;&gt;GitHub&lt;/a&gt; 页面。&lt;/p&gt;
&lt;p&gt;首先于 &lt;code&gt;pico-sdk&lt;/code&gt; 路径下克隆相关库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /home/ubuntu/pico/pico-sdk
git submodule update --init lib/mbedtls
git submodule update --init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若因为网络原因无法完成克隆，可参考错误信息手动克隆至相关目录下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Submodule &apos;lib/mbedtls&apos; (https://github.com/Mbed-TLS/mbedtls.git) registered for path &apos;lib/mbedtls&apos;
Submodule &apos;lib/btstack&apos; (https://github.com/bluekitchen/btstack.git) registered for path &apos;lib/btstack&apos;
Submodule &apos;lib/cyw43-driver&apos; (https://github.com/georgerobotics/cyw43-driver.git) registered for path &apos;lib/cyw43-driver&apos;
Submodule &apos;lib/lwip&apos; (https://github.com/lwip-tcpip/lwip.git) registered for path &apos;lib/lwip&apos;
Submodule &apos;tinyusb&apos; (https://github.com/hathach/tinyusb.git) registered for path &apos;lib/tinyusb&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安装依赖&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;克隆存储库&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cd ~/pico
git clone https://github.com/raspberrypi/picotool.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;编译安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cd picotool
mkdir build
cd build
cmake ..
make -j8
sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;去除 &lt;code&gt;sudo&lt;/code&gt; 权限&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cd ~/pico/picotool
sudo cp udev/99-picotool.rules /etc/udev/rules.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;树莓派 Pico 部分程序&lt;/h1&gt;
&lt;h2&gt;例程下载&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd ~/pico
wget  https://www.waveshare.net/w/upload/2/27/Pico_ePaper_Code.zip
unzip Pico_ePaper_Code.zip -d Pico_ePaper_Code
cd Pico_ePaper_Code
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编写程序&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd c
mv main.c main.c.bak
vi main.c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;程序为以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &quot;DEV_Config.h&quot;
#include &quot;GUI_Paint.h&quot;
#include &quot;ImageData.h&quot;
#include &quot;Debug.h&quot;
#include &amp;lt;stdlib.h&amp;gt;
#include &quot;EPD_2in13_V4.h&quot;
#include &quot;string.h&quot;

int main(void)
{
    stdio_init_all();
    unsigned char data[100]={0};
    unsigned char cpu[100]={0};
    unsigned char cpu_i[100]={0};
    unsigned char cpu_o[100]={0};
    unsigned char mem_p[100]={0};
    unsigned char mem_u[100]={0};
    unsigned char mem_t[100]={0};
    unsigned char disk_p[100]={0};
    unsigned char disk_u[100]={0};
    unsigned char disk_t[100]={0};
    unsigned char ipv4[100]={0};
    unsigned char ipv6[100]={0};

    if(DEV_Module_Init()!=0){
        return -1;
    }

    EPD_2in13_V4_Init();
    EPD_2in13_V4_Clear();

    UBYTE *BlackImage;
    UWORD Imagesize = ((EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1)) * EPD_2in13_V4_HEIGHT;
    if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
        return -1;
    }
    Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
        Paint_Clear(WHITE);

    int n=0;
    int count=0;

    while(1){
    
    n+=1;

    printf(&quot;input name: &quot;);
    scanf(&quot;%s&quot;, data);
    printf(&quot;\nHello, %s\n\n&quot;, data);
    sscanf(data, &quot;%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%s&quot;, &amp;amp;cpu, &amp;amp;cpu_i, &amp;amp;cpu_o, &amp;amp;mem_p, &amp;amp;mem_u, &amp;amp;mem_t, &amp;amp;disk_p, &amp;amp;disk_u, &amp;amp;disk_t, &amp;amp;ipv4, &amp;amp;ipv6);
    printf(&quot;%s\n&quot;,cpu);
    printf(&quot;%s\n\n&quot;,cpu_i);

    EPD_2in13_V4_Init_Fast();
    Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
    Paint_SelectImage(BlackImage);
    
    Paint_ClearWindows(70, 20, 70 + Font20.Width * 4, 20 + Font20.Height, WHITE);
    Paint_ClearWindows(151, 24, 151 + Font16.Width *4, 24 + Font16.Height, WHITE);
    Paint_ClearWindows(206, 24, 206 + Font16.Width *4, 24 + Font16.Height, WHITE);
    Paint_ClearWindows(70, 40, 70 + Font20.Width * 4, 40 + Font20.Height, WHITE);
    Paint_ClearWindows(151, 44, 151 + Font16.Width *4, 44 + Font16.Height, WHITE);
    EPD_2in13_V4_Display_Partial(BlackImage);
    //DEV_Delay_ms(500);
    Paint_DrawString_EN(70, 20, &amp;amp;cpu, &amp;amp;Font20, WHITE, BLACK);
    Paint_DrawString_EN(151, 24, &amp;amp;cpu_i, &amp;amp;Font16, WHITE, BLACK);
    Paint_DrawString_EN(206, 24, &amp;amp;cpu_o, &amp;amp;Font16, WHITE, BLACK);
    Paint_DrawString_EN(70, 40, &amp;amp;mem_p, &amp;amp;Font20, WHITE, BLACK);
    Paint_DrawString_EN(151, 44, &amp;amp;mem_u, &amp;amp;Font16, WHITE, BLACK);
    EPD_2in13_V4_Display_Partial(BlackImage);
    DEV_Delay_ms(500);
    EPD_2in13_V4_Sleep();
    DEV_Delay_ms(4000);
    
    if(n&amp;gt;=50 || count==0){
        count=1;
        n=0;
        EPD_2in13_V4_Init_Fast();
        Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
        Paint_Clear(WHITE);

        Paint_DrawString_EN(27, 0, &quot;Raspberry Pi 5&quot;, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(0, 20, &quot;CPU:     %&quot;, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 24, &quot;|&quot;, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 40, &quot;Mem:     %&quot;, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 44, &quot;/&quot;, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(206, 44, &amp;amp;mem_t, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 60, &quot;Disk:    %&quot;, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 64, &quot;/&quot;, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(70, 60, &amp;amp;disk_p, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(151, 64, &amp;amp;disk_u, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(206, 64, &amp;amp;disk_t, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 82, &quot;IPv4:&quot;, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(55, 80, &amp;amp;ipv4, &amp;amp;Font20, WHITE, BLACK);
        Paint_DrawString_EN(0, 102, &quot;IPv6:&quot;, &amp;amp;Font16, WHITE, BLACK);
        Paint_DrawString_EN(55, 106, &amp;amp;ipv6, &amp;amp;Font8, WHITE, BLACK);
        EPD_2in13_V4_Display_Base(BlackImage);
        DEV_Delay_ms(3000);
    }

    }

    EPD_2in13_V4_Sleep();
    free(BlackImage);
    BlackImage = NULL;
    DEV_Delay_ms(2000);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;加入头文件路径&lt;/h2&gt;
&lt;p&gt;编辑 &lt;code&gt;~/pico/Pico_ePaper_Code/c/CMakeLists.txt&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# add a header directory
include_directories(./lib/e-Paper)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编译程序&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mkdir build
cd build
cmake ..
make -j8
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;运行程序&lt;/h2&gt;
&lt;p&gt;按住树莓派 Pico 上的 &lt;code&gt;BOOTSEL&lt;/code&gt; 按键，同时使用 &lt;code&gt;Micro USB&lt;/code&gt; 数据线将 &lt;code&gt;树莓派 Pico&lt;/code&gt; 连接至 &lt;code&gt;树莓派 5&lt;/code&gt;，连接后放开按键，即可看到树莓派 Pico 的存储空间。&lt;/p&gt;
&lt;p&gt;挂载树莓派 Pico 存储。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mount /dev/sda1 /mnt/pico
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;复制 &lt;code&gt;epd.uf2&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cp -v epd.uf2 /mnt/pico/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;释放树莓派 Pico 存储。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo umount /mnt/pico
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时树莓派 Pico 将自动运行程序。&lt;/p&gt;
&lt;h1&gt;树莓派 5 部分程序&lt;/h1&gt;
&lt;p&gt;树莓派 5 部分为 &lt;code&gt;Python&lt;/code&gt; 程序。&lt;/p&gt;
&lt;h2&gt;安装完整版 &lt;code&gt;Python&lt;/code&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install python3-full
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编写程序&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd ~
mkdir python
cd python
vi pico.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加以下程序。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import psutil
import serial
import time

pico=serial.Serial(&quot;/dev/ttyACM0&quot;,115200)

while True:

    print(&quot;Raspberry Pi 5&quot;)

    cpu=psutil.cpu_percent(1)
    cpu_temp=psutil.sensors_temperatures()
    print(f&quot;CPU: {cpu}% {cpu_temp[&apos;cpu_thermal&apos;][0].current}C/{cpu_temp[&apos;rp1_adc&apos;][0].current}C&quot;)
    cpu_i=round(cpu_temp[&apos;cpu_thermal&apos;][0].current,1)
    cpu_o=round(cpu_temp[&apos;rp1_adc&apos;][0].current,1)


    mem=psutil.virtual_memory()
    print(f&quot;Mem: {mem.percent}%({((mem.total-mem.available)/1024**3):.2f}GB/{(mem.total/1024**3):.2f}GB)&quot;)
    mem_p=mem.percent
    mem_u=round(((mem.total-mem.available)/1024**3),2)
    mem_t=round((mem.total/1024**3),2)

    disk=psutil.disk_usage(&apos;/&apos;)
    print(f&quot;Disk: {disk.percent}%({(disk.used/1024**3):.2f}GB/{(disk.total/1024**3):.2f}GB)&quot;)
    disk_p=disk.percent
    disk_u=round((disk.used/1024**3),1)
    disk_t=round((disk.total/1024**3),1)

    net=psutil.net_if_addrs()
    print(f&quot;IPv4: {net[&apos;eth0&apos;][0].address}&quot;)
    print(f&quot;IPv6: {net[&apos;eth0&apos;][1].address}&quot;)
    ipv4=net[&apos;eth0&apos;][0].address
    ipv6=net[&apos;eth0&apos;][1].address

    data=str(cpu)+&apos;,&apos;+str(cpu_i)+&apos;,&apos;+str(cpu_o)+&apos;,&apos;+str(mem_p)+&apos;,&apos;+str(mem_u)+&apos;,&apos;+str(mem_t)+&apos;,&apos;+str(disk_p)+&apos;,&apos;+str(disk_u)+&apos;,&apos;+str(disk_t)+&apos;,&apos;+str(ipv4)+&apos;,&apos;+str(ipv6)+&apos;\n&apos;
    print(data)
    pico.write(data.encode(&quot;utf-8&quot;))

    time.sleep(5)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;虚拟环境&lt;/h2&gt;
&lt;p&gt;创建虚拟环境。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -m venv venv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入虚拟环境。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装第三方库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install psutil pyserial 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加执行权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x pico.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行程序。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 pico.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;退出虚拟环境。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;开机自动运行&lt;/h2&gt;
&lt;p&gt;利用 &lt;code&gt;bash&lt;/code&gt; 脚本与 &lt;code&gt;systend&lt;/code&gt; 服务使其成为守护进程。&lt;/p&gt;
&lt;h3&gt;编写 &lt;code&gt;bash&lt;/code&gt; 脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;vi pico.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/bash
source /home/ubuntu/python/venv/bin/activate
python3 /home/ubuntu/python/pico.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加执行权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x pico.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加系统服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /etc/systemd/system
sudo vi pico.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=pico e-Paper
After=network-online.target
Wants=network-online.target

[Service]
TimeoutStartSec=0
ExecStart=/home/ubuntu/python/pico.sh
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加开机启动服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl enable pico
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl start pico
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看服务状态。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl status pico
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此墨水屏可以正常显示树莓派 5 系统信息。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;参考&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.waveshare.net/wiki/Pico-ePaper-2.13&quot;&gt;Pico-ePaper-2.13 - Waveshare Wiki&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/raspberrypi/pico-sdk&quot;&gt;raspberrypi/pico-sdk (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/raspberrypi/picotool&quot;&gt;raspberrypi/picotool (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>树莓派 5 安装 Ubuntu Server 24.04 LTS 记录</title><link>https://blog.wely.fun/posts/%E6%A0%91%E8%8E%93%E6%B4%BE-5-%E5%AE%89%E8%A3%85-ubuntu-server-2404-lts-%E8%AE%B0%E5%BD%95/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E6%A0%91%E8%8E%93%E6%B4%BE-5-%E5%AE%89%E8%A3%85-ubuntu-server-2404-lts-%E8%AE%B0%E5%BD%95/</guid><description>树莓派 5 安装 Ubuntu Server 24.04 LTS 作为小型服务器使用，部署包括 docker 在内的各项服务记录</description><pubDate>Fri, 31 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;使用&lt;code&gt;树莓派 5&lt;/code&gt; 安装 &lt;code&gt;Ubuntu Server 24.04 LTS&lt;/code&gt; 作为小型服务器使用，并部署包括 &lt;code&gt;docker&lt;/code&gt; 在内的各项服务，在此进行记录。&lt;/p&gt;
&lt;h1&gt;安装 Ubuntu Server 24.04 LTS&lt;/h1&gt;
&lt;p&gt;此时需要准备一个 TF 卡。&lt;/p&gt;
&lt;h2&gt;刷入系统&lt;/h2&gt;
&lt;p&gt;先到 &lt;a href=&quot;https://cn.ubuntu.com/download/raspberry-pi&quot;&gt;Ubuntu 官网&lt;/a&gt; 下载系统镜像文件，这里我选择的是 Ubuntu 服务器 24.04 LTS 64 位镜像。&lt;/p&gt;
&lt;p&gt;然后到 &lt;a href=&quot;https://www.raspberrypi.com/software/&quot;&gt;树莓派官网&lt;/a&gt; 下载系统刷入工具 &lt;code&gt;Raspberry Pi Imager&lt;/code&gt;。运行后选择&lt;strong&gt;刚才下载的镜像&lt;/strong&gt;并选择&lt;strong&gt;对应的 TF 卡&lt;/strong&gt;进行刷入。&lt;/p&gt;
&lt;p&gt;刷写配置可选择修改主机名、用户名和密码，并&lt;strong&gt;记住勾选使用 &lt;code&gt;SSH&lt;/code&gt; 连接&lt;/strong&gt;，如果需要连接无线网络也可以选择配置。&lt;/p&gt;
&lt;p&gt;刷写结束 TF 卡会自动弹出，将其插入断电状态的树莓派，然后接通电源，系统启动。&lt;/p&gt;
&lt;h2&gt;登录系统&lt;/h2&gt;
&lt;p&gt;使用 &lt;code&gt;ssh&lt;/code&gt; 工具登录系统，若没有配置主机名、用户名和密码，默认主机名为 &lt;code&gt;ubuntu&lt;/code&gt;，默认用户名为 &lt;code&gt;ubuntu&lt;/code&gt;，默认密码为 &lt;code&gt;ubuntu&lt;/code&gt;。第一次登录时会要求修改默认密码。&lt;/p&gt;
&lt;h1&gt;安装中文语言包&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Ubuntu Server&lt;/code&gt; 系统安装时默认语言为&lt;code&gt;英语&lt;/code&gt;，现在将其修改为&lt;code&gt;中文&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;首先安装&lt;strong&gt;简体中文语言包&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install language-pack-zh-hans
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将区域语言设置为&lt;strong&gt;简体中文&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;localectl set-locale LANG=zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;重启&lt;/strong&gt;以应用更改。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看当前区域语言设置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;locale
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试是否为中文输出。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;删除 Snap 商店&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo apt autoremove --purge snapd
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;创建 &lt;code&gt;Swap&lt;/code&gt; 交换空间&lt;/h1&gt;
&lt;h2&gt;开启 &lt;code&gt;Swap&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;创建一个 &lt;code&gt;swap&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dd if=/dev/zero of=/swapfile bs=1M count=8192
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置文件权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo chmod 600 /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把文件设置为 &lt;code&gt;Swap&lt;/code&gt; 空间。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mkswap /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启用 &lt;code&gt;Swap&lt;/code&gt; 空间。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo swapon /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开机自动挂载 &lt;code&gt;Swap&lt;/code&gt; 空间。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;/swapfile none swap sw 0 0&apos; | sudo tee -a /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后，检查 &lt;code&gt;Swap&lt;/code&gt; 空间是否已启用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;free -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;关闭 &lt;code&gt;Swap&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;关闭 &lt;code&gt;Swap&lt;/code&gt; 空间。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo swapoff /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;停止开机自动挂载。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo sed -i &apos;/swapfile/d&apos; /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除 &lt;code&gt;swap&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo rm /swapfile
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;挂载移动硬盘&lt;/h1&gt;
&lt;p&gt;查看当前磁盘情况。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;首先，创建&lt;strong&gt;需要挂载&lt;/strong&gt;的文件夹。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mkdir /mnt/sda1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开机磁盘挂载文件保存于 &lt;code&gt;/etc/fstab&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vi /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加入这一行命令来挂载磁盘。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/dev/sda1 /mnt/sda1 ntfs defaults,nofail 0 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;挂载磁盘。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mount -av
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再次查看当前磁盘情况。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;配置 SMB 文件共享&lt;/h1&gt;
&lt;p&gt;安装 Samba 服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install samba
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;要共享的目录&lt;/strong&gt;必须&lt;strong&gt;存在&lt;/strong&gt;才能被共享，给共享目录赋予权限。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo chmod 777 -R /mnt/sda1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置共享设置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vi /etc/samba/smb.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 &lt;code&gt;[global]&lt;/code&gt; 下加入以兼容 &lt;code&gt;iOS&lt;/code&gt; 文件应用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vfs objects = acl_xattr catia fruit streams_xattr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加入共享目录。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[share]
  path = /mnt/sda1
  writable = yes
  read only = no
  guest ok = yes
  guest only = yes
  public = yes
  browseable = yes
  available = yes
  create mode = 0777
  directory mode = 0777
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;重启&lt;/strong&gt; &lt;code&gt;Samba&lt;/code&gt; 服务守护进程，查看服务运行状态。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart smbd
sudo systemctl status smbd
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;使用 Cloudflared 建立隧道&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb &amp;amp;&amp;amp; 

sudo dpkg -i cloudflared.deb &amp;amp;&amp;amp; 

sudo cloudflared service install &amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;部署 Docker&lt;/h1&gt;
&lt;p&gt;首先卸载可能已经存在的旧版本 &lt;code&gt;docker&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加入 &lt;code&gt;docker&lt;/code&gt; 仓库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Add Docker&apos;s official GPG key:
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

# Add the repository to Apt sources:
echo \
  &quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | \
  sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装 &lt;code&gt;docker&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改镜像源，编辑 &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; 文件，在其中添加以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;registry-mirrors&quot;: [&quot;https://mirror&quot;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重启 &lt;code&gt;docker&lt;/code&gt; 服务。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证安装。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run hello-world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加入用户组以避免权限问题。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 添加 docker 用户组，一般已存在，不需要执行

sudo groupadd docker

# 将用户加入到docker用户组中

sudo gpasswd -a $USER docker

# 更新用户组

newgrp docker

# 测试 docker 命令是否可以直接使用

docker version
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;小雅 5678&lt;/h2&gt;
&lt;p&gt;查看 &lt;a href=&quot;https://www.kdocs.cn/l/cvEe3cv6dGkH&quot;&gt;小雅使用文档&lt;/a&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo bash -c &quot;$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)&quot;

sudo vi /etc/xiaoya/myruntime.txt

sudo bash -c &quot;$(curl http://docker.xiaoya.pro/update_data.sh)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ddns-go&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker run -d --name ddns-go --restart=always --net=host -v /opt/ddns-go:/root jeessy/ddns-go
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在浏览器中打开 &lt;code&gt;http://主机IP:9876&lt;/code&gt;，并修改你的配置。&lt;/p&gt;
&lt;h2&gt;Portainer 9000&lt;/h2&gt;
&lt;p&gt;首先，创建 Portainer Server 将用于存储其数据库的卷。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker volume create portainer_data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后，下载并安装 Portainer Server 容器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Dashdot 3001&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit \
  --restart always \
  --privileged \
  --name dashdot \
  -p 3001:3001 \
  -v /:/mnt/host:ro \
  -e DASHDOT_ENABLE_CPU_TEMPS=true \
  -e DASHDOT_ALWAYS_SHOW_PERCENTAGES=true \
  -e DASHDOT_PAGE_TITLE=&quot;Raspberry Pi 5&quot; \
  -e DASHDOT_SHOW_HOST=true \
  -e DASHDOT_CUSTOM_HOST=&quot;Raspberry Pi 5&quot; \
  mauricenino/dashdot:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Aria2 + AriaNg + Filebrowser 8000&lt;/h2&gt;
&lt;p&gt;首先查看该项目的 &lt;a href=&quot;https://github.com/wahyd4/aria2-ariang-docker&quot;&gt;GitHub 页面&lt;/a&gt; 来创建必要的文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d --name ariang \
  --restart always \
  -p 8000:80 \
  -p 6800:6800 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e ENABLE_AUTH=false \
  -e ENABLE_RCLONE=false \
  -e ARIA2_SSL=false \
  -e ARIA2_EXTERNAL_PORT=6800 \
  -e CADDY_LOG_LEVEL=ERROR \
  -v /mnt/sda1/download:/data \
  -v /home/ubuntu/docker-v/aria2/app/.cache:/app/.cache \
  -v /home/ubuntu/docker-v/aria2/app/a.db:/app/filebrowser.db \
  -v /home/ubuntu/docker-v/aria2/app/conf/key:/app/conf/key \
  -v /home/ubuntu/docker-v/aria2/app/conf:/app/conf \
  wahyd4/aria2-ui
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Aria2&lt;/code&gt;: http://ubuntu:8000&lt;/p&gt;
&lt;p&gt;&lt;code&gt;FileManger&lt;/code&gt;: http://ubuntu:8000/files&lt;/p&gt;
&lt;p&gt;默认用户名和密码均为 &lt;code&gt;admin&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Rclone&lt;/code&gt;: http://ubuntu:8000/rclone&lt;/p&gt;
&lt;h2&gt;Excalidraw 10001&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit --restart always --name excalidraw -p 10001:80 welywely/excalidraw:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Speed Test 10002&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit --restart always --name speedtest -p 10002:80 linuxserver/librespeed:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Draw.io 10003&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit --restart always --name drawio -p 10003:8080 jgraph/drawio:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Flare 5005&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit --restart always --name flare -p 5005:5005 -v /home/ubuntu/docker-v/flare/app:/app soulteary/flare
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Calibre-Web 8083&lt;/h2&gt;
&lt;p&gt;首先，在 &lt;a href=&quot;https://github.com/janeczku/calibre-web&quot;&gt;GitHub 页面&lt;/a&gt; 下载数据库文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d \
  --name=calibre-web \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -p 8083:8083 \
  -v /home/ubuntu/docker-v/calibre-web/data:/config \
  -v /home/ubuntu/docker-v/calibre-web/calibre/library:/books \
  --restart always \
  lscr.io/linuxserver/calibre-web:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;默认用户名为 &lt;code&gt;admin&lt;/code&gt;。
默认密码为 &lt;code&gt;admin123&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;IT-Tools 9600&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d --name it-tools --restart always -p 9600:80 corentinth/it-tools:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Stirling-PDF 9700&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d \
  -p 9700:8080 \
  -v /home/ubuntu/docker-v/s-pdf/trainingData:/usr/share/tessdata \
  -v /home/ubuntu/docker-v/s-pdf/extraConfigs:/configs \
  -v /home/ubuntu/docker-v/s-pdf/logs:/logs \
  -e DOCKER_ENABLE_SECURITY=false \
  -e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
  -e LANGS=zh_CN \
  --name stirling-pdf \
  --restart always \
  frooodle/s-pdf:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;EmulatorJS 9800 3000&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -d \
  --name=emulatorjs \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -e SUBFOLDER=/ `#optional` \
  -p 3000:3000 \
  -p 9800:80 \
  -p 4001:4001 `#optional` \
  -v /home/ubuntu/docker-v/emulatorjs/config:/config \
  -v /home/ubuntu/docker-v/emulatorjs/data:/data \
  --restart always \
  lscr.io/linuxserver/emulatorjs:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Minecraft Bedrock Server&lt;/h2&gt;
&lt;p&gt;创建 &lt;code&gt;Docker Compose&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /home/ubuntu/docker-v/mc-bedrock
cd /home/ubuntu/docker-v/mc-bedrock
vi docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;填写以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  mc:
    image: itzg/minecraft-bedrock-server
    restart: always
    environment:
      TZ: &quot;Asia/Shanghai&quot;
      EULA: &quot;TRUE&quot;
      SERVER_NAME: &quot;Wely&quot;
      LEVEL_NAME: &quot;World&quot;
    ports:
      - &quot;19132:19132/udp&quot;
    volumes:
      - /home/ubuntu/docker-v/mc-bedrock/data:/data
    stdin_open: true
    tty: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后建立容器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Minecraft Server on Docker (Java Edition)&lt;/h2&gt;
&lt;p&gt;创建 &lt;code&gt;Docker Compose&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /home/ubuntu/docker-v/mc-java
cd /home/ubuntu/docker-v/mc-java
vi docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;填写以下内容。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  mc:
    image: itzg/minecraft-server
    restart: always
    environment:
      TZ: &quot;Asia/Shanghai&quot;
      SNOOPER_ENABLED: &quot;false&quot;
      SERVER_NAME: &quot;Wely&quot;
      MAX_PLAYERS: &quot;10&quot;
      LEVEL: &quot;World&quot;
      MODE: &quot;survival&quot;
      DIFFICULTY: &quot;normal&quot;
      EXEC_DIRECTLY: &quot;true&quot;
      GUI: &quot;false&quot;
      INIT_MEMORY: &quot;1G&quot;
      MAX_MEMORY: &quot;4G&quot;
      ENABLE_ROLLING_LOGS: &quot;true&quot;
      EULA: &quot;true&quot;
    ports:
      - &quot;25565:25565&quot;
    volumes:
      - /home/ubuntu/docker-v/mc-java/data:/data
    stdin_open: true
    tty: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者使用 &lt;code&gt;fabric&lt;/code&gt; 服务端.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  mc:
    image: itzg/minecraft-server
    restart: always
    environment:
      TYPE: &quot;FABRIC&quot;
      FABRIC_LAUNCHER: &quot;fabric-server-mc.1.21-loader.0.15.11-launcher.1.0.1.jar&quot;
      TZ: &quot;Asia/Shanghai&quot;
      SNOOPER_ENABLED: &quot;false&quot;
      SERVER_NAME: &quot;Wely&quot;
      MAX_PLAYERS: &quot;10&quot;
      LEVEL: &quot;fabric-world&quot;
      MODE: &quot;survival&quot;
      DIFFICULTY: &quot;normal&quot;
      EXEC_DIRECTLY: &quot;true&quot;
      GUI: &quot;false&quot;
      INIT_MEMORY: &quot;1G&quot;
      MAX_MEMORY: &quot;4G&quot;
      ENABLE_ROLLING_LOGS: &quot;true&quot;
      EULA: &quot;true&quot;
    ports:
      - &quot;25565:25565&quot;
    volumes:
      - /home/ubuntu/docker-v/mc-java/data:/data
    stdin_open: true
    tty: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后建立容器。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;对于 Docker 无法访问的解决方案&lt;/h2&gt;
&lt;p&gt;在另一台&lt;strong&gt;可以访问&lt;/strong&gt;的机器上拉取镜像，再传输到需要使用镜像的机器上。&lt;/p&gt;
&lt;p&gt;首先拉取&lt;strong&gt;对应平台&lt;/strong&gt;的镜像。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull --platform linux/arm64 image
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导出镜像。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker save -o image.tar image
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将 &lt;code&gt;image.tar&lt;/code&gt; 文件传输至需要使用镜像的机器，再导入本地镜像。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker load -i image.tar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时，导入的镜像包含所有的元数据。&lt;/p&gt;
&lt;h1&gt;查看路由器校园网 IP&lt;/h1&gt;
&lt;p&gt;路由器脚本。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /bin/ash
echo &quot;==========Start==========&quot;
echo `date &apos;+%Y-%m-%d %H:%M:%S&apos;`
#get current wan_ip
current_wan_ip=`ifconfig -a | grep inet | grep -v inet6 | grep -v 127.0.0.1 | grep -v 192.168.8.1 | awk &apos;{print $2}&apos; | tr -d &quot;addr:&quot;`
echo &quot;IP: $current_wan_ip&quot;
#if ip.html
if [ ! -f &quot;ip.html&quot; ]; then
	echo ${current_wan_ip} &amp;gt; ip.html
	echo &quot;craete ip.html&quot;
else
	last_ip=`cat ip.html`
	if [ &quot;${current_wan_ip}&quot; != &quot;${last_ip}&quot; ]; then
		#renew ip.html
		echo ${current_wan_ip} &amp;gt; ip.html
		echo &quot;renew ip.html&quot;
	else
		echo &quot;no difference&quot;
	fi
fi
echo `date &apos;+%Y-%m-%d %H:%M:%S&apos;`
echo -e &quot;==========End==========\n&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;树莓派脚本。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo sshpass -p password scp -O -o StrictHostKeyChecking=no -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa root@192.168.8.1:/root/ip.html /home/ubuntu/server-ip/ip.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 &lt;code&gt;nginx&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run -dit --restart always -p 23333:80 --name nginx -v /home/ubuntu/server-ip:/usr/share/nginx/html nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Docker 备份脚本&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;#! /bin/sh
cd /home/ubuntu
sudo tar -czvf docker-v.tar.gz docker-v
sudo mv docker-v.tar.gz /mnt/sda1/docker-backup/docker-v-$(date +%Y%m%d%H%M%S).tar.gz
find /mnt/sda1/docker-backup/ -mtime +7 -name &quot;*.tar.gz&quot; -exec rm -rf {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;树莓派 5 风扇&lt;/h1&gt;
&lt;p&gt;随着树莓派温度的升高，风扇会做出以下反应：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;低于 &lt;code&gt;50°C&lt;/code&gt;，风扇&lt;strong&gt;不旋转&lt;/strong&gt;（ &lt;code&gt;0%&lt;/code&gt; 速度）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;50°C&lt;/code&gt; 时，风扇以&lt;strong&gt;低速&lt;/strong&gt;运转（ &lt;code&gt;30%&lt;/code&gt; 速度）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;60°C&lt;/code&gt; 时，风扇速度增加至&lt;strong&gt;中速&lt;/strong&gt;（ &lt;code&gt;50%&lt;/code&gt; 速度）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;67.5°C&lt;/code&gt; 时，风扇转速增至&lt;strong&gt;高速&lt;/strong&gt;（ &lt;code&gt;70%&lt;/code&gt; 转速）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;75°C&lt;/code&gt; 时，风扇升至&lt;strong&gt;全速&lt;/strong&gt;（ &lt;code&gt;100%&lt;/code&gt; 速度）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;温度降低时风扇速度也与温度范围有相同的匹配关系，具有 &lt;code&gt;5°C&lt;/code&gt; 的&lt;strong&gt;滞后&lt;/strong&gt;；当温度降至低于上述每个阈值 &lt;code&gt;5°C&lt;/code&gt; 时，风扇速度会降低。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;USB&lt;/code&gt; 端口和&lt;code&gt;风扇插口&lt;/code&gt;均采用相同的 &lt;code&gt;1.6 A&lt;/code&gt; 电流限制。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所有型号的 &lt;code&gt;Raspberry Pi&lt;/code&gt; 都进行了一定程度的热管理，以避免在大负荷下过热。&lt;code&gt;SoC&lt;/code&gt; 有一个内部温度传感器，&lt;code&gt;GPU&lt;/code&gt; 上的软件会对其进行轮询，以确保温度不超过我们为所有型号设定的 &lt;code&gt;85°C&lt;/code&gt; &lt;strong&gt;上限&lt;/strong&gt;。可以将其设置为更低的值，但不能设置为更高的值。当设备接近极限值时，芯片上使用的各种频率和电压会&lt;strong&gt;降低&lt;/strong&gt;。这样可以减少产生的热量，从而控制温度。&lt;/p&gt;
&lt;p&gt;当核心温度在 &lt;code&gt;80°C&lt;/code&gt; 到 &lt;code&gt;85°C&lt;/code&gt; 之间时，&lt;code&gt;ARM&lt;/code&gt; 核心将逐渐&lt;strong&gt;降低温度&lt;/strong&gt;。如果温度达到 &lt;code&gt;85°C&lt;/code&gt; ，&lt;code&gt;ARM&lt;/code&gt; 内核和 &lt;code&gt;GPU&lt;/code&gt; 都会&lt;strong&gt;受到限制&lt;/strong&gt;。&lt;/p&gt;
</content:encoded></item><item><title>Docker build drawio with arm v7</title><link>https://blog.wely.fun/posts/docker-build-drawio-with-arm-v7/</link><guid isPermaLink="true">https://blog.wely.fun/posts/docker-build-drawio-with-arm-v7/</guid><description>Build the arm/v7 version of draw.io in docker.</description><pubDate>Mon, 27 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Draw.io is a &lt;em&gt;Security-first diagramming for teams.&lt;/em&gt; And we can run our own &lt;code&gt;draw.io&lt;/code&gt; server with &lt;code&gt;Docker&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But unfortunately, there is no &lt;code&gt;arm/v7&lt;/code&gt; version. There is an similar question on the &lt;a href=&quot;https://github.com/jgraph/docker-drawio/issues/154&quot;&gt;&lt;code&gt;GitHub&lt;/code&gt;&lt;/a&gt;. So I try to build it and answer that question.&lt;/p&gt;
&lt;p&gt;I have solved this question and built an &lt;code&gt;arm/v7&lt;/code&gt; version, which run on my &lt;code&gt;arm/v7&lt;/code&gt; platform successfully.&lt;/p&gt;
&lt;p&gt;I pushed it at &lt;a href=&quot;https://hub.docker.com/r/welywely/drawio&quot;&gt;Docker Hub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Anyone can use the &lt;code&gt;arm/v7&lt;/code&gt; version with &lt;code&gt;docker pull welywely/drawio&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;How can I build the arm/v7 version&lt;/h2&gt;
&lt;p&gt;First, &lt;code&gt;git clone https://github.com/jgraph/docker-drawio.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Dockerfile&lt;/code&gt; is at &lt;code&gt;docker-drawio-dev/main/Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then &lt;code&gt;docker build --platform linux/arm/v7 -t welyfun/drawio:latest --push .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I tried to change &lt;code&gt;FROM openjdk:11-jdk-slim AS build&lt;/code&gt; to &lt;code&gt;FROM adoptopenjdk/openjdk11:armv7l-debianslim-jdk-11.0.23_9-slim AS build&lt;/code&gt; in the first line to support &lt;code&gt;arm/v7&lt;/code&gt; and run build.&lt;/p&gt;
&lt;p&gt;Then I meet this error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Buildfile: /tmp/drawio/etc/build/build.xml

merge:
[jscomp] Compiling 1 file(s) with 112 extern(s)
#
# A fatal error has been detected by the Java Runtime Environment:
#
#SIGBUS (0x7) at pc=0x413ee354, pid=28, tid=101
#
# JRE version: OpenJDK Runtime Environment Temurin-11.0.23+9 (11.0.23+9) (build 11.0.23+9)
# Java VM: OpenJDK Server VM Temurin-11.0.23+9 (11.0.23+9, mixed mode, g1 gc, linux-)
# Problematic frame:
#V[libjvm.so+0xa63354]
#
#No core dump will be written. Core dumps have been disabled. To enable core dumping, try &quot;ulimit -c unlimited&quot; before starting Java again
#
# An error report file with more information is saved as:
# /tmp/drawio/etc/build/hs_err_pid28.log
#
# If you would like to submit a bug report, please visit:
#   https://github.com/adoptium/adoptium-support/issues
#
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tried other similar images, but no one worked.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Run the following command outside the docker to get the &lt;code&gt;draw.war&lt;/code&gt;, which means run in the system directly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone --depth 1 https://github.com/jgraph/drawio.git
cd drawio/etc/build/
ant war
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy the &lt;code&gt;draw.war&lt;/code&gt; at &lt;code&gt;drawio/build/draw.war&lt;/code&gt; to &lt;code&gt;docker-drawio-dev/main/&lt;/code&gt;, which is the same contents with &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then change &lt;code&gt;COPY --from=build /tmp/drawio/build/draw.war /tmp&lt;/code&gt; to &lt;code&gt;COPY draw.war /tmp&lt;/code&gt; in the &lt;code&gt;Dockerfile&lt;/code&gt; and delete the command line before &lt;code&gt;FROM tomcat:9-jre11&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now the &lt;code&gt;Dockerfile&lt;/code&gt; only has these commands.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM tomcat:9-jre11

LABEL maintainer=&quot;JGraph Ltd&quot; \
      org.opencontainers.image.authors=&quot;JGraph Ltd&quot; \
      org.opencontainers.image.url=&quot;https://www.drawio.com&quot; \
      org.opencontainers.image.source=&quot;https://github.com/jgraph/docker-drawio&quot;

ENV RUN_USER            tomcat
ENV RUN_GROUP           tomcat

RUN apt-get update -y &amp;amp;&amp;amp; \
    apt-get install -y --no-install-recommends \
        certbot \
        curl \
        xmlstarlet \
        unzip &amp;amp;&amp;amp; \
    apt-get autoremove -y --purge &amp;amp;&amp;amp; \
    apt-get clean &amp;amp;&amp;amp; \
    rm -r /var/lib/apt/lists/*

COPY draw.war /tmp

# Extract draw.io war &amp;amp; Update server.xml to set Draw.io webapp to root
RUN mkdir -p $CATALINA_HOME/webapps/draw &amp;amp;&amp;amp; \
    unzip /tmp/draw.war -d $CATALINA_HOME/webapps/draw &amp;amp;&amp;amp; \
    rm -rf /tmp/draw.war /tmp/drawio &amp;amp;&amp;amp; \
    cd $CATALINA_HOME &amp;amp;&amp;amp; \
    xmlstarlet ed \
        -P -S -L \
        -i &apos;/Server/Service/Engine/Host/Valve&apos; -t &apos;elem&apos; -n &apos;Context&apos; \
        -i &apos;/Server/Service/Engine/Host/Context&apos; -t &apos;attr&apos; -n &apos;path&apos; -v &apos;/&apos; \
        -i &apos;/Server/Service/Engine/Host/Context[@path=&quot;/&quot;]&apos; -t &apos;attr&apos; -n &apos;docBase&apos; -v &apos;draw&apos; \
        -s &apos;/Server/Service/Engine/Host/Context[@path=&quot;/&quot;]&apos; -t &apos;elem&apos; -n &apos;WatchedResource&apos; -v &apos;WEB-INF/web.xml&apos; \
        conf/server.xml

# Copy docker-entrypoint
COPY docker-entrypoint.sh /
RUN chmod 755 /docker-entrypoint.sh
# Add a tomcat user
RUN groupadd -r ${RUN_GROUP} &amp;amp;&amp;amp; useradd -g ${RUN_GROUP} -d ${CATALINA_HOME} -s /bin/bash ${RUN_USER} &amp;amp;&amp;amp; \
    chown -R ${RUN_USER}:${RUN_GROUP} ${CATALINA_HOME}

USER ${RUN_USER}

WORKDIR $CATALINA_HOME

EXPOSE 8080 8443

ENTRYPOINT [&quot;/docker-entrypoint.sh&quot;]
CMD [&quot;catalina.sh&quot;, &quot;run&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can build the &lt;code&gt;arm/v7&lt;/code&gt; version with &lt;code&gt;docker build --platform linux/arm/v7 -t welywely/drawio:latest --push .&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>使用 Ruffle 复活 Flash 游戏</title><link>https://blog.wely.fun/posts/%E4%BD%BF%E7%94%A8-ruffle-%E5%A4%8D%E6%B4%BB-flash-%E6%B8%B8%E6%88%8F/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E4%BD%BF%E7%94%A8-ruffle-%E5%A4%8D%E6%B4%BB-flash-%E6%B8%B8%E6%88%8F/</guid><description>使用开源 Ruffle 引擎，无需 Flash 即可畅玩 Flash 游戏</description><pubDate>Sun, 05 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;尽管 Flash 已经没落，仍然有许多优秀的 Flash 游戏陪伴我们成长。使用 Ruffle 这一开源 Flash Player 模拟器，可在所有现代操作系统和浏览器上本地运行，无需大惊小怪即可让 Flash 内容栩栩如生。&lt;/p&gt;
&lt;h1&gt;安装 Ruffle&lt;/h1&gt;
&lt;p&gt;对于想要在本地运行 Flash 文件的用户，在 &lt;a href=&quot;https://ruffle.rs/&quot;&gt;官网&lt;/a&gt; 下载安装包即可。如果只想在浏览器中运行 Flash 文件，可以直接安装浏览器扩展。&lt;/p&gt;
&lt;h2&gt;嵌入 HTML 网页&lt;/h2&gt;
&lt;p&gt;如果你是网站管理员，并且希望用户不需要安装任何插件即可运行网页上的 Flash 内容，那么只需要几行代码，即可嵌入 Flash 内容。&lt;/p&gt;
&lt;p&gt;Ruffle 可以自动替换网站上任何带有 Ruffle 元素的旧式 Flash 嵌入，只需要在网页中包含以下脚本标签：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;https://unpkg.com/@ruffle-rs/ruffle&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是嵌入到 HTML 文件中的 Flash 的简单示例，其中 &lt;code&gt;movie.swf&lt;/code&gt; 即为需要运行的 Flash 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;object&amp;gt;
        &amp;lt;embed src=&quot;movie.swf&quot; width=&quot;550&quot; height=&quot;400&quot; /&amp;gt;
    &amp;lt;/object&amp;gt;

    &amp;lt;script src=&quot;https://unpkg.com/@ruffle-rs/ruffle&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者使用 JavaScript API 调用 Ruffle，下面是使用 Ruffle JavaScript API 播放位于 Web 服务器根目录中的 SWF 文件的示例，其中 &lt;code&gt;movie.swf&lt;/code&gt; 即为需要运行的 Flash 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    window.RufflePlayer = window.RufflePlayer || {};
    window.addEventListener(&quot;load&quot;, (event) =&amp;gt; {
        const ruffle = window.RufflePlayer.newest();
        const player = ruffle.createPlayer();
        const container = document.getElementById(&quot;container&quot;);
        container.appendChild(player);
        player.load(&quot;movie.swf&quot;);
    });
&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;https://unpkg.com/@ruffle-rs/ruffle&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是一个浏览器最大界面运行 Flash 文件的完整网页示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;zh&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;游戏名称&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        /* 确保html和body元素占满整个屏幕 */
        html, body {
            height: 100%;
            margin: 0;
            overflow: hidden; /* 隐藏滚动条 */
        }
        /* 使容器和Ruffle播放器全屏和自适应 */
        #container {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        #container ruffle-player {
            flex-shrink: 0; /* 防止播放器被压缩 */
            width: 100%;
            height: 100%;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id=&quot;container&quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script src=&quot;//unpkg.com/@ruffle-rs/ruffle&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      window.addEventListener(&apos;load&apos;, async () =&amp;gt; {
          const ruffle = window.RufflePlayer.newest();
          const player = ruffle.createPlayer();
          const container = document.getElementById(&apos;container&apos;);
          container.appendChild(player);
          player.load(&apos;game.swf&apos;);
      });
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;新建一个文本文档并重命名为 &lt;code&gt;index.html&lt;/code&gt;，将以上网页示例代码粘贴到 HTML 文件中，并将 &lt;code&gt;game.swf&lt;/code&gt; 指定为你需要运行的 Flash 游戏。在该 HTML 文件目录下打开终端，使用 &lt;code&gt;python&lt;/code&gt; 命令 &lt;code&gt;python -m http.server&lt;/code&gt; 快速创建一个本地服务器，然后在浏览器中打开 &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt; 即可查看自己的 Flash 游戏网页。&lt;/p&gt;
&lt;h1&gt;跨域问题&lt;/h1&gt;
&lt;p&gt;如果运行 Flash 的网页地址为 &lt;code&gt;play.example.com&lt;/code&gt;，但运行的 Flash 文件 &lt;code&gt;game.swf&lt;/code&gt; 存放在另一个网页 &lt;code&gt;flash.example.com&lt;/code&gt; 中，如果没有配置跨域访问，便会在运行网页看到类似错误：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.wely.fun/blog/cors-error.png&quot; alt=&quot;跨域错误&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此时按下 &lt;code&gt;F12&lt;/code&gt; 打开浏览器控制台即可看到类似跨域错误：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.wely.fun/blog/cors-error-console.png&quot; alt=&quot;跨域错误控制台&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果你同样使用了 Cloudflare 来托管网站，那么可以采取以下措施。&lt;/p&gt;
&lt;p&gt;来到 &lt;strong&gt;Flash 文件所在&lt;/strong&gt; &lt;code&gt;域名&lt;/code&gt; - &lt;code&gt;规则&lt;/code&gt; - &lt;code&gt;转换规则&lt;/code&gt; - &lt;code&gt;修改相应头&lt;/code&gt; 下 &lt;code&gt;创建规则&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;规则名称&lt;/code&gt; 随便填。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当传入请求匹配时...&lt;/strong&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;主机名&lt;/td&gt;
&lt;td&gt;等于&lt;/td&gt;
&lt;td&gt;&lt;code&gt;flash.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;flash.example.com&lt;/code&gt; 即为&lt;strong&gt;存放 Flash 文件&lt;/strong&gt;的地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;则...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;设置静态&lt;/code&gt;：&lt;code&gt;Access-Control-Allow-Methods&lt;/code&gt; = &lt;code&gt;GET,HEAD,POST,OPTIONS&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;设置静态&lt;/code&gt;：&lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; = &lt;code&gt;*&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后 &lt;code&gt;部署&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;然后即可在网页里享受 Flash 游戏。&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;参考：&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://ruffle.rs/&quot;&gt;Ruffle - Flash 模拟器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ruffle-rs/ruffle/&quot;&gt;GitHub - reffle-rs/fuffle: A Flash Player emulator written in Rust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wzhecnu.cn/2024/03/02/server/ruffle-swf-flash/&quot;&gt;重燃 Flash 游戏 | Ruffle 使用指南&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>博客图床测试</title><link>https://blog.wely.fun/posts/%E5%8D%9A%E5%AE%A2%E5%9B%BE%E5%BA%8A%E6%B5%8B%E8%AF%95/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%8D%9A%E5%AE%A2%E5%9B%BE%E5%BA%8A%E6%B5%8B%E8%AF%95/</guid><description>测试仅有本博客能访问的基于 Cloudflare 的图床</description><pubDate>Thu, 02 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;封面图片 &lt;a href=&quot;https://img.wely.fun/wely/favicon.PNG&quot;&gt;来源&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这篇博客用于测试基于&lt;strong&gt;本博客专用&lt;/strong&gt;的图床系统，该图床基于 Cloudflare Workers 和 Cloudflare R2 存储桶搭建。&lt;/p&gt;
&lt;p&gt;以下查看使用 Markdown 直接插入图片的显示效果。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.wely.fun/wely/favicon.PNG&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;p&gt;理论上来说，该图片&lt;strong&gt;仅在本博客下&lt;/strong&gt;可以正常显示，使用新标签页打开此图片的来源地址时会&lt;strong&gt;禁止访问&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;注意，从本博客点击图片来源地址&lt;strong&gt;仍可以访问&lt;/strong&gt;，例如点击博客开头的封面图片 &lt;a href=&quot;https://img.wely.fun/wely/favicon.PNG&quot;&gt;来源&lt;/a&gt; 或在图片上右击选择新标签页打开，此时&lt;strong&gt;仍可以访问&lt;/strong&gt;图片。如果直接新建空白标签页并粘贴图片地址，访问将被&lt;strong&gt;禁止&lt;/strong&gt;。
搭建方法来源于 &lt;a href=&quot;https://muzihuaner.github.io/2022/07/28/CloudflareR2%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97%E6%95%99%E7%A8%8B/&quot;&gt;CloudflareR2快速开始使用(白嫖)指南&lt;/a&gt; 和 &lt;a href=&quot;https://blog.ver.moe/posts/cloudflare-r2-image-host/&quot;&gt;Cloudflare R2对象存储当图床测试&lt;/a&gt; 。&lt;/p&gt;
&lt;h2&gt;基于 Cloudflare 的搭建方法&lt;/h2&gt;
&lt;p&gt;首先创建 R2 存储桶。&lt;/p&gt;
&lt;p&gt;然后创建 Cloudflare Workers 项目，代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addEventListener(&quot;fetch&quot;, event =&amp;gt; {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url)
  const objectName = url.pathname.slice(1) // /path/to/file =&amp;gt; path/to/file

  console.log(`${request.method} object ${objectName || &apos;(root)&apos;}: ${request.url}`)

  // 只允许 GET / HEAD
  if (request.method !== &apos;GET&apos; &amp;amp;&amp;amp; request.method !== &apos;HEAD&apos;) {
    return new Response(&apos;Method Not Allowed&apos;, { status: 405 })
  }

  // 不提供根路径列表，直接返回 404，避免暴露 bucket 结构
  if (!objectName) {
    return new Response(&apos;Not Found&apos;, { status: 404 })
  }

  // ====== GET：读取对象内容 ======
  if (request.method === &apos;GET&apos;) {
    const object = await R2.get(objectName, {
      // 让 R2 自己解析 Range、条件请求等头
      range: request.headers,
      onlyIf: request.headers,
    })

    if (object === null) {
      return objectNotFound(objectName)
    }

    const headers = new Headers()
    // 将 R2 中保存的 HTTP 元数据写入响应（Content-Type、Cache-Control 等）
    object.writeHttpMetadata(headers)
    headers.set(&apos;etag&apos;, object.httpEtag)

    // 如果客户端发送了 Range 头，则声明支持分块
    if (request.headers.has(&apos;range&apos;)) {
      headers.set(&apos;accept-ranges&apos;, &apos;bytes&apos;)
    }

    // object.body 为空表示满足条件请求（如 If-None-Match），返回 304
    const status = object.body
      ? (request.headers.has(&apos;range&apos;) ? 206 : 200)
      : 304

    return new Response(object.body, { status, headers })
  }

  // ====== HEAD：只返回元信息，不返回 body ======
  if (request.method === &apos;HEAD&apos;) {
    const object = await R2.head(objectName)

    if (object === null) {
      return objectNotFound(objectName)
    }

    const headers = new Headers()
    object.writeHttpMetadata(headers)
    headers.set(&apos;etag&apos;, object.httpEtag)

    return new Response(null, { status: 200, headers })
  }
}

// 404 响应
function objectNotFound(objectName) {
  return new Response(
    `&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;R2 object &quot;&amp;lt;b&amp;gt;${objectName}&amp;lt;/b&amp;gt;&quot; not found&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;`,
    {
      status: 404,
      headers: {
        &apos;content-type&apos;: &apos;text/html; charset=UTF-8&apos;
      }
    }
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;回到新建的 Workers 项目首页，来到 &lt;code&gt;设置&lt;/code&gt; - &lt;code&gt;变量&lt;/code&gt; - &lt;code&gt;R2 存储桶绑定&lt;/code&gt; ，&lt;code&gt;添加绑定&lt;/code&gt; 后变量名称填写 &lt;code&gt;R2&lt;/code&gt; ，R2 存储桶选择&lt;strong&gt;刚才创建的图床存储桶&lt;/strong&gt;，然后 &lt;code&gt;部署&lt;/code&gt; 。&lt;/p&gt;
&lt;h2&gt;使用方法&lt;/h2&gt;
&lt;p&gt;来到 Cloudflare R2 存储桶首页，选择&lt;strong&gt;图床所在的存储桶&lt;/strong&gt;，直接上传图片即可。需要访问图片时，如果你的图床 Workers 项目自定义域为 &lt;code&gt;img.example.com&lt;/code&gt; ，图片文件名为 &lt;code&gt;img.png&lt;/code&gt; ，那么访问地址为 &lt;code&gt;https://img.example.com/img.png&lt;/code&gt; 。&lt;/p&gt;
&lt;h2&gt;安全性措施&lt;/h2&gt;
&lt;p&gt;Cloudflare 提供的 R2 存储桶的免费容量为 &lt;code&gt;10 GB&lt;/code&gt; 每月，免费的 &lt;code&gt;A&lt;/code&gt; 类操作次数为 &lt;code&gt;100&lt;/code&gt; 万次每月，免费的 &lt;code&gt;B&lt;/code&gt; 类操作次数为 &lt;code&gt;1000&lt;/code&gt; 万次每月。正常自己使用是用不完的。&lt;s&gt;被刷了那就乖乖掏钱吧&lt;/s&gt;&lt;/p&gt;
&lt;h3&gt;配置 Cloudflare 缓存&lt;/h3&gt;
&lt;h4&gt;新方法&lt;/h4&gt;
&lt;p&gt;推荐使用新方法，新方法不会占用免费的3个页面规则，两种方法选一种配置即可。&lt;/p&gt;
&lt;p&gt;来到&lt;strong&gt;图床所在&lt;/strong&gt; &lt;code&gt;域名&lt;/code&gt; - &lt;code&gt;缓存&lt;/code&gt; - &lt;code&gt;Cache Rules&lt;/code&gt; 下 &lt;code&gt;创建规则&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;规则名称&lt;/code&gt; 随便填。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当传入请求匹配时...&lt;/strong&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;主机名&lt;/td&gt;
&lt;td&gt;等于&lt;/td&gt;
&lt;td&gt;&lt;code&gt;img.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;img.example.com&lt;/code&gt; 即为图床的地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;则...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;缓存资格：&lt;code&gt;符合缓存条件&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;添加 &lt;code&gt;边缘 TTL&lt;/code&gt;：忽略缓存控制标头，使用此 TTL =&amp;gt; &lt;code&gt;6 个月&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;添加 &lt;code&gt;浏览器 TTL&lt;/code&gt;：忽略缓存控制标头，使用此 TTL =&amp;gt; &lt;code&gt;1 个月&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后 &lt;code&gt;部署&lt;/code&gt; 。&lt;/p&gt;
&lt;h4&gt;传统方法&lt;/h4&gt;
&lt;p&gt;不推荐，此方法会占用免费的3个页面规则。&lt;/p&gt;
&lt;p&gt;来到&lt;strong&gt;图床所在&lt;/strong&gt; &lt;code&gt;域名&lt;/code&gt; - &lt;code&gt;规则&lt;/code&gt; - &lt;code&gt;页面规则&lt;/code&gt; 下 &lt;code&gt;创建页面规则&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;URL&lt;/code&gt; 填 &lt;code&gt;img.example.com/*&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;img.example.com&lt;/code&gt; 即为图床的地址，&lt;code&gt;/*&lt;/code&gt; 是指该地址下所有内容。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;点击 &lt;code&gt;+ 添加设置&lt;/code&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;缓存级别&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;缓存所有内容&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;浏览器缓存 TTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1天&lt;/code&gt; &lt;s&gt;最高都可以到1年&lt;/s&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;边缘缓存 TTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1个月&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;然后 &lt;code&gt;保存和部署页面规则&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;现在访问图片时，访问的都是 Cloudflare CDN 服务器上的内容，&lt;strong&gt;不会占用&lt;/strong&gt; R2 存储桶的操作次数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;浏览器缓存 TTL 是指浏览器第一次访问这个地址后，就会把地址对应的文件缓存到本地。&lt;/p&gt;
&lt;p&gt;接下来在 TTL 时间内，浏览器再次访问这个地址时，都是直接调用本地缓存的文件。&lt;/p&gt;
&lt;p&gt;边缘缓存 TTL 是指你第一次访问这个地址后，为你提供这个地址资源的 CDN 节点会缓存这个地址对应的文件。&lt;/p&gt;
&lt;p&gt;接下来在 TTL 时间内，你再次通过这个节点访问这个地址时，这个节点会直接调用缓存的文件。&lt;/p&gt;
&lt;p&gt;TTL 就是缓存有效期，过期后就要重新缓存。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;防盗链&lt;/h3&gt;
&lt;p&gt;防盗链就是防止别的网站直接抓取我的网站，然后显示在它的网站上，就是防止我的图床承担其他网站的访问流量&lt;s&gt;然后免费次数被刷爆了掏钱&lt;/s&gt;。&lt;/p&gt;
&lt;p&gt;来到图床所在 &lt;code&gt;域名&lt;/code&gt; - &lt;code&gt;安全性&lt;/code&gt; - &lt;code&gt;WAF&lt;/code&gt; 下 &lt;code&gt;创建规则&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;规则名称&lt;/code&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;引用方&lt;/td&gt;
&lt;td&gt;不包含&lt;/td&gt;
&lt;td&gt;&lt;code&gt;blog.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;And&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;code&gt;img.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;其中 &lt;code&gt;blog.example.com&lt;/code&gt; 即为博客地址，&lt;code&gt;img.example.com&lt;/code&gt; 即为图床地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后采取措施：&lt;code&gt;阻止&lt;/code&gt; 。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;此时只有在博客 &lt;code&gt;blog.example.com&lt;/code&gt; 内访问图床 &lt;code&gt;img.example.com&lt;/code&gt; 才可以成功。如果不是从博客 &lt;code&gt;blog.example.com&lt;/code&gt; 内访问图床 &lt;code&gt;img.example.com&lt;/code&gt; ，访问请求将被阻止。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这样对图床地址就有了一个基本的保护。&lt;/p&gt;
</content:encoded></item><item><title>HTML 常用转义字符对照表</title><link>https://blog.wely.fun/posts/html-%E5%B8%B8%E7%94%A8%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E5%AF%B9%E7%85%A7%E8%A1%A8/</link><guid isPermaLink="true">https://blog.wely.fun/posts/html-%E5%B8%B8%E7%94%A8%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E5%AF%B9%E7%85%A7%E8%A1%A8/</guid><description>HTML 中经常用到的转义字符对照表</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下内容来自于 &lt;a href=&quot;https://savalone.com/html/escape-sequence.html&quot;&gt;html 常用转义字符对照表&lt;/a&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;&amp;lt;code&amp;gt; &amp;lt;/code&amp;gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#160;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;nbsp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;空格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#64;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;commat;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;at 符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;©&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#169;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;copy;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;版权符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#33;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;excl;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;感叹号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¡&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#161;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;iexcl;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;倒置感叹号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#58;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;colon;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;冒号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#44;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;comma;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;逗号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;·&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#183;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;middot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;中间点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;‘&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;apos;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;撇号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;‘&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8216;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lsquo;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左单引号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;“&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8220;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ldquo;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左双引号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#40;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lpar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#91;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lsqb;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左方括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#123;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lcub;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左花括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;§&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#167;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;sect;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;分节符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#95;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lowbar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单下划线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;verbar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;竖线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;‖&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8214;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;Verbar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;双竖线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;∠&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8736;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ang;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;角&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#35;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;num;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数字标志&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#36;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;dollar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;美元符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#37;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;percnt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;百分号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;‰&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8240;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;permil;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;千分号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;‱&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8241;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pertenk;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;万分号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#42;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ast;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;星号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#47;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;sol;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;斜线符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#43;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;add;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;加号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;×&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#215;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;times;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;乘号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#61;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;equal;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;等于号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;≈&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8776;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;asymp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;约等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#60;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;小于号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;≤&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8804;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;le;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;小于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¹&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#185;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;sup1;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;上标 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;²&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#178;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;sup2;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;上标 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;³&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#179;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;sup3;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;上标 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#38;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;and 符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;®&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#174;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;reg;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;注册商标符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#63;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;quest;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;问号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¿&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#191;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;iquest;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;倒置问号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#59;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;semi;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;分号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#46;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;period;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;句号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;•&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8226;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;bull;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;加重号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;“&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#34;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;引号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;’&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8217;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;rsquo;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右单引号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;”&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8221;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;rdquo;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右双引号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#41;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;rpar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#93;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;rsqb;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右方括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#125;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;rcub;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;右花括号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¶&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#182;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;para;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;段落符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#818;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;UnderBar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;双下划线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¦&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#166;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;brvbar;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;间断竖线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;…&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8230;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;hellip;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;三点省略号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;^&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#94;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;Hat;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;hat符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;π&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#961;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;pi;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;圆周率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¥&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#165;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;yen;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;元符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;°&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#176;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;deg;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;度符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;√&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8730;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;radic;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;平方根&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;∞&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8734;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;infin;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;正无穷&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;±&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#177;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;plusmn;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;加减符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#92;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;bsol;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;反斜线符号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;–&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8211;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ndash;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;减号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;÷&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#247;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;divide;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;除号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;≠&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8800;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ne;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;不等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;≡&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8801;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;equiv;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;相当于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#62;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;大于号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;≥&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#8805;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;ge;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;大于等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¼&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#188;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;frac14;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;四分之一&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;½&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#189;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;frac12;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;二分之一&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;¾&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;#190;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;frac34;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;四分之三&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;除此之外，还可以使用 &lt;code&gt;\&lt;/code&gt; 来进行转义，例如要转义反引号 &lt;code&gt;`&lt;/code&gt; 可以写为 &lt;code&gt;\`&lt;/code&gt; 的形式。&lt;/p&gt;
</content:encoded></item><item><title>Markdown 语法</title><link>https://blog.wely.fun/posts/markdown-%E8%AF%AD%E6%B3%95/</link><guid isPermaLink="true">https://blog.wely.fun/posts/markdown-%E8%AF%AD%E6%B3%95/</guid><description>快速查看 Markdown 语法</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下内容来自于 &lt;a href=&quot;https://markdown.com.cn/cheat-sheet.html&quot;&gt;Markdown 语法速查表&lt;/a&gt; 。&lt;/p&gt;
&lt;h1&gt;总览&lt;/h1&gt;
&lt;p&gt;Markdown 速查表提供了所有 Markdown 语法元素的基本解释。如果你想了解某些语法元素的更多信息，请参阅更详细的 &lt;a href=&quot;https://markdown.com.cn/basic-syntax/&quot;&gt;基本语法&lt;/a&gt; 和 &lt;a href=&quot;https://markdown.com.cn/extended-syntax/&quot;&gt;扩展语法&lt;/a&gt; 。&lt;/p&gt;
&lt;h1&gt;基本语法&lt;/h1&gt;
&lt;p&gt;这些是 John Gruber 的原始设计文档中列出的元素。所有 Markdown 应用程序都支持这些元素。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;元素&lt;/th&gt;
&lt;th&gt;Markdown 语法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;标题（Heading）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;# H1&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;## H2&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;### H3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;粗体（Bold）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;**bold text**&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;斜体（Italic）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*italicized text*&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;引用块（Blockquote）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;gt; blockquote&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;有序列表（Ordered List）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1. First item&lt;/code&gt; &amp;lt;br&amp;gt;  &lt;code&gt;2. Second item&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;3. Third item&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无序列表（Unordered List）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;- First item&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;- Second item&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;- Third item&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码（Code）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;`code`&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分隔线（Horizontal Rule）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;---&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;链接（Link）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[title](https://www.example.com)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图片（Image）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![alt text](image.jpg)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;扩展语法&lt;/h1&gt;
&lt;p&gt;这些元素通过添加额外的功能扩展了基本语法。但是，并非所有 Markdown 应用程序都支持这些元素。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;元素&lt;/th&gt;
&lt;th&gt;Markdown 语法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;表格（Table）&lt;/td&gt;
&lt;td&gt;&amp;lt;code&amp;gt;  | Syntax       | Description   | &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; | ------------ | ------------- | &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; | Header       | Title         | &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; | Paragraph     | Text         | &amp;lt;/code&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码块（Fenced Code Block）&lt;/td&gt;
&lt;td&gt;&amp;lt;code&amp;gt; ``` &amp;lt;br&amp;gt; { &amp;lt;br&amp;gt; &quot;firstName&quot;: &quot;John&quot;, &amp;lt;br&amp;gt; &quot;lastName&quot;: &quot;Smith&quot;, &amp;lt;br&amp;gt; &quot;age&quot;: 25 &amp;lt;br&amp;gt; } &amp;lt;br&amp;gt; ```&amp;lt;/code&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;脚注（Footnote）&lt;/td&gt;
&lt;td&gt;Here&apos;s a sentence with a footnote. &lt;code&gt;[^1]&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;[^1]&lt;/code&gt;: This is the footnote.`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;标题编号（Heading ID）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;### My Great Heading {#custom-id}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;定义列表（Definition List）&lt;/td&gt;
&lt;td&gt;&amp;lt;code&amp;gt; term &amp;lt;br&amp;gt; : definition &amp;lt;/code&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;删除线（Strikethrough）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~~The world is flat.~~&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;任务列表（Task List）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;- [x] Write the press release&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;- [ ] Update the website&lt;/code&gt; &amp;lt;br&amp;gt; &lt;code&gt;- [ ] Contact the media&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;额外&lt;/h1&gt;
&lt;p&gt;在表格内换行，可使用 &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; 标签。&lt;/p&gt;
&lt;p&gt;在表格内显示字符需要转义，例如插入数线 &lt;code&gt;|&lt;/code&gt; 需要写为 &lt;code&gt;&amp;amp;#124;&lt;/code&gt; ，插入反引号 &lt;code&gt;`&lt;/code&gt; 需要写为 &lt;code&gt;\`&lt;/code&gt; 的形式。&lt;/p&gt;
&lt;p&gt;更多转移字符的写法可以查看我的这一篇 &lt;a href=&quot;https://blog.wely.fun/posts/html-%E5%B8%B8%E7%94%A8%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E5%AF%B9%E7%85%A7%E8%A1%A8/&quot;&gt;博客&lt;/a&gt; 内容。&lt;/p&gt;
</content:encoded></item><item><title>在网页中嵌入随机名言</title><link>https://blog.wely.fun/posts/%E5%9C%A8%E7%BD%91%E9%A1%B5%E4%B8%AD%E5%B5%8C%E5%85%A5%E9%9A%8F%E6%9C%BA%E5%90%8D%E8%A8%80/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E5%9C%A8%E7%BD%91%E9%A1%B5%E4%B8%AD%E5%B5%8C%E5%85%A5%E9%9A%8F%E6%9C%BA%E5%90%8D%E8%A8%80/</guid><description>使用一言 API ,在 html 网页中嵌入随机展示的名言</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;什么是一言？&lt;/h1&gt;
&lt;p&gt;以下是 &lt;a href=&quot;https://developer.hitokoto.cn/sentence/&quot;&gt;一言开发者文档&lt;/a&gt; 中的介绍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;动漫也好、小说也好、网络也好，不论在哪里，我们总会看到有那么一两个句子能穿透你的心。我们把这些句子汇聚起来，形成一言网络，以传递更多的感动。如果可以，我们希望我们没有停止服务的那一天。&lt;/p&gt;
&lt;p&gt;简单来说，一言指的就是一句话，可以是动漫中的台词，也可以是网络上的各种小段子。 或是感动，或是开心，有或是单纯的回忆。来到这里，留下你所喜欢的那一句句话，与大家分享，这就是一言存在的目的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;打开 &lt;a href=&quot;https://hitokoto.cn/&quot;&gt;一言&lt;/a&gt; 的官网，映入眼帘的便是每次都会刷新的一句话，也可以通过它提供的接口，将这句话嵌入到我们自己的网页中。&lt;/p&gt;
&lt;h1&gt;接口的调用&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.hitokoto.cn/sentence/demo.html#%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B-%E4%BB%A5-fetch-api-%E4%B8%BA%E4%BE%8B&quot;&gt;官方文档&lt;/a&gt; 给出了这样的调用方法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p id=&quot;hitokoto&quot;&amp;gt;
  &amp;lt;a href=&quot;#&quot; id=&quot;hitokoto_text&quot;&amp;gt;:D 获取中...&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;script&amp;gt;
  fetch(&apos;https://v1.hitokoto.cn&apos;)
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; {
      const hitokoto = document.querySelector(&apos;#hitokoto_text&apos;)
      hitokoto.href = `https://hitokoto.cn/?uuid=${data.uuid}`
      hitokoto.innerText = data.hitokoto
    })
    .catch(console.error)
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样的调用方式采用了 &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; 标签，链接指向了一言源网页。但这种调用方式会在文字下方生成下划线。下面给出一种采用段落 &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; 标签的示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p id=&quot;hitokoto_text&quot;&amp;gt;:D 获取中...&amp;lt;/p&amp;gt;
&amp;lt;p id=&quot;hitokoto_from&quot;&amp;gt;from&amp;lt;/p&amp;gt;
&amp;lt;script&amp;gt;
    fetch(&apos;https://v1.hitokoto.cn&apos;)
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; {
        hitokoto_text.innerText = data.hitokoto
        hitokoto_from.innerText = data.from
    })
    .catch(console.error)
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此代码中， &lt;code&gt;.hitokoto&lt;/code&gt; 即为获取到的一句话内容， &lt;code&gt;.from&lt;/code&gt; 即为来源。对于其中的参数、返回的内容都可以参考 &lt;a href=&quot;https://developer.hitokoto.cn/sentence/&quot;&gt;官方文档&lt;/a&gt; 进行设定。请注意，请在合适的地方添加对于 &lt;a href=&quot;https://hitokoto.cn/&quot;&gt;一言&lt;/a&gt; 的引用。&lt;/p&gt;
</content:encoded></item><item><title>Markdown Extended Features</title><link>https://blog.wely.fun/posts/markdown-extended/</link><guid isPermaLink="true">https://blog.wely.fun/posts/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;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;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;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>给 Cloudflare Pages 添加标头文件</title><link>https://blog.wely.fun/posts/%E7%BB%99-cloudflare-pages-%E6%B7%BB%E5%8A%A0%E6%A0%87%E5%A4%B4%E6%96%87%E4%BB%B6/</link><guid isPermaLink="true">https://blog.wely.fun/posts/%E7%BB%99-cloudflare-pages-%E6%B7%BB%E5%8A%A0%E6%A0%87%E5%A4%B4%E6%96%87%E4%BB%B6/</guid><description>各种情况下给 Cloudflare Pages 添加 _headers 标头文件的方法</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;为什么需要 _headers 标头文件&lt;/h1&gt;
&lt;p&gt;必应、谷歌等搜索引擎会使用爬虫定期抓取互联网上的网站。通常情况下，我们会给部署在 Cloudflare Pages 上的项目配置一个自定义域，例如使用 &lt;code&gt;www.example.com&lt;/code&gt; 指向默认的 &lt;code&gt;example.pages.dev&lt;/code&gt; 。在搜索引擎的爬虫看来，如果这两个网站下没有配置拒绝索引的 &lt;code&gt;robots.txt&lt;/code&gt;  或标头，那么搜索引擎会毫不犹豫的索引这两个相同内容的网站。为了使搜索引擎只收录我们希望的 &lt;code&gt;www.example.com&lt;/code&gt; ，排除默认的 &lt;code&gt;example.pages.dev&lt;/code&gt; ，我们需要给项目添加 &lt;code&gt;_headers&lt;/code&gt; 标头文件。&lt;/p&gt;
&lt;p&gt;在 &lt;a href=&quot;https://developers.cloudflare.com/pages/configuration/headers/&quot;&gt;Cloudflare 官方文档&lt;/a&gt; 中已经对 _headers 文件的使用给出了详细的说明。&lt;/p&gt;
&lt;h1&gt;如何添加&lt;/h1&gt;
&lt;p&gt;如果是直接上传文件的项目，通常只需要在根目录下新建一个 &lt;code&gt;_headers&lt;/code&gt; 纯文本文档（没有扩展名），并输入以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://:project.pages.dev/*
  X-Robots-Tag: noindex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存，上传，部署，配置网站就像呼吸一样自然。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但是&lt;/strong&gt;，居然报错了，返回了&lt;strong&gt;403错误&lt;/strong&gt;，大意是服务器拒绝了 API 调用的请求，这就很离谱了。我明明是在官网上部署的服务，为什么还会报错？这么离谱的 bug 早该修修了。&lt;/p&gt;
&lt;p&gt;所以，只能通过链接 GitHub 的方式来部署项目，在项目根目录添加 &lt;code&gt;_headers&lt;/code&gt; 文件，上传，这才部署成功，并且成功识别到了添加的标头。&lt;/p&gt;
&lt;h2&gt;Hexo 添加标头文件&lt;/h2&gt;
&lt;p&gt;在 Hexo 中，直接将 &lt;code&gt;_headers&lt;/code&gt; 文件加入 &lt;code&gt;source/&lt;/code&gt; 即可，并且在 &lt;code&gt;_config.yml&lt;/code&gt; 中配置跳过渲染 &lt;code&gt;_headers&lt;/code&gt; 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;skip_render:
  - _headers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hexo 在构建时默认会忽略以下划线 &lt;code&gt;_&lt;/code&gt; 开头的文件，所以还需要在 &lt;code&gt;_config.yml&lt;/code&gt; 中配置包含 &lt;code&gt;_headers&lt;/code&gt; 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;include:
  - _headers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再次运行构建，即可看到在输出网站根目录下出现了 &lt;code&gt;_headers&lt;/code&gt; 文件。&lt;/p&gt;
&lt;h2&gt;Fuwari 主题博客&lt;/h2&gt;
&lt;p&gt;对于本博客使用的基于 Astro 构建的 Fuwari 主题，只需要将 &lt;code&gt;_headers&lt;/code&gt; 文件加入 &lt;code&gt;public/&lt;/code&gt; 即可，运行构建时会自动将 &lt;code&gt;public&lt;/code&gt; 文件夹中的内容原封不动的拷贝到输出网站的根目录中，并且不会忽略以下划线 &lt;code&gt;_&lt;/code&gt; 开头的文件。&lt;/p&gt;
</content:encoded></item><item><title>Expressive Code Example</title><link>https://blog.wely.fun/posts/expressive-code/</link><guid isPermaLink="true">https://blog.wely.fun/posts/expressive-code/</guid><description>How code blocks look in Markdown using Expressive Code.</description><pubDate>Wed, 10 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here, we&apos;ll explore how code blocks look using &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;. The provided examples are based on the official documentation, which you can refer to for further details.&lt;/p&gt;
&lt;h2&gt;Expressive Code&lt;/h2&gt;
&lt;h3&gt;Syntax Highlighting&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;Syntax Highlighting&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Regular syntax highlighting&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;This code is syntax highlighted!&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Rendering ANSI escape sequences&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ANSI colors:
- Regular: [31mRed[0m [32mGreen[0m [33mYellow[0m [34mBlue[0m [35mMagenta[0m [36mCyan[0m
- Bold:    [1;31mRed[0m [1;32mGreen[0m [1;33mYellow[0m [1;34mBlue[0m [1;35mMagenta[0m [1;36mCyan[0m
- Dimmed:  [2;31mRed[0m [2;32mGreen[0m [2;33mYellow[0m [2;34mBlue[0m [2;35mMagenta[0m [2;36mCyan[0m

256 colors (showing colors 160-177):
[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m
[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m
[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m

Full RGB colors:
[38;2;34;139;34mForestGreen - RGB(34, 139, 34)[0m

Text formatting: [1mBold[0m [2mDimmed[0m [3mItalic[0m [4mUnderline[0m
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Editor &amp;amp; Terminal Frames&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/frames/&quot;&gt;Editor &amp;amp; Terminal Frames&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Code editor frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Title attribute example&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;File name comment example&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Terminal frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;This terminal frame has no title&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Write-Output &quot;This one has a title!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Overriding frame types&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Look ma, no frame!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;# Without overriding, this would be a terminal frame
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Text &amp;amp; Line Markers&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/text-markers/&quot;&gt;Text &amp;amp; Line Markers&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Marking full lines &amp;amp; line ranges&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Line 1 - targeted by line number
// Line 2
// Line 3
// Line 4 - targeted by line number
// Line 5
// Line 6
// Line 7 - targeted by range &quot;7-8&quot;
// Line 8 - targeted by range &quot;7-8&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting line marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;this line is marked as deleted&apos;)
  // This line and the next one are marked as inserted
  console.log(&apos;this is the second inserted line&apos;)

  return &apos;this line uses the neutral default marker type&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding labels to line markers&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding long labels on their own lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Using diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;+this line will be marked as inserted
-this line will be marked as deleted
this is a regular line
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+this is an actual diff file
-all contents will remain unmodified
 no whitespace will be removed either
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Combining syntax highlighting with diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;  function thisIsJavaScript() {
    // This entire block gets highlighted as JavaScript,
    // and we can still add diff markers to it!
-   console.log(&apos;Old code to be removed&apos;)
+   console.log(&apos;New and shiny code!&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Marking individual text inside lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // Mark any given text inside lines
  return &apos;Multiple matches of the given text are supported&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Regular expressions&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;The words yes and yep will be marked.&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Escaping forward slashes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Test&quot; &amp;gt; /home/test.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting inline marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;These are inserted and deleted marker types&apos;);
  // The return statement uses the default marker type
  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Word Wrap&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/word-wrap/&quot;&gt;Word Wrap&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Configuring word wrap per block&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Configuring indentation of wrapped lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent (enabled by default)
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Collapsible Sections&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/collapsible-sections/&quot;&gt;Collapsible Sections&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// All this boilerplate setup code will be collapsed
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// This part of the code will be visible by default
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // You can have multiple collapsed sections
  const a = 1
  const b = 2
  const c = a + b

  // This will remain visible
  console.log(`Calculation result: ${a} + ${b} = ${c}`)
  return c
}

// All this code until the end of the block will be collapsed again
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;End of example boilerplate code&apos; })
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Line Numbers&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/line-numbers/&quot;&gt;Line Numbers&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Displaying line numbers per block&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// This code block will show line numbers
console.log(&apos;Greetings from line 2!&apos;)
console.log(&apos;I am on line 3&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Line numbers are disabled for this block
console.log(&apos;Hello?&apos;)
console.log(&apos;Sorry, do you know what line I am on?&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Changing the starting line number&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Greetings from line 5!&apos;)
console.log(&apos;I am on line 6&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Simple Guides for Fuwari</title><link>https://blog.wely.fun/posts/guide/</link><guid isPermaLink="true">https://blog.wely.fun/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.wely.fun/posts/markdown/</link><guid isPermaLink="true">https://blog.wely.fun/posts/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;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.wely.fun/posts/video/</link><guid isPermaLink="true">https://blog.wely.fun/posts/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>