小松鼠嚇了一跳,有了魔法眼鏡後,這世界看起來完全不一樣了

2011年9月21日 星期三

Porting custom rom to Acer Stream

No download available yet.
以前剛接觸 Linux 時,興沖沖的重新編譯完 kernel,往往會發生開機只出現 Li 兩個字的慘劇 (原來應該是顯示 Lilo 後跑出一堆開機訊息,但是連 Lilo 四個字母都跑不完,機器就停在那裡了。)
由於 Acer Stream 都沒人弄 rom,只好自己弄。

一開始傻傻的編譯了一份 AOSP 的 system.img,想說至少可以開機吧,沒想到頗類似當年的 Li。所有程式無法執行,gdbserver 是跑起來了,只是跑起來才發現我是用 adb shell 進去而不是 ssh,網路根本沒跑起來。
還好現在網路發達,大部分的問題網路上都找得到答案。
當然找答案也是要有點方向。

一開始經由官方版本和AOSP的 linker/bin/lib 等等的組合,外加readelf 之後發現官方版本和自己編出的 linker 的 entry point 不同。 大致上猜出是 shared library 放置的記憶體位置問題。

搜尋了一下,發現這是 android prelink 以及 VMSPLIT_2G 的問題。所以這方面把 prelink map 平移一下即可。另外我也 complie 了一份 VMSPLIT_2G=n 的 kernel。
再 來就是 RGBA8888 的問題。 Stream 的 kernel 回報不正確的解析度,而且固定為 32bit 色彩 RGBA8888。32bit 用 #define 寫死了,無法 ioctl 設定。因此把這些 #define 改了,重編成 RGB565 的格式。
最後就是 Acer 的 kernel 大概因為用 zip 壓檔的緣故,很多檔案不見了。Linux 的 kernel 中有些檔案,檔名僅僅只有大小寫不同,但卻是兩個不同的檔。碰到這種除了大小寫外完全相同的檔名,Acer 用的 zip 就會只挑其中一個放入 zip 檔中。所以只好從其他地方的 source 補回來。

這樣之後,只要選對 kernel,很多 2.2 的 custom rom 都能開機到 GUI。我試過了
AOSP (full_passion, 改 prelink map),
liquid metal 官方 2.2
liquid miui 
malez recovery (正常顯示)

基本上都沒怎麼改就能跑 GUI,不過當然硬體也都不太靈。

也試了 liquid metal 的 2.3.3 leak,不過不成功。
大概 kernel 至少要弄到 2.6.34 才行。

2011年9月17日 星期六

ClockworkMod Recovery for Acer Stream

Download here (Warning! Very experimental. Use at your own risk.)

Install:
Use fastboot (or Rom Manager?) to flash the recovery image. See ClockworkMod Recovery for more information.


Acer Stream 這隻手機,就像 Kindle DX 一樣,出來時也都算風風光光,也一度是名義上的旗艦機種,但因為銷售不理想,很快都被原廠打入冷宮,停止更新。現在完全找不到 Acer Stream 的 Custom Rom,所以,只好自力救濟一下了。由於我對 Android custom rom 幾乎毫無經驗,所以先從 Recovery image 開始。
Acer Stream 的特點:
  • image header 是 4K
  • Framebuffer 的 bits per pixel 似乎固定為 32。VSCREENINFO 傳回的 xres 和 yres 不可靠,預設是 1280x800, 但其實 lcd 的解析度是 480x800。OS_RESOLUTION 的傳回值才是對的。framebuffer 的 第二頁的起始值固定在 1280x800x4 bytes 的位置。大部分 recovery image 畫面會壞掉的原因在此。我猜大概要支援 HDMI 的緣故。
  • /data 不是 mtd@userdata 而是 mmcblk1p1 。
原本打算用 malez recovery 來改,但發現好像沒有提供 source。所以抓了野火機的 ClockworkMod Recovery Image,並且抓下 source 重新編譯 recovery。(主要的困難是 kernel.org 被駭,花了一點時間才抓到完整的 source。)
我只修改了 graphics.c ,修改的部份如下:
    if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
        perror("failed to get fb0 info");
        close(fd);
        return -1;
    }
    // should use OS_RESOLUTION ioctl to get xres
    vi.xres=480;

    bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (bits == MAP_FAILED) {
        perror("failed to mmap framebuffer");
        close(fd);
        return -1;
    }

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = vi.xres;
    fb->data = bits;
    fb->format = GGL_PIXEL_FORMAT_RGBX_8888;
    memset(fb->data, 0, vi.yres * vi.xres * 4);

    fb++;

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = vi.xres;
    fb->data = (void*) (((unsigned) bits) + (fi.smem_len>>1));
    fb->format = GGL_PIXEL_FORMAT_RGBX_8888;
    memset(fb->data, 0, vi.yres * vi.xres * 4);

    return fd;
}

static void get_memory_surface(GGLSurface* ms) {
  ms->version = sizeof(*ms);
  ms->width = vi.xres;
  ms->height = vi.yres;
  ms->stride = vi.xres;
  ms->data = malloc(vi.xres * vi.yres * 4);
  ms->format = GGL_PIXEL_FORMAT_RGBX_8888;
}

static void set_active_framebuffer(unsigned n)
{
    if (n > 1) return;
    vi.yoffset = n * vi.yres;
    if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
        printf("active fb swap failed %d\n", n);
    }
}

void gr_flip(void)
{
    GGLContext *gl = gr_context;

    /* swap front and back buffers */
    gr_active_fb = (gr_active_fb + 1) & 1;

    /* copy data from the in-memory surface to the buffer we're about
     * to make active. */
    memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
           vi.xres * vi.yres * 4);

    /* inform the display driver */
    set_active_framebuffer(gr_active_fb);
}

賽德克‧巴萊 太陽旗

熱血‧巴萊。
雖然電影並未特別標榜或宣傳揚熱血,但最真實的熱血在這部影片中被呈現出來了。
而且是赤裸真實,未經多餘烹煮的原始熱血。由於太生了,所以會讓很多吃慣七分熟熱血的人,難以下嚥。是那種真的會流血、拋頭顱的後所灑的熱血。
像不老騎士很熱血吧,因為看正常人看到他們騎車的英姿,都會很怕他們不能繼續老下去。荒野大飆客(Wild Hogs)雖然也是一樣長途騎車來奪回青春,但是光是騎騎車感覺就沒那麼熱血,直到他們生命受到威脅時,不顧危險的奮戰,才開始讓人覺得熱血。
所以難怪台灣熱血界第一品牌九把刀的名言是「人生就是不停的戰鬥」(或報仇)。因為熱血這種情緒本來就源自於不是你流血、就是我流血、大家多少都會留點血的狩獵搏鬥。賽德克巴萊中很忠實的呈現了這種情緒的原始風情,就像電影中的真實場景一樣。
我們現代男人骨子裡也還留有一樣的血液,只是用比較「文明」的方式包裝著。或者更貼切的說,因為文明的關係,只能用比較迂迴的方式來「模擬」原始的熱血。比方「蔣為文黃春明事件」,看似有點脫序離譜,其實不過是男人在爭奪以及守護自己的如天邊彩虹般的虛擬獵場--台灣文學論述權。我舉這個例子並不是因為他們特別野蠻,而是因為他們特別文明(作家以及教授)。無數的現代男人在馬路上、職場上、球場上、遊戲中、電視前(觀看運動比賽或者政治),不自覺的依照原始獵人的本能,在更複雜難解的文明森林裡,爭奪虛幻的虛擬獵場。而現實世界中的真實獵場早己集中於少數資本家及獨裁者手中。
賽德克人在電影中,遇上了從真實獵場到文明虛擬獵場的過渡期。在真實獵場裡驍勇善戰的獵人們,在文明的虛擬獵場中卻成了被宰制的輸家。影片中藉由花岡兄弟為代表的模範番,說明了接受文明的狩獵規則也是一條充滿不公平與忍耐的漫長道路。實質的獵場是註定失去了,雖說還能靠著勝利者的施捨苟活(或者說像狗一樣活著,「連獵犬都看不起」),但這是以彩虹另一端的虛擬獵場作為代價所換來的(「二十年後就不是賽德克了」)。由此,不難理解影片中至少要保住彩虹那端獵場的想法。
廢刀令及西南戰爭時的日本武士是如此,哪天外星人來佔領地球,讓你驚覺到所謂天經地義的社會規範(或「普世價值」)原來並非真實獵場時,你也會有做出相同舉動的衝動來保護僅剩的虛幻獵場(假如你還有熱血的話)。
電影中也藉由老一輩的頭目級人物、花岡一輩有家室和事業者、年輕一輩想成家者、巴萬這樣的小孩等四個不同階段的男人,來描述不同的熱血。相當細膩。

歌舞過多?
片中的歌曲和舞蹈也傳達出動人而豐富的情感,也對於劇中人物的情感做出了闡釋。當然也可以選擇用內心戲、旁白、字幕或台灣長壽劇常見的自言自語的方式呈現劇中人物的心裡轉折和想法。能用微妙的內心戲表達自然最好,但觀眾你摸著良心自問自己看穿人心善解人意的讀心術真的很強嗎?所以用其他方式傳達會比較有效而且有效率。本片用歌舞相當的適當,但也許還是部份人會接收不到。

出草不文明?
這是事實,至少從現代的角度來看,的確不文明。
不過對科幻類作品有一定視聽量的人,對於這種程度的文化差異應該是司空見慣。因為像 Star Trek 這種等級作品的常見的把戲,就是對於外星文明的文化差異來個為拍新戲強說愁。
舉個天元突破裡的例子。一個村莊裡出來了新生兒,大家卻歡喜中帶有憂愁。因為村子中的規矩是,總人數不能超過兩百人(?)。 所以多了兩個人,就要抽兩個號碼,處死這兩人。結果抽到兩個可愛的小朋友(又沒有像飢餓遊戲裡可以自告奮勇取代的規則)。結果外來的主角群當然無法接受,覺得太慘忍。但其實由於與外界封閉,村莊所能生產的資源,只足夠兩百人生存。只要多出一人,整個生態圈會崩潰。為了救兩個人,會讓 202 個人都死掉。
看似野蠻的習俗,其實自有道理。
從另一個角度來看出草,不也是在有限的資源下,讓最強的生命留下,達到適者生存的演化目的,讓整個種族更強?
我們現在強用科技留下原本無法生存於自然中的生命,是否是反演化?是否會導致整個人類族群滅亡?其實也很難說。
現實生活中要真心接受文化差異很難,但至少在電影中看看,應該還沒那麼難跨越,也才能接受影片傳達的情感。

2011年9月13日 星期二

朋友悖論與先承認你就是你朋友


今天在報紙上看到一段話:
伴侶盟的調查不只問受訪者自己的同居經驗,也問其親友的同居經驗,發現兩者有相當大的落差。套句鄉民的術語,這是所謂「你承認你就是你朋友吧」的現象:網路上許多敏感話題的提問,往往發文者會以替朋友上來問的方式,以避免自己「曝光」或「出櫃」的窘境,而實際上問的乃是自己本身的困擾。美國研究同居最重要的學者,前人口學會會長Larry Bumpass教授當年開始到日本做調查,也發現日本人不願意說自己在同居,但卻有極高比例報告親友在同居。同居伴侶所覺知到台灣社會對他們的不友善,有這個鄉民世界的對比可見一斑。  --- 同居伴侶權益 立法保障       2011-09-13     中國時報     【李瑞中】
 讓我聯想到朋友悖論。 簡單的說,就是就是平均來說,你的朋友數量會比你朋友少。這樣說有一點繞口令。或者這樣講好了,平均來說,每個人交往過的對象,會比他交往對象的(平均)交往次數少。
所以說,當你興致一來,將你過去所有交過女友調查一番,把她們交往過的男友次數平均一下,發現遠比你交過的女友多,或者把你 facebook 上所有好友的好友數平均一下,發現自己似乎人緣不佳,請不要太灰心,因為這只是簡單的數學事實,圖論上、統計上的簡單定理。不代表你有低於平均值的人緣。也許這就是人比人會氣死人的理由之一。
回到報紙上的那段話。受訪者自己的同居經驗和親友的同居經驗有落差,會不會也是受到相似因素的影響?不見得完全是因為話題敏感的原因?
因為即使每個人都完全誠實,你也很可能會得到受訪者平均的交往過的對象有 5人,但是問其親友(包含前男女友)的交往對象數量,卻有 10 人,這種現象。
而同居關係和親友數量是否互相會影響?似乎也很難排除。

2011年9月12日 星期一

幾個關於 Kindle 3 firmware on Kindle DXG 的 Hack

之前由 Yifan Lu 發布的 Kindle 3.X updater 實現了讓 Kindle DXG/2 也能使用 Kindle 3.x 的 firmware。這應該是很多人的願望,對一般使用者而言,也遠比我之前的 kindle 3 Open Source on DXG 實用。
但是有三個問題:

2011年9月1日 星期四

WebKit for Kindle DX binary files

下面的 tar ball是一套可以在 kindle dx 執行的 directfb, gtk+, webkit 環境:
WebKitGtkKindleDXG.tar.xz
使用方式
  1. jailbreak, ssh 到你的 kindle DXG (2.5.8 版本)
  2.  解開 tar ball,放到一個 loop file system 下,然後 mount 到 /usr/local
  3. mount -o bind /usr/local/root /var/tmp/root
  4. 執行 /usr/local/bin/gwebkit 即可,會打開一個 html 檔。
  5. shift+方向鍵控制游標。Sym 是 Tab。Menu 可以跳到 URL 輸入框。
  6. Alt-x  離開,Alt-a Alt-z Zoom in, out。Alt-l 刷新螢幕。
  7. 雖然可以使用免費的 3G 網路,但是由於怕違反 Amazon 的使用規範,所以預設關閉,只能手動啟動,
  8. 沒有內附中文輸入法,但是許多的 gtk+ 的輸入法 module 都可以用。scim 不能用的原因有兩個,stdc++ 的版本,我編譯的 DirectFB 只允許單一程式。我自己是寫了個 chewing 的 gtk+ im-module,但是還不完整,沒有附在裡面。
  9. 其他一些程式,也可以試試看,如 gtk-demo, leafpad, gqview, vte, gtkterm2 等。
  10. 基本上是使用 kindle 3 source code,修改過的 source 在 /usr/local/src 。
(更新*****)
GitHub Project: https://github.com/tjwei/WebKitGtkKindleDXG

2011年8月21日 星期日

WebKit Kindle DX backport

Kindle DX 的 netfront 瀏覽器雖然堪用,但是很多網頁讀不出來。
比方說我的部落格首頁就會出現記憶體不足的訊息,網頁呈現的效果雖然似乎挺清爽乾淨,但是 DX 螢幕有 824x1200 的解析度,足以顯示完整的網頁。
整體來看,還是 kindle 3 的瀏覽器較佳。一個作法是直接讓 DX 執行 kindle 3 的作業系統。非常神奇的是,居然沒有什麼問題。但既然 kindle 基於 open source,也釋出了修改過的程式碼,所以我試著將 kindle 3 的 webkit 移植到 dx 上。
初步的結果如下:

還不是很完整,但至少能在 google 裡打個搜尋,顯示一些網頁。
過程是 Directfb -> Gtk+ -> WebKit
  • 編譯環境; scratchbox
    • toolchain 用的是 glibc2.5 2007q1。雖然說 libstdc++ 和 kindle dx 的不相容,但 2006q3 太舊了,很難編譯。而且 gtk+ 用的是 C 而不是 C++,webkit 雖然用 C++ 但是沒有用到 libstdc++ 而是自帶的程式庫,所以問題不大。這點從android 極為貧乏的 C++ runtime 可見端倪。因為顯然同樣是 WebKit based 的 Android web browser 不需要完整的 libstdc++。所以 glibc2.5 的 toolchain 應該都可以。
    • 在 amd64 的 linux 下使用 scratchbox i386 binary, kernel 要增加 vdso32=0 的參數,不然會有 Inconsistency detected by ld.so: rtld.c: 1192: dl_main: Assertion `(void *) ph->p_vaddr ==  的錯誤
    • 我的 cputransp 跑不起來,所以我自己編譯了一個 static linked x64 qemu-arm。然後寫了一個 wrapper 來吃 binfmt 餵進來  --sbox 的參數。除了 pthread 外,似乎沒什麼問題。跑 configure 時,一些 pthread 的測試程式會停不下來,也許是 qemu 的問題。當碰到這個問題的時候,都是手動修改 configure.in 裡面的測試程式,讓他直接通過。
  • 我在 /mnt/us 上弄了個 200mb 的 ext3 loop filesystem,mount 到 /usr/local 上。之後只要 設好 ld.so 或者設定 LD_LIBRARY_PATH=/usr/local/lib 即可,不會影響原系統。
  • 編譯 DirectFB
    • 用的是 kindle 3 的 source。設定 --prefix=/usr/local,gfxdriver=none
    • 編譯所需的 jepg 和 libpng 時,設定 --prefix=/usr。libpng 需要 1.2 版的。我當初一時不察,用了 libpng 1.4 ,所以修改了一點 DirectFB 的程式碼解決 libpng 1.2 的相容問題,還要額外的安裝 libpng 1.4 到 /usr/local
    • 編譯上沒有什麼問題,然後把 /usr/local copy 到 kindle 完成安裝上。可以利用 ssh+tar 或者 ssh mount 來複製檔案。
    •  kindle 的 eink framebuffer 是 4bit 灰階,無法被 directFB 直接支援,所以只好當成 indirect fb 來使用。如果你在這裡花上零點五秒來想想該怎麼解決這個問題,你會發現 amazon 的 lab126 想的解法和你一樣。他用了一個 LUT8 (8bit indexed color) 的 virtual framebuffer 來假裝是真正的 frame buffer,然後就能順利建構 DirectFB 。接下來只要設法讓 virtual frame buffer 和真正的 frame buffer 來互通有無即可。lab126 用的是 call back 的方式讓使用者程式自行決定如何處理。雖然從程式碼來看, lab126 取得 frame buffer address 的方式似乎有點不保險。
    • kindle 3 的 eink 比 DX 多了好幾種 update eink screen 的方式。
    • lab126 版的 DirectfB 基本上有考慮到 DX 的按鍵,除了一個 keymap 的檔案。所以要修改這個檔案,不然之後有些按鍵會出問題。我順便把 Sym 鍵設成 Tab。
    • 要用 no-vt 模式執行。可將 no-vt 加入 ~/.directfbrc 裡面。 
  • 編譯 GTK+
    • 編譯基本上沒有太大的問題,但是很繁雜。有些 kindle 3 source 沒有 autogen.sh 或者 configure 時,就 aclocal && autoconf && automake。還不行,就抓一份相同版本的正版 source ,然後把 lab126 版 copy 過去。
    • DX 的 glib 太舊了,要弄個新版的到 /usr/local 裡。在 scratchbox 中,我也順便把新版的 glib 裝到 /usr/ 下,之後編譯會比較輕鬆。
    • 雖然沒什麼道理,但 gtk-doc 似乎不裝到 /usr/ 下,automake 就抓不太到。雖然常常 configure 時可以關掉 gtk-doc,但有時需要 autogen 的時候, 不裝個  gtk-doc 就過不了關。autogen 應該是設計來簡化問題的,而不是用來增加問題的。 
    • automake 版本要用 SBOX_DEFAULT_AUTOMAKE 設定到 1.9。不然會有 tar-ustar 錯誤。
    •  直接編譯完,執行 gtk-demo 會出現像是 這裡的情形。我的作法是在 gdk_init 裡面加上自己的 kindle dirty rect callback ,把更動過得方塊更新到 eink screen 上。這樣, gtk-demo 就能正常顯示。
    • 如果前面 directfb 的 keymap 沒改好,會發生 gtk-demo 裡面上下鍵無法使用的狀況。
    • 我遇到了 字體都變成方格這個問題。google 查詢到,似乎某些 pango + cairo 的組合會發生這種情形,所以我將 pango 和 cairo 換成稍微新一點的版本。lab126 有更動 cairo 程式碼,不過看起來只是 hack 某些 font 資訊的問題,不是什麼致命的問題,所以我直接使用無修正板。
    • 我設定了 gtkrc-2.0 ,讓字體大一點,也設定了 fontconfig 來使用 /usr/java/lib/fonts 中相對應的字型。
    • 除了 gtk-demo,我試了 leafpad,gtkterm, gqview。 leafpad 和 gtkterm 都能正確編譯執行,但是視窗要修改或者設定成大一點,最好是全螢幕。原因是 gtk游標會在螢幕正中間,如果 gtk 程式的視窗太小,會因為鼠標沒有在視窗上而抓不到 keyboard focus。這大概是 directfb的 wm 的特性。gqview 也可執行和操作,但是似乎圖形顯示有問題。gtkterm 需要 vte,編譯 vte 時,需要 termcap。雖然用 ncurses 取代 termcap 也行,但是 ncurses 我編不起來,也懶得弄。除了 gtkterm 外,vte 本身應該也能跑。和 kindle 上其他的 terminal 程式相比,vte based terminal 的一大優點是可以顯示正確顯示 utf8 中文。LXDE 的 gpicview 雖然標榜純 gtk,但其實有用到 X11。光是 gdkx.h 也就罷了,其中有用到 X11 的檔案,所以無法直接編譯。gedit 因為需要 gtksourceview 一堆的,看起來太複雜了,就沒有真的弄起來。
  • WebKit
    • 查看 kindle 3 的 source code 裡的 Changelog,到 2009年5月18日,所以下載了 webkit r43841。
    • 解開後將 kindle 3 裡面修改過的 source 複製並且覆蓋過去。
    • 修改 configure.ac,讓 directfb 變成 default。因為 build-webkit 似乎沒有這個選項。
    • 執行 WebKitTools/Script/build-webkit --gtk,我選擇關掉 xslt還有一些不需要的選項。
    • make 過程會出現錯誤,因為一些 .h 檔沒有放對位置。可以修改 GNUMakefile 或者 source,或把 .h ln -s 到適當地位置。總之,依個人喜好,讓他編譯過去就是了。
    • 還有一些錯誤是 kindle profiling 相關的,我直接刪除相關的部份。
    • GtkPerf 的 link 會出問題,要把 .libs/libWebcore.a 連進去。
    • make install 後把 /usr/local copy 到 kindle 就行了。
    • 編出來的 GtkLauncher 可以執行,但是 kindle 的 proxy 需要特別的 x-fsn http header,所以暫時還不能上網。可以嘗試用 GtkLauncher 瀏覽 kindle 裡面的 local 檔案,要用完整檔名。如果發現只看到 html 的 source code,那是因為沒有 mime data。將你電腦裡面的 /usr/share/mime copy 去 kindle 即可。
    • 這個版本的 webkit settings 沒有支援 user-agent 修改,也沒有支援 proxy,更沒有支援客製化的 http header,所以修改程式碼送出適當的 header,和使用 proxy。
    • 修改被 lab126 修改過的 GtkLauncher 程式碼,讓 urlbar 顯示出來。
    • urlbar 可以輸入,但是 google 搜尋框無法輸入文字。經 google 查詢後,發現是 ICU 問題。我用的是 ICU 3.6,在 scratchbox 中無法順利編譯,因為 pkgdata 無法執行。我修改 makefile,讓 pkgdata 能順利執行,完成 make。但是顯然我漏了什麼。依照這裡的方式,重新編譯。這時,輸入框就能輸入了。
    • 我不曉得如何用鍵盤完整的操作,GtkLauncher,即使打開 caret browsing,也不知道怎麼操作,介面還需要修改。中文輸入法也還沒整合進去。