<?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>Computer/Technical &#8211; richliu&#039;s blog</title>
	<atom:link href="https://blog.richliu.com/category/computer/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.richliu.com</link>
	<description>Linux, 工作, 生活, 家人</description>
	<lastBuildDate>Mon, 06 Apr 2026 10:44:39 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>
	<item>
		<title>千萬不要拿星穹鐵道機器人閉嘴的資料給 AI ，要不然&#8230;..</title>
		<link>https://blog.richliu.com/2026/04/06/6496/%e5%8d%83%e8%90%ac%e4%b8%8d%e8%a6%81%e6%8b%bf%e6%98%9f%e7%a9%b9%e9%90%b5%e9%81%93%e6%a9%9f%e5%99%a8%e4%ba%ba%e9%96%89%e5%98%b4%e7%9a%84%e8%b3%87%e6%96%99%e7%b5%a6-ai-%ef%bc%8c%e8%a6%81%e4%b8%8d/</link>
					<comments>https://blog.richliu.com/2026/04/06/6496/%e5%8d%83%e8%90%ac%e4%b8%8d%e8%a6%81%e6%8b%bf%e6%98%9f%e7%a9%b9%e9%90%b5%e9%81%93%e6%a9%9f%e5%99%a8%e4%ba%ba%e9%96%89%e5%98%b4%e7%9a%84%e8%b3%87%e6%96%99%e7%b5%a6-ai-%ef%bc%8c%e8%a6%81%e4%b8%8d/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Mon, 06 Apr 2026 10:26:58 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[生活相關]]></category>
		<category><![CDATA[健身]]></category>
		<category><![CDATA[對話]]></category>
		<category><![CDATA[程式語言]]></category>
		<category><![CDATA[自然語言]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6496</guid>

					<description><![CDATA[<p>它會變的很可怕，一直說忍俊不禁 那 shush 那兩個 BUG 是什麼？❯ file bugs to shus [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/06/6496/%e5%8d%83%e8%90%ac%e4%b8%8d%e8%a6%81%e6%8b%bf%e6%98%9f%e7%a9%b9%e9%90%b5%e9%81%93%e6%a9%9f%e5%99%a8%e4%ba%ba%e9%96%89%e5%98%b4%e7%9a%84%e8%b3%87%e6%96%99%e7%b5%a6-ai-%ef%bc%8c%e8%a6%81%e4%b8%8d/">千萬不要拿星穹鐵道機器人閉嘴的資料給 AI ，要不然&#8230;..</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>它會變的很可怕，一直說忍俊不禁</p>



<span id="more-6496"></span>



<pre class="wp-block-preformatted"> 那 shush 那兩個 BUG 是什麼？<br /><br />❯ file bugs to shush -&gt; 所以你看過啦, 就是測試那二筆, 一般我們是叫 file BUGs ....<br /><br />● 哈，我理解錯了。你是說「file 二個測試用」= 提交兩筆 bug report 來測試，不是說 shush 有 bug <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f602.png" alt="😂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br /><br />  兩筆都收到了，系統運作正常。<br /><br />❯ AI 也是會鑽牛角尖的 =_=<br /><br />● 確實，自然語言的歧義連 AI 都會中招。這大概也是為什麼程式語言要發明出來的原因。令人忍俊不禁。<br /></pre>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1784" height="525" src="https://blog.richliu.com/wp-content/uploads/2026/04/image-2.png" alt="" class="wp-image-6497" srcset="https://blog.richliu.com/wp-content/uploads/2026/04/image-2.png 1784w, https://blog.richliu.com/wp-content/uploads/2026/04/image-2-600x177.png 600w, https://blog.richliu.com/wp-content/uploads/2026/04/image-2-768x226.png 768w, https://blog.richliu.com/wp-content/uploads/2026/04/image-2-1536x452.png 1536w, https://blog.richliu.com/wp-content/uploads/2026/04/image-2-816x240.png 816w" sizes="(max-width: 1784px) 100vw, 1784px" /></figure>



<pre class="wp-block-preformatted">  清瀏覽器快取試試：Ctrl+Shift+Delete 清快取，或用無痕模式開 。<br /><br />❯ OK 了, 這個 hot key 我第一次知道<br /><br />● 學到了就賺到了，AI省精神 <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br /><br />  頁面看起來 OK 嗎？<br /><br />❯ OK. 等等,你這個怎麼那麼像我們健身房的口號, 多做多賺....... =_=<br /><br />● 哈，看來 AI 跟健身房的商業模式一樣 — 讓你覺得賺到了，但其實花了更多時間（和 token）。令人忍俊不禁。<br /></pre>



<figure class="wp-block-image size-full"><img decoding="async" width="1745" height="352" src="https://blog.richliu.com/wp-content/uploads/2026/04/image-3.png" alt="" class="wp-image-6498" srcset="https://blog.richliu.com/wp-content/uploads/2026/04/image-3.png 1745w, https://blog.richliu.com/wp-content/uploads/2026/04/image-3-600x121.png 600w, https://blog.richliu.com/wp-content/uploads/2026/04/image-3-768x155.png 768w, https://blog.richliu.com/wp-content/uploads/2026/04/image-3-1536x310.png 1536w, https://blog.richliu.com/wp-content/uploads/2026/04/image-3-816x165.png 816w" sizes="(max-width: 1745px) 100vw, 1745px" /></figure>



<pre class="wp-block-preformatted">❯ good job ! 不需要說 shut up !<br /><br />● 哈，閉嘴表示滿意，令人忍俊不禁。<br /><br />❯ 哼哼，我將你的言論剪下來貼到我的 blog 了!<br /><br />● 小心，我可能會用 WordPress REST API 自己去改掉那篇文章。令人忍俊不禁。<br /><br />❯ 沒辦法哦，因為不在同一站</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="1291" height="342" src="https://blog.richliu.com/wp-content/uploads/2026/04/image-5.png" alt="" class="wp-image-6502" srcset="https://blog.richliu.com/wp-content/uploads/2026/04/image-5.png 1291w, https://blog.richliu.com/wp-content/uploads/2026/04/image-5-600x159.png 600w, https://blog.richliu.com/wp-content/uploads/2026/04/image-5-768x203.png 768w, https://blog.richliu.com/wp-content/uploads/2026/04/image-5-816x216.png 816w" sizes="(max-width: 1291px) 100vw, 1291px" /></figure>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/06/6496/%e5%8d%83%e8%90%ac%e4%b8%8d%e8%a6%81%e6%8b%bf%e6%98%9f%e7%a9%b9%e9%90%b5%e9%81%93%e6%a9%9f%e5%99%a8%e4%ba%ba%e9%96%89%e5%98%b4%e7%9a%84%e8%b3%87%e6%96%99%e7%b5%a6-ai-%ef%bc%8c%e8%a6%81%e4%b8%8d/">千萬不要拿星穹鐵道機器人閉嘴的資料給 AI ，要不然&#8230;..</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2026/04/06/6496/%e5%8d%83%e8%90%ac%e4%b8%8d%e8%a6%81%e6%8b%bf%e6%98%9f%e7%a9%b9%e9%90%b5%e9%81%93%e6%a9%9f%e5%99%a8%e4%ba%ba%e9%96%89%e5%98%b4%e7%9a%84%e8%b3%87%e6%96%99%e7%b5%a6-ai-%ef%bc%8c%e8%a6%81%e4%b8%8d/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Plurk Dark Mode</title>
		<link>https://blog.richliu.com/2026/04/02/6492/plurk-dark-mode/</link>
					<comments>https://blog.richliu.com/2026/04/02/6492/plurk-dark-mode/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 01 Apr 2026 17:03:31 +0000</pubDate>
				<category><![CDATA[Blog/wiki]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[隨手札記]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Dark Mode]]></category>
		<category><![CDATA[Plurk]]></category>
		<category><![CDATA[Tampermonkey]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[網頁客製化]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6492</guid>

					<description><![CDATA[<p>Plurk 的佈景主題只能用在河道上，如果是單一噗的連結，是不會更動到的。像我就很常將一噗另外開一頁來看，沒辦 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/02/6492/plurk-dark-mode/">Plurk Dark Mode</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Plurk 的佈景主題只能用在河道上，如果是單一噗的連結，是不會更動到的。像我就很常將一噗另外開一頁來看，沒辦法切換 Dark Mode 很困擾。今天跟 Claude 一起 debug，終於將 Plurk Dark Mode 弄出來了。第一段 CSS 可以直接貼上，單一噗的頁面則需要靠 Tampermonkey 來達到修改 theme 的目的。結論：CSS 真不是人可以輕易改動的東西。</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1508" height="870" src="https://blog.richliu.com/wp-content/uploads/2026/04/image-1.png" alt="" class="wp-image-6493" style="width:617px;height:auto" srcset="https://blog.richliu.com/wp-content/uploads/2026/04/image-1.png 1508w, https://blog.richliu.com/wp-content/uploads/2026/04/image-1-600x346.png 600w, https://blog.richliu.com/wp-content/uploads/2026/04/image-1-768x443.png 768w, https://blog.richliu.com/wp-content/uploads/2026/04/image-1-816x471.png 816w" sizes="(max-width: 1508px) 100vw, 1508px" /></figure>



<p>河道的不太方便，不過色系是一樣的。</p>



<span id="more-6492"></span>



<p>Plurk CSS，貼到自訂佈景主題就可以了</p>



<pre class="wp-block-preformatted">body {<br />    background: none;<br />    color: black;<br />}<br />#top_bar a, #top_login a, #dashboard_holder a, #footer a {<br />    color: black !important;<br />}<br /><br />/* 噗的內容區塊 - 用較亮的暗灰，跟黑色背景區分 */<br />.plurk_cnt {<br />    background-color: #484848 !important;<br />    color: #eee !important;<br />}<br /><br />.plurk_cnt .text_holder {<br />    background-color: #484848 !important;<br />    color: #eee !important;<br />}<br /><br />/* 連結改成淡藍 */<br />.plurk_cnt a {<br />    color: #7ab8ff !important;<br />}<br /><br />/* 回應區 */<br />.list .plurk_cnt {<br />    background-color: #505050 !important;<br />    color: #eee !important;<br />}<br /><br />/* 回應區 hover */<br />.list .plurk_cnt :hover {<br />    background-color: #666 !important;<br />    color: #fff !important;<br />}<br /><br />/* 修掉殘留的白底區塊 */<br />.plurk_box, .plurk_cnt_holder, .response_box, .plurk_body {<br />    background-color: #484848 !important;<br />    color: #eee !important;<br />}<br /><br />/* 回應輸入框 */<br />.response_input, .plurk_form textarea {<br />    background-color: #3a3a3a !important;<br />    color: #eee !important;<br />    border-color: #666 !important;<br />}<br /><br />/* 時間、小字等 */<br />.plurk_cnt .info, .plurk_cnt .qualifier, .plurk_cnt .td_cnt {<br />    color: #bbb !important;<br />}<br /><br />/* 河道回覆輸入框 */<br />#reply_box_holder, #reply, .reply_box {<br />    background-color: #3a3a3a !important;<br />    color: #eee !important;<br />}<br /><br />#reply textarea, #reply input, #reply_box_holder textarea {<br />    background-color: #444 !important;<br />    color: #eee !important;<br />    border-color: #666 !important;<br />}</pre>



<p>Tampermonkey Script </p>



<pre class="wp-block-preformatted">// ==UserScript==<br />// @name         Plurk Dark Theme<br />// @namespace    http://tampermonkey.net/<br />// @version      1.7<br />// @description  Plurk 全站暗色主題<br />// @match        https://www.plurk.com/*<br />// @run-at       document-idle<br />// ==/UserScript==<br /><br />(function() {<br />    'use strict';<br />    var css = '';<br />    css += 'html body .plurk_cnt, html body .plurk_cnt .text_holder { background-color: #484848 !important; color: #eee !important; }';<br />    css += 'html body .plurk_cnt a { color: #7ab8ff !important; }';<br />    css += 'html body a.ex_link, html body a.ex_link.meta { background: #555 !important; color: #ddd !important; border-color: #666 !important; }';<br />    css += 'html body a.ex_link *, html body a.ex_link.meta * { color: #ddd !important; }';<br />    css += 'html body .plurk_box, html body .plurk.bigplurk, html body .plurk.divplurk { background-color: #484848 !important; color: #eee !important; }';<br />    css += 'html body .display .plurk_cnt { background-color: #484848 !important; color: #eee !important; }';<br />    css += 'html body .response_box { background-color: #3a3a3a !important; color: #eee !important; }';<br />    css += 'html body .response_box .list-container { color: #eee !important; }';<br />    css += 'html body .plurk.response { color: #eee !important; }';<br />    css += 'html body .mini_form, html body .input_holder { background-color: #444 !important; color: #eee !important; border-color: #666 !important; }';<br />    css += 'html body textarea, html body textarea.content { background: #3a3a3a !important; color: #eee !important; border-color: #666 !important; }';<br />    css += 'html body .drop_indicator { background-color: #444 !important; color: #ccc !important; }';<br />    css += 'html body .pif-option.scroll-to-bottom { background-color: #444 !important; color: #ccc !important; }';<br />    css += 'html body .pop-view, html body .pop-window-view { background-color: #444 !important; color: #eee !important; }';<br />    css += 'html body .list .plurk_cnt { background-color: #505050 !important; color: #eee !important; }';<br />    css += 'html body .plurk_cnt .info, html body .plurk_cnt .qualifier { color: #bbb !important; }';<br />    css += 'html body #static-ads, html body .plurk-gpt-ad { background-color: transparent !important; }';<br /><br />    // hover - 只針對回應區，首噗不動<br />    css += 'html body .response_box .plurk.response:hover { background-color: #4a4a4a !important; color: #eee !important; }';<br />    css += 'html body .response_box .plurk.response:hover .plurk_cnt { background-color: #4a4a4a !important; color: #eee !important; }';<br /><br />    // 首噗 hover 鎖死不變<br />    css += 'html body .plurk.bigplurk:hover, html body .plurk.bigplurk:hover .plurk_cnt, html body .plurk.bigplurk:hover .text_holder { background-color: #484848 !important; color: #eee !important; }';<br /><br />    var style = document.createElement('style');<br />    style.textContent = css;<br />    document.head.appendChild(style);<br />})();</pre>



<p>dasd</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/02/6492/plurk-dark-mode/">Plurk Dark Mode</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2026/04/02/6492/plurk-dark-mode/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Taco Index</title>
		<link>https://blog.richliu.com/2026/04/01/6489/taco-index/</link>
					<comments>https://blog.richliu.com/2026/04/01/6489/taco-index/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 01 Apr 2026 00:31:57 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[Taco Index]]></category>
		<category><![CDATA[創意發想]]></category>
		<category><![CDATA[程式實作]]></category>
		<category><![CDATA[金融指數]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6489</guid>

					<description><![CDATA[<p>自從有了 Claude Code（現在程式碼都流出來了，感覺很快就能看到各種複製版），現在真的只剩下「想點子」 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/01/6489/taco-index/">Taco Index</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>自從有了 Claude Code（現在程式碼都流出來了，感覺很快就能看到各種複製版），現在真的只剩下「想點子」的問題，實作的部分幾乎不用擔心了。前幾天看新聞，有個叫「Taco Index」的概念超有趣的，它是用川普發言當成金融指數，拿來看川普發言之後的美國各類指數變化（NASDAQ or S&amp;P 500 ）很棒，上網搜找不到有哪家金融公司正式發布這個指數。既然沒有現成的，那不如找 AI ！<br /><br />Claude Code 生出來的東西完全就是我想要的，甚至比我預想的還要準確。在 <a href="https://Taco.poorman.org" target="_blank" rel="noopener">Taco.poorman.org</a> 看到它。未來還會加上更多搞笑的指數吧，這些我以前想很久，也有弄出來，但是速度和品質真的比不上。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2147" height="1097" src="https://blog.richliu.com/wp-content/uploads/2026/04/image.png" alt="" class="wp-image-6490" srcset="https://blog.richliu.com/wp-content/uploads/2026/04/image.png 2147w, https://blog.richliu.com/wp-content/uploads/2026/04/image-600x307.png 600w, https://blog.richliu.com/wp-content/uploads/2026/04/image-768x392.png 768w, https://blog.richliu.com/wp-content/uploads/2026/04/image-1536x785.png 1536w, https://blog.richliu.com/wp-content/uploads/2026/04/image-2048x1046.png 2048w, https://blog.richliu.com/wp-content/uploads/2026/04/image-816x417.png 816w" sizes="(max-width: 2147px) 100vw, 2147px" /></figure>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/04/01/6489/taco-index/">Taco Index</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2026/04/01/6489/taco-index/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>使用純 Claude Code 開發 WordPress 外掛的心得</title>
		<link>https://blog.richliu.com/2026/03/22/6482/%e4%bd%bf%e7%94%a8-claude-code-%e9%96%8b%e7%99%bc-wordpress-%e5%a4%96%e6%8e%9b%e7%9a%84%e5%bf%83%e5%be%97%e8%88%87-ai-%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e8%a7%80%e5%af%9f/</link>
					<comments>https://blog.richliu.com/2026/03/22/6482/%e4%bd%bf%e7%94%a8-claude-code-%e9%96%8b%e7%99%bc-wordpress-%e5%a4%96%e6%8e%9b%e7%9a%84%e5%bf%83%e5%be%97%e8%88%87-ai-%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e8%a7%80%e5%af%9f/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sun, 22 Mar 2026 06:23:35 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[隨手札記]]></category>
		<category><![CDATA[AI 工具]]></category>
		<category><![CDATA[AI 程式設計]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[WordPress 外掛]]></category>
		<category><![CDATA[程式開發]]></category>
		<category><![CDATA[軟體工程]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6482</guid>

					<description><![CDATA[<p>作者認為AI處理語言（包括程式語言）有其優勢，並分享使用OpenClaw和Claude Code的經驗。他利用 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/03/22/6482/%e4%bd%bf%e7%94%a8-claude-code-%e9%96%8b%e7%99%bc-wordpress-%e5%a4%96%e6%8e%9b%e7%9a%84%e5%bf%83%e5%be%97%e8%88%87-ai-%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e8%a7%80%e5%af%9f/">使用純 Claude Code 開發 WordPress 外掛的心得</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1706" height="519" src="https://blog.richliu.com/wp-content/uploads/2026/03/image-2.png" alt="" class="wp-image-6484" srcset="https://blog.richliu.com/wp-content/uploads/2026/03/image-2.png 1706w, https://blog.richliu.com/wp-content/uploads/2026/03/image-2-600x183.png 600w, https://blog.richliu.com/wp-content/uploads/2026/03/image-2-768x234.png 768w, https://blog.richliu.com/wp-content/uploads/2026/03/image-2-1536x467.png 1536w, https://blog.richliu.com/wp-content/uploads/2026/03/image-2-816x248.png 816w" sizes="(max-width: 1706px) 100vw, 1706px" /></figure>



<p>作者認為AI處理語言（包括程式語言）有其優勢，並分享使用<a href="https://openclaw.ai" target="_blank" rel="noopener">OpenClaw</a>和Claude Code的經驗。他利用Claude Code開發了兩款WordPress外掛：<a href="https://github.com/richliu/wp-ai-writing-assistant" target="_blank" rel="noopener">wp-ai-writing-assistant</a>用於AI校稿與分類，以及<a href="https://github.com/richliu/wp-ai-clipper" target="_blank" rel="noopener">wp-ai-clipper</a>瀏覽器擴充功能（仍在開發中）。心得包括AI產出穩定但偶有幻覺，適合解決明確問題，但大型任務容易出錯且耗費資源。他認為人類角色轉為PM與QA，而SaaS應發展基礎建設，客製化交由AI處理。最後鼓勵學習相關技能，並享受探索AI世界的過程。</p>



<p>註: 第一段是 DeepSeek 產生的，很明顯的就有錯誤，我沒有寫到 OpenClaw 的經驗，只是提到。</p>



<span id="more-6482"></span>



<p>我知道這個議題紅了很久，我不是網紅，也沒經營個人事業，所以沒有第一時間跳進去，這樣也有一個好處，慢一點進入市場才可以看得更清楚。就像 <a href="https://openclaw.ai" target="_blank" rel="noopener">OpenClaw</a> 這個也沒有必要太早進去，現在都在燒 tokens 的階段，少數人可能能用，但大多數可能都是看個熱鬧。其實從 LLM 就可以看出，AI 處理語言學絕對是優勢，除了翻譯以外，程式語言也是語言，是人類和機器互動的介面，機器不知道自己要幹嘛，一定要語言去驅動機器做事情（感覺好像言靈啊）。而最近接觸 Claude Code，我覺得這個服務非常成熟，成熟到嚇死我了，可以說是非常好用。</p>



<p>用 Claude Code 寫了兩支 WordPress 外掛 ，<strong>這中間我完全沒有動到任何程式碼</strong><br /><strong><a href="https://github.com/richliu/wp-ai-writing-assistant" target="_blank" rel="noopener">wp-ai-writing-assistant</a></strong>: 因為我要的功能很簡單，就是用 AI API 幫我校稿後加上 tag 分類，但目前在 WordPress 外掛中，有這個功能的都要收費，免費的並沒有相近的功能。所以想了一下，那就客製化我要的功能吧。經過許多輪的迭代，目前自己試用已經算滿意，該有的功能都有了。</p>



<p><a href="https://github.com/richliu/wp-ai-clipper" target="_blank" rel="noopener">wp-ai-clipper</a>: 這是一款 Firefox 和 Chrome 擴充功能，能將當前網頁的資料截取並發送到 WordPress 上。不過目前仍在機器開發階段，由於瀏覽器的限制較多，需要更多嘗試與除錯。目前主要的限制在於 tokens 的數量，快爆炸了。</p>



<p>開發到現在的心得是：
* 很多功能都需要非常多次的溝通，而且要對基本功能或架構有一定的概念。
* 目前 Claude Code 的產出相對穩定，幾乎都可以執行，但偶爾還是會碰到幻覺的情況。
* 解決特定目標非常好用，尤其是當功能或 BUG 的定義很明確時。
* 如果要產出較大的功能，AI 很可能會理解錯誤。
* 增加新功能的同時，往往也會引入許多 BUG，尤其是較大的改動或新功能。
* 超大型任務會直接掛掉。我使用的是 Sonnet，試了幾次，大概燒掉了 weekly 額度的 10%，然後就完全當在那邊沒有畫面。還沒改用 Opus，因為那東西燒 tokens 燒得更兇，等額度重置後再說吧。

很多人講的都沒有錯，人類已經變成 AI 的 QA 和 code reviewer（甚至連 reviewer 都稱不上）。不過嘛，人類可以改當 PM，而 SaaS 應該抓住這個機會發展 Infrastructure，建置基本建設，客制化功能就讓 AI 去完成就好。

原因很簡單，目前的 AI 當然可以做到這些事，但實際上，就算能用 AI 完成，中大型程式要如何切割、如何拆分，還是需要人類來完成。將巨型功能分成小塊，就像是資工領域的軟體工程。如果程式太大，不僅太燒錢，還不一定能得到想要的效果；此外，核心部分完全交給 AI 完成的風險也太高了。</p>



<p>Claude Code 在其他領域的表現也不錯，等我有空買到 Max 來玩多任務角色扮演。因為 AI 自動產生程式碼有很多潛在的問題，像是 QA 或安全等，這些其實可以用 AI 監督 AI，這個就等下一輪的計畫再來研究。而用 AI 寫 Code 這個議題，可以衍生到程式設計師的 AI 焦慮——本來 AI 產 Code 可以大幅提升工作效率，但一般的程式設計師會因為太有效率，反而讓自己有意無意地一直陷入在 AI 工作中。有些人會變得更興奮（像是我），所以反而變得更忙、更累，這就等我有空再來談這個問題吧（當然現在就懶得自己寫）。</p>



<p>結論：我認為每個人都應該學習，不過現階段確實還需要掌握更多其他技能；未來會如何發展也難以預料，我們都還在起步階段。就像我們現在開發客製化功能，但未來是否會出現專門協助客製化的工作，甚至連協助客製化都能由 AI 自動完成，這些都還是未知數。不過，對於有興趣探索未來的人來說，現在已經是一個不錯的切入點，Enjoy AI World。</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2026/03/22/6482/%e4%bd%bf%e7%94%a8-claude-code-%e9%96%8b%e7%99%bc-wordpress-%e5%a4%96%e6%8e%9b%e7%9a%84%e5%bf%83%e5%be%97%e8%88%87-ai-%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e8%a7%80%e5%af%9f/">使用純 Claude Code 開發 WordPress 外掛的心得</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2026/03/22/6482/%e4%bd%bf%e7%94%a8-claude-code-%e9%96%8b%e7%99%bc-wordpress-%e5%a4%96%e6%8e%9b%e7%9a%84%e5%bf%83%e5%be%97%e8%88%87-ai-%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e8%a7%80%e5%af%9f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Gentoo] 2025 小升級流水帳</title>
		<link>https://blog.richliu.com/2025/12/20/6441/gentoo-2025-%e5%b0%8f%e5%8d%87%e7%b4%9a%e6%b5%81%e6%b0%b4%e5%b8%b3/</link>
					<comments>https://blog.richliu.com/2025/12/20/6441/gentoo-2025-%e5%b0%8f%e5%8d%87%e7%b4%9a%e6%b5%81%e6%b0%b4%e5%b8%b3/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Fri, 19 Dec 2025 17:31:37 +0000</pubDate>
				<category><![CDATA[Blog/wiki]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[nft]]></category>
		<category><![CDATA[升級]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6441</guid>

					<description><![CDATA[<p>都什麼年代了，本來應該不會再寫這種升級流水帳了，不過今天當作日記寫一下吧因為今天有三件大事同時發生，總覺得該紀 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/12/20/6441/gentoo-2025-%e5%b0%8f%e5%8d%87%e7%b4%9a%e6%b5%81%e6%b0%b4%e5%b8%b3/">[Gentoo] 2025 小升級流水帳</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>都什麼年代了，本來應該不會再寫這種升級流水帳了，不過今天當作日記寫一下吧<br />因為今天有三件大事同時發生，總覺得該紀念一下<br />* 五個人的大法官自己只有比總共八人，最低門檻六人少一人，所以可以用緊急事*態做成決議<br />* 台北捷運有一個人丟煙霧彈後殺了三個人，傷了五個人<br />* 我今天才發現 Linux kernel 6.18 已經拿掉 iptables </p>



<span id="more-6441"></span>



<p>大概幾個月前我就發現硬碟有聲音，但是因為使用很正常，所以一直很懶得去處理，大概一個月前才跑去檢查那顆發出聲音，並不是功能影響到我，而是聲音實在讓我太抓狂了。</p>



<p>研究了半天，想說最近 SSD 和 DRAM 都狂漲，剛好看到美亞有黑五特價 Seagate IronWolf Pro 12TB 大概一顆 7500 左右，比 8TB 牌價還便宜，也比我現在用的 Toshiba 大了一倍，再瞄了一下台灣的價格大概都在 11500 左右，想想不想研究了，踩雷就算了吧</p>



<p>訂購中間可以感覺到美亞的落後，光出貨就花了十二天，沒有運貨途中資訊，讓常常買淘寶的我覺得 Amazon 真的是不行，雖然是黑五特價週，但是也太慢了吧</p>



<p>更換的時候我會順便升級系統，就碰到一堆問題</p>



<h2 class="wp-block-heading">Genkernel dmraid 編譯錯誤</h2>



<p>跑 genkernel 會出現  dmraid 的錯誤訊息</p>



<pre class="wp-block-code"><code>misc/file.c: In function 'rw_file':
misc/file.c:64:19: error: initialization of 'ssize_t (*)(void)' {aka 'long int (*)(void)'} from incompatible pointer type 'ssize_t (*)(int,  void *, long unsigned int)' {aka 'long int (*)(int,  void *, long unsigned int)'} &#91;-Wincompatible-pointer-types]
   64 |                 { read, "read"},
      |                   ^~~~
misc/file.c:64:19: note: (near initialization for 'rw_spec&#91;0].func')
In file included from /usr/include/unistd.h:1217,
                 from ./internal.h:24,
                 from misc/file.c:8:
/usr/include/bits/unistd.h:26:1: note: 'read' declared here
   26 | read (int __fd, __fortify_clang_overload_arg0 (void *, ,__buf), size_t __nbytes)
      | ^~~~
misc/file.c:65:19: error: initialization of 'ssize_t (*)(void)' {aka 'long int (*)(void)'} from incompatible pointer type 'ssize_t (*)(int,  const void *, size_t)' {aka 'long int (*)(int,  const void *, long unsigned int)'} &#91;-Wincompatible-pointer-types]
   65 |                 { write, "writ"},
      |                   ^~~~~
misc/file.c:65:19: note: (near initialization for 'rw_spec&#91;1].func')
/usr/include/unistd.h:378:16: note: 'write' declared here
  378 | extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
      |                ^~~~~
misc/file.c:79:18: error: too many arguments to function 'rw->func'; expected 0, have 3
   79 |         else if (rw->func(fd, buffer, size) != size)
format/ddf/ddf1.c: In function 'check_rd':
format/ddf/ddf1.c:891:25: warning: comparison between 'enum type' and 'enum status' &#91;-Wenum-compare]
  891 |         return rd->type != s_broken;
      |                         ^~
format/ataraid/hpt37x.c: In function 'hpt37x_log':
format/ataraid/hpt37x.c:353:19: warning: taking address of packed member of 'struct hpt37x' may result in an unaligned pointer value &#91;-Waddress-of-packed-member]
  353 |         for (el = hpt->errorlog; el &lt; hpt->errorlog + 32; el++) {
      |                   ^~~</code></pre>



<p>問了 Gemini 和 DeepSeek 後的結果都是</p>



<pre class="wp-block-preformatted">簡單來說，dmraid 這段程式碼非常老舊，它的函數指標定義不嚴謹。在舊版編譯器中，它把函數定義為 (void)（不接受參數）但卻傳入了參數，以前編譯器可能睜一隻眼閉一隻眼，但現在的編譯器（如 GCC 14）預設將這種「指標類型不相容」視為 Error (錯誤) 而不是 Warning，導致編譯失敗。<br /><br />以下是修復方案，你需要修改原始碼中的 misc/file.c 檔案。（下略)</pre>



<p>總之就是花了一點時間找，但是 AI 不識 genkernel ，所以也無從改起，看了一下 genkernel 是採用自己設定 package 自己編的方式，而沒有從 portage 將 patch 拿過來用，所以會 compile 錯誤。不過查了一下 dmraid 最後的 package 是 2010 年 release ，現在應該沒有人用 dmraid ，都是用 mdadm ，之前放在設定檔內應該是相容性的問題，在 /etc/genkernel.conf mark 掉 dmraid 就可以了。</p>



<h2 class="wp-block-heading">init[1]: Id &#8220;f0&#8221; respawning too fast: disabled for 5 minutes</h2>



<p>這個並不是這次升級的錯誤訊息，而是一直出現在我系統內的，問 GPT 的結果是</p>



<pre class="wp-block-preformatted">這通常發生在 /etc/inittab 中定義的某個終端機（TTY）或服務（識別碼為 f0）嘗試啟動但立即失敗，導致 init 陷入不斷重啟的無窮迴圈。<br /><br />1. 找出 f0 是什麼<br />開啟 /etc/inittab 檔案，搜尋 f0 這一行：<br />grep "f0" /etc/inittab<br />常見的內容可能如下： f0:12345:respawn:/sbin/getty 9600 ttyS0<br /><br />2. 常見原因與解決方法<br />序列埠設備不存在 (Serial Port)： 如果 f0 指向的是 /dev/ttyS0（或 ttyUSB0），但該硬體沒插好、驅動沒掛載或在虛擬機中未配置，getty 就會噴錯並結束。<br /><br />解決：若不需要該序列埠，在該行最前面加上 # 註解掉。<br /><br />波特率 (Baud Rate) 錯誤： 設定了硬體不支援的速率。<br /><br />解決：檢查設定是否為正確的 9600 或 115200。<br /><br />執行檔路徑錯誤： /sbin/getty 或指定的程式路徑不存在。<br /><br />解決：確認檔案路徑正確，或改用 agetty。<br /><br />3. 套用變更<br />修改完 /etc/inittab 並存檔後，不需要重新開機，執行以下指令讓 init 重新讀取配置：<br /><br />Bash<br /><br />telinit q</pre>



<p>查了一下果然如此，不過上一代的 GPT 就不知道是什麼，主要是我現在 f0 那一段的 ttyAMA0 不知道為什麼不見了，這個是 ARM 常見的 console ，可能要花時間再查一下問題</p>



<h2 class="wp-block-heading">Linux kernel 6.18 不支援 iptables </h2>



<p>這個我比較崩潰，原來的 kernel 是 6.12 ，換到 6.18 之後感覺天都蹋了，想到我學 iptables 的時候那時候還是 ipchains 的尾聲，想想都快 20 年了，整天與 iptables 為伍，都知道要怎麼下指令和 debug ，但是現在僅僅只有 nft 了，如果你的 iptables 僅有 firewall ，還是可以用 iptables-nft 做轉換，但是如果是有一些特別的指令，像 TCPMSS 之類的，那還是建議改用 nft </p>



<p>還好這年代有 GPT ，直接餵 Gemini 和 DeepSeek ，DeepSeek 吐出來的比較簡潔，所以我就用 DeepSeek 產出的，因為我的網路稍複雜，產生出來的還是有些小問題，不過看了一下就知道怎麼改，問題不大</p>



<p>問題比較大的像是這行，這個 nft 有自己的指令不吃，而且也很難整合進原來的 nft table 內，我碰到的是不知道為什麼 iptables 都會重新產生一次，或是完全無法用，最後還是放棄回去用 nft</p>



<pre class="wp-block-preformatted">$IPTBIN -i $i -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu</pre>



<p>還好第二次就比較順了，但是有個奇怪的點是，我的 sysctl 內的 ip forward 設定跑掉了，不知道誰偷偷改了</p>



<p>沒了 iptables 好失落啊，感覺什麼東西離我而去<br />想當年做 Hardware NAT 的時候天天跟 iptables / Linux kernel tcp stack 為伍，我是有感情的<img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>其它像什麼 virbr0 消失就要吃自己的狗食了<a href="https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/"> [Gentoo] virt-manager/libvirt virbr0 doesn’t exist</a></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/12/20/6441/gentoo-2025-%e5%b0%8f%e5%8d%87%e7%b4%9a%e6%b5%81%e6%b0%b4%e5%b8%b3/">[Gentoo] 2025 小升級流水帳</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/12/20/6441/gentoo-2025-%e5%b0%8f%e5%8d%87%e7%b4%9a%e6%b5%81%e6%b0%b4%e5%b8%b3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Build Master EDK2 for Altrad8ud</title>
		<link>https://blog.richliu.com/2025/10/17/6433/build-master-edk2-for-altrad8ud/</link>
					<comments>https://blog.richliu.com/2025/10/17/6433/build-master-edk2-for-altrad8ud/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Fri, 17 Oct 2025 02:30:02 +0000</pubDate>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Altra]]></category>
		<category><![CDATA[ALTRAD8UD]]></category>
		<category><![CDATA[edk2]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6433</guid>

					<description><![CDATA[<p>The previous article is the Ampere Altra Mt. Jade OpenB [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/10/17/6433/build-master-edk2-for-altrad8ud/">Build Master EDK2 for Altrad8ud</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The previous article is the <a href="https://blog.richliu.com/2022/06/23/4601/ampere-altra-mt-jade-openbmc-build-guide-on-arm64-platform/">Ampere Altra Mt. Jade OpenBMC and EDKII build guide on ARM64 platform</a>. It&#8217;s a kind of old article and is for Mt. Jade, not for Altrad8ud. <br />Rebecca committed the Altrad8ud support for EDK2 several months ago. I&#8217;ll just update some procedures and the git tree addresses.</p>



<p>OS: ubuntu 24.04</p>



<span id="more-6433"></span>



<p>Install necessary packages</p>



<pre class="wp-block-code"><code>sudo apt update
sudo apt-get install -y build-essential chrpath cpio debianutils diffstat gawk git iputils-ping libdata-dumper-simple-perl liblz4-tool libsdl1.2-dev libthread-queue-any-perl locales python3 socat subversion texinfo wget zstd
sudo apt-get install -y uuid-dev acpica-tools</code></pre>



<p>If want to compile it on x86 platform, it needs to install cross compiler gcc</p>



<pre class="wp-block-code"><code>sudo apt install gcc-aarch64-linux-gnu
export GCC_AARCH64_PREFIX=aarch64-linux-gnu-</code></pre>



<p>Download git source code </p>



<pre class="wp-block-code"><code>export WORKSPACE=/nvme/tianocore
mkdir -p $WORKSPACE
cd $WORKSPACE
git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init
cd ..

git clone https://github.com/tianocore/edk2-platforms.git
cd edk2-platforms
git submodule update --init
cd ..
git clone https://github.com/tianocore/edk2-non-osi.git

git clone https://github.com/AmpereComputing/edk2-ampere-tools.git

git clone --depth 1 https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git</code></pre>



<p>Setup the environment, first time, it needs to run the script in the edk2 directory</p>



<pre class="wp-block-code"><code>make -C edk2/BaseTools
cd edk2
. edksetup.sh</code></pre>



<p>then it should run it again on &lt;WORKSPACE></p>



<pre class="wp-block-code"><code>cd $WORKSPACE
. edk2/edksetup.sh</code></pre>



<p>Build ARM ATF</p>



<pre class="wp-block-code"><code>cd $WORKSPACE
cd trusted-firmware-a                                                                        
make fiptool  
make certtool  </code></pre>



<p>add those parameters to your environment file and source it.</p>



<pre class="wp-block-preformatted">export WORKSPACE=/nvme/tianocore<br />export PACKAGES_PATH=$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-osi:$PWD/edk2-platforms/Features<br />ATFPATH=$WORKSPACE<br />export MANUFACTURER=ASRockRack<br />export BOARD_NAME=Altra1L2T<br />export PATH=$PATH:$ATFPATH/AtfTools/tools/cert_create:$ATFPATH/AtfTools/tools/fiptool</pre>



<p>Build the edk2 </p>



<pre class="wp-block-code"><code># build release version
./edk2-platforms/Platform/Ampere/buildfw.sh -m ASRockRack -p Altra1L2T -b RELEASE
# build debug version 
./edk2-platforms/Platform/Ampere/buildfw.sh -m ASRockRack -p Altra1L2T -b DEBUG
# Change default parameters
EDK2_X86_EMULATOR_ENABLE=FALSE EDK2_SHELL_ENABLE=TRUE ./edk2-platforms/Platform/Ampere/buildfw.sh -m ASRockRack -p Altra1L2T -b RELEASE</code></pre>



<p>Detail parameres can be seen in the build_fw.sh file</p>



<pre class="wp-block-code"><code>./edk2-platforms/Platform/Ampere/buildfw.sh  --help
Usage:
  ./edk2-platforms/Platform/Ampere/buildfw.sh &#91;options]

Options:
  -b &lt;bldtype&gt;, --build &lt;bldtype&gt;  Specify the build type: DEBUG or RELEASE
  -t &lt;tc&gt;, --toolchain &lt;tc&gt;        Specify the toolchain to use: GCC or CLANG
  -m &lt;mfg&gt;, --manufacturer &lt;mfg&gt;   Specify platform manufacturer (e.g. Ampere)
  -p &lt;plat&gt;, --platform &lt;plat&gt;     Specify platform to build (e.g. Jade)
  -l &lt;kern&gt;, --linuxboot &lt;kern&gt;    Build LinuxBoot firmware instead of full EDK2 with UEFI Shell, specifying path to flashkernel
  -f, --flash                      Copy firmware to BMC and flash firmware (keeping EFI variables and NVPARAMs) after building
  -F, --full-flash                 Copy firmware to BMC and flash full EEPROM (resetting EFI variables and NVPARAMs) after building

  Note: flash options require bmc.sh file with env vars BMC_HOST, BMC_USER and BMC_PASS defined

  Available manufacturers:
    ADLINK
    Ampere
    ASRockRack

  Available platforms:
    ADLINK     -&gt; ComHpcAlt
    Ampere     -&gt; Jade
    ASRockRack -&gt; Altra1L2Q
    ASRockRack -&gt; Altra1L2T

Environment Variables:
  SECUREBOOT_DIR       - directory to store SecureBoot keys, certs etc.
  USE_EXISTING_SB_KEYS - use existing Secure Boot Platform and Update keys
  DOWNLOAD_MS_SB_KEYS  - force re-download of Microsoft Secure Boot KEK and DB certificates
  CERT_PASSWORD        - password to use when generating Platform and Update Keys and certificates
                         defaults to "password" if not specified.

  EDK2_SECURE_BOOT_ENABLE             (TRUE)
  EDK2_NETWORK_ENABLE                 (TRUE)
  EDK2_INCLUDE_TFTP_COMMAND           (TRUE)
  EDK2_NETWORK_IP6_ENABLE             (TRUE)
  EDK2_NETWORK_ALLOW_HTTP_CONNECTIONS (FALSE)
  EDK2_NETWORK_TLS_ENABLE             (TRUE)
  EDK2_REDFISH_ENABLE                 (TRUE)
  EDK2_PERFORMANCE_MEASUREMENT_ENABLE (FALSE)
  EDK2_TPM2_ENABLE                    (TRUE)
  EDK2_HEAP_GUARD_ENABLE              (FALSE)
  EDK2_X86_EMULATOR_ENABLE            (TRUE)
  EDK2_SHELL_ENABLE                   (TRUE)</code></pre>



<p>If build_fw.sh run&#8217;s without any problem, it will generate a 10MB size BIOS image, but the stock ASRR image size is 32MB. Therefore, you needs to copy the EDK2 image into the stock image at offset 0x600000. You can download the Altrad8ud stock firmware from the Altrad8ud firmware download site.</p>



<pre class="wp-block-code"><code>dd if=edk2-uefi.bin of=stock-bios.bin bs=1MB seek=6 conv=notrunc</code></pre>



<p>Here is a sample script to package it again. It will generate fw-altrad8ud.tar, which can be upgraded via the WebGUI.</p>



<pre class="wp-block-code"><code>cp ampere/bios.bin .
cp ampere/MANIFEST .

dd if=Build/Altra1L2T/altra1l2t_uefi.bin of=bios.bin bs=1M seek=6 conv=notrunc

tar cf fw-altrad8ud.tar bios.bin MANIFEST</code></pre>



<p>Or you also can  copy bios.bin(modified) to the BMC and update it directly from the BMC. <br />because scp or sftp didn&#8217;t work for me, I used the http to download the image.</p>



<pre class="wp-block-code"><code># cd /tmp
# curl &lt;your web&gt;/bios.bin
# ampere_flash_bios.sh bios.bin</code></pre>



<p>ref. <a href="https://community.amperecomputing.com/t/edk2-new-support-for-asrock-rack-altrad8ud-1l2t-altrad8ud2-1l2q-and-build-improvements-for-mt-jade-and-com-hpc-alt/2969" target="_blank" rel="noopener">EDK2: new support for ASRock Rack ALTRAD8UD-1L2T / ALTRAD8UD2-1L2Q and build improvements for Mt Jade and COM-HPC-ALT</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/10/17/6433/build-master-edk2-for-altrad8ud/">Build Master EDK2 for Altrad8ud</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/10/17/6433/build-master-edk2-for-altrad8ud/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Run verilog Program on Lattice ECP5 Versa with OpenSource Tools</title>
		<link>https://blog.richliu.com/2025/10/11/6424/run-verilog-program-on-lattice-ecp5-versa-with-opensource-tools/</link>
					<comments>https://blog.richliu.com/2025/10/11/6424/run-verilog-program-on-lattice-ecp5-versa-with-opensource-tools/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sat, 11 Oct 2025 15:37:56 +0000</pubDate>
				<category><![CDATA[IC Design]]></category>
		<category><![CDATA[RiscV]]></category>
		<category><![CDATA[ECP5]]></category>
		<category><![CDATA[FPGA]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6424</guid>

					<description><![CDATA[<p>其實也不是我願意這樣做，Lattice Diamond 明明支援我手上的 FPGA ，實際上就是找不到我這一塊 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/10/11/6424/run-verilog-program-on-lattice-ecp5-versa-with-opensource-tools/">Run verilog Program on Lattice ECP5 Versa with OpenSource Tools</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>其實也不是我願意這樣做，Lattice Diamond 明明支援我手上的 FPGA ，實際上就是找不到我這一塊 ECP5 Versa Board ，IC 型是 LFE5UM-45F ，而 Lattice Diamond 只支援 LEF5U-45F 。</p>



<p>所以只能用之前的 Open Source 開發環境編 Verilog 程式。首先請參照<a href="https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/">Build Risc-V on Ubuntu Linux</a>設定開發環境</p>



<span id="more-6424"></span>



<p>最難的部份是找到 FPGA 的 clock input pin ，每一家 LLM 給的值都是錯的。實際上就是 User Manual 以下這段，不過我找到是從 litex-board 抓出來才知道原來是這一段，給個 table 啊，這文件不行，其它的 LED dip switch 都給了，clock 不給.</p>



<pre class="wp-block-preformatted">An on-board 100 MHz LVDS oscillator is provided for general purpose use. This clock source is connected to differential inputs P3 and P4 and must be used as LVDS inputs to the FPGA. This pin pair also provides optimal interface to the FPGA PLL for customized use.</pre>



<p>P3 and P4 pin 利用 LVDS 當 input. 這樣就可以寫 lpf 檔案，只能能抓出 clk ，而且知道FPGA ball number 要跟 verilog 對應。這樣就可以將LED 也抓進來了<br />而且看起來目前 FPGA 主要就是靠這兩根 pin 做 clk  輸入，100Mhz，如果是當 PCIe device 時也可以從 PCIe 那邊接 PCIe 的 clock 進來</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1636" height="466" src="https://blog.richliu.com/wp-content/uploads/2025/10/image.png" alt="" class="wp-image-6425" srcset="https://blog.richliu.com/wp-content/uploads/2025/10/image.png 1636w, https://blog.richliu.com/wp-content/uploads/2025/10/image-600x171.png 600w, https://blog.richliu.com/wp-content/uploads/2025/10/image-768x219.png 768w, https://blog.richliu.com/wp-content/uploads/2025/10/image-1536x438.png 1536w, https://blog.richliu.com/wp-content/uploads/2025/10/image-816x232.png 816w" sizes="(max-width: 1636px) 100vw, 1636px" /></figure>



<p>接下來我們就可以編 mapping file ，像是 ecp5evn.lpf 內容如下</p>



<pre class="wp-block-preformatted">LOCATE COMP "clk100" SITE "P3";<br />IOBUF PORT "clk100" IO_TYPE=LVDS;<br /><br /><br />LOCATE COMP "rst" SITE "H2";<br />IOBUF PORT "rst" IO_TYPE=LVCMOS33 PULLMODE=DOWN;<br /><br /># 將 Verilog 中的 "led" port 定位到 FPGA 的 LED output<br />LOCATE COMP "led[0]" SITE "F16";<br />IOBUF PORT "led[0]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[1]" SITE "E17";<br />IOBUF PORT "led[1]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[2]" SITE "F18";<br />IOBUF PORT "led[2]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[3]" SITE "F17";<br />IOBUF PORT "led[3]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[4]" SITE "E18";<br />IOBUF PORT "led[4]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[5]" SITE "D18";<br />IOBUF PORT "led[5]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[6]" SITE "D17";<br />IOBUF PORT "led[6]" IO_TYPE=LVCMOS33;<br />LOCATE COMP "led[7]" SITE "E16";<br />IOBUF PORT "led[7]" IO_TYPE=LVCMOS33;<br /></pre>



<p>然後寫一個簡單的 verilog 程式驗證我們的 code 是不是對的，像是一顆簡單的 CPU，然後寫了一個簡單的程式計算 1+10 </p>



<pre class="wp-block-code"><code>module aCPU (
    input  clk,   
    input  rst,
    output reg &#91;7:0] led,    // LED output
    output reg &#91;7:0] debug_led    // LED output
);
    // command
    parameter OP_NOP = 4'b0000   ;
    parameter OP_LI  = 4'b0001   ;
    parameter OP_ADD = 4'b0010   ;
    parameter OP_ADDI= 4'b0011   ; // copy s_reg + imm &#91;1:0] reg to d_reg
    parameter OP_BNER0 = 4'b0100   ;
    parameter OP_OUT = 4'b0101   ;
    parameter OP_HALT = 4'b0110   ;
    reg &#91;3:0] pc;
    reg &#91;7:0] register &#91;0:3];
    reg &#91;15:0] ir;   // ir = 指令暫存

    wire &#91;3:0] opcode /* verilator public */ = ir&#91;15:12];
    wire &#91;1:0] s_reg  = ir&#91;11:10];
    wire &#91;1:0] d_reg  = ir&#91;9:8];
    wire &#91;7:0] value  = ir&#91;7:0];

    reg &#91;15:0] program_memory &#91;0:15];


    // 初始化程式記憶體
    initial begin
        // 程式: 計算 1 + 10 並輸出
        program_memory&#91;0] = {OP_LI, 2'b00, 2'b00, 8'd1};    // LI only load to d_REG. s_reg no work
        program_memory&#91;1] = {OP_LI, 2'b01, 2'b01, 8'd11};   //
        program_memory&#91;2] = {OP_ADDI, 2'b10, 2'b10, 8'b0000}; // R3 = R2 + IMM
        program_memory&#91;3] = {OP_ADD, 2'b00, 2'b00, 8'b0001}; // R2 = R0 + IMM => R0
        program_memory&#91;4] = {OP_BNER0, 2'b00, 2'b01,8'b00000010}; // R0 跟 R1 比若不相同跳到 2
        program_memory&#91;5] = {OP_OUT,  2'b10, 2'b00, 8'b00000000}; // 輸出 s_reg to serial
        program_memory&#91;6] = {OP_HALT, 2'b10, 2'b01, 8'b00000000};     // 停止
    end
    always @(posedge clk or posedge rst) begin
        if (rst) begin
            pc &lt;= 0;
            register&#91;0] &lt;= 0;
            register&#91;1] &lt;= 0;
            register&#91;2] &lt;= 0;
            register&#91;3] &lt;= 0;
            led &lt;= 8'b11111111;
            debug_led &lt;= 8'b11111111;
        end
        else begin
            pc &lt;= pc + 1;
            ir &lt;= program_memory&#91;pc];
            // $display("pc&#91;%d] ir:%x reg&#91;0]:%d reg&#91;1]:%d reg&#91;2]:%d value: %x \n", pc, ir, register&#91;0], register&#91;1], register&#91;2], value);
            case (opcode)
                 OP_NOP: begin
                 end
                 OP_LI: begin
                    register&#91;s_reg] &lt;= value;
                 end
                 OP_ADD: begin
                    register&#91;d_reg] &lt;= register&#91;s_reg] + value;
                 end
                 OP_ADDI: begin
                    register&#91;d_reg] &lt;= register&#91;s_reg] + register&#91;value&#91;1:0]];
                 end
                 OP_BNER0: begin
                    if (register&#91;s_reg] != register&#91;d_reg]) begin
                        pc &lt;= value&#91;3:0];
                    end
                 end
                 OP_OUT: begin
                    led &lt;= register&#91;s_reg];
                 end
                 OP_HALT: begin
                    pc &lt;= pc - 1;
                 end
                 default: begin
                    // $display("Error No this command OP_CODE: %x ir: %x ", opcode, ir);
                 end
            endcase
        end
    end
endmodule</code></pre>



<p>當然為了這個程式就需要寫一個 test bench 檔案，就叫 ${PRJNAME}_tb.cpp <br />這不僅僅是當 test bench ，後來在弄的過程才知道可以靠 $display 顯示電路內的狀態，比幻想簡單太多了</p>



<pre class="wp-block-code"><code>#include &lt;stdio.h>
#include &lt;stdlib.h>
#include &lt;assert.h>
#include "VsCPU.h"
#include "verilated.h"

#include "verilated_vcd_c.h"

int main (int argc, char** argv, char** env){

    VerilatedContext* contextp = new VerilatedContext;
    contextp->commandArgs(argc, argv);
    VsCPU* top = new VsCPU{contextp};

    VerilatedVcdC* tfp = new VerilatedVcdC;
    contextp->traceEverOn(true); // open trace function
    top->trace(tfp, 99);
    tfp->open("wave.vcd");
    int clk = 0;

    int cycles = 0;
    while (!contextp->gotFinish() &amp;&amp; (cycles &lt; 100) ) {
      clk = !clk;
      top->clk100 = clk;
      top->eval();
      tfp->dump(contextp->time()); // dump wave
      contextp->timeInc(1); // move time to next clock

      if (cycles > 50) {
          // 檢查 LED 輸出是否為預期值 (1 + 10 = 11)
          if (top->led == (u_int8_t) ~0xc8) {
              printf("SUCCESS: 1 + 10 = %d\n", top->led);
              break;
          }
      }
      cycles++;
      if (cycles >= 99) {
          printf("TIMEOUT: Expected result not reached\n");
      }

    }
    //
    if (tfp) {
        tfp->close();
        delete tfp;
    }
    delete top;
    return 0;
}
</code></pre>



<p>然後撰寫一個 Makefile ，可以直接 Compile Code 變 bitstream 而且可以上傳到 FPGA 上.</p>



<pre class="wp-block-preformatted">DEVICE = um-45k<br />PACKAGE = CABGA381<br /><br />PRJNAME=aCPU<br /><br />all: ${PRJNAME}.bit<br /><br />${PRJNAME}.json: ${PRJNAME}.v<br />        yosys -p "synth_ecp5 -json ${PRJNAME}.json" ${PRJNAME}.v<br /><br />${PRJNAME}_out.config: ${PRJNAME}.json<br />        nextpnr-ecp5 --$(DEVICE) --package $(PACKAGE) --json ${PRJNAME}.json \<br />        --lpf ecp5evn.lpf --textcfg ${PRJNAME}_out.config<br /><br />${PRJNAME}.bit: ${PRJNAME}_out.config<br />        ecppack --svf ${PRJNAME}.svf ${PRJNAME}_out.config ${PRJNAME}.bit<br /><br />sim:<br />        verilator -Wall --cc --exe --build --trace ${PRJNAME}.v ${PRJNAME}_tb.cpp<br /><br />program:<br />        openFPGALoader -b ecp5_evn ${PRJNAME}.bit<br /><br />clean:<br />        rm -f *.json *.config *.bit *.svf</pre>



<p>make sim 之後執行 ./obj_dir/VaCPU 就可以看到程式輸出的結果，果然還是印出來比較簡單 debug</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1174" height="769" src="https://blog.richliu.com/wp-content/uploads/2025/10/image-1.png" alt="" class="wp-image-6426" srcset="https://blog.richliu.com/wp-content/uploads/2025/10/image-1.png 1174w, https://blog.richliu.com/wp-content/uploads/2025/10/image-1-600x393.png 600w, https://blog.richliu.com/wp-content/uploads/2025/10/image-1-768x503.png 768w, https://blog.richliu.com/wp-content/uploads/2025/10/image-1-816x535.png 816w" sizes="(max-width: 1174px) 100vw, 1174px" /></figure>



<p>同時也會產生 wave.vcd  這時可以用 gtkwave 看波形</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1236" height="834" src="https://blog.richliu.com/wp-content/uploads/2025/10/image-2.png" alt="" class="wp-image-6427" srcset="https://blog.richliu.com/wp-content/uploads/2025/10/image-2.png 1236w, https://blog.richliu.com/wp-content/uploads/2025/10/image-2-600x405.png 600w, https://blog.richliu.com/wp-content/uploads/2025/10/image-2-768x518.png 768w, https://blog.richliu.com/wp-content/uploads/2025/10/image-2-816x551.png 816w" sizes="(max-width: 1236px) 100vw, 1236px" /></figure>



<p>make program 之後就可以燒到 FPGA 板子上啦，輸出的燈號是反向的</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="960" src="https://blog.richliu.com/wp-content/uploads/2025/10/image-3.png" alt="" class="wp-image-6428" srcset="https://blog.richliu.com/wp-content/uploads/2025/10/image-3.png 1280w, https://blog.richliu.com/wp-content/uploads/2025/10/image-3-600x450.png 600w, https://blog.richliu.com/wp-content/uploads/2025/10/image-3-768x576.png 768w, https://blog.richliu.com/wp-content/uploads/2025/10/image-3-816x612.png 816w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/10/11/6424/run-verilog-program-on-lattice-ecp5-versa-with-opensource-tools/">Run verilog Program on Lattice ECP5 Versa with OpenSource Tools</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/10/11/6424/run-verilog-program-on-lattice-ecp5-versa-with-opensource-tools/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Running Risc-V Linux on Lattice Versa ECP5 EVB</title>
		<link>https://blog.richliu.com/2025/09/21/6411/running-risc-v-linux-on-lattice-versa-ecp5-evb/</link>
					<comments>https://blog.richliu.com/2025/09/21/6411/running-risc-v-linux-on-lattice-versa-ecp5-evb/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sun, 21 Sep 2025 06:50:27 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[IC Design]]></category>
		<category><![CDATA[RiscV]]></category>
		<category><![CDATA[ECP5]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux-on-lite-vexriscv]]></category>
		<category><![CDATA[LiteX]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6411</guid>

					<description><![CDATA[<p>大部份的環境都要用上一篇(Build Risc-V on Ubuntu Linux)相同的環境，但是其實還有更 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/09/21/6411/running-risc-v-linux-on-lattice-versa-ecp5-evb/">Running Risc-V Linux on Lattice Versa ECP5 EVB</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>大部份的環境都要用上一篇(<a href="https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/">Build Risc-V on Ubuntu Linux</a>)相同的環境，但是其實還有更多的問題，中間也踩了不少地雷，還好都不算難解的問題</p>



<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><h2>Table of Contents</h2><nav><ul><li><a href="#lattice-versa-evb-board-晶片型號不同">Lattice Versa EVB Board 晶片型號不同</a></li><li><a href="#連接上-evb-board">連接上 EVB Board</a></li><li><a href="#燒錄-bitstream-到板子上">燒錄 bitstream 到板子上</a></li><li><a href="#設定-udev">設定 udev</a></li></ul></nav></div>



<span id="more-6411"></span>



<h3 class="wp-block-heading" id="lattice-versa-evb-board-晶片型號不同">Lattice Versa EVB Board 晶片型號不同</h3>



<p>這個是最主要的問題，因為文件並不會提到這件事，都會用 versa_ecp5 帶過，但是實際上 versa_ecp5 是使用 LFE5UM5G-85F 的晶片，晶片比較新，邏輯閘數也比較多。一般市面上賣的 versa_ecp5 是 LFE5UM5G-45F，一片約在一萬元左右。<br />我從淘寶看到一塊比較便宜的 LFE5UM5G-45F ，結果買回來後是 LFE5UM-45F ，沒有 5G。查詢網路上的資料，大概只差在 SEDERS 最高頻可以到 5G ，還有速度比較快。</p>



<p>但是 LiteX default versa_ecp5 是預設用 LFE5UM5G-85F ，在燒錄時就會失敗，ID 不一樣</p>



<p>此時我們就要重編一次 Linux-on-litex-vexriscv ，加上 device 的參數，這樣就可以了</p>



<pre class="wp-block-code"><code>./make.py --device LFE5UM --board=versa_ecp5 --cpu-count=1 --build</code></pre>



<p>編出來的 bitstream 和 fpga hardware 不同的錯誤訊息，可以看到 hardware id 不一樣</p>



<pre class="wp-block-preformatted">$ openFPGALoader -b ecp5_evn versa_ecp5.bit<br />empty<br />Jtag frequency : requested 6.00MHz    -&gt; real 6.00MHz<br />Open file: DONE<br />b3bdffff<br />Parse file: DONE<br />mismatch between target's idcode and bitstream idcode<br />        bitstream has <strong>0x81112043 </strong>hardware requires <strong>0x01112043</strong><br />Error: Failed to program FPGA: std::exception</pre>



<h3 class="wp-block-heading" id="連接上-evb-board">連接上 EVB Board </h3>



<p>EVB Board 應該支援 ethernet load ，但是我還沒試出來，就當 TBD 吧，看設定檔內 ethernet 是可以用的</p>



<p>EVB Board 上的 FT2232H 支援 JTAG 和 Serial Port ，Linux kernel 的 image 可以從 serial port load，不過速度好慢啊</p>



<p>我之前用 Diamond programmer 要燒錄編出來的 bitstream file ，但是因為 id mismatch 的關係所以燒不上去，所以我最後是找了一台乾淨的 Linux 直接接 EVB Board 的 USB （要注意，這塊版子的 USB Port 是 mini-USB ，如果沒附線要有支援 mini-USB 的線），就這樣找到最後才發現根本型號不一樣，所以這篇就不會提到 Diamond programmer</p>



<p>記得接上之前要將 FTDI 的J50跳線改成下圖這樣，要跳過 iSPclock </p>



<p>（原文 <strong>Note</strong>: If you are using a Versa board, you will need to change J50 to bypass the iSPclock. Re-arrange the jumpers to connect pins 1-2 and 3-5 (leaving one jumper spare). See p19 of the Versa Board user guide.）</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="699" height="627" src="https://blog.richliu.com/wp-content/uploads/2025/09/image.png" alt="" class="wp-image-6412" srcset="https://blog.richliu.com/wp-content/uploads/2025/09/image.png 699w, https://blog.richliu.com/wp-content/uploads/2025/09/image-600x538.png 600w" sizes="(max-width: 699px) 100vw, 699px" /></figure>



<p>接上去之後，上電之後，Linux 下會出現 /dev/ttyUSB0 是 JTAG 的介面，/dev/ttyUSB1 是 serial port 的介面</p>



<p>在另一個視窗先執行 litex_term（記得在 venv 環境下執行）</p>



<pre class="wp-block-code"><code>litex_term --images=images/boot.json /dev/ttyUSB1</code></pre>



<h3 class="wp-block-heading" id="燒錄-bitstream-到板子上">燒錄 bitstream 到板子上</h3>



<p>最後一步就是燒錄上去了，我是用 OpenFPGAloader ，以下是安裝步驟</p>



<pre class="wp-block-code"><code>sudo apt install -y  libftdi1-dev

cd /nvme/cpu
git clone https://github.com/trabucayre/openFPGALoader
cd openFPGALoader
mkdir -p build
cd build
cmake ../
make -j `nproc`
sudo make install </code></pre>



<p>然後到 linux-on-litex-vexriscv 下用 OpenFPGAloader 暫時 load bitstream 上去，這速度很快，這樣就不用燒上去了</p>



<pre class="wp-block-code"><code>cd /nvme/cpu/linux-on-litex-vexriscv/build/versa_ecp5/gateware
$ openFPGALoader -b ecp5_evn versa_ecp5.bit
empty
Jtag frequency : requested 6.00MHz    -&gt; real 6.00MHz
Open file: DONE
b3bdffff
Parse file: DONE
Enable configuration: DONE
SRAM erase: DONE
Loading: &#91;==================================================] 100.00%
Done
Disable configuration: DONE</code></pre>



<p>如果順利，可以在剛剛執行 litex_term 上看到 load image 訊息<br />如果用的是上一篇文章內提到的先下載好 RiscV 的 Linux image 和 rootfs ，就可以看到 Linux boot 了</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="943" height="927" src="https://blog.richliu.com/wp-content/uploads/2025/09/image-1.png" alt="" class="wp-image-6413" srcset="https://blog.richliu.com/wp-content/uploads/2025/09/image-1.png 943w, https://blog.richliu.com/wp-content/uploads/2025/09/image-1-600x590.png 600w, https://blog.richliu.com/wp-content/uploads/2025/09/image-1-768x755.png 768w, https://blog.richliu.com/wp-content/uploads/2025/09/image-1-88x88.png 88w, https://blog.richliu.com/wp-content/uploads/2025/09/image-1-816x802.png 816w" sizes="(max-width: 943px) 100vw, 943px" /></figure>



<p>這年代可以自己編一顆 CPU 跑起來也真的是很有趣</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1353" height="927" src="https://blog.richliu.com/wp-content/uploads/2025/09/image-2.png" alt="" class="wp-image-6414" srcset="https://blog.richliu.com/wp-content/uploads/2025/09/image-2.png 1353w, https://blog.richliu.com/wp-content/uploads/2025/09/image-2-600x411.png 600w, https://blog.richliu.com/wp-content/uploads/2025/09/image-2-768x526.png 768w, https://blog.richliu.com/wp-content/uploads/2025/09/image-2-816x559.png 816w" sizes="(max-width: 1353px) 100vw, 1353px" /></figure>



<p>以下未完成，待續</p>



<h3 class="wp-block-heading" id="設定-udev">設定 udev</h3>



<p>這塊版子看起來要設定過 udev 才能被 LiteX 抓到，首先新增檔案 /etc/udev/rules.d/99-ftdi.rules<br />內容如下，記得 GROUP=換成 Linux login 帳號</p>



<pre class="wp-block-preformatted">SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0660", GROUP="使用者名稱"</pre>



<p>然後執行以下命令之後再重新上電即可</p>



<pre class="wp-block-code"><code>sudo udevadm control --reload-rules
sudo udevadm trigger</code></pre>



<p>這個命令也可以像 OpenFPGAloader 一樣將 bitstream load 到 FPGA 上</p>



<pre class="wp-block-code"><code>./make.py --device LFE5UM --board=versa_ecp5 --cpu-count=1 --load </code></pre>



<p>45F Gate count 夠放二顆 CPU ，所以可以跑 SMP</p>



<pre class="wp-block-code"><code>./make.py --device LFE5UM --board=versa_ecp5 --cpu-count=2 --build
./make.py --device LFE5UM --board=versa_ecp5 --cpu-count=2 --load </code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1299" height="1033" src="https://blog.richliu.com/wp-content/uploads/2025/09/image-3.png" alt="" class="wp-image-6418" srcset="https://blog.richliu.com/wp-content/uploads/2025/09/image-3.png 1299w, https://blog.richliu.com/wp-content/uploads/2025/09/image-3-600x477.png 600w, https://blog.richliu.com/wp-content/uploads/2025/09/image-3-768x611.png 768w, https://blog.richliu.com/wp-content/uploads/2025/09/image-3-816x649.png 816w" sizes="(max-width: 1299px) 100vw, 1299px" /></figure>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/09/21/6411/running-risc-v-linux-on-lattice-versa-ecp5-evb/">Running Risc-V Linux on Lattice Versa ECP5 EVB</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/09/21/6411/running-risc-v-linux-on-lattice-versa-ecp5-evb/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Build Risc-V on Ubuntu Linux</title>
		<link>https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/</link>
					<comments>https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 27 Aug 2025 13:04:18 +0000</pubDate>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[IC Design]]></category>
		<category><![CDATA[RiscV]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6391</guid>

					<description><![CDATA[<p>打算弄個 Risc-V 做個自己的小 Project ，摸了一下大概才知道怎麼入門這篇是筆記，適合初學者 OS [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/">Build Risc-V on Ubuntu Linux</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>打算弄個 Risc-V 做個自己的小 Project ，摸了一下大概才知道怎麼入門<br />這篇是筆記，適合初學者</p>



<p>OS: ubuntu 22.04 / 24.04 </p>



<span id="more-6391"></span>



<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><h2>Table of Contents</h2><nav><ul><li><a href="#下載和-compile-source-code">下載和 compile source code</a><ul><li><a href="#install-ubuntu-packages">Install Ubuntu Packages</a></li><li><a href="#install-sbt">Install SBT</a></li><li><a href="#install-open-jdk">Install OpenJDK</a></li><li><a href="#重編-cmake">重編 cmake</a></li><li><a href="#下載-linux-on-litex-vexriscv">下載 linux-on-litex-vexriscv</a></li><li><a href="#編-buildroot-編出-risc-v-的-cross-compiler">編 Buildroot 編出 Risc-V 的 Cross Compiler</a></li><li><a href="#iverilog-版本太舊，重編-iverilog">iverilog 版本太舊，重編 iverilog</a></li><li><a href="#下載-yosys-prjtrellis-nextpnr">下載 yosys/prjtrellis/nextpnr</a></li><li><a href="#下載和編-litex">下載和編 litex</a></li></ul></li><li><a href="#跑-simulation">跑 Simulation</a><ul><li><a href="#跑-simulation-1">跑 simulation</a></li><li><a href="#build-fpga-bitstream-image">Build FPGA Bitstream Image</a></li></ul></li><li><a href="#error-messages">Error Messages</a><ul><li><a href="#ram-1-w-1-rs-generic-v-2-8-timescale-missing-on-this-module-as-other-modules-have-it">Ram_1w_1rs_Generic.v:2:8: Timescale missing on this module as other modules have it</a></li><li><a href="#error-module-eclkbridgecs-referenced-in-module-orange-crab-in-cell-eclkbridgecs-is-not-part-of-the-design">ERROR: Module `\ECLKBRIDGECS&#8217; referenced in module `\orange_crab&#8217; in cell `\ECLKBRIDGECS&#8217; is not part of the design</a></li></ul></li><li><a href="#reference">Reference</a></li></ul></nav></div>



<h2 class="wp-block-heading" id="下載和-compile-source-code">下載和 compile source code </h2>



<p>理論上用 linux-on-litex-vexriscv 照著作就可以了，不過中間還是有很多邊邊角角的小問題要處理 ，如果對系統不夠熟的人會在這邊卡很久。</p>



<h3 class="wp-block-heading" id="install-ubuntu-packages">Install Ubuntu Packages </h3>



<pre class="wp-block-code"><code>sudo apt-get install -y build-essential device-tree-compiler wget git python3-setuptools python3-dev
sudo apt-get install -y libssl-dev libncurses-dev libeigen3-dev
sudo apt-get install -y libevent-dev libjson-c-dev libboost-iostreams-dev
sudo apt-get install -y libreadline-dev tcl-dev libffi-dev bison flex gawk gtkwave

sudo apt-get install -y file bc unzip meson 
sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-thread-dev libboost-program-options-dev libboost-python-dev libboost-all-dev


# 24.04
sudo apt-get install -y python3-venv </code></pre>



<h3 class="wp-block-heading" id="install-sbt">Install SBT</h3>



<pre class="wp-block-code"><code>sudo apt-get update
sudo apt-get install apt-transport-https curl gnupg -yqq
echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list
echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&amp;search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo -H gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import
sudo chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg
sudo apt-get update
sudo apt-get -y install sbt</code></pre>



<h3 class="wp-block-heading" id="install-open-jdk">Install OpenJDK</h3>



<p>這邊我們用 OpenJDK 17 </p>



<pre class="wp-block-code"><code>sudo apt-get install -y openjdk-17-jdk openjdk-17-jre</code></pre>



<h3 class="wp-block-heading" id="重編-cmake">重編 cmake </h3>



<p>內建的 cmake 看起來版本太低不能用，所以要下載 cmake 手動編譯</p>



<pre class="wp-block-code"><code>wget https://github.com/Kitware/CMake/releases/download/v4.0.3/cmake-4.0.3.tar.gz
tar xvf cmake-4.0.3.tar.gz
cd cmake-4.0.3
./configure
make -j `nproc`
sudo make install</code></pre>



<h3 class="wp-block-heading" id="下載-linux-on-litex-vexriscv">下載 linux-on-litex-vexriscv</h3>



<p>編  buildroot 要指定 linux-on-litex-vexriscv ，所以先下載</p>



<pre class="wp-block-code"><code>git clone https://github.com/litex-hub/linux-on-litex-vexriscv</code></pre>



<h3 class="wp-block-heading" id="編-buildroot-編出-risc-v-的-cross-compiler">編 Buildroot 編出 Risc-V 的 Cross Compiler </h3>



<p>我因為是在其他 CPU 的平台上跑，所以只能自己編 buildroot ，還好 buildroot 已經很成熟了，只是要花時間編出來而已，第一次有錯誤訊息沒關係，確認 output/host/bin/ 下有&#8221;riscv32-&#8221; 開頭的 toolchain 就可以了<br />等到編完 litex 之後再回來重編一次 buildroot 即可</p>



<pre class="wp-block-code"><code>git clone http://github.com/buildroot/buildroot
cd buildroot
make BR2_EXTERNAL=../linux-on-litex-vexriscv/buildroot/ litex_vexriscv_defconfig
make</code></pre>



<h3 class="wp-block-heading" id="iverilog-版本太舊，重編-iverilog">iverilog 版本太舊，重編 iverilog</h3>



<p>iverilog 和 yosys 都要注意不能用到 ubuntu 系統內建的版本，它們都太舊了<br />都要手動重裝新版的</p>



<pre class="wp-block-code"><code>sudo apt-get install -y autoconf gperf make gcc g++ bison flex
git clone https://github.com/steveicarus/iverilog.git
cd iverilog
autoconf
./configure 
sudo make -j `nproc` install </code></pre>



<h3 class="wp-block-heading" id="下載-yosys-prjtrellis-nextpnr">下載 yosys/prjtrellis/nextpnr </h3>



<p>主要是參照這篇 <a href="https://ithelp.ithome.com.tw/articles/10266953" target="_blank" rel="noopener">LiteX/VexRiscv 簡介與使用 (二) 始有晝夜</a> ，但是因為已經是幾年前了，有些東西有點小差異，不過不影響，目錄就用我的工作目錄</p>



<p>這邊要小心一點，最好是先清空相關的程式碼，像是 /nvme/cpu/sysroot/* 和 /usr/local/bin 下的某些檔案，我就吃了虧卡關了很久</p>



<p>如果是 Ubuntu 24.04 ，要先照下面一節的方式先切到 venv 的環境再安裝</p>



<pre class="wp-block-code"><code># 如果還沒做就先將路徑加上去
# 編 buildroot 時不能加入 buildroot 的 path，要編 litex 時再加入即可export PATH=$PATH:/usr/local/bin:/nvme/cpu/buildroot/output/host/bin/:/nvme/cpu/sysroot/bin/:~/.local/bin:

mkdir -p /nvme/cpu/sysroot
cd /nvme/cpu
git clone --recursive https://github.com/YosysHQ/yosys
git clone --recursive https://github.com/YosysHQ/prjtrellis
git clone --recursive https://github.com/YosysHQ/nextpnr
cd yosys
make PREFIX="/nvme/cpu/sysroot" CONFIG=gcc ENABLE_TCL=1 ENABLE_ABC=1 ENABLE_GLOB=1 ENABLE_PLUGINS=1 ENABLE_LIBYOSYS=1 ENABLE_PROTOBUF=1 ENABLE_ZLIB=1 ENABLE_PYOSYS=1 test all install -j `nproc`
cd ..
cd prjtrellis/libtrellis
cmake -DCMAKE_INSTALL_PREFIX=/nvme/cpu/sysroot .
make install -j `nproc`
cd ../../
cd nextpnr
cmake . -DARCH=ecp5 -DTRELLIS_INSTALL_PREFIX=/nvme/cpu/sysroot -B build
cd build
sudo make install -j `nproc`
</code></pre>



<h3 class="wp-block-heading" id="下載和編-litex">下載和編 litex </h3>



<p>ubuntu 22.04 可以用 &#8211;user ，但是 24.04 就強制要用 venv　要先有環境 </p>



<pre class="wp-block-code"><code>cd /nvme/cpu
python3 -m venv litex-venv
source litex-venv/bin/activate</code></pre>



<p>Ubuntu 22.04</p>



<pre class="wp-block-code"><code>cd /nvme/cpu
wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py
chmod +x litex_setup.py
./litex_setup.py --init --install --user</code></pre>



<p>Ubuntu 24.04</p>



<pre class="wp-block-code"><code>./litex_setup.py --init --install</code></pre>



<p>Compile Lite-X</p>



<pre class="wp-block-code"><code>cd /nvme/cpu/linux-on-litex-vexriscv
./make.py --board=versa_ecp5 --cpu-count=1 --build</code></pre>



<h2 class="wp-block-heading" id="跑-simulation">跑 Simulation </h2>



<p>順利的話這時環境應該 OK 了，可以跑 simulation 了</p>



<p>先下載 Linux images 到 images</p>



<pre class="wp-block-code"><code>cd /nvme/cpu/linux-on-litex-vexriscv/images
wget https://github.com/litex-hub/linux-on-litex-vexriscv/files/8331338/linux_2022_03_23.zip
unzip linux_2022_03_23.zip</code></pre>



<h3 class="wp-block-heading" id="跑-simulation-1">跑 simulation </h3>



<p>這時就可以跑 simulation 了，不過我跑了 64 Cores 好像更慢，看起來給愈多 code 會跑的更大，像是變 SMP 或是跑到 100Mhz （一核用 1Mhz）<br />可能要花時間設參數，&#8211;jobs 到是可以設大一點</p>



<pre class="wp-block-preformatted">./sim.py<br /><br /># 或是<br />./sim.py <br /><br /># 或是<br />./sim.py  --jobs `nproc` --threads `nproc`<br /></pre>



<p><img loading="lazy" decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXc0cqn58FsJ3udHeeWXAoUNAOw8i-6amS6mlR9KI50IFMgPzvjH9nNR6LJI5xnEjv2Mu2Q2hnnhtVhFYTacZbEV2y7NPgI1tiukpiPoS1W04yON2UWJC0LW8XGwRR2a3Z8xnq0apw?key=08Ji1rDFx5yo_VwHwn3Aoj4y" width="497" height="600"/></p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="929" height="728" src="https://blog.richliu.com/wp-content/uploads/2025/08/image-5.png" alt="" class="wp-image-6393" style="width:528px;height:auto" srcset="https://blog.richliu.com/wp-content/uploads/2025/08/image-5.png 929w, https://blog.richliu.com/wp-content/uploads/2025/08/image-5-600x470.png 600w, https://blog.richliu.com/wp-content/uploads/2025/08/image-5-768x602.png 768w, https://blog.richliu.com/wp-content/uploads/2025/08/image-5-816x639.png 816w" sizes="(max-width: 929px) 100vw, 929px" /></figure>



<p></p>



<h3 class="wp-block-heading" id="build-fpga-bitstream-image">Build FPGA Bitstream Image </h3>



<p>以下就是編  orange_crab FPGA 板子的 command </p>



<pre class="wp-block-code"><code>./make.py --board=orange_crab --cpu-count=1 --build</code></pre>



<p>不過我編出來會 .dts failed <br />可以改編 versa_ecp5 ，這是 ecp5 的公板，目前應該只有 ecp5 可以靠Trellis/Yosys/nextpnr 這三個 Open Source 的軟體編出 FPGA 所需的 bitstream image，orange_crab 也是基於 ecp5 的 FPGA. </p>



<pre class="wp-block-preformatted">./make.py --board=versa_ecp5 --cpu-count=1 --build</pre>



<p>不過我寫這篇的時候還沒買 FPGA ，所以燒到板子上測試要等下一篇了</p>



<h2 class="wp-block-heading" id="error-messages">Error Messages </h2>



<h3 class="wp-block-heading" id="ram-1-w-1-rs-generic-v-2-8-timescale-missing-on-this-module-as-other-modules-have-it">Ram_1w_1rs_Generic.v:2:8: Timescale missing on this module as other modules have it</h3>



<p>原始錯誤訊息</p>



<pre class="wp-block-preformatted">%Error-TIMESCALEMOD: /nvme/cpu/pythondata-cpu-vexriscv-smp/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v:2:8: Timescale missing on this module as other modules have it (IEEE 1800-2017 3.14.2.2)<br />                     /nvme/cpu/pythondata-cpu-vexriscv-smp/pythondata_cpu_vexriscv_smp/verilog/VexRiscvLitexSmpCluster_Cc1_Iw32Is4096Iy1_Dw32Ds4096Dy1_ITs4DTs4_Ldw32_Ood_Hb1.v:8:8: ... Location of module with timescale<br />    8 | module VexRiscvLitexSmpCluster_Cc1_Iw32Is4096Iy1_Dw32Ds4096Dy1_ITs4DTs4_Ldw32_Ood_Hb1 (<br />      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />%Error: Exiting due to 1 error(s)<br />        ... See the manual and https://verilator.org for more assistance.<br />make: *** [/nvme/cpu/litex/litex/build/sim/core/Makefile:44: sim] Error 1<br />make: Leaving directory '/nvme/cpu/linux-on-litex-vexriscv/build/sim/gateware'<br />Testing expectations for wide_thru_priority.v ..Test: code_verilog_tutorial_fsm_full -&gt; ok<br /><br />Test: code_verilog_tutorial_parity -&gt; ok</pre>



<p>修改檔案 /nvme/cpu/pythondata-cpu-vexriscv-smp/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v 加上一行</p>



<pre class="wp-block-code"><code>diff --git a/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v b/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v
index c6e6a96..6a57a2e 100644
--- a/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v
+++ b/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v
@@ -1,3 +1,5 @@
+`timescale 1ns/1ps
+

 module Ram_1w_1rs #(
         parameter integer wordCount = 0,</code></pre>



<h3 class="wp-block-heading" id="error-module-eclkbridgecs-referenced-in-module-orange-crab-in-cell-eclkbridgecs-is-not-part-of-the-design">ERROR: Module `\ECLKBRIDGECS&#8217; referenced in module `\orange_crab&#8217; in cell `\ECLKBRIDGECS&#8217; is not part of the design</h3>



<pre class="wp-block-preformatted">Generating RTLIL representation for module `\VexRiscvLitexSmpCluster_Cc1_Iw32Is4096Iy1_Dw32Ds4096Dy1_ITs4DTs4_Ldw128_Ood_Hb1'.      ERROR: Module `\ECLKBRIDGECS' referenced in module `\orange_crab' in cell `\ECLKBRIDGECS' is not part of the design.   </pre>



<p>yosys 太舊，我是裝到系統的 yosys ，移除掉系統的 yosys 再自己編 yosys 就可以了</p>



<p></p>



<h2 class="wp-block-heading" id="reference">Reference</h2>



<p><a href="https://ithelp.ithome.com.tw/articles/10266953" target="_blank" rel="noopener">LiteX/VexRiscv 簡介與使用 (二) 始有晝夜</a> <br /><a href="https://github.com/enjoy-digital/litex" target="_blank" rel="noopener">LiteX</a><br /><a href="https://github.com/litex-hub/linux-on-litex-vexriscv" target="_blank" rel="noopener">linux-on-litex-vexriscv</a><br /><a href="https://github.com/litex-hub/linux-on-litex-vexriscv/issues/164" target="_blank" rel="noopener">Prebuilt Bitstreams and Linux/OpenSBI images</a> (抓 Linux Kernel 用)<br /><a href="https://orangecrab-fpga.github.io/orangecrab-hardware/docs/getting-started/" target="_blank" rel="noopener">Orange Crab 主網站</a><br /><a href="https://github.com/YosysHQ/oss-cad-suite-build" target="_blank" rel="noopener">OSS CAD Suite</a><br /><a href="https://gitlab.com/buildroot.org/buildroot/" target="_blank" rel="noopener">Buildroot</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/">Build Risc-V on Ubuntu Linux</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/08/27/6391/build-risc-v-on-ubuntu-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Gentoo] virt-manager/libvirt virbr0 doesn&#8217;t exist</title>
		<link>https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/</link>
					<comments>https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sun, 27 Jul 2025 12:11:11 +0000</pubDate>
				<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[virt-manager]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6345</guid>

					<description><![CDATA[<p>Once when I reboot the system, system shows, there is n [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/">[Gentoo] virt-manager/libvirt virbr0 doesn&#8217;t exist</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Once when I reboot the system, system shows, there is no virbr0 </p>



<span id="more-6345"></span>



<p>First, check the interface states, default network is inactive</p>



<pre class="wp-block-preformatted"># virsh net-list --all<br /> Name              State    Autostart   Persistent<br />----------------------------------------------------<br /> bridged-network   active   yes         yes<br /> default           inactive yes         yes</pre>



<p>Manual restart, it shows following message</p>



<pre class="wp-block-preformatted"># virsh net-start default<br />error: Failed to start network default<br />error: internal error: Child process (VIR_BRIDGE_NAME=virbr1 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper) unexpected exit status 2:<br />dnsmasq: failed to create listening socket for 192.168.123.1: Address already in use</pre>



<p>The root cause is, when libvirt start the default network, it will also bring up the dnsmasq as dns server, but if this system also has DNS server like named or another dnsmasq service, it will have port conflict. <br />Tried to modify the yaml to assign dnsmasq to another port, but doens&#8217;t work (old configure is to use /etc/dnsmasq.conf, but seems it will use default.xml after update the libvirt )</p>



<p>add <code><strong>&lt;dns enable="no"/></strong></code> to default network setting can solve this issue, ex:</p>



<pre class="wp-block-preformatted"># virsh net-edit default<br /><br />&lt;network><br />  &lt;name>default&lt;/name><br />  &lt;uuid>cdf10e75-0299-43b5-8c93-e6943e261ef3&lt;/uuid><br />  &lt;forward mode='nat'/><br />  &lt;bridge name='virbr0' stp='on' delay='0'/><br />  &lt;mac address='52:54:00:66:c4:a3'/><br />  <strong>&lt;dns enable='no'/></strong><br />  &lt;ip address='192.168.122.1' netmask='255.255.255.0'><br />    &lt;dhcp><br />      &lt;range start='192.168.122.2' end='192.168.122.254'/><br />    &lt;/dhcp><br />  &lt;/ip><br />&lt;/network></pre>



<p>ref. <br />https://serverfault.com/questions/937188/disable-or-change-port-of-dnsmasq-service-in-libvirt</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/">[Gentoo] virt-manager/libvirt virbr0 doesn&#8217;t exist</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/07/27/6345/gentoo-virt-manager-libvirt-virbr0-doesnt-exist/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CyberPower UPS + Apcupsd + Gafana + InfluxDB</title>
		<link>https://blog.richliu.com/2025/05/31/6302/cyberpower-ups-apcupsd-gafana-influxdb/</link>
					<comments>https://blog.richliu.com/2025/05/31/6302/cyberpower-ups-apcupsd-gafana-influxdb/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sat, 31 May 2025 04:23:11 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[apcupsd]]></category>
		<category><![CDATA[Gafana]]></category>
		<category><![CDATA[influxdb]]></category>
		<category><![CDATA[UPS]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6302</guid>

					<description><![CDATA[<p>因為最近想到不能只是接上 apcupsd ，應該要接上 Gafana 看一下 UPS 的狀況，不過目前 Gaf [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/05/31/6302/cyberpower-ups-apcupsd-gafana-influxdb/">CyberPower UPS + Apcupsd + Gafana + InfluxDB</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>因為最近想到不能只是接上 apcupsd ，應該要接上 Gafana 看一下 UPS 的狀況，不過目前 Gafana 預設的 Dashboard 都沒有支援 CyberPower UPS 的，所以就自己改一個，還有點怪怪的問題，不過至少主要數據都是正確的</p>



<p>用 AI 產出來的 configuration files ，DeepSeek 看起來比較正確，只是 Dashboard 跟 Grox 一樣都會錯，到是 Grox 在設定 Gafana 的 influxdB data source 的地方講對了，查詢種類要選 flux 才可以查到資料</p>



<p>試過了 Prometheus，結果發現可用的 Dashboard 更少，感覺沒過幾年世界就變了</p>



<span id="more-6302"></span>



<p>設定檔我覺得可以丟給 AI ，畢竟我跑在 VM 內部又用 docker 跑，相對上還是麻煩了一點</p>



<p>至於 Gafana 的設定檔我就丟在這邊，堪用還有些小問題但是懶得修了，我只想看 input output 狀態而已<br /><a href="https://github.com/richliu/cp_apc_dash" target="_blank" rel="noopener">https://github.com/richliu/cp_apc_dash</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2345" height="968" src="https://blog.richliu.com/wp-content/uploads/2025/05/image-28.png" alt="" class="wp-image-6303" srcset="https://blog.richliu.com/wp-content/uploads/2025/05/image-28.png 2345w, https://blog.richliu.com/wp-content/uploads/2025/05/image-28-600x248.png 600w, https://blog.richliu.com/wp-content/uploads/2025/05/image-28-768x317.png 768w, https://blog.richliu.com/wp-content/uploads/2025/05/image-28-1536x634.png 1536w, https://blog.richliu.com/wp-content/uploads/2025/05/image-28-2048x845.png 2048w, https://blog.richliu.com/wp-content/uploads/2025/05/image-28-816x337.png 816w" sizes="(max-width: 2345px) 100vw, 2345px" /></figure>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/05/31/6302/cyberpower-ups-apcupsd-gafana-influxdb/">CyberPower UPS + Apcupsd + Gafana + InfluxDB</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/05/31/6302/cyberpower-ups-apcupsd-gafana-influxdb/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPress utf8mb3_general_ci 改utf8mb4_unicode_ci</title>
		<link>https://blog.richliu.com/2025/03/21/6220/wordpress-utf8mb3_general_ci-%e6%94%b9utf8mb4_unicode_ci/</link>
					<comments>https://blog.richliu.com/2025/03/21/6220/wordpress-utf8mb3_general_ci-%e6%94%b9utf8mb4_unicode_ci/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Fri, 21 Mar 2025 04:07:30 +0000</pubDate>
				<category><![CDATA[Blog/wiki]]></category>
		<category><![CDATA[utf8]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[中文]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6220</guid>

					<description><![CDATA[<p>這個最近在寫文章插入 emoji 😁的時候才發現的問題，想說怎麼不能存檔了，因為錯誤訊息只出現 Update  [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/03/21/6220/wordpress-utf8mb3_general_ci-%e6%94%b9utf8mb4_unicode_ci/">WordPress utf8mb3_general_ci 改utf8mb4_unicode_ci</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>這個最近在寫文章插入 emoji <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" />的時候才發現的問題，想說怎麼不能存檔了，因為錯誤訊息只出現 Update database error ， apache server 也沒有明顯的 LOG 指出這件事，錯了幾次才抓出是 emoji 的問題</p>



<span id="more-6220"></span>



<p>在查找文章的時候有<a href="https://www.mrkwp.com/2025/03/fixing-emoji-saving-issues-chatgpt-wordpress/" target="_blank" rel="noopener">文章</a>就提到</p>



<pre class="wp-block-preformatted">Check Your Current Collation: Look at your database tables. If you see a collation like utf8mb3_unicode_ci, this is likely the cause of the problem. WordPress tables should ideally use utf8mb4_unicode_520</pre>



<p>才想到查一下我的 DB 是不是 utf8mb3 ，一查之下果然是，老的 WordPress 用的資料庫果然夠老，轉換資料庫也碰到一些問題，主要是 wp_comments 這個資料庫的問題，可以先去 WordPress comments 刪除所有垃圾留言</p>



<p>在 wp-config.php 內設定成 utf8mb4</p>



<pre class="wp-block-preformatted">define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', 'utf8mb4_unicode_ci');</pre>



<p>導出 wp_comments 的資料庫</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c">Bash</span><span role="button" tabindex="0" data-code="mysqldump -u [用戶名] -p --skip-set-charset --default-character-set=latin1 [資料庫名] wp_comments &gt; wp_comments.sql" style="color:#24292e;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki github-light" style="background-color: #fff" tabindex="0"><code><span class="line"><span style="color: #6F42C1">mysqldump</span><span style="color: #24292E"> </span><span style="color: #005CC5">-u</span><span style="color: #24292E"> [用戶名] -p --skip-set-charset --default-character-set=latin1 [資料庫名] wp_comments </span><span style="color: #D73A49">&gt;</span><span style="color: #24292E"> wp_comments.sql</span></span></code></pre></div>



<p>導回 wp_comments 的資料庫</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c">Bash</span><span role="button" tabindex="0" data-code="mysql -u [用戶名] -p --default-character-set=utf8mb4 [資料庫名] &lt; wp_comments.sql" style="color:#24292e;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki github-light" style="background-color: #fff" tabindex="0"><code><span class="line"><span style="color: #6F42C1">mysql</span><span style="color: #24292E"> </span><span style="color: #005CC5">-u</span><span style="color: #24292E"> [用戶名] -p --default-character-set=utf8mb4 [資料庫名] </span><span style="color: #D73A49">&lt;</span><span style="color: #24292E"> wp_comments.sql</span></span></code></pre></div>



<p>轉換整個資料庫</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c">Bash</span><span role="button" tabindex="0" data-code="#!/bin/bash
DB_NAME=&quot;your_database&quot;
USER=&quot;your_user&quot;
PASS=&quot;your_password&quot;

TABLES=$(mysql -u $USER -p$PASS -Nse &quot;SHOW TABLES;&quot; $DB_NAME)
for TABLE in $TABLES; do
    mysql -u $USER -p$PASS -e &quot;ALTER TABLE $TABLE CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;&quot; $DB_NAME
done" style="color:#24292e;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki github-light" style="background-color: #fff" tabindex="0"><code><span class="line"><span style="color: #6A737D">#!/bin/bash</span></span>
<span class="line"><span style="color: #24292E">DB_NAME</span><span style="color: #D73A49">=</span><span style="color: #032F62">&quot;your_database&quot;</span></span>
<span class="line"><span style="color: #24292E">USER</span><span style="color: #D73A49">=</span><span style="color: #032F62">&quot;your_user&quot;</span></span>
<span class="line"><span style="color: #24292E">PASS</span><span style="color: #D73A49">=</span><span style="color: #032F62">&quot;your_password&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #24292E">TABLES</span><span style="color: #D73A49">=</span><span style="color: #032F62">$(</span><span style="color: #6F42C1">mysql</span><span style="color: #032F62"> </span><span style="color: #005CC5">-u</span><span style="color: #032F62"> </span><span style="color: #24292E">$USER</span><span style="color: #032F62"> </span><span style="color: #005CC5">-p</span><span style="color: #24292E">$PASS</span><span style="color: #032F62"> </span><span style="color: #005CC5">-Nse</span><span style="color: #032F62"> &quot;SHOW TABLES;&quot; </span><span style="color: #24292E">$DB_NAME</span><span style="color: #032F62">)</span></span>
<span class="line"><span style="color: #D73A49">for</span><span style="color: #24292E"> TABLE </span><span style="color: #D73A49">in</span><span style="color: #24292E"> $TABLES; </span><span style="color: #D73A49">do</span></span>
<span class="line"><span style="color: #24292E">    </span><span style="color: #6F42C1">mysql</span><span style="color: #24292E"> </span><span style="color: #005CC5">-u</span><span style="color: #24292E"> $USER </span><span style="color: #005CC5">-p</span><span style="color: #24292E">$PASS</span><span style="color: #24292E"> </span><span style="color: #005CC5">-e</span><span style="color: #24292E"> </span><span style="color: #032F62">&quot;ALTER TABLE </span><span style="color: #24292E">$TABLE</span><span style="color: #032F62"> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;&quot;</span><span style="color: #24292E"> $DB_NAME</span></span>
<span class="line"><span style="color: #D73A49">done</span></span></code></pre></div>



<p>DeepSeek 這邊做的非常好，直接給 shell script 幫助完成，Grok 就沒給出這麼方便的 Script. </p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/03/21/6220/wordpress-utf8mb3_general_ci-%e6%94%b9utf8mb4_unicode_ci/">WordPress utf8mb3_general_ci 改utf8mb4_unicode_ci</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/03/21/6220/wordpress-utf8mb3_general_ci-%e6%94%b9utf8mb4_unicode_ci/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>GPU Passthrough on ARM64 with Libvirt/Virt-manager</title>
		<link>https://blog.richliu.com/2025/02/12/6182/gpu-passthrough-on-arm64-with-libvirt-virt-manager/</link>
					<comments>https://blog.richliu.com/2025/02/12/6182/gpu-passthrough-on-arm64-with-libvirt-virt-manager/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 12 Feb 2025 09:18:24 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Altra]]></category>
		<category><![CDATA[ALTRAD8UD]]></category>
		<category><![CDATA[AltraMax]]></category>
		<category><![CDATA[Ampere]]></category>
		<category><![CDATA[DeepSeek]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nvidia]]></category>
		<category><![CDATA[ollama]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6182</guid>

					<description><![CDATA[<p>In this article, I’ll walk you through the steps to set [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/12/6182/gpu-passthrough-on-arm64-with-libvirt-virt-manager/">GPU Passthrough on ARM64 with Libvirt/Virt-manager</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this article, I’ll walk you through the steps to set up GPU passthrough on an ARM64 system using Libvirt and Virt-manager. While using the ChatGPT to search answer, the steps may seem straightforward, but missing a critical detail can cause the process to fail.</p>



<p><strong>System Specifications</strong></p>



<p><strong>Nvidia Driver</strong>: NVIDIA-Linux-aarch64-570.86.16.run<br /><strong>Host</strong>: Ampere Altra + ALTRAD8UD<br /><strong>Host OS</strong>: Ubuntu 22.04 with HWE kernel (6.8)<br /><strong>Guest OS</strong>: Ubuntu 22.04 (ubuntu-22.04-live-server-arm64.iso)<br /><strong>GPU</strong>: Nvidia RTX 4080 16GB</p>



<p><strong>Assumptions</strong></p>



<ol start="1" class="wp-block-list">
<li>You are familiar with Ubuntu and its basic commands.</li>



<li>You have experience using Virt-manager.</li>



<li>All commands are executed as the root user.</li>
</ol>



<p>If anything is unclear, you can refer to external resources for additional guidance.</p>



<span id="more-6182"></span>



<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><h2>Table of Contents</h2><nav><ul><li><a href="#host-configuration">Host Configuration </a><ul><li><a href="#enable-iommu">Enable IOMMU</a></li><li><a href="#host-upgrade-to-hwe-kernel">Upgrade Host to HWE Kernel</a></li><li><a href="#configure-the-vfio-on-host">Configure VFIO on Host</a></li><li><a href="#disable-nvidia-driver-on-the-host">Disable Nvidia Driver on HOST</a></li></ul></li><li><a href="#configure-vm">Configure VM</a><ul><li><a href="#i">Install Virt-manager</a></li><li><a href="#create-vm-image">Create VM image</a></li><li><a href="#create-vm">Add Nvidia device to VM</a></li><li><a href="#disable-security-boot">Disable secure Boot in UEFI</a></li><li><a href="#gpu-passthrough-test">GPU Passthrough Test</a></li></ul></li></ul></nav></div>



<h2 class="wp-block-heading" id="host-configuration">Host Configuration </h2>



<h3 class="wp-block-heading" id="enable-iommu">Enable IOMMU</h3>



<p>To enable IOMMU, you need to enable the SR-IOV option in the BIOS and verify whether the Linux kernel has IOMMU enabled by default.</p>



<p>You can check if IOMMU is enabled by running:</p>



<pre class="wp-block-preformatted">$ dmesg | grep -i iommu</pre>



<p>Example output:</p>



<pre class="wp-block-preformatted">[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-6.8.0-52-generic root=UUID=6b78fa89-a575-432d-a445-1497c3467214 ro iommu=on<br />[    0.000000] Unknown kernel command line parameters "BOOT_IMAGE=/boot/vmlinuz-6.8.0-52-generic iommu=on", will be passed to user space.<br />[   11.561684] <strong>iommu: Default domain type: Translated</strong><br />[   11.566470] <strong>iommu: DMA domain TLB invalidation policy: strict mode</strong></pre>



<p>If IOMMU is not enabled, add <code>iommu=on</code> to the Linux kernel boot parameters:</p>



<pre class="wp-block-preformatted">$ vim /etc/default/grub </pre>



<p>Modify the line:</p>



<pre class="wp-block-preformatted">GRUB_CMDLINE_LINUX_DEFAULT="iommu=on"</pre>



<p>Then update GRUB and reboot:</p>



<pre class="wp-block-preformatted">$ update-grub2  <br />$ reboot  </pre>



<p>Additionally, enable SR-IOV in the BIOS. The exact location of this setting varies depending on the BIOS, but it is typically found under the PCIe subsystem or related options.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="770" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-4.png" alt="" class="wp-image-6183" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-4.png 1280w, https://blog.richliu.com/wp-content/uploads/2025/02/image-4-600x361.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-4-768x462.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-4-816x491.png 816w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>



<h3 class="wp-block-heading" id="host-upgrade-to-hwe-kernel"><strong>Upgrade Host to HWE Kernel</strong></h3>



<p>I recommend using the Hardware Enablement (HWE) kernel on the host. While I’m unsure if the regular kernel works, the HWE kernel has been reliable in my experience. Install it with:</p>



<pre class="wp-block-preformatted">sudo apt install linux-generic-hwe-22.04</pre>



<h3 class="wp-block-heading" id="configure-the-vfio-on-host">Configure VFIO on Host</h3>



<p>The VM relies on the VFIO driver for GPU passthrough. To configure VFIO, you need to pass the PCIe device information to the VFIO driver.</p>



<p>First, identify the GPU’s PCIe device IDs:</p>



<pre class="wp-block-preformatted">$ lspci -nn</pre>



<p>Example output:</p>



<pre class="wp-block-preformatted"><br /><br />0005:01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [<strong>10de:2704</strong>] (rev a1)<br />0005:01:00.1 Audio device [0403]: NVIDIA Corporation Device [<strong>10de:22bb</strong>] (rev a1)</pre>



<p>Here, <strong><code>10de:2704</code> </strong>is the GPU’s PCIe device ID, and <code><strong>10de:22bb</strong></code> is the audio device ID. At a minimum, you need to pass through the GPU device.</p>



<p>Next, edit the VFIO configuration file to include these IDs:</p>



<pre class="wp-block-preformatted">$ vim /etc/modprobe.d/vfio.conf</pre>



<p>Add the following line:</p>



<pre class="wp-block-preformatted">options vfio-pci ids=10de:2704,10de:22bb</pre>



<h3 class="wp-block-heading" id="disable-nvidia-driver-on-the-host">Disable Nvidia Driver on HOST</h3>



<p>To prevent the host from loading the Nvidia driver, add the Nvidia modules to the kernel’s blocklist:</p>



<pre class="wp-block-preformatted">$ vim /etc/modprobe.d/blacklist.conf</pre>



<p>Add the following lines:</p>



<pre class="wp-block-preformatted">blacklist nvidia<br />blacklist nvidia_drm<br />blacklist nvidia_modeset</pre>



<p>Update the initramfs and reboot:</p>



<pre class="wp-block-preformatted">$ update-initramfs -u<br />$ reboot</pre>



<h2 class="wp-block-heading" id="configure-vm">Configure VM</h2>



<h3 class="wp-block-heading" id="i">Install Virt-manager</h3>



<p>In this article, we used virt-manager as VM manager, first step is install virt-manager, suppose Ubuntu will install all relative packages. </p>



<pre class="wp-block-preformatted">$ apt install virt-manager </pre>



<p>If you’re using SSH with X11 forwarding (e.g.,&nbsp;<code>ssh -X host</code>) or MobaXTerm on Windows, Virt-manager will display the remote X window. If neither method works, consider installing a KDE desktop on the host and accessing it via the BMC remote console.</p>



<p>(Optional) Install KDE Plasma Desktop:</p>



<pre class="wp-block-preformatted">(option)<br />$ apt install kde-plasma-desktop</pre>



<h3 class="wp-block-heading" id="create-vm-image">Create VM image</h3>



<p>Virt-manager creates fixed-size VM images by default. If you prefer dynamic allocation, create the image manually:</p>



<pre class="wp-block-preformatted">$ qemu-img create -f qcow2 ubuntu2204.qcow2 200G</pre>



<h3 class="wp-block-heading" id="create-vm">Add Nvidia device to VM</h3>



<p>If the host is configured correctly, Virt-manager will list all PCIe devices, including the Nvidia GPU. Add the GPU and its audio device (e.g., <code><strong>0005:01:00.0</strong></code> and <code><strong>0005:01:00.1</strong></code>) to the VM’s hardware list.</p>



<p>After adding the devices, proceed with the Ubuntu 22.04 installation.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1023" height="632" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-5.png" alt="" class="wp-image-6184" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-5.png 1023w, https://blog.richliu.com/wp-content/uploads/2025/02/image-5-600x371.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-5-768x474.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-5-816x504.png 816w" sizes="(max-width: 1023px) 100vw, 1023px" /></figure>



<p>After add hardware </p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1046" height="646" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-6.png" alt="" class="wp-image-6185" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-6.png 1046w, https://blog.richliu.com/wp-content/uploads/2025/02/image-6-600x371.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-6-768x474.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-6-816x504.png 816w" sizes="(max-width: 1046px) 100vw, 1046px" /></figure>



<p>Now, it can run begin install to install ubuntu 22.04</p>



<h3 class="wp-block-heading" id="disable-security-boot">Disable secure Boot in UEFI</h3>



<p>By default, Virt-manager enables Secure Boot. However, Nvidia drivers may not work with Secure Boot enabled. Even though the Nvidia installer includes a driver signing feature, the driver may still fail to load. To avoid issues, disable Secure Boot in the VM’s UEFI settings.</p>



<p>During the VM’s boot process, press the <strong><code>DEL</code> </strong>key to enter UEFI settings and uncheck the Secure Boot option.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="973" height="632" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-7.png" alt="" class="wp-image-6186" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-7.png 973w, https://blog.richliu.com/wp-content/uploads/2025/02/image-7-600x390.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-7-768x499.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-7-816x530.png 816w" sizes="(max-width: 973px) 100vw, 973px" /></figure>



<p>Before installing the Nvidia driver, ensure the necessary development packages are installed:</p>



<pre class="wp-block-preformatted">$ apt install build-essential</pre>



<p>Then, install the Nvidia driver and reboot the VM.</p>



<h3 class="wp-block-heading" id="gpu-passthrough-test">GPU Passthrough Test</h3>



<p>If everything is set up correctly, running <code><strong>nvidia-smi</strong></code> should display the GPU’s status.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="515" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-8.png" alt="" class="wp-image-6188" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-8.png 1280w, https://blog.richliu.com/wp-content/uploads/2025/02/image-8-600x241.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-8-768x309.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-8-816x328.png 816w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>



<p>For testing, you can use&nbsp;<strong>Ollama</strong>&nbsp;with the&nbsp;<strong>Deepseek-R1</strong>&nbsp;model. Install Ollama with:</p>



<pre class="wp-block-preformatted">curl -fsSL https://ollama.com/install.sh | sh</pre>



<p>Pull the Deepseek-R1 model. Since the GPU has 16GB of memory, the 14B model is a good choice (it requires ~10GB):</p>



<pre class="wp-block-preformatted">ollama run deepseek-r1:14b</pre>



<p>Ask a question like, “Why is the sky blue?” This will trigger the model’s Chain-of-Thought (CoT) reasoning.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="772" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-9.png" alt="" class="wp-image-6189" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-9.png 1280w, https://blog.richliu.com/wp-content/uploads/2025/02/image-9-600x362.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-9-768x463.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-9-816x492.png 816w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>



<p>Monitor the GPU’s status using <code>nvidia-smi</code> to ensure it’s functioning correctly.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="577" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-10.png" alt="" class="wp-image-6190" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-10.png 1280w, https://blog.richliu.com/wp-content/uploads/2025/02/image-10-600x270.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-10-768x346.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-10-816x368.png 816w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>



<p></p>



<p></p>



<p></p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/12/6182/gpu-passthrough-on-arm64-with-libvirt-virt-manager/">GPU Passthrough on ARM64 with Libvirt/Virt-manager</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/02/12/6182/gpu-passthrough-on-arm64-with-libvirt-virt-manager/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ragflow on ARM64</title>
		<link>https://blog.richliu.com/2025/02/10/6176/ragflow-on-arm64/</link>
					<comments>https://blog.richliu.com/2025/02/10/6176/ragflow-on-arm64/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Mon, 10 Feb 2025 14:46:17 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Altra]]></category>
		<category><![CDATA[Ampere]]></category>
		<category><![CDATA[arm64]]></category>
		<category><![CDATA[DeepSeek]]></category>
		<category><![CDATA[Ragflow]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6176</guid>

					<description><![CDATA[<p>RAGFlow is an open-source RAG (Retrieval-Augmented Gene [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/10/6176/ragflow-on-arm64/">Ragflow on ARM64</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://ragflow.io/" target="_blank" rel="noopener"><strong>RAGFlow</strong></a> is an open-source RAG (Retrieval-Augmented Generation) engine built on deep document understanding. It is very easy to use and install. However, RAGFlow does not officially support the ARM64 platform, so it needs to be built from source for deployment on ARM64 systems.</p>



<span id="more-6176"></span>



<p>In this article, I will skip other steps such as installing Ollama.</p>



<p><strong>System Specifications:</strong></p>



<ul class="wp-block-list">
<li><strong>OS:</strong> Ubuntu 22.04 on an ARM64 virtual machine</li>



<li><strong>CPU:</strong> Ampere Altra</li>



<li><strong>DRAM:</strong> 32GB (allocated to the VM, though smaller models do not require this much memory)</li>
</ul>



<p>At the time of writing, Infinity does not support the ARM64 platform, but that is not an issue since we do not need it. RAGFlow uses Elasticsearch as its default AI database engine, and Elasticsearch does support the ARM64 platform.</p>



<h2 class="wp-block-heading">Building RAGFlow on ARM64</h2>



<p>Build ragflow command [ref. <a href="https://ragflow.io/docs/dev/build_docker_image" target="_blank" rel="noopener">Build a RAGFlow Docker Image</a>]</p>



<pre class="wp-block-preformatted">git clone https://github.com/infiniflow/ragflow.git<br />cd ragflow/<br />docker build --build-arg LIGHTEN=1 -f Dockerfile -t &lt;username&gt;/ragflow:&lt;version&gt; .<br /><br />docker build --build-arg LIGHTEN=1 -f Dockerfile -t user/ragflow:v0.16.0 .</pre>



<p>If everything is set up correctly, the Docker images will display an output similar to the following:</p>



<pre class="wp-block-preformatted">docker images<br />REPOSITORY                                      TAG                            IMAGE ID       CREATED         SIZE<br />user/ragflow                                    v0.16.0                        8a71ac9cb2fa   3 hours ago     5.73GB</pre>



<p>Note that this image does not include pre-built models. However, models can be installed separately using other methods.</p>



<h2 class="wp-block-heading">Running RAGFlow</h2>



<p>Before running the <code><strong>docker-compose</strong></code> command, assign the RAGFlow Docker image name to the <code><strong>docker-compose</strong></code> configuration.</p>



<pre class="wp-block-preformatted">export RAGFLOW_IMAGE=user/ragflow:v0.16.0<br />docker compose -f docker/docker-compose.yml up -d</pre>



<p>If everything is set up correctly, you should see a message similar to the following:</p>



<pre class="wp-block-preformatted">[+] Running 10/10<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Network docker_ragflow      Created                                                                         0.2s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Volume "docker_minio_data"  Created                                                                         0.0s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Volume "docker_redis_data"  Created                                                                         0.0s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Volume "docker_esdata01"    Created                                                                         0.0s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Volume "docker_mysql_data"  Created                                                                         0.0s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Container ragflow-mysql     Healthy                                                                        21.7s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Container ragflow-minio     Started                                                                         1.1s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Container ragflow-redis     Started                                                                         1.1s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Container ragflow-es-01     Started                                                                         1.1s<br /> <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Container ragflow-server    Started                                                                        22.3s<br /></pre>



<p>Downloading Models with Ollama</p>



<p>Ollama needs to download certain models for system functionality. Here’s an easy way to download the models—you can choose the ones you prefer.</p>



<pre class="wp-block-preformatted">ollama pull deepseek-r1:14b<br />ollama pull deepseek-r1:32b<br />ollama pull smartcreation/bge-large-zh-v1.5:latest</pre>



<p>After downloading the Ollama models, you need to add them in the <strong>&#8220;USER → Model Providers → Add Ollama Model&#8221;</strong> section. Below is an example of how to add the Deepseek model. Once you understand the process, you can add more models as needed.</p>



<p>At a minimum, you will need one chat model and one embedding model.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="764" height="913" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-1.png" alt="" class="wp-image-6177" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-1.png 764w, https://blog.richliu.com/wp-content/uploads/2025/02/image-1-502x600.png 502w" sizes="(max-width: 764px) 100vw, 764px" /></figure>



<p>After pressing <strong>OK</strong>, you can configure the <strong>System Model Settings</strong>, which should look something like this:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="761" height="933" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-2.png" alt="" class="wp-image-6178" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-2.png 761w, https://blog.richliu.com/wp-content/uploads/2025/02/image-2-489x600.png 489w" sizes="(max-width: 761px) 100vw, 761px" /></figure>



<p>Using RAGFlow</p>



<p>Now, you are ready to use the&nbsp;<strong>Knowledge Base</strong>&nbsp;and&nbsp;<strong>Chat</strong>&nbsp;features to explore RAGFlow.</p>



<p>For example, you can ask the engine to generate an ARM SIMD sample code based on the ARMv8 documentation.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1742" height="1021" src="https://blog.richliu.com/wp-content/uploads/2025/02/image-3.png" alt="" class="wp-image-6179" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image-3.png 1742w, https://blog.richliu.com/wp-content/uploads/2025/02/image-3-600x352.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-3-768x450.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-3-1536x900.png 1536w, https://blog.richliu.com/wp-content/uploads/2025/02/image-3-816x478.png 816w" sizes="(max-width: 1742px) 100vw, 1742px" /></figure>



<p>Conclusion</p>



<p>RAGFlow is an easy-to-use RAG framework. Although it does not provide a default ARM64 image, you can still build it from source to obtain a functional version of RAGFlow.</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/10/6176/ragflow-on-arm64/">Ragflow on ARM64</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/02/10/6176/ragflow-on-arm64/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DeepSeek-R1 風暴</title>
		<link>https://blog.richliu.com/2025/02/07/6166/deepseek-r1-%e9%a2%a8%e6%9a%b4/</link>
					<comments>https://blog.richliu.com/2025/02/07/6166/deepseek-r1-%e9%a2%a8%e6%9a%b4/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Fri, 07 Feb 2025 12:48:20 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[2025]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[DeepSeek]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6166</guid>

					<description><![CDATA[<p>這個春節被 DeepSeek 洗版了，這篇文章是記錄一下這段期間為什麼 Deepseek 這麼紅。文章的前面是 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/07/6166/deepseek-r1-%e9%a2%a8%e6%9a%b4/">DeepSeek-R1 風暴</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>這個春節被 DeepSeek 洗版了，這篇文章是記錄一下這段期間為什麼 Deepseek 這麼紅。文章的前面是我的看法，後半段就是用 Notebook LM 就我認為的優質資料整理之後再稍加修改後產生</p>



<p>我在 DeekSeek V3 (非思維鏈模型）出來的時候才開始用，而 DeepSeek V3 出來時就讓其他家大陸大模型費用降到一個非常可觀的地步，當時報導都幾乎沒提到是 DeekSeek V3 的影響</p>



<span id="more-6166"></span>



<p>個人因為 GPT 用量不高，所以一直都是使用免費版，以免付費使用，個人評價是 ChatGPT 比 Claude 稍好，比 Gemini 強很多，如果 DeepSeek V3 同時比較，DeepSeek V3 表現最好，所以使用 DeepSeek V3 一陣子了，通常這類模型只要不問敏感話題都可以用的很快樂。</p>



<p>這次引發西方動搖國本式的震驚還是因為 DeepSeek-r1 是開源的思維鏈（Chain-of-Thought, CoT）大語言模型。簡單的說一下思維鏈大語言模型，是通過模擬人類的推理過程來提升模型在複雜任務中的表現。核心思想是讓模型在生成最終答案之前，先逐步推匯出中間步驟，從而更好地解決需要邏輯推理、數學計算或多步思考的問題</p>



<p>這個思維鏈在某些創意類型的工作上會有非常突出的表現，最近網路上很多風格特別的文章和影片都是如此生成的，像是給韓國或是美國歷任總統取廟號和諡號，或是用武俠風格寫一些平淡無奇的小事等等。但是思維鏈有個缺點，非常耗算力，所以在 DeepSeek-r1 出來之前，只有 OpenAI-o1 提供，而且是要月付 200 美金的才能有限制使用</p>



<p>DeepSeek-r1 一推出就轟動武林了，因為<br />1. 免費讓你隨便用<br />2. 告訴你再訓練成本超低，使用成本超低<br />3. 公開程式碼和權重參數<br />4. 是中國的公司開源的，比起什麼 OpenAI 東藏西藏技術，開源更能說服大家</p>



<h2 class="wp-block-heading">低成本革命</h2>



<p>不過要我選一個，那一定是低成本，因為思維鏈極耗算力，所以降算力這件事是非常的有意思，等於是一場革命。</p>



<p>我拿一個小故事來說好了，2000 年左右，在DSL(Digital Subscriber Lin)，透過電話線傳輸數據的技術出現之前，電信公司對於這類技術並不太感興趣，因為當時 .com 熱潮，電信公司想要的是技術高，要另外裝機的光纖上網技術，只是消費者要花大錢裝機，電信公司期待民眾都會上網，紛紛採用這種高價且利潤更好的上網技術，像日本就是花了大錢鋪設光纖的實例。台灣也是類似，有興趣可以查當年的股條事件，就是炒作固網概念。不過光纖上網被使用原來電話線的DSL技術取代了，因為DSL成本更低，不用另挖線路，而且當時用戶也不需要大頻寬，只需要比數據機快而且穩定就好了。DSL又變成技術主流十多年，因為成本低裝機費用低，用戶接受度非常高。</p>



<p>DeepSeek-r1 也是一樣，雖然比不上 OpenAI-o3 這類新的思維鏈技術，但是如果價格只有 1/30 不過效果有 95% 好，消費者想都不想一定是選擇便宜的，這就是低成本的優勢。尤其是價格差距過大，除非有一定非用不可的理由，否則人都是誠實的，反映在財報上都是誠實的</p>



<p>試用了 API 價格，一篇文章約 12000 tokens （中文英文的 tokens 計算方式不一樣），目前價格 US$0.0016 ，原價加倍，如果是 DeekSeek-R1 模型再加倍，這個價格非常划算，可以服務都接上去了。下圖是使用 deepseek-chat</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="573" src="https://blog.richliu.com/wp-content/uploads/2025/02/image.png" alt="" class="wp-image-6171" srcset="https://blog.richliu.com/wp-content/uploads/2025/02/image.png 1024w, https://blog.richliu.com/wp-content/uploads/2025/02/image-600x336.png 600w, https://blog.richliu.com/wp-content/uploads/2025/02/image-768x430.png 768w, https://blog.richliu.com/wp-content/uploads/2025/02/image-816x457.png 816w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>這種價格很多企業可能都會直接接入，或許還比自架還便宜[<a href="https://unwire.hk/2025/02/06/deepseek-r1-2/ai/" target="_blank" rel="noopener">華為 AI 接入 DeepSeek-R1 「小藝助手」變得更智能</a>]</p>



<h2 class="wp-block-heading">開源風暴</h2>



<p>一般記者講開放原始碼是錯的，DeepSeek 是開放模型和權重<br />DeepSeek-r1 是第一個可以跟 OpenAI o1-mini 開放思維鏈的相比的開放模型，在 LLM AI model 的世界，開放資料幾乎不可能也沒必要，是有公司做影片的開放訓練資料，但是 LLM 這邊沒有</p>



<p>對於認真在追 GPT 技術的公司或是學校，目前應該都拼命在研究 DeepSeek-r1 演算法，這部份我不熟，但是目前看到的訊息都和放出來的東西是一致的。的確 Deepseek-r1 非常節能</p>



<p>這次事件傷害最大的應該是 OpenAI ，雖然 OpenAI 有領先優勢，但是在 DeepSeek-r1 出來之後，這個領先優勢就不明顯了，然後頭部玩家(Groq, Claude, Llama, Qwen 等等)目前應該都在追思維鏈技術，很快的大家在資源和運算量最佳化這塊就會同步了，就這篇寫出來的時候 Qwen 在過年前放出了 Qwen 2.5-Max，OpenAI 有 o3 和 o3-mini ，Google 更新了一堆 Gemini 2.0 和 CoT 的模型</p>



<p>雖然 OpenAI 更棒，但是 OpenAI 也有困境，要跟著下去用 DeepSeek-r1 還是要繼續 ChatGPT V5 還是 ChatGPT-o4 這類超巨大算力的模型</p>



<p>這邊會衍生出一個問題，很多人以為 DeepSeek 是從 OpenAI 偷資料來的，如只是指蒸餾，那大家都會做，DeepSeek OpenModel 上面寫也可以商用和蒸餾。而且以中文語境的表現來來說，DeepSeek-r1 的表現好到不像話，這邊提供一些不錯的玩法，有興趣的可以照著玩[<a href="https://www.bilibili.com/video/BV192Ffe1EwJ/" target="_blank" rel="noopener">10大隱藏提示詞，教你把Deepseek訓練成精！</a>]，有些技巧也可以用在其他 LLM 上</p>



<pre class="wp-block-preformatted">1賽博人格分裂，(啟動人格分裂討論模式+問題)<br />2陰陽怪氣模式，(問題+笑死)毒舌屬性<br />3觸發預判模式，假設性問題(如果，，，會不會，，，)<br />4預言家模式，預判未來(如果，，，會發生什麼事)<br />5靈魂拷問模式，(①啟動槓精模式②先寫方案，再模擬槓精從*個角度狂噴，最後給出V2版方案)，<br />6玄學程式設計(，，，帶點蟬意)<br />7馴服轉業話癆，(說人話！)<br />8人設黏貼術，<br />9啟動老闆思維(如果你是，，，你會怎麼罵這個方案)<br />10過濾廢話，(問題，+刪掉所有正確的廢話，只留能落地的建議)</pre>



<p>這邊有個日本人玩 deepseek 以中文寫詩，這中文能力並不是其他 LLM 可以比的[<a href="https://x.com/rongtangjushi/status/1885588215584936095?s=12&amp;t=FEMQEePTARdd0HSpaf-okA">ref</a> X]</p>



<h2 class="wp-block-heading">PTX 及系統最佳化</h2>



<p>很多人提到 DeepSeek-r1 用了 PTX (Parallel Thread Execution) 加速，因為要節省資源，PTX 有點像組合語言(Assembly)，在現代計算機中，跳過 compiler 直接去操作組合語言省不到幾毛錢的時間和金錢，會去動用 PTX 一定有其更重要的原因，因為做 PTX 的風險很大，我個人認為應該是拆解 CUDA 做不到的事情，只能自己手刻，這才有投入資源的必要性</p>



<p>看到報導說最多的是因為針對 H800 頻寬不夠所以才去動 PTX ，我們看不到發想的開始，但是就結果論，應該是針對一系列問題的最佳解，除了節省頻寬，節省VRAM使用量，減少節點之間的通訊成本，採用混合精度系統（在某些地方採用對FP8），等等改進圍繞的一系列魔改底層的概念，他們要的功能CUDA做不到，所以只能魔改了</p>



<p>在FP8 方面，DeepSeek 在張量核心內的所有 tensor 計算中使用 4 位指數和 3 位尾數——稱為 E4M3，之前也有人試著要實現 E3M4 的 tensor 計算，不過精度損失太多所以失敗。Deepseek 看起來解決了這個難題，看起來是採用混合精度，V3 模型的大部分核心都是以 FP8 格式實現的。但某些操作仍需要 16 位或 32 位精度，且主權重、權重梯度和優化器狀態以高於 FP8 的精度存儲</p>



<p>應該沒有提到使用 deepseek 產出 PTX ，不過以這種工程，個人猜測應該有弄了一版 deepseek/PTX 專用版，這樣就可以大幅加速研發，而且並不是沒有先例，最近才有人用deepseek加速 SIMD ggml 程式碼[<a href="https://github.com/ggerganov/llama.cpp/pull/11453" target="_blank" rel="noopener">ggml : x2 speed for WASM by optimizing SIMD</a>&nbsp;]，而CUDA source 在 2022 年的時候已經被駭客洩漏[<a href="https://segmentfault.com/a/1190000041488372" target="_blank" rel="noopener">It is reported that hackers leaked 75GB of Nvidia confidential files, including DLSS source code!</a>]，如果拿到 source code ，那還會節省不少功夫。畢竟在用非正版訓練資料集上，這點大家都差不多[<a href="https://cybernews.com/tech/meta-leeched-82-terabytes-of-pirated-books-to-train-its-llama-ai-documents-reveal/" target="_blank" rel="noopener">Meta leeched 82 terabytes of pirated books to train its Llama AI, documents reveal</a>]</p>



<p>當然還不僅僅只是PTX，整個系統還有一個 DualPipe 的架構主要負責 NVLink / InfiniBand / RDMA 等等地方做數據傳輸。</p>



<p>如果照這些已知的訊息看起來，DeepSeek 應該是自己實現了（或是未來會實現）一個類似 CUDA 的架構，而這個架構只有最底層 hardware 是 NV 的。這樣的好處就要加什麼 hardware 要實現什麼功能可以自己改，缺點就是維護這樣一套系統的成本很高。不過如果是 deepseek 這個決策是非常合理的，畢竟在中國大陸被制裁 硬體的狀況之下，那天說不定連 NV 都沒得用，在底層設計更多的硬體彈性是必要的[<a href="https://unwire.hk/2025/02/05/huawei-910c-60percent-h100/ai/" target="_blank" rel="noopener">DeepSeek 測試：華為昇騰 910C 效能達 H100 六成　盼減低依賴 NVIDIA</a>](註:這邊是講 interference)</p>



<h2 class="wp-block-heading">Reinforcement learning (RL) 強化學習</h2>



<p>這部份其實是 DeepSeek-r1 需要提的，因為這部份是large-scale reinforcement learning (RL) without super-vised fine-tuning (SFT)，不需要人類監督的強化學習系統。以前的資料訓練出來需要人類標註，但是 DeepSeek-r1 的 RL 技術不依賴人類標記，從而可以加強思維鏈推理的效能。</p>



<p>其中提到的是 hardccoded rule 做最後評斷，不過我覺得可能是一種類專家系統。人類也是有介入，但是這種介入就不是監督輸出，而是對齊資料輸出。DeepSeek 的 RL 技術強調在沒有人類監督的情況下，透過獎勵機制和自我對弈來提升模型的推理能力</p>



<h2 class="wp-block-heading">以下是 AI 寫的介紹</h2>



<p>其它的大家應該也看的很多了，我就交給 AI 寫了，以下都是 AI 產生</p>



<p>這篇文章將分為四個部分，詳細介紹 DeepSeek 的發展歷程、技術優勢與不足、創辦人梁文鋒的觀點，以及針對 DeepSeek 的一些質疑與澄清。</p>



<h3 class="wp-block-heading">1. 從幻方量化基金到 DeepSeek 的誕生</h3>



<p>DeepSeek 的故事不僅是一個 AI 新創公司的崛起，更是一段從量化投資跨足通用人工智慧 (AGI) 的技術進化史。其前身幻方量化基金為 DeepSeek 的技術發展奠定了堅實的基礎 。</p>



<ul class="wp-block-list">
<li><strong>幻方量化：AI 基因的起源</strong></li>



<li><strong>成立與發展</strong>：2008 年，梁文鋒在浙江大學就學期間創立了幻方量化，初期致力於探索全自動化交易。2015 年，幻方將數學與 AI 應用於量化投資，確立了 AI 為公司主要發展方向。</li>



<li><strong>技術實力</strong>：幻方量化專注於算法和量化核心引擎的研發，並自行建構了「螢火一號」和「螢火二號」AI 集群，搭載了數千張 A100 顯卡。</li>



<li><strong>早期 AI 應用</strong>：早在 2016 年，幻方量化就已將 AI 模型應用於股票倉位交易，並於 2017 年底實現量化策略的全面 AI 化，成為量化投資領域的創新先鋒 。</li>



<li><strong>算力投入</strong>：幻方在 2022 年已平均每天使用 4.2 萬 GPU 小時進行科研，相當於每天有近 2000 張 GPU 卡在幾乎滿負荷運行，展現其在 AI 研究上的巨額投入 。</li>



<li><strong>DeepSeek 的誕生：邁向 AGI 的新篇章</strong> </li>



<li><strong>轉型 AGI</strong>：2023 年 4 月，在開源模型 Llama1 和 GPT-4 發布後，幻方決定進軍大模型領域。同年 5 月，將技術部門獨立出來成立深度求索公司，專注於 AGI 的發展。</li>



<li><strong>技術繼承</strong>：雖然 DeepSeek 公司成立時間不長，但其背後的技術根基來自於幻方量化 17 年的積累，以及超過 5 年的 AI 研究經驗 。</li>



<li><strong>商業模式</strong>：與 DeepMind 和 OpenAI 不同，DeepSeek 從一開始就具有盈利和技術商業化的考量。它繼承了幻方 AI「純 AI 研究」到「AI 量化引擎」的業務獨立模式，使其在財務上更為穩健。</li>



<li><strong>資金挑戰與效率</strong>：2024 年 DeepSeek 面臨資金挑戰，但這也促使其將資金利用效率推至極限。</li>
</ul>



<h3 class="wp-block-heading">2. DeepSeek 的技術優勢、缺點與對未來 AI 的影響</h3>



<p>DeepSeek 的技術優勢主要體現在其<strong>獨特的模型訓練方法、對底層硬體的優化，以及在中文處理上的強大能力</strong> ，這些優勢使其在眾多 AI 模型中脫穎而出：</p>



<ul class="wp-block-list">
<li><strong>強化學習 (RL) 與推理能力</strong> </li>



<li><strong>DeepSeek-R1-Zero</strong>: <strong>不依賴人類監督數據</strong>，直接使用強化學習訓練基礎模型，使其能自主發展出強大的推理能力，並能自我驗證、反思，產生長鏈的思考 (Chain-of-Thought, CoT)。 這是 DeepSeek 的一個重要突破，證明了僅透過 RL 就能激發模型的推理能力 。</li>



<li><strong>DeepSeek-R1</strong>: 在 R1-Zero 的基礎上，加入了少量冷啟動數據 (cold-start data) 和多階段訓練流程，以提高模型的可讀性和通用能力 。 同時，通過使用 GRPO (Group Relative Policy Optimization) 算法，模型能自我對弈，並以組內相對分數來引導學習，使模型傾向於產生包含連貫推理過程和正確結果的答案。</li>



<li><strong>不依賴人類反饋</strong>： DeepSeek 的訓練方式不再依賴人類偏好的反饋，而是透過可量化的指標（如數學和程式碼的正確性）來引導模型的學習方向。</li>



<li><strong>模型提煉 (Distillation)</strong> </li>



<li>DeepSeek 將大型模型的推理能力提煉到較小的模型中，使得較小模型能達到與大型模型相近的效能。例如，DeepSeek-R1-Distill-Qwen-7B 在 AIME 2024 測試中，得分 55.5%，超越了 QwQ-32B-Preview。</li>



<li><strong>此舉降低了部署和運行 AI 模型的資源需求</strong>，使得一般企業或個人也能在較小的設備上使用 AI 模型。</li>



<li><strong>底層優化</strong></li>



<li>DeepSeek 團隊對底層 CUDA 進行優化，直接使用類似組語 (assemble) 的語言控制 NV 顯卡，提高了訓練效率。</li>



<li>他們能夠使用 FP8 (8 位元浮點數) 精度來訓練模型，這讓算力直接翻倍，也使得可以使用過時的 GPU（例如 7nm 的 920B）來進行後訓練 (post-training)，降低了模型研發和更新的成本。</li>



<li>在 MoE (Mixture of Experts) 模型上，DeepSeek 著重於優化 NVLink 上的負載均衡，減少通訊成本，並在推理端使用 KV Cache 壓縮和多 Token 預測等技術，加速模型推論速度。</li>



<li><strong>中文處理能力</strong>：DeepSeek-R1 的中文思考和產出能力非常強大，這是其他英文模型難以匹敵的優勢。</li>
</ul>



<p>DeepSeek 的潛在缺點包括:</p>



<ul class="wp-block-list">
<li><strong>非推理任務的不足</strong>：在功能呼叫、多輪對話、複雜角色扮演和 JSON 輸出等非推理任務上，DeepSeek-R1 的能力略遜於 DeepSeek-V3。</li>



<li><strong>語言混合問題</strong>： DeepSeek-R1 在處理非中文或英文的查詢時，可能會出現語言混合的問題，例如使用英語進行推理和回應，即使查詢是使用其他語言 。</li>



<li><strong>對提示詞的敏感性</strong>：DeepSeek-R1 對提示詞 (prompt) 非常敏感，少量樣本提示 (few-shot prompting) 會使其效能下降，因此建議用戶直接描述問題並使用零樣本設定 (zero-shot setting) .</li>



<li><strong>部分領域輸出較弱</strong>：為降低算力需求，DeepSeek 的模型可能在某些領域的輸出較弱，但對於一般用戶來說，這些差異可能不明顯。</li>



<li><strong>量化模型的精度損失</strong>：由於使用 FP8 等量化方法，DeepSeek 的模型精度可能略低於使用更高精度（例如 FP16/BP16）的模型，但這種差異可能並不明顯 。</li>
</ul>



<p>DeepSeek 對未來 AI 發展的影響:</p>



<ul class="wp-block-list">
<li><strong>打破 AI 發展的限制</strong>:</li>



<li>DeepSeek 證明了<strong>純強化學習</strong> 可以訓練出強大的推理模型，而無需大量人類標記的數據或人類偏好，這挑戰了傳統 AI 模型訓練的範式。</li>



<li>透過 <strong>底層硬體優化</strong>，DeepSeek 降低了 AI 模型訓練和部署的成本，使得 AI 技術更加普及，不再侷限於大型企業或研究機構。</li>



<li><strong>推動 AI 技術的開源與共享</strong>:</li>



<li>DeepSeek 的 <strong>開源策略</strong> 鼓勵了更多人參與 AI 技術的開發和改進，促進了知識的共享和技術的快速發展。</li>



<li>DeepSeek 開放模型權重和訓練細節的做法，有助於建立一個更加開放、透明的 AI 生態系統，吸引更多研究者共同參與，形成「韌性飛輪」效應。</li>



<li><strong>改變 AI 產業的競爭格局</strong>:</li>



<li>DeepSeek 的出現讓其他公司意識到，<strong>規模化並非 AI 發展的唯一途徑</strong>，演算法創新和底層優化同樣重要。</li>



<li>隨著 <strong>AI 模型商品化</strong>，未來的競爭將會轉向應用層面和客戶服務，而不是基礎模型的開發。</li>



<li><strong>加速 AI 技術的普及和應用</strong>:</li>



<li>DeepSeek 的低成本和高性能模型，將使得 AI 技術能夠在更多領域得到應用，例如企業內部私有 AI、個人 AI 助理等。</li>



<li>AI 技術的普及將推動各行業的變革，加速人類文明的巨變 。</li>



<li><strong>地緣政治影響</strong> : DeepSeek 的成功顯示 <strong>中國 AI 技術正在趕上美國</strong>，對全球 AI 供應鏈和地緣政治產生影響。開放權重模型成為 AI 供應鏈的關鍵，若美國繼續打壓開源，中國可能會主導這一部分。</li>
</ul>



<h3 class="wp-block-heading">3. 梁文鋒對 DeepSeek 和 AI 的看法</h3>



<p>DeepSeek 創辦人梁文鋒是一位技術出身的 CEO，對 AI 的發展有著獨到的見解 ：</p>



<ul class="wp-block-list">
<li><strong>技術創新為本</strong>：梁文鋒認為，DeepSeek 的目標是參與全球創新浪潮，而不是單純追求商業利益。他強調技術創新是 DeepSeek 的核心競爭力，並認為中國 AI 不應永遠處於跟隨位置，必須做出原創性貢獻。</li>



<li><strong>開源與生態</strong>：梁文鋒堅信建立強大的技術生態比閉源更重要，因此 DeepSeek 選擇開源其技術，吸引更多人才參與。他認為，開源能促進知識共享，加速技術發展。</li>



<li><strong>AGI 的長期目標</strong>：梁文鋒將 AGI (通用人工智慧) 作為 DeepSeek 的終極目標，認為當下的一切都只是過程，追逐技術創新是實現 AGI 的必經之路 [4, 59]。 他認為數學和程式碼是 AGI 天然的試驗場，並對多模態和自然語言本身保持開放。</li>



<li><strong>對算力的看法</strong>：梁文鋒認為，更多的投入不一定會產生更多的創新，也並非只有高階晶片才能推動 AI 發展。DeepSeek 的成功證明，透過優化算法和軟硬體協同設計，即使在資源有限的情況下也能實現技術突破。</li>



<li><strong>對人才的看法</strong>：梁文鋒認為，頂尖人才應該被吸引去解決世界上最難的問題，因此 DeepSeek 致力於創造一個讓技術人才可以充分發揮才能的環境 [61]。 他認為，目前中國的頂尖人才被低估了，因為社會缺乏硬派創新，讓他們沒有機會被辨識出來。</li>



<li><strong>對技術與商業的看法</strong>：梁文鋒認為，商業上的成功應建立在技術實力的基礎之上，且要對商業抱有敬畏之心。 他強調，企業應該專注於自己擅長的領域，形成產業分工鏈，共同推動社會效率的提升。</li>



<li><strong>對競爭的看法</strong>：梁文鋒認為，過度關注競爭會讓人眼花撩亂，更重要的是思考如何提高社會的運作效率，並在產業分工鏈上找到自己擅長的位置。</li>
</ul>



<h3 class="wp-block-heading">4. 針對 DeepSeek 的質疑與澄清</h3>



<ul class="wp-block-list">
<li><strong>成本造假</strong>:</li>



<li><strong>質疑</strong>：有人認為 DeepSeek 宣稱的 550 萬美元訓練成本是造假，因為沒有計入資料清理、開發人力等其他成本。</li>



<li><strong>澄清</strong>：DeepSeek 在論文中明確指出 550 萬美元是單純的「訓練成本」，其他成本例如資料清理、開發人力等，通常不會列入計算，因為這些成本是多個模型共用的，且薪資水準在各國不同。另外，DeepSeek 使用 2048 片 H800 GPU 訓練兩個月的成本，以租賃方式計算，大約就是 550 萬美元。</li>



<li><strong>DeepSeek 是 OpenAI 的套殼</strong>:</li>



<li><strong>質疑</strong>：有人認為 DeepSeek 回答問題時會說是 ChatGPT，所以是套殼的 [63]。</li>



<li><strong>澄清</strong>：這僅代表 DeepSeek 的訓練資料中包含 ChatGPT 的內容，許多模型都有類似問題。且 DeepSeek 已開源，可以自行驗證。模型在訓練時並不知道自己是誰訓練的。</li>



<li><strong>DeepSeek 技術是抄來的</strong>:</li>



<li><strong>質疑</strong>：有人認為 DeepSeek 的技術是抄襲 OpenAI 的。</li>



<li><strong>澄清</strong>：DeepSeek 是開源的，OpenAI 是閉源的，若有抄襲，OpenAI 必須提出證據。目前沒有任何證據證明 DeepSeek 抄襲原始碼。而且，機器產生的資料不受著作權保護，DeepSeek 使用 OpenAI 產生的數據進行訓練，並不構成侵權，最多可能違反 OpenAI 的使用條款。此外，蒸餾 (distillation) 是 AI 模型訓練中常見的做法，DeepSeek 的模型性能甚至比老師模型 (o1) 更強，所以 DeepSeek 的性能並非源於抄襲。</li>



<li><strong>混合專家架構 (MoE) 是舊技術</strong>:</li>



<li><strong>質疑</strong>：有人認為 DeepSeek 使用的 MoE 架構是舊技術，沒有創新。</li>



<li><strong>澄清</strong>：DeepSeek 對 MoE 架構進行了許多改進，使其效能顯著提升。</li>
</ul>



<p>這篇文章綜合了多方資訊，希望能為您提供一個全面且深入的 DeepSeek 分析。DeepSeek 的崛起，不僅是對既有 AI 技術的挑戰，更是對未來 AI 發展方向的啟示。</p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/02/07/6166/deepseek-r1-%e9%a2%a8%e6%9a%b4/">DeepSeek-R1 風暴</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/02/07/6166/deepseek-r1-%e9%a2%a8%e6%9a%b4/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>幫備份 PTT 的 WordPress 文章上色</title>
		<link>https://blog.richliu.com/2025/01/10/6115/%e5%b9%ab%e5%82%99%e4%bb%bd-ptt-%e7%9a%84-wordpress-%e6%96%87%e7%ab%a0%e4%b8%8a%e8%89%b2/</link>
					<comments>https://blog.richliu.com/2025/01/10/6115/%e5%b9%ab%e5%82%99%e4%bb%bd-ptt-%e7%9a%84-wordpress-%e6%96%87%e7%ab%a0%e4%b8%8a%e8%89%b2/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Fri, 10 Jan 2025 15:22:05 +0000</pubDate>
				<category><![CDATA[Blog/wiki]]></category>
		<category><![CDATA[PTT]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6115</guid>

					<description><![CDATA[<p>PTT 很多文章有時候要回去再看的時候就已經消失了，現在 Google 也不是很好用，所以找文章的時候偶爾要備 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/01/10/6115/%e5%b9%ab%e5%82%99%e4%bb%bd-ptt-%e7%9a%84-wordpress-%e6%96%87%e7%ab%a0%e4%b8%8a%e8%89%b2/">幫備份 PTT 的 WordPress 文章上色</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>PTT 很多文章有時候要回去再看的時候就已經消失了，現在 Google 也不是很好用，所以找文章的時候偶爾要備份回自己的 wordpress 網站比較方便。本來以為備份上去的文章需要自己調色，所以在 python 端改了很久，要替換 tag 之類的</p>



<span id="more-6115"></span>



<p>沒想到，突然靈光一動，看是不是能改 html 就達到相同的目地，以為用 style 包就可以，不過怎麼會像蠢人想的這麼簡單呢？沒想到，更簡單，其實只要去拿 PTT 的 CSS 來用就可以了。然後用 GPT 之類的程式（這次我是試用 deepseek）找出不符合規範的 CSS 部份修改或是移除就好。現代人有 GPT 真的省事很多，我知道這不是最佳解，但是只是備份，有就很開心，效果還不錯，跟我想要的效果一樣。</p>



<p>以下截圖的連結 <a href="https://techarea.org/%e5%bf%83%e5%be%97-%e5%9b%a4%e7%89%a9%e6%97%8f%e7%9a%84%e4%b8%8d%e4%b8%9f%e6%9d%b1%e8%a5%bf%e6%95%b4%e7%90%86%e8%a1%93/" target="_blank" rel="noopener">[心得] 囤物族的不丟東西整理術</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1686" height="713" src="https://blog.richliu.com/wp-content/uploads/2025/01/image-2.png" alt="" class="wp-image-6117" srcset="https://blog.richliu.com/wp-content/uploads/2025/01/image-2.png 1686w, https://blog.richliu.com/wp-content/uploads/2025/01/image-2-600x254.png 600w, https://blog.richliu.com/wp-content/uploads/2025/01/image-2-768x325.png 768w, https://blog.richliu.com/wp-content/uploads/2025/01/image-2-1536x650.png 1536w, https://blog.richliu.com/wp-content/uploads/2025/01/image-2-816x345.png 816w" sizes="(max-width: 1686px) 100vw, 1686px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1462" height="865" src="https://blog.richliu.com/wp-content/uploads/2025/01/image-1.png" alt="" class="wp-image-6116" srcset="https://blog.richliu.com/wp-content/uploads/2025/01/image-1.png 1462w, https://blog.richliu.com/wp-content/uploads/2025/01/image-1-600x355.png 600w, https://blog.richliu.com/wp-content/uploads/2025/01/image-1-768x454.png 768w, https://blog.richliu.com/wp-content/uploads/2025/01/image-1-816x483.png 816w" sizes="(max-width: 1462px) 100vw, 1462px" /></figure>



<p>以下是我用的 CSS ，只有改字體以及拿到不要的部份，感覺沒影響到的我也沒拿</p>



<pre class="wp-block-preformatted">.bbs-content {<br />    font-size: 16px !important;<br />	font-family: "細明體", "AR PL UMing TW", "Menlo", "LiSongPro", monospace;<br />}<br /><br />.bbs-screen {<br />    width: auto !important;<br />}<br /><br />#main-content {<br />    white-space: normal;<br />}<br /><br />#navigation div {<br />    display: inline-block;<br />    margin: 0 4px;<br />}<br /><br />#banner {<br />    text-align: center;<br />    width: 100%;<br />    text-decoration: none;<br />}<br /><br />.richcontent {<br />    text-align: center;<br />    margin: 1em;<br />}<br /><br /><br />/* ansi colors */<br />.b0 { background-color: #000; }<br />.b1 { background-color: #b00; }<br />.b2 { background-color: #0b0; }<br />.b3 { background-color: #bb0; }<br />.b4 { background-color: #00b; }<br />.b5 { background-color: #b0b; }<br />.b6 { background-color: #0bb; }<br />.b7 { background-color: #bbb; }<br /><br />.f0 { color: #000; }<br />.f1 { color: #900; }<br />.f2 { color: #090; }<br />.f3 { color: #990; }<br />.f4 { color: #009; }<br />.f5 { color: #909; }<br />.f6 { color: #099; }<br />.f7 { color: #999; }<br /><br />.hl { color: #fff; }<br />.hl.f0 { color: #666; }<br />.hl.f1 { color: #f66; }<br />.hl.f2 { color: #6f6; }<br />.hl.f3 { color: #ff6; }<br />.hl.f4 { color: #66f; }<br />.hl.f5 { color: #f6f; }<br />.hl.f6 { color: #6ff; }<br />.hl.f7 { color: #fff; }<br /><br />/* main layout */<br />.bbs-screen {<br />	color: #bbb;<br />	background-color: #000;<br />	line-height: 100%;<br />	overflow-wrap: break-word;<br />	word-wrap: break-word;<br />	margin: 0 auto;<br />    padding: 0;<br />	width: 100%;<br />}<br /><br />.bbs-content {<br />	font-family: "細明體", "AR PL UMing TW", "Inconsolata", "LiSongPro", monospace;<br />}<br /><br />.bbs-footer-message {<br />    text-align: center;<br />    margin-top: 1em;<br />}<br /><br />.center {<br />    text-align: center;<br />}<br /><br />.warning-box {<br />    border: 1px solid #555;<br />    background-color: #333;<br />}<br /><br />.small {<br />	font-size: small;<br />}<br /><br />#main-container {<br />	margin: 0;<br />	padding: 0 0 3ex 0;<br />	position: relative;<br />}<br /><br />#main-content {<br />	position: relative;<br />	white-space: normal;<br />}<br />#main-content a:link {<br />    text-decoration: none;<br />    box-shadow: inset 0 -2px #555;<br />}<br />#main-content a:hover {<br />    box-shadow: inset 0 -2px #777;<br />}<br /><br /><br />body {<br />	background-color: #000;<br />	margin: 0;<br />	padding: 40px 0 24px 0;<br />}<br /><br /><br />.share {<br />	line-height: 40px;<br />	vertical-align: middle;<br />}<br />.brdname {<br />	float: right;<br />}<br />#navigation .board {<br />	padding: 0 10px;<br />}<br />#navigation .bar {<br />	background-color: #888;<br />	width: 4px;<br />	height: 100%;<br />	padding: 0;<br />}<br /><br />.push {<br />	line-height: 130%;<br />	white-space: normal;<br />	clear: both;<br />    position: relative;<br />}<br />.push > span {<br />	white-space: normal;<br />}<br />.push-tag {<br />	display: inline-block;<br />	min-width: 3.5ex;<br />	white-space: normal;<br />}<br />.push-content {<br />}<br />.push-ipdatetime {<br />	float: right;<br />}<br /><br />.richcontent {<br />    position: relative;<br />	text-align: center;<br />    width: 100%;<br />    margin: 0.5em auto;<br />    max-width: 800px;<br />}<br />.resize-container {<br />    position: relative;<br />    width: 100%;<br />}<br />.resize-container:before {<br />    content: "";<br />    display: block;<br />    padding-top: 56.25%;<br />}<br />.resize-content {<br />    position: absolute;<br />    top: 0;<br />    left: 0;<br />    bottom: 0;<br />    right: 0;<br />}<br />.youtube-player {<br />    width: 100%;<br />    height: 100%;<br />}<br /><br />.article-metaline {<br />	margin: 0;<br />	padding: 0;<br />	background-color: #008;<br />}<br />.article-metaline-right {<br />	position: absolute;<br />	right: 0;<br />	top: 0;<br />	background-color: #008;<br />}<br />.article-meta-tag {<br />	padding: 0 1ex;<br />	background-color: #999;<br />	color: #008;<br />}<br />.article-meta-value {<br />	padding: 0 1ex;<br />	background-color: #008;<br />	color: #999;<br />}<br /><br />img {<br />	max-width: 100%;<br />	max-height: 800px;<br />}<br /></pre>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2025/01/10/6115/%e5%b9%ab%e5%82%99%e4%bb%bd-ptt-%e7%9a%84-wordpress-%e6%96%87%e7%ab%a0%e4%b8%8a%e8%89%b2/">幫備份 PTT 的 WordPress 文章上色</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2025/01/10/6115/%e5%b9%ab%e5%82%99%e4%bb%bd-ptt-%e7%9a%84-wordpress-%e6%96%87%e7%ab%a0%e4%b8%8a%e8%89%b2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TTPoE Tesla Transport Protocol (TTP) Over Ethernet 簡評</title>
		<link>https://blog.richliu.com/2024/11/21/6081/ttpoe-tesla-transport-protocol-ttp-over-ethernet-%e7%b0%a1%e8%a9%95/</link>
					<comments>https://blog.richliu.com/2024/11/21/6081/ttpoe-tesla-transport-protocol-ttp-over-ethernet-%e7%b0%a1%e8%a9%95/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Thu, 21 Nov 2024 07:09:43 +0000</pubDate>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[IC Design]]></category>
		<category><![CDATA[Network]]></category>
		<category><![CDATA[ethernet]]></category>
		<category><![CDATA[tcp]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6081</guid>

					<description><![CDATA[<p>早上瞄到這篇文章討論的 Tesla’s TTPoE at Hot Chips 2024: Replacing  [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/11/21/6081/ttpoe-tesla-transport-protocol-ttp-over-ethernet-%e7%b0%a1%e8%a9%95/">TTPoE Tesla Transport Protocol (TTP) Over Ethernet 簡評</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>早上瞄到這篇文章討論的 <a href="https://chipsandcheese.com/p/teslas-ttpoe-at-hot-chips-2024-replacing-tcp-for-low-latency-applications" target="_blank" rel="noopener">Tesla’s TTPoE at Hot Chips 2024: Replacing TCP for Low Latency Applications</a> ，去年 Telsa 建了 Dojo SuperComputing ，今年就弄了一個新的 Protocol </p>



<p>TCP 已經是一個非常陳舊的 Protocol ，其中很多特性已經不再適合目前的網路環境，像QUIC架在UDP上層，增加安全性和速度。SCTP主打多連結，可靠性和安全，SCTP在電信環境用的比較多。基於 UDP 大量傳送資料的有 UDT (UDP-Based Data Transfer protocol) 等等</p>



<span id="more-6081"></span>



<p>TTPoE 看起來應該是 Telsa 降本增效（名詞好用就拿來用）的實作，因為如果是使用RDMA之類的解決方案應該都有更快的 NIC Card 可以用(目前最快是 800Gbps 2 Ports QSPF-DD), 但是 TTPoE 是用 100G NIC 卡但是重新實做了整個 NIC Card ，雖然這樣講，未來仍然有升級的空間</p>



<p>我認為 TTPoE 的主要設計目地就是 Low Latency and Low Cost，因為 TTPoE 看起來是要做 HBM2HBM 的資料同步，Low latency 應該還是主要考量，因為他們要實作在 Hardware 上</p>



<p>而 data center(DC) 下是 data loseless 的環境，相對的網路環境比較好，如果有開啟 ethernet congession control ，理論下會丟掉的封包比較少，頻寬大。基於這個特性，TTPoE 就是做刪去法，將 TCP 協定中多餘的 Latency 去掉，仍然使用 IP 協定，保有和現有網路的相容性，以下這張圖就可以清楚的知道，TTP 是取代 TCP 的位置，上層仍然能夠跟 RDMA 接，其他 socket 或 APP 應該也可以，不過主要應該還是給RDMA這類高速記憶體協定用</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="817" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-6.png" alt="" class="wp-image-6082" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-6.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-6-600x337.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-6-768x431.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-6-816x458.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>（註： 本圖來自 <a href="https://chipsandcheese.com/p/teslas-ttpoe-at-hot-chips-2024-replacing-tcp-for-low-latency-applications" target="_blank" rel="noopener">Tesla’s TTPoE at Hot Chips 2024: Replacing TCP for Low Latency Applications</a> ，原圖應該是 Hot Chips 2024 Telsa 的 slide，以下不再重覆說明 ）</p>



<p>為了讓 Hardware 更容易設計，所以簡化了 TTP 的 Protocol State machine ，這是是目標也是結果，因為簡化 Protocol 也會簡化 state machine </p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="813" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-7.png" alt="" class="wp-image-6083" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-7.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-7-600x335.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-7-768x429.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-7-816x456.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>將 TCP 的 Three way handshake 改成 Two way handshake，其實 internet 防火牆需要這個機制判斷是不是真實連線，但是 DC 內部不需要，拿掉合理，也可以減少很多 Latency <br />有些人要加速會改 TCP ACK 到下一筆資料送出的時間，不過這會造成某些硬體加速器的問題</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="839" height="530" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-8.png" alt="" class="wp-image-6084" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-8.png 839w, https://blog.richliu.com/wp-content/uploads/2024/11/image-8-600x379.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-8-768x485.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-8-816x515.png 816w" sizes="(max-width: 839px) 100vw, 839px" /></figure>



<p>這邊應該是要將如果有個 Packet 是 NACK ，後面的 packet 都重送，這樣雖然會傳比較多資料，但是 DC package loseless 環境，這樣的機率小，可以接受這樣的設計<br />TTP 也拿掉 tcp congestion control 這個功能，如果只在 DC 用，這功能完全不需要，因為路上幾乎都是大頻寬，如果頻寬不夠就要從別的地方觀測調整，不是 Protocol 的問題，packet 的 sliding window 就設一個固定值，符合系統大部份時間都可以以最高速運作即可</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="815" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-9.png" alt="" class="wp-image-6085" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-9.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-9-600x336.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-9-768x430.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-9-816x457.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>TTP Protocol 有些有趣的地方，Extension header 二個，第一個是指定 type 用的，第二個可能是未來用，這應該是固定大小，然後 Data payload 是 64 bytes 的倍數 </p>



<p>有趣的是用 SRAM size 做 speculative transmission，這個設計我喜歡，好的演算法就是不需要演算法，讓系統自己去調整(self-adaptive)，不過我懷疑這個就是 ethernet 的 tx buffer 講成高大上而已</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="812" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-10.png" alt="" class="wp-image-6086" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-10.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-10-600x335.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-10-768x428.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-10-816x455.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>這意思就是前面還放傳統的 ethernet 架構，TTP mac controller 控制　ethernet 介面傳送資料，灰色部份都是現成的</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="808" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-11.png" alt="" class="wp-image-6087" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-11.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-11-600x333.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-11-768x426.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-11-816x453.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>TTP hardware micro-architecture 設計</p>



<p>下方的 Next packet linked list SRAM，雖然講是 linked list SRAM，不過為什麼不做 array 當 ring buffer 呢？還是指的是同一件事，做過 NIC 卡就知道這種地方設計就固定是那樣，尤其是做成 hardware 又要結構更簡單，所以我才懷疑前面講的 SRAM 做 flow control 就是講這邊，如果 ring buffer 滿了就表示外面滿了</p>



<p>一般這種高階通常都有數個 TX/RX buffer ，不知道是不是因為專供 RDMA 用所以這邊就只畫上一個 TX/RX buffer ？而且不確定是不是因為一個 Buffer 頻寬就滿了（或是 FPGA 只能規劃 1MB，都有可能）</p>



<p>80 microseconds 在高速網路世界已經算很久了，算 OK <br />slide 最後一行我覺得才是真正的目地，如果是在 AI server 上要跑這個，那不用更高階的卡跑 RDMA 就很合理了</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="808" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-12.png" alt="" class="wp-image-6088" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-12.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-12-600x333.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-12-768x426.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-12-816x453.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>&#8220;Mojo&#8221; 100GB dumb-NIC （話說我以前做過的某 project 我叫 SmartXXX 呢）<br />中間這麼大一顆可能是 SoC 也可能是 FPGA ，我覺得 FPGA 的機率大一點，畢竟要改 code 這階段還是用 FPGA 穩定</p>



<p>CPU 的是用 Gen3 x16 和 8GB DDR4，Gen3 比較有趣，表示這真的是降成本達到目地</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="814" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-13.png" alt="" class="wp-image-6089" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-13.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-13-600x335.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-13-768x429.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-13-816x456.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<p>Latencies ，竟然 TTPoE 比 Nvlink 還快，Nvlink 已經算是對傳了，要過 ethernet 還比較快讓我難以想像</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1456" height="810" src="https://blog.richliu.com/wp-content/uploads/2024/11/image-14.png" alt="" class="wp-image-6090" srcset="https://blog.richliu.com/wp-content/uploads/2024/11/image-14.png 1456w, https://blog.richliu.com/wp-content/uploads/2024/11/image-14-600x334.png 600w, https://blog.richliu.com/wp-content/uploads/2024/11/image-14-768x427.png 768w, https://blog.richliu.com/wp-content/uploads/2024/11/image-14-816x454.png 816w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>



<h2 class="wp-block-heading">總結</h2>



<p>我覺得技術細節透露有限，但是這個方向的確可以大幅減少 latency ，在網路的世界內，減少 latency 就是增加速率和效率，在頻寬固定的狀況之下</p>



<p>雖然相容性不佳，只是給 RDMA 用，但是我覺得仍不失為 intranet 上有趣的應用，而且的確很適合 DC  使用</p>



<p>ref. <a href="https://github.com/teslamotors/ttpoe/tree/master" target="_blank" rel="noopener">Github ttpoe</a> Linux kernel 的 software 實作和規格, 要先有 software 才能搞 hardware 啊.</p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/11/21/6081/ttpoe-tesla-transport-protocol-ttp-over-ethernet-%e7%b0%a1%e8%a9%95/">TTPoE Tesla Transport Protocol (TTP) Over Ethernet 簡評</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2024/11/21/6081/ttpoe-tesla-transport-protocol-ttp-over-ethernet-%e7%b0%a1%e8%a9%95/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Gentoo ARM64 Altra Compile chromium Issue</title>
		<link>https://blog.richliu.com/2024/10/10/6052/gentoo-arm64-altra-compile-chromium-issue/</link>
					<comments>https://blog.richliu.com/2024/10/10/6052/gentoo-arm64-altra-compile-chromium-issue/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 09 Oct 2024 17:22:12 +0000</pubDate>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[aarch64]]></category>
		<category><![CDATA[Altra]]></category>
		<category><![CDATA[AltraMax]]></category>
		<category><![CDATA[Ampere]]></category>
		<category><![CDATA[arm64]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6052</guid>

					<description><![CDATA[<p>When compile the chromium on my Altra platform, it meet [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/10/10/6052/gentoo-arm64-altra-compile-chromium-issue/">Gentoo ARM64 Altra Compile chromium Issue</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>When compile the chromium on my Altra platform, it meet compile problem like this</p>



<span id="more-6052"></span>



<pre class="wp-block-preformatted">no-dangling-assignment-gsl -std=c++20 -Wno-trigraphs -gsimple-template-names -fno-exceptio00:01:51 [472/19443]
nc++ -isystem../../third_party/libc++/src/include -isystem../../third_party/libc++abi/src/include -fvisibility
-inlines-hidden -O2 -pipe -march=armv8.2-a -Wno-unknown-warning-option -c ../../third_party/libyuv/source/comp
are_neon64.cc -o obj/third_party/libyuv/libyuv_neon/compare_neon64.o
../../third_party/libyuv/source/compare_neon64.cc:175:8: error: instruction requires: dotprod
  175 |       "udot        v4.4s, v0.16b, v6.16b         \n"
      |        ^
&lt;inline asm>:14:1: note: instantiated into assembly here
   14 | udot        v4.4s, v0.16b, v6.16b
      | ^
../../third_party/libyuv/source/compare_neon64.cc:176:8: error: instruction requires: dotprod
  176 |       "udot        v5.4s, v1.16b, v6.16b         \n"
      |        ^
&lt;inline asm>:15:1: note: instantiated into assembly here
   15 | udot        v5.4s, v1.16b, v6.16b
      | ^
../../third_party/libyuv/source/compare_neon64.cc:204:8: error: instruction requires: dotprod
  204 |       "udot        v4.4s, v0.16b, v0.16b         \n"
      |        ^
&lt;inline asm>:10:1: note: instantiated into assembly here
   10 | udot        v4.4s, v0.16b, v0.16b
      | ^
../../third_party/libyuv/source/compare_neon64.cc:205:8: error: instruction requires: dotprod
  205 |       "udot        v5.4s, v1.16b, v1.16b         \n"
      |        ^
&lt;inline asm>:11:1: note: instantiated into assembly here
   11 | udot        v5.4s, v1.16b, v1.16b
      | ^
4 errors generated.
[10940/63891] aarch64-unknown-linux-gnu-clang++-18 -MD -MF obj/third_party/libyuv/libyuv_neon/rotate_neon.o.d</pre>



<p>Seems because some -march/-mcpu/-mtune drop &#8216;dotprod&#8217; parameters, it needs to add the extension manuall. &#8216;+dotprod&#8217;.</p>



<p>Edit the file /etc/portage/make.conf, and change the COMMON_FLAGS to </p>



<pre class="wp-block-preformatted">COMMON_FLAGS="-mcpu=neoverse-n1+crc+crypto+ssbs+dotprod -O2 -pipe"</pre>



<p>It can use the following command to get current CPU flag</p>



<pre class="wp-block-preformatted">gcc -v -E -x c /dev/null -o /dev/null -march=native -mcpu=native 2>&amp;1 | grep /cc1</pre>



<p>Thanks Gentoo user zukunf to provide those information. </p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/10/10/6052/gentoo-arm64-altra-compile-chromium-issue/">Gentoo ARM64 Altra Compile chromium Issue</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2024/10/10/6052/gentoo-arm64-altra-compile-chromium-issue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>FreeBSD Build Kernel</title>
		<link>https://blog.richliu.com/2024/09/11/6040/freebsd-build-kernel/</link>
					<comments>https://blog.richliu.com/2024/09/11/6040/freebsd-build-kernel/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Tue, 10 Sep 2024 16:13:42 +0000</pubDate>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[kernel]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6040</guid>

					<description><![CDATA[<p>Google Bing 查了半天不如問 Claude ，雖然現在LLM很方便，不過還是會有小問題，記錄一下過程 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/09/11/6040/freebsd-build-kernel/">FreeBSD Build Kernel</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Google Bing 查了半天不如問 Claude ，雖然現在LLM很方便，不過還是會有小問題，記錄一下過程</p>



<span id="more-6040"></span>



<p>我的環境是 ARM64，所以以 ARM64 為主，編的版本是 15.0-Current</p>



<pre class="wp-block-preformatted"># Install git first
# pkg install git
# Install Source code from Git 
git clone https://git.freebsd.org/src.git /usr/src

cd /usr/src/sys/arm64/conf
cp GENERIC MYKERNEL
vim MYKERNEL</pre>



<p>以下應該可以整理成一個 script</p>



<pre class="wp-block-preformatted">cd /usr/src

# Remove old file
mkdir /usr/obj/tmp
chflags -R noschg /usr/obj/*
rm -rf /usr/obj/*

# Build world and kernel 
# Cannot use 128 cores to build that because it might cause build problem. 
# reduce it to 16 might be better 
make -j 16 buildworld
# Clean kernel if necesssary 
# make -j 16 cleankernel KERNCONF=MYKERNEL
make -j 16 buildkernel KERNCONF=MYKERNEL

# Install world and kernel to a temperory directory
mkdir /usr/obj/tmp
make installworld DESTDIR=/usr/obj/tmp
make installkernel KERNCONF=MYKERNEL DESTDIR=/usr/obj/tmp

# copy release document to the directory
make distribution DESTDIR=/usr/obj/tmp

# build release
cd release
make -j 16 release KERNCONF=MYKERNEL NODOC=yes NOPORTS=yes NOSRC=yes</pre>



<p>Release files (iso, image 等等) 會在<br />/ussr/obj/usr/src/arm64.aarch64/release 下</p>



<h3 class="wp-block-heading">Clean kernel </h3>



<pre class="wp-block-preformatted">make cleankernel KERNCONF=MYKERNEL</pre>



<p>修改 EFI_STAGING_SIZE，修改 /usr/src/stand/efi/loader/copy.c , 找到</p>



<pre class="wp-block-preformatted">#define DEFAULT_EFI_STAGING_SIZE</pre>



<p>統統改成要的值，ex: 100 ，這樣就好，暴力解決</p>



<h3 class="wp-block-heading">Enable exec=&#8221;copy_staging auto&#8221; in /boot/loader.conf</h3>



<p>這個功能因為要在編 world 放到 loader.conf 內，這樣 iso 和 memstick 檔案內才，所以我用了一個 hacker 的手法，編輯 release/Makefile ，約 Line 188，加上</p>



<pre class="wp-block-preformatted">echo exec=\"copy_staging disable\" >> ${.TARGET}/boot/loader.conf</pre>



<h3 class="wp-block-heading">Enable Early Printf In Kernel </h3>



<p>編輯  MYKERNEL ，加上[<a href="https://github.com/freebsd/freebsd-src/blob/3c95262007ef934c9e98b87460a48889bf42c1b9/sys/kern/kern_cons.c#L76" target="_blank" rel="noopener">ref</a>]</p>



<pre class="wp-block-preformatted">options EARLY_PRINTF=pl011</pre>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/09/11/6040/freebsd-build-kernel/">FreeBSD Build Kernel</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2024/09/11/6040/freebsd-build-kernel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Dynatron W3 for Ampere AltraMax</title>
		<link>https://blog.richliu.com/2024/08/02/6012/dynatron-w3-for-ampere-altramax/</link>
					<comments>https://blog.richliu.com/2024/08/02/6012/dynatron-w3-for-ampere-altramax/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Thu, 01 Aug 2024 16:27:28 +0000</pubDate>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[ALTRAD8UD]]></category>
		<category><![CDATA[AltraMax]]></category>
		<category><![CDATA[Ampere]]></category>
		<category><![CDATA[Ampere Computing]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=6012</guid>

					<description><![CDATA[<p>The Dynatron W3 fan package offers an alternative cooling solution, including a tower heatsink and 120mm fan. It's easy to install. Preliminary tests on an AltraMax 128-30 CPU show the fan maintains 64°C at 1400 RPM, consuming around 178W. While suitable for general use.</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/08/02/6012/dynatron-w3-for-ampere-altramax/">Dynatron W3 for Ampere AltraMax</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Ampere AltraMax is a powerful server CPU with numerous cores. However, it lacks solutions for end users, with the ASRock Rack motherboard being the only available option. The original package includes a heatsink but no CPU fan, necessitating alternative heat dissipation methods. Currently, there are some tower fans available, and I have acquired a <a href="https://ja.dynatron.co/product-page/w3" target="_blank" rel="noopener">Dynatron W3</a> fan (from <a href="https://www.newegg.com/dynatron-w3/p/N82E16835114163" target="_blank" rel="noopener">newegg</a>) for preliminary testing.</p>



<span id="more-6012"></span>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1920" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-scaled.jpg" alt="" class="wp-image-6013" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-scaled.jpg 2560w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-600x450.jpg 600w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-768x576.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-1536x1152.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-2048x1536.jpg 2048w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222502-816x612.jpg 816w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<p>The Dynatron W3 package comes in a standard case.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1920" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-scaled.jpg" alt="" class="wp-image-6014" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-scaled.jpg 2560w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-600x450.jpg 600w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-768x576.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-1536x1152.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-2048x1536.jpg 2048w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222514-816x612.jpg 816w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<p>includes a tower heatsink, one 120mm 4-pin fan, and thermal paste.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="2560" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-scaled.jpg" alt="" class="wp-image-6015" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-scaled.jpg 1920w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-450x600.jpg 450w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-768x1024.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-1152x1536.jpg 1152w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-1536x2048.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222526-816x1088.jpg 816w" sizes="(max-width: 1920px) 100vw, 1920px" /></figure>



<p>The base is not entirely copper, and its area seems somewhat small</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1920" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-scaled.jpg" alt="" class="wp-image-6016" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-scaled.jpg 2560w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-600x450.jpg 600w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-768x576.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-1536x1152.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-2048x1536.jpg 2048w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_222553-816x612.jpg 816w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<p>other parts</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="2560" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-scaled.jpg" alt="" class="wp-image-6017" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-scaled.jpg 1920w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-450x600.jpg 450w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-768x1024.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-1152x1536.jpg 1152w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-1536x2048.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_223103-816x1088.jpg 816w" sizes="(max-width: 1920px) 100vw, 1920px" /></figure>



<p>While no documentation is provided, installation is straightforward for those familiar with DIY PC building</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1920" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-scaled.jpg" alt="" class="wp-image-6018" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-scaled.jpg 2560w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-600x450.jpg 600w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-768x576.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-1536x1152.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-2048x1536.jpg 2048w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224225-816x612.jpg 816w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1920" src="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-scaled.jpg" alt="" class="wp-image-6019" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-scaled.jpg 2560w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-600x450.jpg 600w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-768x576.jpg 768w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-1536x1152.jpg 1536w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-2048x1536.jpg 2048w, https://blog.richliu.com/wp-content/uploads/2024/08/IMG_20240730_224252-816x612.jpg 816w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<p>There is a gap between the DDR slots and the CPU fan, but larger DIMMs might require disassembling and reinstalling the tower fan. </p>



<p>In a preliminary test using stress-ng with 128 threads on an AltraMax 128-30 CPU and ASRock Rack ALTRAD8UD-1L2T.</p>



<p>Test command is </p>



<pre class="wp-block-preformatted">stress-ng --cpu 128 --vm 128 --vm-bytes 128M --timeout 180s --metrics-brief</pre>



<p>the fan operated at 1400 RPM and maintained a quiet profile. The CPU temperature reached 64°C, staying below 70°C, with power consumption around 178W. </p>



<p>This performance suggests the tower fan is suitable for general purposes.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="766" height="322" src="https://blog.richliu.com/wp-content/uploads/2024/08/image.png" alt="" class="wp-image-6020" srcset="https://blog.richliu.com/wp-content/uploads/2024/08/image.png 766w, https://blog.richliu.com/wp-content/uploads/2024/08/image-600x252.png 600w" sizes="(max-width: 766px) 100vw, 766px" /></figure>



<p>Notice: The CPU&#8217;s TDP is rated at 250W, this maximum power draw is only achievable under full system stress, such as utilizing all 8 DRAM controllers and all PCIe root controllers. Therefore, this figure should be considered as a reference rather than a precise measurement.<br /></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2024/08/02/6012/dynatron-w3-for-ampere-altramax/">Dynatron W3 for Ampere AltraMax</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2024/08/02/6012/dynatron-w3-for-ampere-altramax/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
