<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Technology | Felix's Blog</title>
	<atom:link href="https://felixc.at/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>https://felixc.at</link>
	<description>@felixonmars</description>
	<lastBuildDate>Tue, 08 Nov 2022 20:19:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>[Arch] systemd 时代的 NBD 客户端持久化配置方法</title>
		<link>https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/</link>
					<comments>https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Tue, 08 Nov 2022 20:19:02 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[systemd]]></category>
		<guid isPermaLink="false">https://felixc.at/?p=1911</guid>

					<description><![CDATA[<p>NBD 用于提供块设备给远程设备使用是一种非常简便、低成本的方法。然而，让 NBD 开始工作的方法在网上能找到很多，但是 NBD 客户端的配置持久化却很难搜到比较完整的资料。在参考了一些过时博客、manpage 等比较分散的资料之后，我总算是凭借蛛丝马迹找到了应当是正确的配置方法。 1、自动加载 nbd 内核模块 echo nbd > /etc/modules-load.d/nbd.conf （虽然——我觉得这件事应该在 nbd 包里完成，因为上游不愿意默认提供的理由只是为了考虑 nbd 未被编译为内核模块的情况。） 2、/etc/nbdtab 没错，光是发现这个东西就花了我不少时间。 nbd 服务器、连接选项等本来在 nbd-client 命令中配置的内容，应当被写到这个文件里。 一个简单的例子： nbd0 192.168.0.10 export0 persist 显而易见，分别对应设备名、服务器地址、服务器上配置的 export 名、其他选项。完整的介绍可以参考对应的 manpage。 3、/etc/fstab 和 nbd@&#60;设备名>.service 到这里就是最后一步了，也是非常容易出错的一步。 此处的设备名应当和 nbdtab 内配置的设备名相符，nbdtab 的配置由这个对应的服务应用。和其他网络设备一样，挂载点、挂载相关的配置应当设置在 /etc/fstab。 这里需要使用 x-systemd.requires 来声明对 systemd 服务的依赖关系。由于服务会被这个依赖关系自动唤起，不需要手动 enable 服务。 /dev/nbd0 /var/lib/archbuild btrfs defaults,x-systemd.requires=nbd@nbd0.service,_netdev,nofail 0 &#8230; <a href="https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/" class="more-link">Continue reading <span class="screen-reader-text">[Arch] systemd 时代的 NBD 客户端持久化配置方法</span></a></p>
The post <a href="https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/">[Arch] systemd 时代的 NBD 客户端持久化配置方法</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>NBD 用于提供块设备给远程设备使用是一种非常简便、低成本的方法。然而，让 NBD 开始工作的方法在网上能找到很多，但是 NBD 客户端的配置持久化却很难搜到比较完整的资料。在参考了一些过时博客、manpage 等比较分散的资料之后，我总算是凭借蛛丝马迹找到了应当是正确的配置方法。</p>



<h2 class="wp-block-heading">1、自动加载 nbd 内核模块</h2>



<pre class="wp-block-code"><code lang="bash" class="language-bash">echo nbd > /etc/modules-load.d/nbd.conf</code></pre>



<p>（虽然——我觉得这件事应该在 nbd 包里完成，因为<a href="https://github.com/NetworkBlockDevice/nbd/issues/56#issuecomment-331634532" title="上游不愿意默认提供的理由只是为了考虑 nbd 未被编译为内核模块的情况">上游不愿意默认提供的理由只是为了考虑 nbd 未被编译为内核模块的情况</a>。）</p>



<h2 class="wp-block-heading">2、/etc/nbdtab</h2>



<p><s>没错，光是发现这个东西就花了我不少时间。</s></p>



<p>nbd 服务器、连接选项等本来在 nbd-client 命令中配置的内容，应当被写到这个文件里。</p>



<p>一个简单的例子：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">nbd0 192.168.0.10 export0 persist</code></pre>



<p>显而易见，分别对应设备名、服务器地址、服务器上配置的 export 名、其他选项。完整的介绍可以参考<a href="https://man.archlinux.org/man/nbdtab.5" title="对应的 manpage">对应的 manpage</a>。</p>







<h2 class="wp-block-heading">3、/etc/fstab 和 nbd@&lt;设备名>.service</h2>



<p>到这里就是最后一步了，也是非常容易出错的一步。</p>



<p>此处的设备名应当和 nbdtab 内配置的设备名相符，nbdtab 的配置由这个对应的服务应用。和其他网络设备一样，挂载点、挂载相关的配置应当设置在 /etc/fstab。</p>



<p>这里需要使用 x-systemd.requires 来声明对 systemd 服务的依赖关系。由于服务会被这个依赖关系自动唤起，不需要手动 enable 服务。</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">/dev/nbd0 /var/lib/archbuild btrfs defaults,x-systemd.requires=nbd@nbd0.service,_netdev,nofail 0 0</code></pre>



<p>这里的 _netdev 会让 systemd 等待网络可用后再进行挂载。注意我在这里写了 nofail 以避免因为网络原因使设备无法启动。如果要考虑在访问时再挂载，也可以改用 noauto,x-systemd.automount 之类的方法。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>参考资料：</p>



<ul class="wp-block-list">
<li><a href="https://mattgadient.com/how-to-using-systemd-to-mount-nbd-devices-on-boot-ubuntu/">https://mattgadient.com/how-to-using-systemd-to-mount-nbd-devices-on-boot-ubuntu/</a></li>



<li><a href="https://manpages.ubuntu.com/manpages/impish/man1/nbdkit-client.1.html">https://manpages.ubuntu.com/manpages/impish/man1/nbdkit-client.1.html</a></li>
</ul>



<p></p>The post <a href="https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/">[Arch] systemd 时代的 NBD 客户端持久化配置方法</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2022/11/arch-systemd-era-nbd-client-persistent-config/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>[Arch] OpenSSL 3 更新杂记</title>
		<link>https://felixc.at/2022/11/notes-about-arch-openssl-3-update/</link>
					<comments>https://felixc.at/2022/11/notes-about-arch-openssl-3-update/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Mon, 07 Nov 2022 14:10:36 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://felixc.at/?p=1904</guid>

					<description><![CDATA[<p>最近 Arch Linux 终于把 OpenSSL 更新到了 3.x 系列版本。一直以来，在处理涉及打包工具链本身的 soname bump 等更新问题时，我们一直缺乏一个透明、优雅的流程。 以往采用过的方法包括但不限于：临时往编译环境里手动塞旧版本兼容包、手动在过渡版本的新版 PKGBUILD 里再编译一份旧版包然后把 lib 装进去等。由于处理这件事的开发者一般独自完成了整个过程，留下来的资料除了 IRC 里的寥寥几语往往十分有限，对于其他开发者、或是下游发行版试图重现这个过程来说，都是一个比较痛苦的过程。 这一次趁着 OpenSSL 3 的机会，本喵深度参与了整个 bootstrap rebuild 过程，并且在 RISC-V port 里复现了一遍。现在记录一下大致的过程和遇到的问题，以备不时之需。 1、首先把旧版库打包，使其可以与新版库同时安装。 openssl-1.1：https://github.com/archlinux/svntogit-packages/commit/d50ecccc79b637830b71795bd919e6467e118ef0 由于需要避免文件冲突，相应的编译选项（&#8211;libdir）和 package() 过程中做了一些兼容性处理。如果这个包还需要在 rebuild 之后留下来，比如这次的 openssl-1.1 的情况，头文件和 pkgconfig 的 .pc 文件也需要做处理。如果只是作为兼容包，可以仅保留带 soname 和具体版本的库文件本身。（当然，这种情况下也可以考虑在新版包里直接编译一份旧版库安装进去，毕竟只是临时使用。） 2、让新版库临时依赖旧版库的包 https://github.com/archlinux/svntogit-packages/commit/eef05b437f55c4d9403668ebdc27973c6a6c2134#diff-37538beb61ff63edebbf735dfcf39e5d732f49183d6beb097169d971875ca422R56 这里用到的技巧是，在 package() 方法内追加 depends，以避免编译环境中提前引入这个依赖，产生文件冲突（此时的仓库中，原包名对应的包仍然是旧版本，和 openssl-1.1 兼容包存在文件冲突）。 3、用此时的环境 rebuild 整个工具链需要用到的基础包 这一步具体要处理哪些包需要仔细分析。以这次 &#8230; <a href="https://felixc.at/2022/11/notes-about-arch-openssl-3-update/" class="more-link">Continue reading <span class="screen-reader-text">[Arch] OpenSSL 3 更新杂记</span></a></p>
The post <a href="https://felixc.at/2022/11/notes-about-arch-openssl-3-update/">[Arch] OpenSSL 3 更新杂记</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>最近 Arch Linux 终于把 OpenSSL 更新到了 3.x 系列版本。一直以来，在处理涉及打包工具链本身的 soname bump 等更新问题时，我们一直缺乏一个透明、优雅的流程。</p>



<p>以往采用过的方法包括但不限于：临时往编译环境里手动塞旧版本兼容包、手动在过渡版本的新版 PKGBUILD 里再编译一份旧版包然后把 lib 装进去等。由于处理这件事的开发者一般独自完成了整个过程，留下来的资料除了 IRC 里的寥寥几语往往十分有限，对于其他开发者、或是下游发行版试图重现这个过程来说，都是一个比较痛苦的过程。</p>



<p>这一次趁着 OpenSSL 3 的机会，本喵深度参与了整个 bootstrap rebuild 过程，并且在 RISC-V port 里复现了一遍。现在记录一下大致的过程和遇到的问题，以备不时之需。</p>



<p>1、首先把旧版库打包，使其可以与新版库同时安装。</p>



<p>openssl-1.1：<a href="https://github.com/archlinux/svntogit-packages/commit/d50ecccc79b637830b71795bd919e6467e118ef0">https://github.com/archlinux/svntogit-packages/commit/d50ecccc79b637830b71795bd919e6467e118ef0</a></p>



<p>由于需要避免文件冲突，相应的编译选项（&#8211;libdir）和 package() 过程中做了一些兼容性处理。如果这个包还需要在 rebuild 之后留下来，比如这次的 openssl-1.1 的情况，头文件和 pkgconfig 的 .pc 文件也需要做处理。如果只是作为兼容包，可以仅保留带 soname 和具体版本的库文件本身。（<s>当然，这种情况下也可以考虑在新版包里直接编译一份旧版库安装进去，毕竟只是临时使用。</s>）</p>







<p>2、让新版库临时依赖旧版库的包</p>



<p><a href="https://github.com/archlinux/svntogit-packages/commit/eef05b437f55c4d9403668ebdc27973c6a6c2134#diff-37538beb61ff63edebbf735dfcf39e5d732f49183d6beb097169d971875ca422R56">https://github.com/archlinux/svntogit-packages/commit/eef05b437f55c4d9403668ebdc27973c6a6c2134#diff-37538beb61ff63edebbf735dfcf39e5d732f49183d6beb097169d971875ca422R56</a></p>



<p>这里用到的技巧是，在 package() 方法内追加 depends，以避免编译环境中提前引入这个依赖，产生文件冲突（此时的仓库中，原包名对应的包仍然是旧版本，和 openssl-1.1 兼容包存在文件冲突）。</p>



<p>3、用此时的环境 rebuild 整个工具链需要用到的基础包</p>



<p>这一步具体要处理哪些包需要仔细分析。以这次 openssl rebuild 为例，一共有这么多包需要先使用这个依赖了旧版库的新版包来 bootstrap 以避免破坏打包环境本身：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">coreutils
cryptsetup
curl
kmod
krb5
libarchive
libevent
libfido2 (for systemd's tests)
libssh2
openldap
pacman
sudo
systemd
tpm2-tss (for systemd's tests)</code></pre>



<p>4、rebuild 新版库，去掉对旧版库的依赖</p>



<p>在完成这个步骤之后，需要重建 build chroot 以去掉之前引入的旧版库（这确实是 Arch 工具链的一个毛病，当前的机制不能自动保证 chroot 是干净、完整的）。</p>



<p>5、将前面步骤里 rebuild 过的基础包再次 rebuild</p>



<p>这一步主要是为了保证环境干净。编译得到的包应该和之前没有差异。</p>



<p>至此，已经可以继续平常的 rebuild 过程处理剩下的包了。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>OpenSSL 更新进入稳定仓库后，在群组里果然遇到了大胆部分更新的用户不幸炸掉自己的 pacman。甚至有使用 pacman-static 的用户也因为 sudo 链接到 openssl 而悲剧了。再次奉劝大家切忌对官方仓库内的软件包部分更新，尤其是这种一看就不好惹的系统核心库！</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>另外，本喵自己的老 OpenVPN 配置在更新后也被制裁了：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">SSL_CTX_use_certificate:ca md too weak</code></pre>



<p>于是只好加入了 <code>tls-cipher "DEFAULT:@SECLEVEL=0"</code> <s>从此远离了推荐的配置</s>。</p>The post <a href="https://felixc.at/2022/11/notes-about-arch-openssl-3-update/">[Arch] OpenSSL 3 更新杂记</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2022/11/notes-about-arch-openssl-3-update/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>用 pacman-accel 给 pacman 加速</title>
		<link>https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/</link>
					<comments>https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Sun, 06 Nov 2022 00:43:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://felixc.at/?p=1825</guid>

					<description><![CDATA[<p>我在选镜像站的时候，总会遇到一个矛盾：镜像站访问快、镜像站和上游同步延迟低（同步到了最新的包）两者不可兼得。 比较容易想到的解决思路是：只从同步延迟低的镜像下 db，然后从速度快的镜像开始依次试，跳过 404 的镜像，直到找到一个已经存在该文件的镜像。 在过往的十来年里，我一直是通过写一个脚本来分别给 pacman -Sy 和 pacman -Su 设置不同的镜像来勉强解决的。但是这个用法在 pacman 最新系列中被破坏了——pacman 加入了一个镜像站如果 404 次数过多，在同一次更新中就再也不尝试了的新行为。 想到以往的用法会在命令中夹杂许多 404 报错，需要专门的脚本来换镜像体验也并不是很好，我写了个非常简单的本地服务来实现这个需求： #!/usr/bin/ruby # # A simple local redirector for pacman, to get you the latest packages and # utilize available mirrors. # # Usage: # - Set multiple mirrors in /etc/pacman.d/mirrorlist-accel with ordering: # https://fastest-mirror-but-updates-once-a-day/archlinux/ # &#8230; <a href="https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/" class="more-link">Continue reading <span class="screen-reader-text">用 pacman-accel 给 pacman 加速</span></a></p>
The post <a href="https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/">用 pacman-accel 给 pacman 加速</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>我在选镜像站的时候，总会遇到一个矛盾：镜像站访问快、镜像站和上游同步延迟低（同步到了最新的包）两者不可兼得。</p>



<p>比较容易想到的解决思路是：只从同步延迟低的镜像下 db，然后从速度快的镜像开始依次试，跳过 404 的镜像，直到找到一个已经存在该文件的镜像。</p>



<p>在过往的十来年里，我一直是通过写一个脚本来分别给 pacman -Sy 和 pacman -Su 设置不同的镜像来勉强解决的。但是这个用法在 pacman 最新系列中被破坏了——pacman 加入了一个镜像站如果 404 次数过多，在同一次更新中就再也不尝试了的新行为。</p>



<p>想到以往的用法会在命令中夹杂许多 404 报错，需要专门的脚本来换镜像体验也并不是很好，我写了个非常简单的本地服务来实现这个需求：</p>



<pre class="wp-block-code"><code lang="ruby" class="language-ruby">#!/usr/bin/ruby
#
# A simple local redirector for pacman, to get you the latest packages and
# utilize available mirrors.
#
# Usage:
# - Set multiple mirrors in /etc/pacman.d/mirrorlist-accel with ordering:
# https://fastest-mirror-but-updates-once-a-day/archlinux/
# https://relatively-slower-mirror-that-updates-more-frequently/archlinux/
# ...
# https://pkgbuild-dot-com-or-another-mirror-that-gives-you-the-latest-packages/
#
# - Set /etc/pacman.d/mirrorlist to this redirector:
# Server = http://127.0.0.1:4567/$repo/os/$arch

require 'http'
require 'sinatra'

mirrors = File.readlines("/etc/pacman.d/mirrorlist-accel").filter_map { |line| line.strip if line &amp;&amp; line[0] != "#" }

get '/*' do |path|
    # Set TIER 0/1 mirrors as the last one, for:
    #  - DB syncing
    #  - Download fallback
    # These two use cases always the same server for consistency.
    mirror = mirrors[-1]

    unless path.end_with? '.db'
        # Find a faster mirror with the requested file present
        mirrors[..-2].each { |m|
            response = HTTP.head(m + path)
            if response.status == 200
                mirror = m
                break
            else
                logger.info "skipping #{m} for #{path}, code: #{response.status}"
            end
        }
    end

    logger.info "redirecting to #{mirror + path}"
    redirect mirror + path, 302
end

set :bind, ENV.fetch("PACMAN_ACCEL_BIND", "127.0.0.1")
set :port, ENV.fetch("PACMAN_ACCEL_PORT", "4567")</code></pre>



<p>如注释所说，在 /etc/pacman.d/mirrorlist-accel 里按照本地访问速度依次设置几个快的镜像，并把最后一个镜像设置为和上游同步频繁的镜像即可。</p>







<p>贴上我目前使用的配置供参考：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">$ cat /etc/pacman.d/mirrorlist-accel
https://mirrors.bfsu.edu.cn/archlinux/
https://mirrors.wsyu.edu.cn/archlinux/
https://geo.mirror.pkgbuild.com/

$ cat /etc/pacman.d/mirrorlist
Server = http://127.0.0.1:4567/$repo/os/$arch</code></pre>



<p>原理很简单：pacman 访问本地 HTTP 服务，这个服务对非 .db 的下载请求按照配置依次 HTTP HEAD 直到找到一个返回值为 200 的镜像，然后返回 302 让 pacman 从这个镜像下载。</p>



<p>由于 .db 文件全部由最后一个镜像提供，而前面配置的镜像不存在对应文件时最终也会 fallback 到最后一个镜像，这样使用应该不会产生新的 db 不一致问题。</p>



<p>这个简单的工具日后会在我的<a href="https://github.com/felixonmars/archlinux-futils/blob/master/pacman-accel" title="小工具集 GitHub 仓库继续维护">小工具集 GitHub 仓库继续维护</a>，同时我也创建了一个简单的 AUR 包：<a href="https://aur.archlinux.org/packages/pacman-accel-git">https://aur.archlinux.org/packages/pacman-accel-git</a></p>The post <a href="https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/">用 pacman-accel 给 pacman 加速</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2022/11/use-pacman-accel-to-accelerate-pacman/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>萌新的 PolarFire SoC Icicle Kit 初体验</title>
		<link>https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/</link>
					<comments>https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Fri, 03 Jun 2022 19:26:07 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[RISC-V]]></category>
		<guid isPermaLink="false">https://felixc.at/?p=1729</guid>

					<description><![CDATA[<p>这两天翻出来了去年代收的 PolarFire SoC Icicle Kit。因为隔壁的 FPGA 大佬们看不上这块板子，我打算尝试物尽其用一下，目标只是用板子上的 RISC-V 核启动 Arch Linux RISC-V 的 rootfs 测试（把它当作一块 SD 卡槽没有问题、并且带 PCIE 的 HiFive Unleashed 来用。隔壁嵌入式群的大佬们：买椟还珠！）。如此便开始了年轻人的 FPGA 初体验（可能还是不能算）。 噩梦的开始 一开始尝试的当然是最新版的 Yocto 镜像，毕竟这是“官方”的 Linux 镜像。结果刷完后立刻遇到了启动失败： 一开始我还以为是 SD 卡坏了。在多次尝试未果后…… 当时的猜测是（不一定对），可能因为板子上 FPGA 部分（抱歉，我不知道专业的称呼）不够新，所以我打算刷一下 HSS。结果这成为了噩梦的开始。 可怕的“硬件”工具链 我最初参考的文档来自 U-boot：https://u-boot.readthedocs.io/en/latest/board/microchip/mpfs_icicle.html 这份文档可能已经颇为过时，里面编译 HSS 的部分从一开始就找不到名叫“icicle-kit-es”的 BOARD. 在我加上 mpfs- 前缀，并根据后续报错依次按照我的 CROSS 工具链目标修改了 PLATFORM_RISCV_ABI=lp64d PLATFORM_RISCV_ISA=rv64gc 之后，我遇到了第一个大魔王：SoftConsole。 好在这个工具可以无需注册直接下载。 顺利安装完成后，按照要求设置 SC_INSTALL_DIR，我终于看到了……下个错误：缺少 &#8230; <a href="https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/" class="more-link">Continue reading <span class="screen-reader-text">萌新的 PolarFire SoC Icicle Kit 初体验</span></a></p>
The post <a href="https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/">萌新的 PolarFire SoC Icicle Kit 初体验</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>这两天翻出来了去年代收的 PolarFire SoC Icicle Kit。因为隔壁的 FPGA 大佬们看不上这块板子，我打算尝试<s>物尽其用</s>一下，目标只是用板子上的 RISC-V 核启动 Arch Linux RISC-V 的 rootfs 测试（把它当作一块 SD 卡槽没有问题、并且带 PCIE 的 HiFive Unleashed 来用。隔壁嵌入式群的大佬们：买椟还珠！）。如此便开始了年轻人的 FPGA 初体验（可能还是不能算）。</p>



<h2 class="wp-block-heading">噩梦的开始</h2>



<p>一开始尝试的当然是<a href="https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp/releases/tag/v2022.05">最新版的 Yocto 镜像</a>，毕竟这是“官方”的 Linux 镜像。结果刷完后立刻遇到了启动失败：</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="841" src="https://felixc.at/wp-content/uploads/2022/06/2022-05-31-12-13-51-1024x841.png" alt="" class="wp-image-1731" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-05-31-12-13-51-1024x841.png 1024w, https://felixc.at/wp-content/uploads/2022/06/2022-05-31-12-13-51-300x246.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-05-31-12-13-51-768x631.png 768w, https://felixc.at/wp-content/uploads/2022/06/2022-05-31-12-13-51.png 1153w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>一开始我还以为是 SD 卡坏了。在多次尝试未果后……</p>



<p>当时的猜测是（不一定对），可能因为板子上 FPGA 部分（抱歉，我不知道专业的称呼）不够新，所以我打算刷一下 <a href="https://github.com/polarfire-soc/hart-software-services">HSS</a>。结果这成为了噩梦的开始。</p>







<h2 class="wp-block-heading">可怕的“硬件”工具链</h2>



<p>我最初参考的文档来自 U-boot：<a href="https://u-boot.readthedocs.io/en/latest/board/microchip/mpfs_icicle.html">https://u-boot.readthedocs.io/en/latest/board/microchip/mpfs_icicle.html</a></p>



<p>这份文档可能已经颇为过时，里面编译 HSS 的部分从一开始就找不到名叫“icicle-kit-es”的 BOARD.</p>



<p>在我加上 <code>mpfs-</code> 前缀，并根据后续报错依次按照我的 CROSS 工具链目标修改了 <code>PLATFORM_RISCV_ABI=lp64d PLATFORM_RISCV_ISA=rv64gc</code> 之后，我遇到了第一个大魔王：<a href="https://www.microchip.com/en-us/products/fpgas-and-plds/fpga-and-soc-design-tools/programming-and-debug/softconsole">SoftConsole</a>。</p>



<figure class="wp-block-image size-full"><img decoding="async" width="840" height="136" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-33-49.png" alt="" class="wp-image-1735" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-33-49.png 840w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-33-49-300x49.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-33-49-768x124.png 768w" sizes="(max-width: 840px) 100vw, 840px" /></figure>



<p></p>



<p>好在这个工具可以无需注册直接下载。</p>



<figure class="wp-block-image size-full"><img decoding="async" width="562" height="431" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-23-03.png" alt="" class="wp-image-1732" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-23-03.png 562w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-23-03-300x230.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></figure>



<p>顺利安装完成后，按照要求设置 <code>SC_INSTALL_DIR</code>，我终于看到了……下个错误：缺少 fpgenprog。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="82" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-1024x82.png" alt="" class="wp-image-1733" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-1024x82.png 1024w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-300x24.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-768x62.png 768w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-1536x123.png 1536w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-25-28-2048x164.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>由于不想安装完整的 <code>Libero SoC</code>（一个巨大的需要折腾 license 的开发工具集），我试图去下载这里提到的 <code>Program Debug Tool</code>。从<a href="https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/software-development/polarfire-soc-software-tool-flow.md#tools-required-to-program-a-polarfire-soc-fpga">文档</a>上找到下载链接点开后，看到了这样的悲剧：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="293" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-30-26-1024x293.png" alt="" class="wp-image-1734" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-30-26-1024x293.png 1024w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-30-26-300x86.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-30-26-768x220.png 768w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-30-26.png 1448w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>它没了。</p>



<p>后面提到的 <code>Programming and Debug</code> 工具下载也藏在了注册墙后面，我考虑转向其他思路试试，先暂时没有继续了。</p>



<p>（另：关于 <code>Libero SoC</code> 的安装会有多坑，可以参考这位受害者的体验：<a href=" https://www.cnx-software.com/2021/10/25/installing-libero-soc-in-ubuntu-and-windows-10/"> https://www.cnx-software.com/2021/10/25/installing-libero-soc-in-ubuntu-and-windows-10/</a> ）</p>



<h2 class="wp-block-heading">Arch 内核的陨落</h2>



<p>由于目前 Arch Linux RISC-V 基本没有处理 bootloader 部分的工作，我打算先试试直接使用旧版 Yocto 自带的 U-boot 来启动 Arch 的内核、rootfs。由于不熟悉 U-boot 和这些嵌入式镜像格式，我先花了点时间学习 <a href="https://developer.toradex.com/linux-bsp/how-to/boot/distro-boot/">U-boot 的启动逻辑</a> 和操作 uImage 的常用命令等。</p>



<p>Yocto 的镜像里有一个很小的 /boot 分区，里面有 boot.scr.uimg 脚本和 fitImage 镜像。我遇到的第一个问题是，这个 FAT16 的 /boot 分区装不下 Arch 的 kernel，而且把 FAT16 扩容并转换为 FAT32 是 libparted 等常用工具不支持的操作。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="882" height="260" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-44-13.png" alt="" class="wp-image-1737" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-44-13.png 882w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-44-13-300x88.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-21-44-13-768x226.png 768w" sizes="auto, (max-width: 882px) 100vw, 882px" /></figure>



<p>在艰难尝试了许多次之后，我确定了这个分区后面的那个类型为 BIOS boot 但 GParted 抱怨为损坏分区的分区可能存放的是 uboot 本体（或者含它的 HSS？尚未仔细研究）。因此向后扩容 /boot 的想法可能不大靠谱。我只好退而求其次，把第一个分区删掉，直接把最后的 rootfs 所在分区标记为 <code>legacy_boot</code>。</p>



<p>然后我复制了 Unmatched 上的 <code>extlinux.conf</code> 并做了相应修改（内核版本、UUID 等）。第一次尝试启动失败在缺少了两个环境变量：</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="889" height="288" src="https://felixc.at/wp-content/uploads/2022/06/2022-05-31-16-40-49.png" alt="" class="wp-image-1738" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-05-31-16-40-49.png 889w, https://felixc.at/wp-content/uploads/2022/06/2022-05-31-16-40-49-300x97.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-05-31-16-40-49-768x249.png 768w" sizes="auto, (max-width: 889px) 100vw, 889px" /></figure>



<p>后来在大佬们的帮助下，我找到了设置它的办法。其实正确的值就来自上面的 <code>boot.scr.uimg</code>，设置前者为 <code>${ramdisk_addr_r}</code>，后者则只需要设置一个足够大的值。</p>



<p>然而这次 Arch 的内核挂在了无限循环刷屏 L2CACHE ERROR 上。</p>



<p>由于大佬觉得这个问题不好解决，我决定先暂时放弃内核，用 Yocto 的内核启动 Arch rootfs 测试。</p>



<h2 class="wp-block-heading">用魔法打败魔法</h2>



<p>在现在的情况下，直接用原版的 boot.scr.uimg 和 fitImage 组合至少存在这样的问题：</p>



<ul class="wp-block-list">
<li>1、Arch rootfs 期待一个 rw 的 /。默认的 ro 环境会导致启动后一大堆服务失败、SSH Host Key 未生成等奇怪的问题。</li>
</ul>



<ul class="wp-block-list">
<li>2、默认的 <code>root=</code> 设置为了 SD 卡的第三个分区（<code>/dev/mmcblk0p3</code>）。但经过上面的操作，SD 卡上现在已经只剩两个分区了。</li>
</ul>



<p>为了修改 cmdline 解决这些问题，我在 U-boot shell 和 uEnv.txt 里鼓捣了各种操作都没有成功。看起来这个内核是把 cmdline 写死编译进去了。</p>



<p>在不重新编译内核的情况下，怎么更改里面写死的 cmdline 呢？<s>那当然是直接修改二进制了！</s></p>



<p>首先把 fitImage 拆开，用 dumpimage 工具提取出里面的内核和 fdt 文件。从输出中可以看到，内核是 gzip 压缩过的：</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="750" height="258" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-00-34.png" alt="" class="wp-image-1739" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-00-34.png 750w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-00-34-300x103.png 300w" sizes="auto, (max-width: 750px) 100vw, 750px" /></figure>



<p>用 gzip 解压这个文件，然后用 vim 打开：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="89" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36-1024x89.png" alt="" class="wp-image-1740" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36-1024x89.png 1024w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36-300x26.png 300w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36-768x67.png 768w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36-1536x133.png 1536w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-22-01-36.png 1892w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>诶嘿，我们的 cmdline 找到了。直接修改为想要的值（分区号直接替换，然后换掉一个应该影响不那么大的参数写上 rw），并保持字符串总长度不变（填空格补齐）。一共有两处，做同样处理即可。</p>



<p>修改完后，直接把未压缩的内核、fdt 复制到 rootfs 内，然后添加一个 extlinux 启动项：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">label yocto
        menu label Arch Linux with Yocto kernel
        linux /boot/yocto.kernel.patched
        fdt /boot/yocto.dtb</pre></code></pre>



<p>Bingo！成功启动。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="819" height="828" src="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-20-20-02.png" alt="" class="wp-image-1741" srcset="https://felixc.at/wp-content/uploads/2022/06/2022-06-03-20-20-02.png 819w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-20-20-02-297x300.png 297w, https://felixc.at/wp-content/uploads/2022/06/2022-06-03-20-20-02-768x776.png 768w" sizes="auto, (max-width: 819px) 100vw, 819px" /></figure>



<p>至此，最初的目标有了一个最低限度的成果。</p>



<h2 class="wp-block-heading">尾声/题外话</h2>



<p>感谢 PLCT 实验室、TUNA、AOSC 等社区一直以来的帮助，肥猫现在可能从完全不懂嵌入式稍微进步了一点点。</p>



<p>没想到折腾这块难啃的板子会成为我荒废三年多的博客再次更新的契机。我的这一轮 Arch Linux RISC-V 移植项目从最初尝试至今也已经超过三年，而今年年底就是我进入 Arch 十周年了。希望自己下次写博客不要又是三年以后 😛</p>The post <a href="https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/">萌新的 PolarFire SoC Icicle Kit 初体验</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2022/06/newbies-polarfire-soc-icicle-kit-first-experience/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>nspawn.org：简单的 systemd 发行版容器</title>
		<link>https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/</link>
					<comments>https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Thu, 04 Apr 2019 22:03:09 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1640</guid>

					<description><![CDATA[<p>如果你想要运行一个发行版容器，而又不想被 docker 一类的重量级方案打扰，现在有一个新的简单方案了。 nspawn.org 目前提供了 Arch、CentOS、Debian、Fedora、Ubuntu 的各版本镜像，并可以直接用 systemd-nspawn 的验证机制进行签名验证。 推荐的用法是使用其提供的 &#8220;nspawn&#8221; 工具。下面以创建一个 Fedora 30 容器为例： 1、获取工具： $ wget https://raw.githubusercontent.com/nspawn/nspawn/master/nspawn $ chmod +x nspawn 2、获取 Fedora 30 镜像： $ sudo ./nspawn init fedora/30/tar 3、启动容器并获取 shell： $ sudo machinectl start fedora-30-tar $ sudo machinectl shell fedora-30-tar Connected to machine fedora-30-tar. Press ^] three times within 1s to &#8230; <a href="https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/" class="more-link">Continue reading <span class="screen-reader-text">nspawn.org：简单的 systemd 发行版容器</span></a></p>
The post <a href="https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/">nspawn.org：简单的 systemd 发行版容器</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>如果你想要运行一个发行版容器，而又不想被 docker 一类的重量级方案打扰，现在有一个新的简单方案了。</p>



<p><a href="http://nspawn.org">nspawn.org</a> 目前提供了 Arch、CentOS、Debian、Fedora、Ubuntu 的各版本镜像，并可以直接用 systemd-nspawn 的验证机制进行签名验证。</p>



<p>推荐的用法是使用其提供的 &#8220;nspawn&#8221; 工具。下面以创建一个 Fedora 30 容器为例：</p>



<p>1、获取工具：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ wget https://raw.githubusercontent.com/nspawn/nspawn/master/nspawn
$ chmod +x nspawn</pre></code></pre>



<p>2、获取 Fedora 30 镜像：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ sudo ./nspawn init fedora/30/tar</pre></code></pre>



<p>3、启动容器并获取 shell：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ sudo machinectl start fedora-30-tar
$ sudo machinectl shell fedora-30-tar
Connected to machine fedora-30-tar. Press ^] three times within 1s to exit session.
[root@fedora30 ~]#</pre></code></pre>







<p>一些背景：容器默认的存储路径在 /var/lib/machines/。nspawn.org 的创建者是 shibumi，目前是 Arch Linux Trusted User。所有的镜像使用 mkosi 制作，定义文件均<a href="https://github.com/nspawn/mkosi-definitions">在 GitHub 上</a>。除了 nspawn 容器镜像，这个站点还提供可引导的 GPT-UEFI 镜像。<br></p>The post <a href="https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/">nspawn.org：简单的 systemd 发行版容器</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2019/04/nspawn-org-simple-container-for-systemd-distributions/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>用脏办法解决 BLE 鼠标重连后指针不动的问题</title>
		<link>https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/</link>
					<comments>https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Thu, 10 Jan 2019 18:39:43 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1630</guid>

					<description><![CDATA[<p>我的蓝牙鼠标（雷柏 MT750）使用 BLE（Bluetooth Low Energy） 连接笔记本时，时常遇到自动重连后电脑这边认为已连接，而鼠标那边灯自动灭掉，鼠标指针无反应的问题。在网上反复搜索 bluez 相关问题找到了许多类似问题，鼠标类型也集中在罗技、ThinkPad 等 BLE 鼠标上。 偶然间发现每次重连后，如果手动用 bluetoothctl 发一个 “pair” 指令（会超时失败），就能令鼠标正常连接。给 bluez 报了一个 bug 后，我写了下面的简单脚本先绕过问题： #!/usr/bin/python import dbus import dbus.mainloop.glib from gi.repository import GLib adapter = "hci0" device = "xx:xx:xx:xx:xx:xx" device_path = '/org/bluez/' + adapter + "/dev_" + device.replace(":", "_") dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) system_bus = dbus.SystemBus() device_object = system_bus.get_object('org.bluez', device_path) device_interface = &#8230; <a href="https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/" class="more-link">Continue reading <span class="screen-reader-text">用脏办法解决 BLE 鼠标重连后指针不动的问题</span></a></p>
The post <a href="https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/">用脏办法解决 BLE 鼠标重连后指针不动的问题</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>我的蓝牙鼠标（雷柏 MT750）使用 BLE（Bluetooth Low Energy） 连接笔记本时，时常遇到自动重连后电脑这边认为已连接，而鼠标那边灯自动灭掉，鼠标指针无反应的问题。在网上反复搜索 bluez 相关问题找到了许多类似问题，鼠标类型也集中在罗技、ThinkPad 等 BLE 鼠标上。</p>



<p>偶然间发现每次重连后，如果手动用 bluetoothctl 发一个 “pair” 指令（会超时失败），就能令鼠标正常连接。给 bluez 报了一个 bug 后，我写了下面的简单脚本先绕过问题：</p>



<pre class="wp-block-code"><code lang="python" class="language-python line-numbers"><pre class="wp-block-syntaxhighlighter-code">#!/usr/bin/python
import dbus
import dbus.mainloop.glib
from gi.repository import GLib
adapter = "hci0"
device = "xx:xx:xx:xx:xx:xx"
device_path = '/org/bluez/' + adapter + "/dev_" + device.replace(":", "_")
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
system_bus = dbus.SystemBus()
device_object = system_bus.get_object('org.bluez', device_path)
device_interface = dbus.Interface(device_object, 'org.bluez.Device1')
def device_info(_arg0, event, _arg2):
    if event.get("Connected"):
        print("Mouse connected, attempt to pair...")
        try:
            device_interface.Pair()
        except dbus.exceptions.DBusException:
            pass
system_bus.add_signal_receiver(
    device_info,
    dbus_interface='org.freedesktop.DBus.Properties',
    signal_name="PropertiesChanged",
    arg0='org.bluez.Device1')
GLib.MainLoop().run()</pre></code></pre>



<p>保持在后台运行即可。我自己测试了一段时间，效果非常好。</p>



<p>PS: bluez 上游 bugzilla 堆满了各种没有回答的错误报告，目测不是那么好修的……</p>The post <a href="https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/">用脏办法解决 BLE 鼠标重连后指针不动的问题</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2019/01/dirty-hack-to-workaround-cursor-not-move-issue-after-ble-mouse-reconnect/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>为 glibc localedata 添加民国纪年支持</title>
		<link>https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/</link>
					<comments>https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Sat, 03 Nov 2018 14:11:35 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1612</guid>

					<description><![CDATA[<p>昨天被 @聞其詳 问起 glibc 对日本平成XX年的纪年支持情况（感谢 @farseerfc 老师），发现 glibc localedata 中并未包括民国纪年支持。在查询文档后稍微鼓捣了一下，简单实现了这个功能： $ LC_TIME=zh_TW.UTF-8 date +%EY 民國107年 $ LC_TIME=zh_TW.UTF-8 date +%EY --date="1912/4/3" 民國元年 $ LC_TIME=zh_TW.UTF-8 date +%EY --date="1913/4/3" 民國2年 $ LC_TIME=zh_TW.UTF-8 date +%EY --date="1911/4/3" 民前1年 $ LC_TIME=zh_TW.UTF-8 date +%EY --date="1900/4/3" 民前12年 修改方法： 编辑&#160;/usr/share/i18n/locales/zh_TW 文件，找到 END LC_TIME，在它之前加入这样三行： era "+:2:1913//01//01:+*:民國:%EC%Ey年";/ "+:1:1912//01//01:1912//12//31:民國:%EC元年";/ "+:1:1911//12//31:-*:民前:%EC%Ey年" 保存后重新 locale-gen 即可。 不足：暂时没有弄明白怎么实现中文数字，不过阿拉伯数字也还过得去…… 提交：glibc 的提交方式好像比较麻烦，所以先写篇博客好了。已提交并合并到 glibc。 &#8230; <a href="https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/" class="more-link">Continue reading <span class="screen-reader-text">为 glibc localedata 添加民国纪年支持</span></a></p>
The post <a href="https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/">为 glibc localedata 添加民国纪年支持</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>昨天被 @聞其詳 问起 glibc 对日本平成XX年的纪年支持情况（感谢 @farseerfc 老师），发现 glibc localedata 中并未包括民国纪年支持。在查询文档后稍微鼓捣了一下，简单实现了这个功能：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ LC_TIME=zh_TW.UTF-8 date +%EY
民國107年
$ LC_TIME=zh_TW.UTF-8 date +%EY --date="1912/4/3"
民國元年
$ LC_TIME=zh_TW.UTF-8 date +%EY --date="1913/4/3"
民國2年
$ LC_TIME=zh_TW.UTF-8 date +%EY --date="1911/4/3"
民前1年
$ LC_TIME=zh_TW.UTF-8 date +%EY --date="1900/4/3"
民前12年
</pre></code></pre>



<p>修改方法：</p>



<p>编辑&nbsp;/usr/share/i18n/locales/zh_TW 文件，找到 END LC_TIME，在它之前加入这样三行：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">era "+:2:1913//01//01:+*:民國:%EC%Ey年";/
    "+:1:1912//01//01:1912//12//31:民國:%EC元年";/
    "+:1:1911//12//31:-*:民前:%EC%Ey年"
</pre></code></pre>



<p>保存后重新 locale-gen 即可。</p>







<p>不足：暂时没有弄明白怎么实现中文数字，不过阿拉伯数字也还过得去……</p>



<p>提交：<del>glibc 的提交方式好像比较麻烦，所以先写篇博客好了。</del><a href="https://sourceware.org/git/?p=glibc.git;a=commit;h=238d60a1fb5081450ca57d3e20f6c1c27df9afb5">已提交并合并到 glibc。</a></p>



<p>发散：这个方法当然还可以用来实现各种自定义年号，比如朝鲜的主体纪年同样在 1912 年为元年，另外还有1970 &#8220;Unix 元年&#8221;、2013（咚咚咚，敲门声</p>The post <a href="https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/">为 glibc localedata 添加民国纪年支持</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2018/11/add-minguo-calendar-support-as-glibc-localedata-era/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>请不要把 Wifi Dongle 翻译成加密狗</title>
		<link>https://felixc.at/2018/10/please-dont-translate-wifi-dongle-to-encryption-lock/</link>
					<comments>https://felixc.at/2018/10/please-dont-translate-wifi-dongle-to-encryption-lock/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Mon, 08 Oct 2018 08:25:41 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1595</guid>

					<description><![CDATA[<p>在许多翻译过来的文本里，无线网卡（Wifi Dongle / Wifi Adapter）被翻译成了“加密狗”。最近在微博大火的一篇《俄罗斯特工又蠢了！实名行动暴露自己还卖了300多特工队友&#8230;..》里面，又出现了类似的错误，让我不得不想说说这个问题。 先来看看这个例子： 文章描述了几个黑客在目标附近发射伪造热点钓鱼，此处的未翻译单词包括了 Wifi 和 Dongle。根据上下文，带一个无线网卡发射热点应该是正确的意思，而加密狗在这里和上下文没啥关系…… 我尝试在搜索引擎里搜索对应词组，很不幸，惨状令人叹息： 就连正规电子产品的用户界面都中了枪： 这个问题的来源，看起来是国内加密狗早年被简单称呼为 Dongle： Dongle，按照维基百科的解释，是和 Adapter（适配器）很类似的一个词，泛指了一大类连接、转换器。 Wireless/Wifi Dongle = Wifi 适配器，Bluetooth Dongle = 蓝牙适配器，以此类推。所以，在看到类似 USB Dongle 这样模糊名字的时候，请务必联系上下文。如果原文用了 Wifi Dongle 这样比较明确含义的词组，请翻译为 Wifi 适配器，或者无线适配器，不要再翻译成加密狗了。</p>
The post <a href="https://felixc.at/2018/10/please-dont-translate-wifi-dongle-to-encryption-lock/">请不要把 Wifi Dongle 翻译成加密狗</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>在许多翻译过来的文本里，无线网卡（Wifi Dongle / Wifi Adapter）被翻译成了“加密狗”。最近在微博大火的一篇《俄罗斯特工又蠢了！实名行动暴露自己还卖了300多特工队友&#8230;..》里面，又出现了类似的错误，让我不得不想说说这个问题。</p>



<p>先来看看这个例子：</p>



<figure class="wp-block-image"><a class="highslide img_6" href="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="1041" height="210" src="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220.png" alt="" class="wp-image-1596" srcset="https://felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220.png 1041w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220-300x61.png 300w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220-768x155.png 768w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-160502-971220-1024x207.png 1024w" sizes="auto, (max-width: 1041px) 100vw, 1041px" /></a></figure>



<p>文章描述了几个黑客在目标附近发射伪造热点钓鱼，此处的未翻译单词包括了 Wifi 和 Dongle。根据上下文，带一个无线网卡发射热点应该是正确的意思，而加密狗在这里和上下文没啥关系……</p>



<p>我尝试在搜索引擎里搜索对应词组，很不幸，惨状令人叹息：</p>







<figure class="wp-block-image"><a class="highslide img_7" href="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="1147" height="484" src="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec.png" alt="" class="wp-image-1602" srcset="https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec.png 1147w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec-300x127.png 300w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec-768x324.png 768w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162338-157aec-1024x432.png 1024w" sizes="auto, (max-width: 1147px) 100vw, 1147px" /></a></figure>



<p>就连正规电子产品的用户界面都中了枪：</p>



<figure class="wp-block-image"><a class="highslide img_8" href="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="1150" height="1161" src="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5.png" alt="" class="wp-image-1598" srcset="https://felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5.png 1150w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5-150x150.png 150w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5-297x300.png 297w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5-768x775.png 768w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-155032-db82e5-1014x1024.png 1014w" sizes="auto, (max-width: 1150px) 100vw, 1150px" /></a></figure>



<p>这个问题的来源，看起来是国内加密狗早年被简单称呼为 Dongle：</p>



<figure class="wp-block-image"><a class="highslide img_9" href="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162036-674ec1.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="981" height="543" src="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162036-674ec1.png" alt="" class="wp-image-1601" srcset="https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162036-674ec1.png 981w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162036-674ec1-300x166.png 300w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162036-674ec1-768x425.png 768w" sizes="auto, (max-width: 981px) 100vw, 981px" /></a></figure>



<p>Dongle，按照维基百科的解释，是和 Adapter（适配器）很类似的一个词，泛指了一大类连接、转换器。</p>



<figure class="wp-block-image"><a class="highslide img_10" href="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162418-0cec7f.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="981" height="384" src="https://blog.felixc.at/wp-content/uploads/2018/10/2018-10-08-162418-0cec7f.png" alt="" class="wp-image-1603" srcset="https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162418-0cec7f.png 981w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162418-0cec7f-300x117.png 300w, https://felixc.at/wp-content/uploads/2018/10/2018-10-08-162418-0cec7f-768x301.png 768w" sizes="auto, (max-width: 981px) 100vw, 981px" /></a></figure>



<p>Wireless/Wifi Dongle = Wifi 适配器，Bluetooth Dongle = 蓝牙适配器，以此类推。所以，在看到类似 USB Dongle 这样模糊名字的时候，请务必联系上下文。如果原文用了 Wifi Dongle 这样比较明确含义的词组，请翻译为 Wifi 适配器，或者无线适配器，不要再翻译成加密狗了。</p>The post <a href="https://felixc.at/2018/10/please-dont-translate-wifi-dongle-to-encryption-lock/">请不要把 Wifi Dongle 翻译成加密狗</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2018/10/please-dont-translate-wifi-dongle-to-encryption-lock/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Thunderbolt 3 eGPU Bumblebee 方案尝鲜</title>
		<link>https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/</link>
					<comments>https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Fri, 28 Sep 2018 08:54:53 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1585</guid>

					<description><![CDATA[<p>最近从公司淘了一块 GTX 1060，淘宝了一个显卡盒折腾 TB3 eGPU 方案。由于笔记本经常带出门，打算采用即插即用的 bumblebee 方案（回家插上盒子用独显，拔下盒子可以带出门，可以正常待机不用重启）。下面记录一下 Arch 上配置的步骤和遇到的坑。 1、准备软件包 # pacman -S bumblebee primus lib32-primus nvidia-dkms lib32-nvidia-utils bolt 2、修改 bumblebee 配置 修改 /etc/bumblebee/xorg.conf.nvidia，在 Section &#8220;Device&#8221; 中加入： Option "AllowExternalGpus" "true" 修改 /etc/bumblebee/bumblebee.conf，在 [optirun] 中修改： Bridge=primus 3、插入 TB 线，验证设备（不建议完全关闭设备验证！） 输入 boltctl 查看设备信息，记下设备的 uuid。 $ boltctl ● TUL TBX-550CA ├─ type: peripheral ├─ name: TBX-550CA ├─ &#8230; <a href="https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/" class="more-link">Continue reading <span class="screen-reader-text">Thunderbolt 3 eGPU Bumblebee 方案尝鲜</span></a></p>
The post <a href="https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/">Thunderbolt 3 eGPU Bumblebee 方案尝鲜</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>最近从公司淘了一块 GTX 1060，淘宝了一个显卡盒折腾 TB3 eGPU 方案。由于笔记本经常带出门，打算采用即插即用的 bumblebee 方案（回家插上盒子用独显，拔下盒子可以带出门，可以正常待机不用重启）。下面记录一下 Arch 上配置的步骤和遇到的坑。</p>



<h4 class="wp-block-heading">1、准备软件包</h4>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code"># pacman -S bumblebee primus lib32-primus nvidia-dkms lib32-nvidia-utils bolt</pre></code></pre>



<h4 class="wp-block-heading">2、修改 bumblebee 配置</h4>



<p>修改 /etc/bumblebee/xorg.conf.nvidia，在 Section &#8220;Device&#8221; 中加入：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">Option "AllowExternalGpus" "true"</pre></code></pre>



<p>修改 /etc/bumblebee/bumblebee.conf，在 [optirun] 中修改：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">Bridge=primus</pre></code></pre>



<h4 class="wp-block-heading">3、插入 TB 线，验证设备（不建议完全关闭设备验证！）</h4>







<p>输入 boltctl 查看设备信息，记下设备的 uuid。</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ boltctl
 ● TUL TBX-550CA
   ├─ type:          peripheral
   ├─ name:          TBX-550CA
   ├─ vendor:        TUL
   ├─ uuid:          00xxxxxx-xxxx-xxxx-ffff-ffffffffffff
   ├─ status:        authorized
   │  ├─ domain:     domain0
   │  └─ authflags:  none
   ├─ authorized:    Fri 28 Sep 2018 08:23:25 AM UTC
   ├─ connected:     Fri 28 Sep 2018 08:23:21 AM UTC
   └─ stored:        Thu 27 Sep 2018 05:22:07 AM UTC
      ├─ policy:     auto
      └─ key:        no</pre></code></pre>



<p>验证设备并设置为自动验证：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ boltctl enroll --policy=auto 00xxxxxx-xxxx-xxxx-ffff-ffffffffffff</pre></code></pre>



<h4 class="wp-block-heading">4、启动 bumblebeed</h4>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code"># systemctl start bumblebeed</pre></code></pre>



<h4 class="wp-block-heading">5、测试、运行程序</h4>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">$ optirun glxspheres64
Polygons in scene: 62464 (61 spheres * 1024 polys/spheres)
Visual ID of window: 0x13f
Context is Direct
OpenGL Renderer: GeForce GTX 1060 5GB/PCIe/SSE2
……</pre></code></pre>



<h4 class="wp-block-heading">6、安全删除设备（参考了 <a href="https://jpamills.wordpress.com/2017/03/18/hotplug-support-for-egpu-on-linux/" rel="home">jpamills 博客</a>里的脚本）</h4>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><pre class="wp-block-syntaxhighlighter-code">#!/bin/bash
secs=5
tbt_chain=/sys/bus/thunderbolt/devices/0-0/../../../..
echo "Unplug eGPU script started."
if [ "$(id -u)" != "0" ]; then
        echo "Please run using sudo. Exiting."
        exit 1
fi
systemctl restart bumblebeed
sleep 2
modprobe -r nvidia_modeset
modprobe -r nvidia-uvm
modprobe -r nvidia
if [ -e $tbt_chain/remove ]
then
        echo 1 > $tbt_chain/remove
        echo "Thunderbolt chain removed from PCI tree. Please unplug eGPU now."
        while [ $secs -gt 0 ]; do
                echo -ne "$secs to rescan...\033[0K\r"
                sleep 1
                : $((secs--))
        done
        echo 1 > /sys/bus/pci/rescan
        echo "Rescanned the PCI bus. Completed."
        exit 0
else
        echo "eGPU does not appear to be attached. Exiting."
        exit 1
fi
</pre></code></pre>



<p>如果和我一样在盒子上插了外置硬盘，还可以在脚本里加上相应的 umount 语句。删除设备时需要先把使用设备的程序退出。</p>



<h4 class="wp-block-heading">效果展示</h4>



<figure class="wp-block-image"><a class="highslide img_14" href="https://blog.felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d.jpg" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="1019" height="1920" src="https://blog.felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d.jpg" alt="" class="wp-image-1586" srcset="https://felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d.jpg 1019w, https://felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d-159x300.jpg 159w, https://felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d-768x1447.jpg 768w, https://felixc.at/wp-content/uploads/2018/09/6fad324557b24b0d-543x1024.jpg 543w" sizes="auto, (max-width: 1019px) 100vw, 1019px" /></a></figure>



<figure class="wp-block-image"><a class="highslide img_15" href="https://blog.felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38.jpg" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="2560" height="1440" src="https://blog.felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38.jpg" alt="" class="wp-image-1587" srcset="https://felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38.jpg 2560w, https://felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38-300x169.jpg 300w, https://felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38-768x432.jpg 768w, https://felixc.at/wp-content/uploads/2018/09/2018-09-27_01.15.38-1024x576.jpg 1024w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a></figure>



<figure class="wp-block-image"><a class="highslide img_16" href="https://blog.felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4.png" onclick="return hs.expand(this)"><img loading="lazy" decoding="async" width="1239" height="607" src="https://blog.felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4.png" alt="" class="wp-image-1588" srcset="https://felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4.png 1239w, https://felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4-300x147.png 300w, https://felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4-768x376.png 768w, https://felixc.at/wp-content/uploads/2018/09/2018-09-28-165326-1f15a4-1024x502.png 1024w" sizes="auto, (max-width: 1239px) 100vw, 1239px" /></a></figure>



<h4 class="wp-block-heading">剩下的问题</h4>



<ul class="wp-block-list">
<li>脚本里可以考虑通过判断 nvidia-smi 列出的 PID 自动杀掉所有还在用卡的进程</li>



<li>Vulkan 应用程序暂时无法使用外置卡运行（仍然使用集显），可能需要 bumblebee 提供支持</li>
</ul>The post <a href="https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/">Thunderbolt 3 eGPU Bumblebee 方案尝鲜</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2018/09/trying-out-thunderbolt-3-egpu-with-bumblebee/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Arch Linux 社区中不成文的约定（一）</title>
		<link>https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/</link>
					<comments>https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/#comments</comments>
		
		<dc:creator><![CDATA[Felix Yan]]></dc:creator>
		<pubDate>Sun, 26 Aug 2018 17:33:13 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Arch]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog.felixc.at/?p=1577</guid>

					<description><![CDATA[<p>作为一个年轻和小众的社区（咳咳），Arch Linux 社区中有着许多不成文的约定。本文希望通过稍稍讲解一二，来消除一些新人们常常感到的困惑。由于预感到日后可能还会有更多问题，暂且认为这是系列里的第一篇 😛 修理“坏”包和提醒更新 仓库里一般的包可能有一个或多个维护者，也可能没有维护者，成为“孤儿”。如果坏掉或者过期的包是一个孤儿，申请从仓库里删掉是更有效的方法，这样它可以在 AUR 找到新的主人。发邮件到 aur-general 解释一下情况，并表明自己或者别人想维护它，一般都会很快得到解决。 如果“坏”包有维护者，但他太忙了呢？这种情况下，这个包很可能已经在 Bug Tracker 里泥足深陷。这种时候可以通过帮维护者一个小忙的方式来促进问题的解决。如果有人找到了上游 Bug Report，并且上游已经修复提供了 patch 的话，可以考虑把 patch 贴到 Arch 的 Bug Tracker；如果这件事已经有人做了，可以修改 PKGBUILD 打上 patch，然后把改好的 PKGBUILD 贴上去；如果连 PKGBUILD 都有人准备好了，而且过去了一段时间的话，可以考虑把这份准备好的 srcpkg 或者 diff 直接发邮件给维护者，附上简短的感谢和一个笑脸 🙂 同样的道理，如果一个过期包已经被标记过期很久了，也可以准备一个新版的 PKGBUILD 发邮件给维护者。 提供旧版软件包 因为懒得迁移各种各样的原因，你可能希望某些软件包的新旧版本同时提供。在 Arch 的实践中，这种情况被尽量避免了。把无法迁移的古老软件删掉还是提供一个旧版库让古老的软件能用，一定程度上取决于维护者对这个古老的软件有多坚持。 另一个考虑的因素是上游如何看待新旧版本。有的软件新版发布后，旧版就不再维护了，这种情况下 Arch 通常尽力避免成为新的上游。而有的上游则同时维护多个版本，Arch 这边根据其他软件的依赖情况，可能会有选择性地同时维护几个。 第三方 patch 能不能加上 Arch 对 patch 的态度比较保守，在规则里写的是一般只有修复编译和主要功能的上游已经接受的 patch &#8230; <a href="https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/" class="more-link">Continue reading <span class="screen-reader-text">Arch Linux 社区中不成文的约定（一）</span></a></p>
The post <a href="https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/">Arch Linux 社区中不成文的约定（一）</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p>作为一个年轻和小众的社区（咳咳），Arch Linux 社区中有着许多不成文的约定。本文希望通过稍稍讲解一二，来消除一些新人们常常感到的困惑。由于预感到日后可能还会有更多问题，暂且认为这是系列里的第一篇 😛</p>



<ul class="wp-block-list">
<li>
<h4>修理“坏”包和提醒更新</h4>
</li>
</ul>



<p>仓库里一般的包可能有一个或多个维护者，也可能没有维护者，成为“孤儿”。如果坏掉或者过期的包是一个孤儿，<strong>申请从仓库里删掉是更有效的方法</strong>，这样它可以在 AUR 找到新的主人。发邮件到 aur-general 解释一下情况，并表明自己或者别人想维护它，一般都会很快得到解决。</p>



<p>如果“坏”包有维护者，但他太忙了呢？这种情况下，这个包很可能已经在 Bug Tracker 里泥足深陷。<strong>这种时候可以通过帮维护者一个小忙的方式来促进问题的解决</strong>。如果有人找到了上游 Bug Report，并且上游已经修复提供了 patch 的话，可以考虑把 patch 贴到 Arch 的 Bug Tracker；如果这件事已经有人做了，可以修改 PKGBUILD 打上 patch，然后把改好的 PKGBUILD 贴上去；如果连 PKGBUILD 都有人准备好了，而且过去了一段时间的话，可以考虑把这份准备好的 srcpkg 或者 diff 直接发邮件给维护者，附上简短的感谢和一个笑脸 🙂</p>



<p>同样的道理，如果一个过期包已经被标记过期很久了，也可以准备一个新版的 PKGBUILD 发邮件给维护者。</p>







<ul class="wp-block-list">
<li>
<h4>提供旧版软件包</h4>
</li>
</ul>



<p>因为<del>懒得迁移</del>各种各样的原因，你可能希望某些软件包的新旧版本同时提供。在 Arch 的实践中，这种情况被尽量避免了。把无法迁移的古老软件删掉还是提供一个旧版库让古老的软件能用，一定程度上取决于维护者对这个古老的软件有多坚持。</p>



<p>另一个考虑的因素是上游如何看待新旧版本。有的软件新版发布后，旧版就不再维护了，这种情况下 Arch 通常尽力避免成为新的上游。而有的上游则同时维护多个版本，Arch 这边根据其他软件的依赖情况，可能会有选择性地同时维护几个。</p>



<ul class="wp-block-list">
<li>
<h4>第三方 patch 能不能加上</h4>
</li>
</ul>



<p>Arch 对 patch 的态度比较保守，在规则里写的是一般只有修复编译和主要功能的上游已经接受的 patch 会考虑。在实践中，有些时候没有这么严格，比如<del>我</del>开发者自己写的 patch 一边提交给上游，还没等答复，一边就加到了包里。因为 Arch 打包并没有 Review 过程，实际上加了什么 patch、靠不靠谱就全靠开发者自己掂量了。</p>



<p>一般来说，被上游明确拒绝的功能性 patch 是不怎么会考虑的。修复一个特定问题，尤其是影响比较大的问题的上游有点意见的 patch 有可能会被考虑。修复一个安全问题的 patch 经常会被接受，尤其是已经拿到 CVE 号的。</p>



<ul class="wp-block-list">
<li>
<h4>使用上游二进制 vs 从源码编译</h4>
</li>
</ul>



<p>一般常识是发行版们倾向于从源码编译一个软件，理由包括确保二进制真的来自这份源码、尽量使用系统中的动态链接库而不是静态编译一份以满足安全更新和体积方面的考虑、进行必要的修改等。</p>



<p>但是因为<del>太懒</del>一些问题，即使是在 Arch 官方仓库里也直接重新打包了一些上游的二进制。这些问题包括：源代码不开放（nvidia、flash 等）、编译过程中会去下载东西，而且不容易解决（dart、一些 java 软件等）。</p>



<ul class="wp-block-list">
<li>
<h4>文档是否打包</h4>
</li>
</ul>



<p>现在互联网十分发达，开发者们查询文档通常都是直接上网搜索。在这样的背景下，是否打包软件包的文档（通常都是开发文档）成为了一个问题。早些时候的包开启文档较多，如果太占体积还会考虑拆一个单独的文档包。后来才增加的新包则很多都没有启用文档，除非被用户要求提供文档才考虑这件事。</p>The post <a href="https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/">Arch Linux 社区中不成文的约定（一）</a> first appeared on <a href="https://felixc.at">Felix's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://felixc.at/2018/08/arch-linux-community-undocumented-details-1/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
	</channel>
</rss>
