November 14, 2008
MicroXwin : 針對嵌入式系統的高效能 X Window System 實作

新創公司 DSPSOFT INC 日前提出針對嵌入式系統的高效能 X Window System 實作,即 [
MicroXwin],由該公司創辦人兼 CEO,Vasant Kanchan,領導嶄新途徑的開發與產品化。MicroXwin 的思維乃是著眼於拜自由軟體蓬勃發展所賜,豐富的 X 應用程式有如過江之鯽,但,在有限硬體能力的嵌入式環境中,是否有機會獲得良好的呈現與使用者互動能力呢?為此,MicroXwin 用獨特的方式改良 X 的設計。
X Window System 本質上是圍繞於網路通訊的視窗系統,X server 透過硬體,負責將 X client 要求的繪圖動作,予以呈現並處理運作所需的 I/O,而 X protocol 就是如此設計的核心。X 應用程式就是 X client,為了開發豐富的應用程式,會有 Gtk+ 與 Qt 一類的 Toolkit / widget set,下圖是運作示意圖:

在沒有特殊硬體加速機制 (如 DRI 與 GLX/OpenGL) 的前提,以下因素導致原本 X Window System 效能低落並佔用系統資源:
- 基於 X protocol 的規範,X client 與 X server 各自保有 buffer 與格式化的繪圖指令操作
- X client 與 X server 間的必要的同步化通訊與 round-trip
- 對於 ARM 9 一類廣泛使用的嵌入式處理器架構,系統設計有 MMU/cache 本該能提昇的處理效能與彈性,但頻繁地在 X 應用程式與 X server 間作 context switch,導致 cache flush,致使效能大打折扣
是此,MicroXwin 提出新的途徑,在不更動既有 X client / Toolkit 的前提下,將 X serever 的工作搬移到底層作業系統,成為一個新的服務,並且,捨棄 X protocol 與網路通透性的機制,成為修正性、典型的繪圖系統,以下是示意圖:

由上圖,我們可見到若干元件:
- X11.ko kernel module : 實做部份 X server 的功能,並開放 /dev/x11dev 的介面給 X client library 存取
- libX11.so 保持與原本 Xlib 二進位相容的 API
- libXext.so 等 X extension library 則實做 X extension 所需的呼叫,但針對 /dev/x11devb 介面,而非網路通訊的 X protocol
- X core font 由 X11.ko kernel 處理,免除繁複的記憶體操作
- 針對向量字體,則由 X client 端,透過 Xft/Fontconfig 處理,但更直接的呈現
如此嶄新的設計有著以下優點:
- Low latency 與 Low round trip
- 大幅減少 X request / response 所需的 buffering,免去昂貴的通訊成本
- 消去 context switch 的負擔,並避免 ARM 9 一類嵌入式硬體的 cache flush 問題
- 透過 X11.ko kernel module,圖形資料是直接由 userspace 複製到 framebuffer 硬體
- (幾乎) 不需更動到任何既有 X 應用程式
現在 libX11 與 libXext 等 userspace library 依據 BSD style license 發佈,也提供針對 x86, ARM, MIPS 等硬體架構的 kernel module,就官方的說法,MicroXwin 在空間與記憶體需求量,均大幅低於 Xorg server,以 x86 架構為例,個別軟體元件的空間需求如下:
- libX11.so : 720K bytes
- libXext.so : 7K bytes
- Kernel module x11.ko : 200K bytes
相較而下,Xorg X server 佔用了 1.8M bytes 的空間。而針對 ARM 9 硬體,以 Nokia 770 Linux Tablet 為主要效能評比的對象,OpenHanded (已被 Intel 收購) 與 Nokia 的工程團隊已做了若干效能改進,提出 Xomap,這個奠基於 KDrive / TinyX 架構、針對 TI OMAP 硬體加速的 X server,MicroXwin 與其相較,絲毫不遜色,而且有亮眼的效能突破。網頁 [
Demo] 透過 x11perf 羅列了效能評比數據,筆者做了圖表整理如下:

由此可見,MicroXwin 相較於 Xorg X server,在 asynchronous display 有著 62% 的效能提昇,而在 synchronous display of images 則有 384% 的提昇,這是主要架構變異使然,官方也提供若干組態與執行檔供驗證評估。整體來說,MicroXwin 的設計特點:
- 快速的 round-trip 與 synchronus request 時間
- 讓 UI Toolkit 得以有更快更順暢的表現
- Kernel module x11.ko 有著較 Xorg server 更高的處理優先權
由 jserv 發表於
01:20 PM
|
迴響 (13)
November 12, 2008
自由軟體法律授權工作坊

本月 (11 月) 的 26 日,中央研究院資訊科技創新研究中心自由軟體鑄造場 (OSSF) 將舉辦 [
自由軟體法律授權工作坊] 的研討會,藉此活動共同探討企業在使用開放源碼時所遇到的授權與法律議題,以下摘錄活動訊息:
- 對象:嵌入式廠商及對自由軟體法律議題有興趣者
- 人數:約 80 人
- 費用:全程免費,中午供餐
- 議程:
- 09:40~10:30 主題一:軟體的授權觀念與自由軟體授權類別
- 10:40~11:30 主題二:自由軟體的法律爭訟及商業應用模式
- 11:40~12:00 主題三:Focus Group Discussion
小弟也會出席此研討會,歡迎指教,謝謝!
由 jserv 發表於
08:18 PM
|
迴響 (0)
fbvncserver : 將 Linux framebuffer 作為輸出的 VNC server
日前在調整 LCD panel / controller 的 Linux device driver 時,因疑似 panel 硬體處理不善,導致無法釐清問題是發生於軟體層面,抑或潛在的硬體議題,於是需要觀察 /dev/fb* 的內容,將腦筋動到 VNC 上面,最後做了一個小工具 fbvncserver,將 Linux framebuffer 作為輸出的 VNC server。
參與 OpenEZX 專案時,Harald Welte 寫了一個小工具 [
fbgrab-viewer],原理是透過在標的裝置 (target) 端執行 [
fbgrab],不斷將從 Linux frambuffer 擷取的影像,經由轉換,傳輸到桌面 (host) 端的 viewer,即可監控裝置端的畫面,當然,實際上得考慮傳輸的間隔,所以大概是每五秒傳輸一張。這個小工具在我們早期進行 Openmoko 硬體驗證時,仍派上用場,不過,問題是間歇性的擷取與轉換影像為 PNG 圖檔,還是太沈重。而過去 Sharp Zaurus Linux PDA 上,有個 [
fbVNCServer] 工具,則巧妙地建立一個 VNC server,將 Linux framebuffer 作為輸出,允許桌面端瀏覽與操控 PDA 的畫面,看似很理想,但這個軟體太依賴 Zaurus PDA 的硬體組態,本身也有點複雜,也沒有維護,所以乾脆弄個新專案。
同樣透過 [
LibVNCServer] 來建構 VNC server,大幅減輕工作量,雛型實做可參考 [
fbvncserver.c],授權方式為 GNU GPL,參考的執行畫面如下:

上圖主要的畫面是 TightVNC client,視窗標題列的 AG101 則為我的裝置端名稱,當 VNC server 啟動時,終端機會有以下輸出:
/tmp # ./fbvncserver
Initializing framebuffer device /dev/fb0...
xres=800, yres=480, xresv=800, yresv=480, xoffs=0, yoffs=0, bpp=16
Initializing Framebuffer VNC server:
width: 800
height: 480
bpp: 16
port: 5900
Initializing server...
07/11/2008 14:00:24 Listening for VNC connections on TCP port 5900
這裡裝置端的 IP 為 10.0.4.80,而桌面端為 10.0.4.78,現在後者的 VNC client 試圖連線到前者的 fbVNCserver,會看到以下的終端機訊息更新:
07/11/2008 14:00:31 Got connection from client 10.0.4.78
07/11/2008 14:00:31 other clients:
07/11/2008 14:00:31 Client Protocol Version 3.8
07/11/2008 14:00:31 Protocol version sent 3.8, using 3.8
Dirty page: 70x80+6+0...
07/11/2008 14:00:31 rfbProcessClientSecurityType: executing handler for type 1
07/11/2008 14:00:31 rfbProcessClientSecurityType: returning securityResult for client rf8
07/11/2008 14:00:31 Pixel format for client 10.0.4.78:
07/11/2008 14:00:31 32 bpp, depth 24, little endian
07/11/2008 14:00:31 true colour: max r 255 g 255 b 255, shift r 16 g 8 b 0
07/11/2008 14:00:32 Using compression level 1 for client 10.0.4.78
07/11/2008 14:00:32 Using image quality level 6 for client 10.0.4.78
07/11/2008 14:00:32 Enabling X-style cursor updates for client 10.0.4.78
07/11/2008 14:00:32 Enabling full-color cursor updates for client 10.0.4.78
07/11/2008 14:00:32 Enabling cursor position updates for client 10.0.4.78
07/11/2008 14:00:32 Enabling LastRect protocol extension for client 10.0.4.78
... (略) ...
這些訊息是由 [
LibVNCServer] 所輸出,表示 VNC/RFB session 已正確建立與運作。目前的實做假設裝置端的 bpp 為 16-bit (RGB565),在多數的硬體裝置應算堪用,當然,任何修改與 patch 都非常歡迎 :-)
由 jserv 發表於
11:37 AM
|
迴響 (0)
November 01, 2008
簡易測量 X round-trip time
前文 [
非同步 Xlib 處理機制] 探討了鮮為人知的 X Window System 的非同步設計議題。無論 XOrg 實做上引入哪些新機制,基本上,典型的運作模式大致為,在 reply-receiving 函式呼叫前,client 端會預先保存 reply data,接著,server 端施行對於 client 要求而生的同步動作,而控制權從 server 重回到 client 的這段期間,稱為 "round-trip" time,可視作作繪圖指令 / 操作的往返。本文則提出一個簡易測量 X round-trip time 的途徑。
X protocol 的設計相當洗練且豐富,在 X client 這端,我們可透過 Xlib 中的 XNoOp 函式,對 protocol 傳送 "NoOperation" 的 request,一旦經過 X transport 處理後,即可得知大概一來一往 round-trip time,以下是簡單的實做: [
xttl.c]
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <X11/Xlib.h>
#include <sys/time.h>
#define TRY_TIMES (10)
#define INTERVAL (1)
int main()
{
Display *disp;
struct timeval start = { 0UL, 0UL }, end = { 0UL, 0UL };
char *disp_name;
int ret = 0;
int count = 0;
disp_name = XDisplayName(NULL);
if ((disp = XOpenDisplay(NULL)) == NULL) {
errx(1, "cannot open display %s", disp_name);
}
printf("X server version is %i.%i\n",
ProtocolVersion(disp), ProtocolRevision(disp));
printf("X Vendor string: %s\n", ServerVendor(disp));
printf("X Vendor release number: %i\n", XVendorRelease(disp));
while (count++ < TRY_TIMES) {
ret = gettimeofday(&start, NULL);
if (ret < 0) {
err(1, "gettimeofday");
}
if (XNoOp(disp)) {
struct timeval diff = { 0UL, 0UL };
if ((ret = gettimeofday(&end, NULL)) < 0)
err(1, "gettimeofday");
if (end.tv_sec < start.tv_sec &&
end.tv_usec < start.tv_usec) {
break;
}
diff.tv_sec = end.tv_sec - start.tv_sec;
diff.tv_usec = end.tv_usec - start.tv_usec;
printf(" reply from display %s: XNoOP_seq=%i time=%lu.%lu ms\n",
disp_name, count,
(diff.tv_sec * 1000 * INTERVAL), diff.tv_usec);
}
sleep(INTERVAL);
}
XCloseDisplay(disp);
return 0;
}
參考輸出如下:
$ ./xttl
X server version is 11.0
X Vendor string: The X.Org Foundation
X Vendor release number: 10502000
reply from display :0: XNoOP_seq=1 time=0.4 ms
reply from display :0: XNoOP_seq=2 time=0.5 ms
reply from display :0: XNoOP_seq=3 time=0.6 ms
reply from display :0: XNoOP_seq=4 time=0.7 ms
reply from display :0: XNoOP_seq=5 time=0.9 ms
reply from display :0: XNoOP_seq=6 time=0.5 ms
reply from display :0: XNoOP_seq=7 time=0.6 ms
reply from display :0: XNoOP_seq=8 time=0.5 ms
reply from display :0: XNoOP_seq=9 time=0.6 ms
reply from display :0: XNoOP_seq=10 time=0.5 ms
由 jserv 發表於
06:39 PM
|
迴響 (0)