<?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>Yuanle&#039;s Blog</title>
	<atom:link href="https://blog2.emacsos.com/feed" rel="self" type="application/rss+xml" />
	<link>https://blog2.emacsos.com</link>
	<description></description>
	<lastBuildDate>Wed, 25 Mar 2026 02:17:49 +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>

<image>
	<url>https://blog2.emacsos.com/wp-content/uploads/2025/05/favicon-150x150.png</url>
	<title>Yuanle&#039;s Blog</title>
	<link>https://blog2.emacsos.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>how to upgrade bwrap for codex on debian 12 bookworm</title>
		<link>https://blog2.emacsos.com/how-to-upgrade-bwrap-for-codex-on-debian-12-bookworm.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Wed, 25 Mar 2026 02:17:04 +0000</pubDate>
				<category><![CDATA[Programming and Software Engineering]]></category>
		<category><![CDATA[tip]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=127</guid>

					<description><![CDATA[If you get this error when using codex on debian 12 bookworm, this post is for you. The --argv0 parameter [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If you get this error when using codex on debian 12 bookworm, this post is for you.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<pre class="wp-block-code"><code>I’m currently blocked from editing your repo: every shell/tool call fails with:<br>bwrap: Unknown option --argv0</code></pre>
</blockquote>



<p>The <code>--argv0</code> parameter requires requires bubblewrap 0.9.0+, debian 12 bookworm has 0.8.0-2. To fix this issue, you can upgrade bwrap on your host.</p>



<p>Clone the source code from <a href="https://github.com/containers/bubblewrap">https://github.com/containers/bubblewrap</a></p>



<p>Install some dependencies</p>



<pre class="wp-block-code"><code>sudo apt instal -t bookworm-backports meson
sudo apt install libcap-dev ninja-build</code></pre>



<p>Get the code and build it</p>



<pre class="wp-block-code"><code>git clone <a href="https://github.com/containers/bubblewrap">https://github.com/containers/bubblewrap</a>
cd bubblewrap
meson build
cd build
ninja
sudo ninja install</code></pre>



<p>Confirm bwrap is installed</p>



<pre class="wp-block-code"><code>which bwrap
#/usr/local/bin/bwrap
bwrap --version
#bubblewrap 0.11.1</code></pre>



<p>Now the problem is codex only use /usr/bin/bwrap, so you have to copy it to that path.</p>



<pre class="wp-block-code"><code>sudo cp /usr/bin/bwrap /usr/bin/bwrap.old
sudo cp /usr/local/bin/bwrap /usr/bin/bwrap
ldd /usr/bin/bwrap</code></pre>



<p>Now restart codex, bwrap should work now. Happy coding.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Build Kernel Module for CP2102 Serial Module</title>
		<link>https://blog2.emacsos.com/how-to-build-kernel-module-for-cp2102-serial-module.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 14 Dec 2025 07:12:04 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=120</guid>

					<description><![CDATA[Some CP2102 device is recognized as &#8220;VeriFone Inc Verifone USB to Modem&#8221;, doesn&#8217;t register Serial support. It&#8217;s hardware driver issue. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Some CP2102 device is recognized as &#8220;VeriFone Inc Verifone USB to Modem&#8221;, doesn&#8217;t register Serial support. It&#8217;s hardware driver issue. You can build a new cp210x module to solve this issue.</p>



<h2 class="wp-block-heading">Get kernel source code</h2>



<p>I use Linux mainline kernel source. My Debian has 6.12.12 kernel.</p>



<pre class="wp-block-code"><code>wget https://mirror.nju.edu.cn/kernel.org/linux/kernel/v6.x/linux-6.12.12.tar.xz</code></pre>



<p>unpack to ~/fromsource/linux-6.12.12/</p>



<p>I think the debian source pkg should also work.</p>



<h2 class="wp-block-heading">Modify the cp210x driver&#8217;s source code</h2>



<p>You need to add support for your device in the source code. First get the USB vendor ID and product ID. You can get it from kernel log (<code>journalctl -k |tail</code>) or <code>lsusb </code>command. Kernel log is usually like &#8220;idVendor=11ca, idProduct=0211, bcdDevice=1.00&#8221;, lsusb output is like &#8220;Bus 007 Device 005: ID 11ca:0211 VeriFone Inc Verifone USB to Modem&#8221;. In my example, vendor ID is 11ca, product ID is 0211. Now you need to modify the source code at <code>~/fromsource/linux-6.12.12/drivers/usb/serial/cp210x.c</code></p>



<p>add<br><code>{ USB_DEVICE(0x11CA, 0x0211) },</code></p>



<p>between all those device vendor ID, product ID lines.</p>



<h2 class="wp-block-heading">Build the cp210x module</h2>



<p>Install some dependencies: pahole and resolve_btfids.</p>



<p>sudo apt install pahole libelf-dev</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
cd ~/fromsource/linux-6.12.12/
cd ./tools/bpf/resolve_btfids
make
ls -l resolve_btfids
sudo mkdir -p /usr/src/linux-headers-`uname -r`/tools/bpf/resolve_btfids
sudo ln -s $(realpath resolve_btfids) /usr/src/linux-headers-`uname -r`/tools/bpf/resolve_btfids
</pre></div>


<p>To avoid Skipping BTF generation for xxx Error:</p>



<pre class="wp-block-code"><code>sudo cp /sys/kernel/btf/vmlinux /usr/lib/modules/`uname -r`/build/</code></pre>



<p>Now it&#8217;s time to build the cp210x kernel module.</p>



<pre class="wp-block-code"><code>cd ~/fromsource/linux-6.12.12/drivers/usb/serial/
make -C /lib/modules/`uname -r`/build M=$PWD
ls -l cp210x.ko</code></pre>



<h2 class="wp-block-heading">Install and load cp210x module</h2>



<pre class="wp-block-code"><code># install cp210x
sudo cp usbserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/usbserial.ko
sudo cp cp210x.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/cp210x.ko
# you must update module dependency map after cp new file to kernel
# module dir. otherwise, you will get "unknown symbol in module" error.
sudo depmod -a

# load cp210x
sudo modprobe cp210x</code></pre>



<p>Now plugin your device, you should have /dev/ttyUSB0</p>



<p>In kernel log you should see</p>



<pre class="wp-block-code"><code>Nov 29 00:25:26 agem10.dev.emacsos.com kernel: usbcore: registered new interface driver usbserial_generic
Nov 29 00:25:26 agem10.dev.emacsos.com kernel: usbserial: USB Serial support registered for generic
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usbcore: registered new interface driver cp210x
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usbserial: USB Serial support registered for cp210x
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: cp210x 7-1.2:1.0: cp210x converter detected
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usb 7-1.2: cp210x converter now attached to ttyUSB0</code></pre>



<p>Now the device is fully working.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Qihoo 360T7 UART TTL Flash OpenWRT Guide</title>
		<link>https://blog2.emacsos.com/qihoo-360t7-uart-ttl-flash-openwrt-guide.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 14 Dec 2025 06:36:37 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=110</guid>

					<description><![CDATA[Qihoo 360T7 is one of the routers that uses MediaTek MT7981B SoC (System-On-Chip). It is a WiFi-6 router with 128M [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Qihoo 360T7 is one of the routers that uses MediaTek MT7981B SoC (System-On-Chip). It is a WiFi-6 router with 128M flash and 256MB RAM. It has good performance and is very affordable. The stock firmware runs an old version of OpenWRT. To get latest security patch and features, this guide shows you how to flash latest OpenWRT on the device.</p>



<h2 class="wp-block-heading">Before You Start</h2>



<p>Before you try to access the UART via TTL, check whether telnet is enabled on the current firmware. If telnet is enabled, you don&#8217;t need to use UART. Also check if a 3rd party u-boot is installed on the device. If it is, you don&#8217;t need to use UART.</p>



<p>Check your USB TTL device is working properly. Plug in your device, you should see /dev/ttyUSB0 shown up in your device tree. In my case, I use a CP2102 USB device, I need to build my own kernel module for it to work.</p>



<p>Get latest OpenWRT files for this device. You can find them at <a href="https://firmware-selector.openwrt.org/">https://firmware-selector.openwrt.org/</a>, type in 360t7, the files will show up. You need the SYSUPGRADE, PRELOADER.BIN, BL31-UBOOT.FIP files.</p>



<h2 class="wp-block-heading">Connect the UART TTL Cables</h2>



<p>It is possible to connect 3 cables to the device without opening the case. Put the device on the table, face down. Put antenna on the left side, put RJ45 sockets on the right side. Put a cellphone flashlight on the back of the device, adjust the flashlight spotlight so you can see 4 holes on the board. The first hole is square; the rest are circles. Ignore the first hole, the remaining 3 circle holes are GND, TX, RX. You need to connect them to your TTL device&#8217;s GND, RX, TX.</p>



<p>Get 3 thin metal wire. Those used to fasten charging cables works fine. Remove the outside of the wire. Fold them to Z shape so they can be insert to the 360t7 device through the louver holes on the case. Use tape to fix each wire once they are in position. Connect all 3 wires to duPont wire on your USB TTL device. GND-GND, TX-RX, RX-TX.</p>



<h2 class="wp-block-heading">Prepare Terminal to Connect to Serial</h2>



<p>On Linux, install minicom package. Run minicom with</p>



<pre class="wp-block-code"><code>sudo minicom -D /dev/ttyUSB0</code></pre>



<p>Configure minicom by pressing <code>Ctrl-A O</code></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
 Serial port setup
 F - Hardware Flow Control
 G - Software Flow Control
</pre></div>


<p>Make sure both says No. Otherwise, keyboard input won&#8217;t work.</p>



<p>Save this configure as default in <code>Ctrl-A O</code> menu. Otherwise, each time you start minicom, you need to config this again.</p>



<h2 class="wp-block-heading">Go To OpenWRT Failsafe Mode</h2>



<p>With minicom running, all cables connected, now connect power cable to boot your device. You should see u-boot and kernel output in minicom terminal. After kernel boot, wait for 3s, then press F and Enter key repeatedly to enter failsafe mode.</p>



<p>If you never saw failsafe mode text prompt, let the router boot normally, then flash <code>360T7-v4.2.4.7959_upgrade.bin</code> in stock firmware web UI. In newer firmware, failsafe mode is disabled, revert to this older version to allow OpenWRT failsafe mode.</p>



<h2 class="wp-block-heading">Enable Telnet and Set Root Password in Failsafe Mode</h2>



<p>Once you get to failsafe mode root shell, run these commands:</p>



<pre class="wp-block-code"><code>fw_setenv bootmenu_delay 3
mount_root
# Enable telnet service
sed -i 's/.*local debug=.*/\tlocal debug=1/' /etc/init.d/telnet
# Set password for root, type a password of your choice twice.
passwd root
cat /proc/mtd
# you should see stock Qihoo 360t7 layout.</code></pre>



<pre class="wp-block-code"><code>root@(none):/# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 08000000 00020000 "spi0.0"
mtd1: 00100000 00020000 "bl2"
mtd2: 00080000 00020000 "u-boot-env"
mtd3: 00200000 00020000 "Factory"
mtd4: 00200000 00020000 "fip"
mtd5: 02400000 00020000 "ubi"
mtd6: 02400000 00020000 "firmware-1"
mtd7: 02400000 00020000 "plugin"
mtd8: 00100000 00020000 "config"
mtd9: 00080000 00020000 "factory"
mtd10: 00700000 00020000 "log"</code></pre>



<p>Run &#8220;reboot&#8221; to reboot the device. Now you should use stock u-boot menu. You can use u-boot menu to flash u-boot and firmware, or you can do it in telnet session after the device is fully boot. I choose to use u-boot menu.</p>



<p>On u-boot menu, select &#8220;Upgrade ATF BL2&#8221;, serve OpenWRT preloader.bin via TFTP. Run mtkautoboot to show u-boot menu again.</p>



<p>Select &#8220;Upgrade ATF FIP&#8221;, serve OpenWRT bl31-uboot.fip via TFTP. Run &#8220;reset&#8221; to reboot device. Now you should see OpenWRT&#8217;s u-boot menu. It is different than stock u-boot menu.</p>



<pre class="wp-block-code"><code>  ( ( ( OpenWrt ) ) )       U-Boot 2024.10-OpenWrt-r28872-daca7c049b (Sep 19 20

1. Run default boot command.
2. Boot system via TFTP.
3. Boot production system from NAND.
4. Boot recovery system from NAND.
5. Load production system via TFTP then write to NAND.
6. Load recovery system via TFTP then write to NAND.
7. Load BL31+U-Boot FIP via TFTP then write to NAND.
8. Load BL2 preloader via TFTP then write to NAND.
9. Reboot.
a. Reset all settings to factory defaults.
0. Exit

Press UP/DOWN to move, ENTER to select, ESC to quit</code></pre>



<h2 class="wp-block-heading">Flash OpenWRT</h2>



<p>On Linux computer, serve <code>openwrt-mediatek-filogic-qihoo_360t7-initramfs-recovery.itb</code> via 192.168.1.254 TFTP server. In OpenWRT u-boot menu, select &#8220;Boot system via TFTP.&#8221; It will boot to OpenWRT initramfs-recovery. When initramfs-recovery boots, use ssh or luci to flash OpenWRT sysupgrade image.</p>



<p>After that, router will auto reboot, you will have latest OpenWRT running on Qihoo 360T7.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Cloud Provider Free Tier Services</title>
		<link>https://blog2.emacsos.com/cloud-provider-free-tier-services.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sat, 20 Sep 2025 12:53:00 +0000</pubDate>
				<category><![CDATA[Cloud Service]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=107</guid>

					<description><![CDATA[Oracle Cloud Oracle Cloud has an always free tier, providing arm(aarch64) Ampere server with 24GB RAM and enough disk space [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Oracle Cloud</h2>



<p>Oracle Cloud has an always free tier, providing arm(aarch64) Ampere server with 24GB RAM and enough disk space to get you started. It provides significant value for customers. Does other cloud provider offer free tier compute services like this?</p>



<h2 class="wp-block-heading"> Google Cloud Platform (GCP)</h2>



<p>Compute Engine: One e2-micro instance (0.25–0.5 vCPU, 1 GB RAM) per month in select regions (e.g., Iowa, Oregon, South Carolina), with 30 GB HDD and 1 GB egress.</p>



<h2 class="wp-block-heading">Amazon Web Service (AWS)</h2>



<p>No free VM, only free lambda service.</p>



<h2 class="wp-block-heading">Microsoft Azure</h2>



<p>One free VM for 1 year. After that no free VM, only limited function (serverless), container, static web app.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to write to a protected FIP partition in openwrt?</title>
		<link>https://blog2.emacsos.com/how-to-write-to-a-protected-fip-partition-in-openwrt.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sat, 21 Jun 2025 09:58:03 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=102</guid>

					<description><![CDATA[When you try to write u-boot image to a partition, sometimes you get this error msg: You may use this [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>When you try to write u-boot image to a partition, sometimes you get this error msg:</p>



<pre class="wp-block-code"><code>Could not open mtd device: fip
Can't open device for writing!</code></pre>



<p>You may use this trick to allow write to the FIP and other MTD partitions.</p>



<pre class="wp-block-code"><code>opkg update
opkg install kmod-mtd-rw

insmod /lib/modules/$(uname -r)/mtd-rw.ko i_want_a_brick=1
# the i_want_a_brick=1 part is required! Otherwise, the command will fail.</code></pre>



<p>Now you can run the mtd write command again.</p>



<p>If write still fail, make sure the partition name is correct. The partition name is case sensitive. You can check the partition name using</p>



<pre class="wp-block-code"><code>cat /proc/mtd</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Linux IPv6 debug checklist</title>
		<link>https://blog2.emacsos.com/linux-ipv6-debug-checklist.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Tue, 13 May 2025 03:31:08 +0000</pubDate>
				<category><![CDATA[Linux Server and Sysadmin]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[sysadmin]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=82</guid>

					<description><![CDATA[If IPv6 is not working properly in Linux, here are steps you can follow to debug the issue. check kernel [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If IPv6 is not working properly in Linux, here are steps you can follow to debug the issue.</p>



<h2 class="wp-block-heading">check kernel boot param</h2>



<ol class="wp-block-list"></ol>



<p>Check these two files</p>



<pre class="wp-block-code"><code>cat /proc/cmdline
cat /etc/default/grub</code></pre>



<p>If <code>ipv6.disable=1</code> is set, the kernel IPv6 stack will be disabled. If <code>ipv6.disable_ipv6=1</code> is set, the kernel keeps the IPv6 stack functional but will not assign IPv6 addresses to any of your network devices.</p>



<p>Make sure you do not use any of these kernel options if you want to use IPv6.</p>



<h2 class="wp-block-heading">check interface disable_ipv6 settings</h2>



<pre class="wp-block-code"><code>sysctl net.ipv6.conf.lo.disable_ipv6
sysctl net.ipv6.conf.eno1.disable_ipv6
# -r list all values matching this pattern
sysctl -r 'net.ipv6.conf.*.disable_ipv6' net.ipv6.conf</code></pre>



<p>Make sure all of the interfaces that you want to have ipv6 enabled has <code>disable_ipv6=0</code>. Specifically, you SHOULD also enable ipv6 on <code>lo</code> interface. You should also enable IPv6 on Linux bridge and the physical interface that it is connected to.</p>



<h2 class="wp-block-heading">check interface RA settings if you use SLAAC</h2>



<p>RA stands for router advertisement. It is a broadcast packet that allow configuration of IP address and routing. SLAAC relies on RA to work.</p>



<pre class="wp-block-code"><code>sysctl net.ipv6.conf.all.accept_ra
# replace vmbr0 with your interface
sysctl net.ipv6.conf.vmbr0.accept_ra</code></pre>



<p>It should be 1 or 2 depending on your device.<br>If it&#8217;s 0, you need to set this at boot time. e.g. in <code>/etc/network/interfaces</code></p>



<p><a href="https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html">To learn more about <code>accept_ra</code> param, see Linux kernel document.</a> Search <code>accept_ra</code> in that page.</p>



<p>For example, on one of my promox VE node, I have</p>



<pre class="wp-block-code"><code>auto vmbr0
iface vmbr0 inet static
        address 192.168.2.47/24
        gateway 192.168.2.1
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
iface vmbr0 inet6 auto
        accept_ra 2</code></pre>



<p>If you doubt whether RA is working properly, run <code>tcpdump</code> to capture the packet and view it in wireshark.</p>



<pre class="wp-block-code"><code># replace INTERFACE with your interface name
sudo tcpdump -i INTERFACE -w /tmp/ra_packets.pcap 'icmp6 and (ip6&#91;40] = 134 or ip6&#91;40] = 133)'</code></pre>



<h2 class="wp-block-heading">check lo ip6-loopback ping</h2>



<pre class="wp-block-code"><code>ping6 ::1<br>ping6 ip6-loopback</code></pre>



<h2 class="wp-block-heading">check local hostname is ipv6 resolvable</h2>



<p>in <code>/etc/hosts</code><br>::1 entry should include your fqdn</p>



<h2 class="wp-block-heading">check whether ipv6 address is assigned on interface</h2>



<pre class="wp-block-code"><code>ip -6 a<br>ip -6 a vmbr0</code></pre>



<p>If your IPv6 network use <a href="https://howdoesinternetwork.com/2013/slaac">SLAAC</a>, IP address should be assigned automatically. One interface usually has one public IPv6 address (starts with <code>2x:xx:xx</code>) and more than one private IPv6 address (starts with <code>fx:xx:xx</code>).</p>



<p>If your IPv6 network use DHCPv6 only, you should config DHCP in <code>/etc/network/interface</code> or corresponding RHEL config file or Network Manager config file. To just test DHCPv6 is working, you can run:</p>



<pre class="wp-block-code"><code>dhclient -6 INTERFACE</code></pre>



<h2 class="wp-block-heading">check ipv6 routes is added</h2>



<pre class="wp-block-code"><code>ip -6 r
ip -6 r | grep default</code></pre>



<p>IPv6 routes are added by clients via RA (router advertisement).</p>



<p>Make sure the default route either has no expire field or has a good expire field. In <a href="https://openwrt.org/">openwrt</a> default config, default route expire should be between 1200s and 1800s. If it&#8217;s less than 1200s, RA is not properly received and processed by host.</p>



<p>In some home server, if you enable IPv6 on IPMI/SBC/iLO/iDrac and use the shared network port, host OS will no longer receive the RA packet. You may see low expire on default route or missing a default route. In that case, you should disable IPv6 on IPMI.</p>



<h2 class="wp-block-heading">check IPv6 neighbors for nodes in the same LAN</h2>



<pre class="wp-block-code"><code>ip -6 n show|grep -v -E '(FAILED|STALE)'</code></pre>



<p>At least one router should be listed when IPv6 is working. You can compare results on different nodes in the same LAN.</p>



<h2 class="wp-block-heading">check you can visit other IPv6 nodes on the Internet</h2>



<pre class="wp-block-code"><code>ping6 aliyun.com
curl -6 https://aliyun.com
curl -I -6 https://mirrors.tuna.tsinghua.edu.cn/
# test whether your OS prefer IPv6 or IPv4 when both are available
curl test.ipw.cn</code></pre>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Intel AX200 bluetooth and wifi suddenly not working in Linux GNOME</title>
		<link>https://blog2.emacsos.com/fix-intel-ax200-bluetooth.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 04 May 2025 04:36:46 +0000</pubDate>
				<category><![CDATA[Linux Desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[tip]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=14</guid>

					<description><![CDATA[Symptom You can&#8217;t toggle bluetooth on/off in GNOME applets. rfkill list show bluetooth is not blocked. bluetoothctl list show empty [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Symptom</h2>



<p>You can&#8217;t toggle bluetooth on/off in GNOME applets.</p>



<p><code>rfkill list</code> show bluetooth is not blocked.</p>



<p><code>bluetoothctl list</code> show empty bluetooth controller list.</p>



<h2 class="wp-block-heading">Solution</h2>



<pre class="wp-block-code"><code>sudo modprobe -r btusb<br>sudo modprobe btusb</code></pre>



<p>This will unload and reload btusb module, which may be able to fix the issue.</p>



<p>ref: <a href="https://bbs.archlinux.org/viewtopic.php?id=272643">[SOLVED] No bluetooth adaptater on AX200 / Kernel &amp; Hardware / Arch Linux Forums</a></p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Units Tool in Linux</title>
		<link>https://blog2.emacsos.com/the-units-tool.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 23 Oct 2016 10:14:00 +0000</pubDate>
				<category><![CDATA[Linux Desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[tool]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=59</guid>

					<description><![CDATA[GNU Units can be used for many things. It is such a useful tool that I always install it on all [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.gnu.org/software/units/">GNU Units</a> can be used for many things. It is such a useful tool that I always install it on all Linux nodes.</p>



<p>Here is how I use it:</p>



<p>Convert network speed. ISPs and network device use <em>bit per second</em>, downloaders usually use <em>byte per second</em>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 1000Mbps MiB/s
; 119.21 MiB/s
units 100Mbps MiB/s
; 11.92 MiB/s
units 20Mbps MiB/s
; 2.38 MiB/s
units 4Mbps KiB/s
; 488 KiB/s
</pre></div>


<p>Calculate average download speed</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 800MiB/25min KiB/s
; 546.1 KiB/s
</pre></div>


<p>Convert hard drive space. Operating systems show GiB/TiB, while vendors use GB/TB.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 1TB GiB
; 931.3 GiB
units 2TB GiB
; 1862.6 GiB
</pre></div>


<p>You can do calculation too. For example, if you have 24 16TB disks. Each data is stored in 3 replicas. At 80% capacity, you may store up to</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
units 16TB*24/3*0.8 TiB
; 93.13 TiB
</pre></div>


<p>Do time calculations</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units &#039;2 hour + 34 min + 1 day&#039;
; 95640 s
units &#039;2 hour + 34 min + 1 day&#039; hour
; 26.6 hour
units 8mo weeks
; 34.8 weeks
</pre></div>


<p>Convert between tps and maximum possible total request per day</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 132tps req/day
; 11404800 req/day
units 132tps million*req/day
; 11.4 million*req/day
</pre></div>


<p>Convert between (single node) tps and average response time</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 132tps ms/req
; 7.5 ms/req
</pre></div>


<p>Convert foreign currency to local currency</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
units 39.99hkd usd
; 5.1 usd

units 500hkd/mo usd/year
; 765 usd/year
</pre></div>


<p>You may have notice some units are not built-in. Units allow you to define your own units very easily. Here is my <code>~/.units</code> file:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
word    !
words   1 word

rmb     !
cny     rmb
RMB     rmb
hkd     0.9393 rmb
aud     4.6608 rmb
usd     7.2959 rmb
eur     8.266 rmb
euro    eur
gbp     9.7282 rmb
GBp     0.01gbp
jpy     0.050583 rmb
sgd     5.5781 rmb
s$      sgd
inr     0.081919 rmb
rs      inr
mvr     0.4637 rmb
laari   0.01 mvr

request !
req     request
r       request
tps     req/s

BTC     64219 usd
bitcoin 1 BTC
btc     BTC

ETH     3490 usd
Ether    1 ETH
Ethereum 1 ETH
eth      ETH

# units 0K tempC
# units 0K tempF

core    !

jin     0.5kg

char    !

share   !

w       10000
yi      100000000

tx      !
transaction   tx
trans   tx

kwh     1000*watt*hour

</pre></div>


<p>You can define basic unit by using &#8216;!&#8217;, you can define unit alias, you can define conversion. See&nbsp;<code>man units</code>&nbsp;for more information.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Why I Choose Debian Over Ubuntu, Arch Linux, Gentoo, FreeBSD</title>
		<link>https://blog2.emacsos.com/why-debian.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 21 Aug 2016 03:30:00 +0000</pubDate>
				<category><![CDATA[Linux Server and Sysadmin]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=89</guid>

					<description><![CDATA[Debian is my favorite Linux distro, as you may already know from my technology radar. In this post, I will [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.debian.org/" target="_blank" rel="noreferrer noopener">Debian</a> is my favorite Linux distro, as you may already know from <a href="https://blog.emacsos.com/tech-radar.html" target="_blank" rel="noreferrer noopener">my technology radar</a>. In this post, I will tell you what features I need in a distro and why I choose Debian. Note that all distros in title are good ones, that&#8217;s why I list them for comparison.</p>



<p>Of the choices in title, I have used Ubuntu, Debian and FreeBSD. I had evaluated Arch Linux and Gentoo to a great extend and decide not to use them. I have started to use Linux since around 2005. The first distros that got me interested in Linux was Red Hat Linux 9 and Fedora Core 4. I remember the days when I burned Fedora Core 4 and Ubuntu 6.10 CDs and gave them to others when I was in college. And Ubuntu sent free CDs with free shipping all over the world at that time.</p>



<p>Without further ado, let&#8217;s talk about features I care in Linux distro.</p>



<h2 class="wp-block-heading" id="sec-1">Stable Release Instead of Rolling Release</h2>



<p>Actually rolling release means no release at all. In stable release, the kernel and package are tested, work together well and the feature set is frozen. Security or critical bug fix patches are provided without breaking backward compatibility. Stable release also means there is a documented process of upgrading old release to a new one. All backward incompatible changes are well documented.</p>



<p>Using a stable release doesn&#8217;t mean you have to stick with old versions of software. You can always compile the software you do want. For example, I used to compile <a href="http://www.mplayerhq.hu/" target="_blank" rel="noreferrer noopener">mplayer</a> and <a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noreferrer noopener">Emacs</a> in Debian stable. Some software encourage you to use an official build, such as <a href="https://www.bugzilla.org/" target="_blank" rel="noreferrer noopener">bugzilla</a>. Some software have latest build maintained for Debian stable, such as <a href="https://www.postgresql.org/" target="_blank" rel="noreferrer noopener">postgresql</a>. You are definitely not constrained by the software version that is in Debian stable&#8217;s apt repository. A stable release will make sure the underlying system and library is solid, if you want to get latest applications, go ahead. On the Linux desktop, <a href="https://appimage.org/" target="_blank" rel="noreferrer noopener">AppImage</a> and <a href="https://flatpak.org/" target="_blank" rel="noreferrer noopener">Flatpak</a> is also becoming more popular. If you want to get <a href="https://obsproject.com/download#linux" target="_blank" rel="noreferrer noopener">OBS</a> or <a href="https://www.digikam.org/download/" target="_blank" rel="noreferrer noopener">DigiKam</a>, there is a build for any Linux. Personally I still prefer OS native builds though.</p>



<p>If you want to learn more about how a stable release is made. Read <a href="https://release.debian.org/" target="_blank" rel="noreferrer noopener">Debian Release Management</a> or <a href="https://www.freebsd.org/doc/en/articles/releng/index.html" target="_blank" rel="noreferrer noopener">FreeBSD&#8217;s release engineering</a>. If you are a developer or project manager, you know making a good release is hard.</p>



<p>This rules out Arch Linux, which is a rolling release. Rolling release doesn&#8217;t mean install once and upgrade forever. It&#8217;s more like every package may break at every upgrade. You need to test software you use in a stage environment by yourself if you don&#8217;t want surprises. This also rules out Ubuntu non-LTS releases. I don&#8217;t call it a release anymore.</p>



<h2 class="wp-block-heading" id="sec-2">Binary Packages Instead of Source Packages</h2>



<p>Unless you only use a fixed set of packages and rarely upgrade them, binary packages will greatly simplify and speed up software installation. Even if you have a fairly powerful machine, it still cause great pain if a low level library requires an update, which triggers a chain of recompiles. I was bitten by this once while I was using FreeBSD. For some dedicated web or database server, this may not be a big problem.</p>



<p>A side note for python developers. Since this year (2016), most <a href="https://pypi.python.org/pypi" target="_blank" rel="noreferrer noopener">PyPI packages</a> are in wheel binary format, which makes installing faster and easier. It&#8217;s amazing that <a href="https://m.reddit.com/r/Python/comments/4jaaib/pypi_download_stats_have_stopped_working_again/d355dt6" target="_blank" rel="noreferrer noopener">PyPI is developed and maintained by a single person</a>.</p>



<p>This rules out Gentoo and FreeBSD ports.</p>



<h2 class="wp-block-heading" id="sec-3">Large Selection of Software and Large User Base</h2>



<p>The core team should maintain a large selection of software, so if there are problems, they can be exposed and handled inside the project. Large user base means if you hit a problem, it&#8217;s likely there is already a fix or a workaround.</p>



<p>This rules out FreeBSD. Its binary package system is not as sophisticated as Debian&#8217;s. Binary packages and ports are not part of the official release.</p>



<p>Edit: In 2025, FreeBSD 14 offers significantly more binary packages than it did in 2016. If your hardware runs well on FreeBSD and you don&#8217;t need any Linux-only non-free software, you should give FreeBSD a try.</p>



<h2 class="wp-block-heading" id="sec-4">Worldwide Mirrors for Packages</h2>



<p>This will speed up operating system install and upgrade, and package install greatly.</p>



<h2 class="wp-block-heading" id="sec-5">Honor Mentions About Other Distro</h2>



<p>RedHat Enterprise Linux (RHEL)/Oracle Linux/Amazon Linux, Ubuntu LTS, OpenSUSE.</p>



<p>RHEL is very similar to Debian, if you prefer RedHat&#8217;s way of doing things, they are good choices. Also, RHEL has the best documentation between RHEL, Ubuntu and Debian. The document quality order from high to low is RHEL, Debian, Ubuntu. You do need to register an account to view most of the documents though.</p>



<p>Oracle Linux and Amazon Linux are derived from RHEL (or CentOS-stream, Fedora). If you run on <a href="https://www.oracle.com/cloud/" target="_blank" rel="noreferrer noopener">Oracle Cloud</a> or <a href="https://aws.amazon.com/" target="_blank" rel="noreferrer noopener">AWS</a>, you may use these flavors. They behave similarly to RHEL and do not require a paid license to use. In comparison, the RHEL does require a license to use in mass production. There is a <a href="https://developers.redhat.com/articles/faqs-no-cost-red-hat-enterprise-linux" target="_blank" rel="noreferrer noopener">no-cost RHEL developer license</a> that you can use in development environment and small production environment. There are a few community versions of RHEL re-pack when CentOS is acquired and discontinued by RedHat, such as <a href="https://rockylinux.org/" target="_blank" rel="noreferrer noopener">RockyLinux</a> and <a href="https://almalinux.org/" data-type="link" data-id="https://almalinux.org/" target="_blank" rel="noreferrer noopener">AlmaLinux</a>. The offer binary compatibility with RHEL. But the default dnf repo and management tools are not all the same.</p>



<p>Ubuntu LTS, although the release is not as good as Debian, does have a large user base and a long term support (LTS). That makes it a much better choice than Ubuntu non-LTS release. Ubuntu LTS also got commercial support if you needs that. I found Ubuntu&#8217;s release not as stable as Debian. That&#8217;s why I always choose Debian over Ubuntu LTS. Only choose Ubuntu LTS only if you want to purchase support from <a href="https://canonical.com/" target="_blank" rel="noreferrer noopener">Canonical</a>.</p>



<p>I have not used OpenSUSE for real, so I won&#8217;t remark on them. Based on short experience of OpenSUSE Leap, the installer is very enterprisy. Side note: I think <a href="https://openbuildservice.org/" target="_blank" rel="noreferrer noopener">Open Build Service</a> (e.g. <a href="https://build.opensuse.org/" target="_blank" rel="noreferrer noopener">OpenSUSE OBS</a>) is a cool project, which works for all Linux projects and distros. But I haven&#8217;t tried it yet.</p>



<p>Edit: CentOS is acquired by RedHat and <a href="https://blog.centos.org/2020/12/future-is-centos-stream/" target="_blank" rel="noreferrer noopener">rebrand to CentOS stream</a>. Added notes on Oracle Linux, Amazon Linux and some CentOS remakes.</p>



<p>If you need advice on choosing a Linux distro, you can leave a comment or email me. Do tell me what you want to do with Linux so the advice could be specific to your use case.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What Makes Emacs Different and Unique</title>
		<link>https://blog2.emacsos.com/emacs-is-different.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 31 Jul 2016 05:40:27 +0000</pubDate>
				<category><![CDATA[Programming and Software Engineering]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[lisp]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=7</guid>

					<description><![CDATA[Created On: 2016-07-31 Updated On: 2021-08-11 Emacs is Highly Dynamic In Emacs, every keystroke and command can be customized (redefined) [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Created On: 2016-07-31 Updated On: 2021-08-11</p>



<h2 class="wp-block-heading" id="org99c2c96">Emacs is Highly Dynamic</h2>



<p>In Emacs, every keystroke and command can be customized (redefined) when the editor is still running, including typing characters, pressing arrow keys. Usually in an editor, you would expect typing character and moving cursor via arrow keys to be basic and not customizable. Not in Emacs.</p>



<p>In Emacs, typing a character most likely runs <code>self-insert-command</code>. As the name implies, it just insert the character itself. However, this binding is fully customizable just like your F6 key or other keys. There is nothing special for it. And in deed, in some built-in modes, pressing a character no longer does <code>self-insert-command</code> any more. For example, in <code>electric-pair-mode</code>, when you insert an open parenthesis, Emacs automatically insert a matching closing parenthesis. When cursor is at a matching closing parenthesis, typing the closing parenthesis again will just move cursor after it instead of inserting an additional unwanted one. In viper mode, typing characters mimics their behavior in the VIM editor, which can do very different things than inserting characters.</p>



<p>This is all possible because the dynamic feature of the lisp language. Some low level infrastructure of the editor is bootstrapped using C, then everything else is either implemented directly in Emacs lisp or is exposed via Emacs lisp.</p>



<p>Major modes, minor modes, font faces, keymaps, almost everything defined in Emacs can be redefined on the fly easily. There is even a built-in tetris game (run <code>M-x tetris</code>). So you get the idea how dynamic it is.</p>



<h2 class="wp-block-heading" id="orgb946bea">Text Based System is Powerful</h2>



<p>Emacs has many built-in commands for moving cursor and manipulating text. Text, although lacking in multimedia capabilities like HTML, is still a very useful and powerful representation for different things.</p>



<p>There are a few things that are considerably more powerful when run in a text based system like Emacs.</p>



<p>For example, running shells. Usually people run dedicated terminal emulators like rxvt-unicode or Konsole. Those are OK at running commands. But in emacs, there is a shell mode, which makes the shell&#8217;s input and output as plain text in a emacs buffer. Scrolling, searching output, copying, pasting can&#8217;t be easier. You have the full power of emacs such as word/path based cursor movement, input history, path expansion, e.g.&nbsp;<code>cd /u/loc/bi TAB</code>&nbsp;expanding to&nbsp;<code>cd /usr/local/bin/</code>. You can query replace substrings. Your abbreviations will just work. You can run many shells and switch between them the same way you switch between file buffers.</p>



<p>Another example is bulk file renaming, like removing a common prefix or renaming all .JPG files to .jpg. In&nbsp;<a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html">emacs&#8217;s file manager dired</a>, renaming multiple files is as easy as editing the filename as text. You can do search &amp; replace,&nbsp;<code>downcase-word</code>, rectangle editing. Any command that works on regular text buffer will work there. And full undo history is available as well. When you save the buffer, the files will get renamed. It&#8217;s very convenient and intuitive.</p>



<p>Viewing man page in Emacs is also much more pleasant than in terminal. Since the rendered result is just text, all Emacs&#8217;s search commands are available. You can use <code>occur</code> to find specific text or option, you can jump to man page sections, you can jump to other referenced man pages by clicking them, you can copy &amp; paste or do cross buffer auto completion in shell buffer. On regular man command, the rendered result is just piped to less, which doesn&#8217;t know about sections and links to other man pages at all.</p>



<p>Writing Email, git commit message, doing git rebase, chatting via IRC, they all have been easier in Emacs because of the universal text interface.</p>



<h2 class="wp-block-heading" id="org543ed7d">Great Extensibility with Great Documentation</h2>



<p>Emacs&#8217;s built-in documentation covers the core editor&#8217;s features and programming interfaces very well. That includes the info doc for Emacs and elisp, the <code>describe-function</code> and <code>describe-variable</code> facility, which is bound on <code>C-h f</code> and <code>C-h v</code> respectively, and the source code (.el.gz) which is usually quite readable.</p>



<p>To change behavior of existing features, you just write and execute elisp code inside Emacs. When you want to persist a change across restarts, you put them in&nbsp;<code>~/.emacs.d/init.el</code>. To write new features, you can build on top of existing modes and a large collection of existing functions easily.</p>



<p>Emacs has many useful features during its many years of development. New modes and extensions are also being created from different people in different areas. The most important change for me in recent 2 or 3 years is the huge growth of org-mode and the package system (<a href="https://elpa.gnu.org/">elpa</a>&nbsp;and&nbsp;<a href="https://melpa.org/">melpa</a>).&nbsp;<a href="http://orgmode.org/">Org-mode</a>&nbsp;is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system. The package system allows searching, distributing, installing and removing Emacs extensions more easily. It also encourages code reuse. Emerging programming languages usually have an Emacs mode to support syntax highlighting and other features, because it is a powerful editor and it is easy to add a major or minor mode.</p>



<p>In comparison, other editors and IDEs usually either lack in extensibility or documentation or both. Emacs is the only editor that I knows that doesn&#8217;t distinguish between built-in features and user defined features. They are written in the same way, and loaded in the same way. When you add or change something, there is no need to compile it somewhere else or restart Emacs. User defined code looks and works just like built-in code. Actually this is a feature of the lisp language. You can think of Emacs as an editor DSL on top of Emacs lisp. It just makes writing editor and related things easier. Your running Emacs instance is just a lisp image that is configured to accept keyboard/mouse events and can load more elisp code.</p>



<h2 class="wp-block-heading" id="org3b97acb">Conclusion</h2>



<p>Emacs is a highly dynamic, easily extensible and well documented text based system with good predefined text editing facilities. There are also bad things about Emacs, but I will leave it for another day.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
