發表文章

Linux 下程序的記憶體映射

Linux 下的執行檔為 ELF 格式,其啟動原理與各作業系統上的執行檔一樣,不外乎是載入檔案到記憶體上,並讀取需要的 Shared library link 清單,最後找到於 Filesystem 上對應的 symbol link 和 library,載入外部函式和執行程式。 這邊以 VIM 為例,我們透過 Linux 下的 ldd 指令可以得知執行檔需要的外部 Libraries: $ ldd /usr/bin/vim linux-gate.so.1 => (0xb7837000) libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb77f2000) libncurses.so.5 => /lib/libncurses.so.5 (0xb77b8000) libselinux.so.1 => /lib/libselinux.so.1 (0xb779c000) libacl.so.1 => /lib/libacl.so.1 (0xb7795000) libgpm.so.2 => /usr/lib/libgpm.so.2 (0xb778f000) libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7649000) libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7645000) /lib/ld-linux.so.2 (0xb7838000) libattr.so.1 => /lib/libattr.so.1 (0xb763f000) 由以上結果可以看到 VIM 所需的 library,以及在 filesystem 上找到的對應 library ,然後還可以得到當 library 被載入到記憶體上時的起始位置。其中比較特別的是 linux-gate.so.1,實體並不存在於 filesystem 中,這代表 kernel system call 的記憶體映射和其位址。 Kernel 其實有 Interface 提供我們取得更多 Process 的記憶體映射資料,藉由讀取 /proc/[Process ID]/maps 這檔案,我們除了可以得到 Process 連結的 libra...

寫支 C 程式用 XRandr Extension 設定你的螢幕解析度

在 X11 下取得螢幕顯示大小,最快的方式就是得到當前的 Screen ,然後用 DisplayWidth() 和 DisplayHeight() 得到寬高,如果是在高階的圖形介面架構下開發應用程式,如:GTK+,也有相關的 API 可以取得 display 的大小。然而,要是我們想取得更多關於螢幕和顯示晶片所支援的模式,便要引入 XRandr Extension 來達成。 若不了解 XRandr 是什麼,可以開啟終端機(Terminal)程式,接著輸入 xrandr 指令,就會看到顯示器的相關訊息,除了可以得到有幾種螢幕可以用,還分別可以看到支援的模式(解析度和掃描頻率),以下是在筆者 X200t (有外接一台支援 1920x1080 的 24" 顯示器)上執行的結果: $ xrandr Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192 VGA1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 531mm x 299mm 1920x1080 60.0*+ 60.0 60.0 1440x900 59.9 1280x800 59.8 1152x864 75.0 1024x768 70.1 60.0 800x600 60.3 56.2 640x480 66.7 60.0 720x400 70.1 LVDS1 connected (normal left inverted right x axis y axis) 1280x800 60.0 + 1024x768 60.0 800x600 60.3 56.2 640x480 59.9 HDMI1 disconnected (normal left inverted right x axis y axis) DP1 disconn...

Mandice Superted - Non-GoogleTV Web Browser for TV Device

由於一些合作廠商們不願意使用 GoogleTV 或 Android 做 TV Devices,最近實作了 Connected TV 專用的網頁瀏覽器(Web Browser) - 『Superted』。他們選擇不走 Google 之路有很多因素,像是 Google 雖有遠大願景,但當前還不夠成熟,所以目前為止 Android 在 Connected TV 上,還未有立即性的應用程式擴充價值。其次,中國大陸的 PPStream Content 和山寨市場之大,讓華人市場不接受只有 Youtube 的 GoogleTV。再來,就是跨平台開發成本與硬體驅動的議題。這也是為什麼我們會被要求寫一個『比較適合』在 TV Device 上使用的網頁瀏覽器,當然,廠商們的聖旨也說要有大又明顯的 UI,又或者是與 GoogleTV 雷同。 延續過去的 Webkit 網頁瀏覽器實驗品,加上了 3D User Interface 的支援,便完成了 Superted 的原型: 後記 影片中是使用 Acer AspireOne(Intel Atom N270) 第一代 netbook 做功能演示,也已經在 VIA platform 上順利測試過。

Mandice 為您在 Linux 和新產業機會開路

近來忙於工作和協助新團隊的建立,付出於 Blog 上的時間也少了許多,不過,雖然在 Blog 上與自己對話的時間減少,但這些日子,卻自我反省甚多。 回想起過去的經歷,總讓一波波湧出來的『資訊新名詞』,將自己不停往岸上沖。這就是資訊業,三天一小變,五天一大變,稍不留神,已改朝換代而擱淺在岩岸上。但在這浪花四起的時代,總不曉得是被誰所欺負。有時欲求助卻會惹一身麻煩,每每都問自己,到底要忍到何時?知道被沖上岸者眾,人人都不甘心,卻也莫可奈何世代交替,也在擔心哪一天自己會被衝上岸。 經過風風雨雨,能體會許多外界不瞭解的心聲;隨『科技業』起舞多時,我們多少也有在第一線立足的經驗和能力。尋思,與其每天趕潮流拼出貨,日日廢寢忘食只為解決沒價值的人為遐疵,何不帶著最新的技術為沉睡多年的前輩們『重新開路』,開一條不孤單的路,開一條喚醒巨龍的路? 為此,一個全新的台灣車庫團隊 [ Mandice ] 誕生,宗旨『做正確的事(Do the right thing)』,我們不盲目跟從,我們創造和領導新方向。 由於團隊的存活與堅顧理想是無法避免的考量,我們目前的經營三大方向為: 保本 以接案、顧問服務、銷售軟硬體和商業合作為主要訴求 創新 建立商業模式,開發有產業價值或有自身創意之產品 擴展 強健內部團隊技術發展和體制 我們計畫推出的服務項目: 各式軟硬體技術整合顧問服務,讓企業精準做正確決策  代理維護底層軟體系統平台,讓企業專注自身優勢發展  伺服器軟硬體建置支援,協助 IT 系統建設  快速供應完全免授權費的商業用 Linux 作業系統,今天下單明天出貨  量身訂做各式專門用途作業系統,使產品效能和品質兼具  協助將 Linux 系統導入自家產品設計,協助業者迎接資訊新世代 設計並生產自己的概念產品,創造新時代  此外,我們也將投入網路服務的發展和創新,期望在台灣重建網路泡沫化後,各界對網路失去的信心。 當前,如果您有以下需求,您就將會是我們的商業夥伴 想有劃時代資作為的老闆和企業  想將原本的應用轉移至更有機會的平台  需要隨機出貨的免授權作業系統  不想自己養大隊人馬貢奉底層系統  不想傷腦筋卻又必需追新東西的人 燒錢燒到失望...

Linux 上原生的 Google Map 應用程式

為了一些想法和方向,最近開始實作 Google Map 應用程式。經過些許研究,得知了如何從 Google 取得 Map 圖檔,然後自己刻了一支簡單的貼圖引擎,便大致完成了這個應用程式。 或許很多人覺得這種東西只要引入個 Web 瀏覽器引擎,再用 JavaScript 來做就好,但考量到 Web 瀏覽器引擎需要龐大的硬體資源支持,若是什麼小東西都使用它,將可能成為莫大的問題。所以,此次實作使用 C 語言,並在 X11 的架構上繪圖,是一個原生的 Linux Application。

你不需要自由

曾幾何時,『自由』兩字變成了信仰,更變成了宗教狂熱,終以救世主姿態降臨。確實,我們都不喜歡被鎖在一片漆黑毫無自由可言的房中,許多心理實驗也證明了這樣做會造成人們發狂,但是自古到今,絕大多數人類被鎖在地球表面上卻也不曾為此發狂,尋思,自由有這麼重要嗎?我們又真的需要自由嗎?或許,我們只需要有能夠發洩的管道,其實自不自由一點都不重要。 歷史上為了自由而戰的事績何其多,有人為獨立而戰,有人為自己生存權利而戰,更有人為地位而戰,無論如何,大家追求的不過是長久心理壓力的出口。反觀當前科技業,近來開口自由軟體,閉口也自由軟體,暢導『自由』已不是為追求瓶頸出口,而是種貪婪的表現。到最後,雖不花分毫取得和掌控軟體各種權利,卻花了更大的代價去維護,甚至可能因無法控制而走火毀滅。 說到底,身為科技產業的商人要的是什麼?到底是軟體業合作廠商口袋裡的錢?還是市場上的錢? 一個通過重重升學考驗,有一技之長的精英,花了數十年成就一身,使用他們身上的東西,都有每個月個把萬的價值,更何況一個通過重重研發關卡的軟體,餵飽這些軟體的龐大成本更不在話下。而將這些軟體成本放在自己身上,更是種風險和壓力。所以,各自放出口袋不屬於自己的餅,丟掉這份不需要的自由,讓所有人共同追求最大利益不是更好? 一個商人或商業機構,追求利益的出口,無可後非,不過,一個皇帝可以穫得大片江山,卻不能任意奪取民脂民膏,更是不能忘記。 後記 若自由軟體不能勝任,就算熱愛自由軟體,也不應貿然使用,否則造成的後遺症,可不是打出『義和拳』推廣旗織就能解決的。

用 apt-get 節省系統開發和評估的時間

使用 Debian 系統(包括 Ubuntu)的人,應該早就熟於使用 apt-get 去安裝、移除或更新系統,其無痛和方便的操作,帶給 Debian 家族很大的優勢。而對於研發人員而言,我們比較在乎的是如何取得各套件的程式碼,更在乎的是能在『不出錯』的情況下將取得的程式碼完整編譯通過。 你可能碰到過一種情況,辛辛苦苦從各程式的專案首頁去抓回 Source Code 後,卻怎麼也無法在自己的電腦上編譯,單純點的情況是相依性問題,複雜點則是在不同系統上的相容問題,更誇張的是根本不清楚下載回來的 Source Code 是不是『真的沒問題』。相信很多人早已浪費過不少生命在這些麻煩問題上,導致開發效率低落,不過以上問題,卻在 Debian 裡相當容易解決,因為 apt-get 提供了一系列選項,讓我們輕易從下載原始碼、解決相依性問題、到確保通過編譯一次搞定。 # 下載套件原始程式碼: apt-get source <package> # 安裝該套件編譯過程必要的東西 apt-get build-dep <package> 從 apt-get 下載回來的程式碼,會在自動解開時將該 Package Maintainer 所做的 Patch 一併打進程式碼,以此方法解決系統相容性問題,這邊用 lxterminal package 為例,粗字部份就是在解壓縮時上的 patch: $ apt-get source lxterminal 正在讀取套件清單... 完成 正在重建相依關係 正在讀取狀態資料... 完成 NOTICE: 'lxterminal' packaging is maintained in the 'Git' version control system at: git://git.debian.org/git/collab-maint/lxterminal.git 需要下載 293kB 的原始套件檔。 下載:1 http://ftp.tw.debian.org/debian/ sid/main lxterminal 0.1.8-2 (dsc) [1,372B] 下載:2 http://ftp.tw.debian.org/debian/ sid/main lxterminal 0....

超強大的 Bash - Networking 支援

當全世界都在瘋各種擴充性多元的 Script 語言時,所有人便開始遺忘 Unix 上古老的 Shell script,的確,和當今主流的 Python 、Perl 等語言相比,Bash 像個醜小鴨,但是不可否認,其功能和 footprint 的相對價值遠超過其他 script 語言甚多,因此在大多數 Linux 發行版之中,仍然會預設安裝 Bash 。 也因為 Bash 被太多人忽視了,很少人知道, Bash 其實也可以操作 Networking,舉例來說,可以一行指令便連上時間伺服器,透過 Daytime Protocol (RFC-867) 取得目前的標準時間: $ cat </dev/tcp/time.nist.gov/13 55442 10-09-03 11:19:58 50 0 0 839.8 UTC(NIST) * Bash 內建了這樣的功能,讓使用者可以透過讀寫 /dev/proto/host/port 的方式去操作網路連線,當然這路徑並不真實存在於系統中,所以透過其他的 script 或程式是無法存取。瞭解有這樣的功能後,我們也可以去試著去抓取網頁內容: $ exec 3<> /dev/tcp/www.google.com/80 $ echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3 $ cat <& 3 HTTP/1.1 404 Not Found Content-Type: text/html; charset=UTF-8 X-Content-Type-Options: nosniff Date: Fri, 03 Sep 2010 11:40:10 GMT Server: sffe Content-Length: 1354 X-XSS-Protection: 1; mode=block Connection: close <html><head> ... 內容省略 </body></html> 後記 使用 Shell script 是一種身為 Linux/BSD 等 Unix's...

為你的程式加上 Debugging Mode

使用 C 語言開發程式,往往面對的都是數不盡的奇怪臭蟲,若想為程式除錯,通常會使用很多的 printf function,將所有程式執行的流程以及階段訊息印在畫面上。不過,太多的除錯訊息多半也會造成效能的影響,甚至是造成程式在使用上的不便。尋思,若能在 compile 階段設定是否開啟 Debugging Mode,對程式開發和最後包裝釋出,都可減少不少時間花費。 本文主要說明,如何利用 Autotool 和 C 語言 Macro,在 ./configure 執行階段決定啟動 Debugging Mode: ./configure --enable-debug 要達成目標,首先必需修改 configure.ac 並增加設定,使之後產生的 configure 檔案可支援 --enable-debug: AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [Enable debugging]), CFLAGS="$CFLAGS -g -D_DEBUG") 然後在程式中的 C Header (確定該檔案是所有程式碼都會 Include 的 Header),加讓以下 Macro: #ifdef _DEBUG #define DEBUG(format, args...) printf("[%s:%d] "format, __FILE__, __LINE__, ##args) #else #define DEBUG(args...) #endif 然後我們就可以在程式中使用 DEBUG() 的 Macro,用法和 printf function 一樣,只是該字串只在 Debugging Mode 被啟用時才會被編譯進程式裡: void main() { DEBUG("Debugging Mode was enabled\n") printf("Hello World!\n"); } 該程式執行後,就會看到類似下面的訊息: [main.c:3] Debugging mode was enabled Hello World! 由於在 C header ...

GStreamer Debugging 參數說明

[ GStreamer ] 是一個優異的多媒體處理元件 Library,其架構了最先進的多媒體資料流機制,在目前主流的 Linux 系統中,應用極為廣範。GStreamer 支援以 Plugin 的形態擴充自身功能,可以是編解碼器(Encoder/Decoder),亦或是效果處理(Processing),因此,有許多生產硬體解碼晶片的廠商,都會透過提供 Gstreamer Plugin 的方式,支援 Linux 上的多媒體播放。說到多媒體架構,或許讀者也曾聽過 OpenCore/OpenMax,其實 Gstreamer 和 OpenCore 兩者是相類似的東西,只是前者主要被應用在桌面系統居多,後者則常見於嵌入式系統(Embedded System)應用,最廣為人知的便是 Android Multimedia Framework。在此,細節就不多談,本文將要探討 GStreamer Debugging 的一些手段。 如果曾開發過 GStreamer Application,對初始化 GStreamer Backend 應該很熟悉: gst_init(&argc, &argv); 我們可以理解所有的 GStreamer Application,都會經過這段 Initialization 的動作,因此 gst_init() 會從 main() 得到程式被執行時所代入的後綴參數,換言之,理論上不管是什麼 Application ,我們可以透過這種方式去開啟 GStreamer 的 Debug 模式: $ ./totem --gst-debug-level=3 0:00:00.003322140 13127 0x8c530a0 INFO GST_INIT gstquery.c:105:_gst_query_initialize: init queries 0:00:00.004700946 13127 0x8c530a0 INFO GST_INIT gstmessage.c:73:_gst_message_initialize: init messages 0:00:00.005529752 13127 0x8c530a0 INFO GST_PLUGIN_LOADING g...

親手打造 Window Manager - Transient 和 OverrideRedirect

若嘗試去讀各個 Window Manager 的程式碼,最大的挫折就是會遭遇其中了龐大數量的專有名詞和屬性,假設沒有對 XWindow 和 Window Manager 整體架構有清楚概念,必定會花不少時間在查詢 X11/Xlib 的官方文件和映證,不過,查證過程雖繁瑣,對瞭解整個實作很有幫助。筆者將在本文記錄幾個比較特別的視窗(window)屬性,以便讀者懂得如何處理一些特殊的 window。 WM_TRANSIENT_FOR 此 Hint 屬性記載著短暫視窗的父視窗的 Window ID,若不是短暫視窗,將回傳沒有父視窗。短暫視窗有與一般視窗不同之特性,其將不會在工作列上被顯示,只是用來做短時間顯示使用,如對話視窗(Dialog Window) 就屬此類。想取得該屬性的設定值,可以藉由此 XGetTransientForHint() 得到: XGetTransientForHint(Display *, Window, Window*) OverrideRedirect 此 Window Attributes 參數表明忽略重新定向,若此參數為真(True),視窗管理員(Window Manager) 將不會為該視窗畫上標題框和邊框,如選單視窗(Menu Window)就屬此種會忽略重新定向的視窗。我們可以透過 XGetWindowAttributes() 去取得該屬性,簡單的範例如下: XWindowAttributes attr; XGetWindowAttributes(display, win, &attr); if (attr.overrideRedirect) .... else .... 暫且撇開一般 X Application 開發者熟知的視窗形態(Type),如:Dock 、Desktop、Toolbar 等等,Window Manager 在畫視窗時,首先要處理的是 WM_TRANSIENT_FOR 和 overrideRedirect 這類的屬性,而視窗形態應該是考量於 Window Manager 自身的應用後,才有不同的設計和呈現。

親手打造 Window Manager - 監聽 Screen 上的 XEvent

在 Linux 等 Unix's like 的系統上,擁有數十載歷史的 X11 通常為主流的圖形介面支援方案,雖架構看似老舊,卻在世界上眾高手的努力下,成就了現在的各種極絢麗的桌面環境,而最為眾人所知的,便是 Compiz 這類『視窗管理器(Window Manager)』,其運用 3D 技術帶來震憾的桌面體驗,因此在目前主流的 Linux 發行版中,無一不預設搭載。而許多人在此時,才真正了解 Window Manager 的厲害和重要性,新興的系統中,無論是 Moblin 還是 Google Chrome OS,也都特地為自家系統打造專屬的 Window Manager。 然而,Window Manager 實作細節雖看起來複雜,但實際上沒有想像中這麼艱澀,單純透過 X Protocol 和 API 去控制 window 的行為,這類工作極為簡單,而真正令人感到棘手的,是在事件(event)處理和 ICCCM/EWMH 的部份。ICCCM/EWMH 現在是由 [ FreeDesktop.org ] 所維護,其定義了一系列的屬性,用來記錄視窗環境的狀態,並可供所有 X Client 存取,而 Window Manager 要做的就是成為一個常註程式(Daemon),並隨時去提供和更新這些狀態。不過由於 ICCCM/EWMH 這部份細節繁雜,暫不在本文討論範疇(有興趣可自行參閱 FreeDesktop.org EWMH Spec ),我們主要是討論如何監聽畫面上視窗的 event。 一般 window 監聽自己的 XEvent 是家常便飯,只要有以 Xlib 寫過純 X Application 的人應該都多少有些了解,會比較不瞭解的部份,就是該如何去監聽整個 screen 上的 event,但在這之前,我們有必要先大致瞭解 X window 的架構。通常在 X 上所呈現的桌面環境,是一層層 window 疊起來而成,舉例來說,桌面上常見的工具列(Panel),上面的狀態 Icon ,如:網路管理、Pidgin Icon 等,都是一個個 window 放在 Panel 的 window 之上,而在 Panel 之後,到最底層便是 screen 的 Root Window,Root Window 在所有 window 之下。 所以,若要做到監聽整個 s...