«深入淺出 – Android 系統移植與開發測試» 的補充

這本書的發行的時候, Android 的版本只是 2.2. 現在 Android 已經到 4.2 版了, 所以有些內容需要修改. 我把需要改變的地方整理如下:

0. 首先要安裝 64 bit 的 ubuntu

如果沒有光碟機, 會有點小麻煩. 因為 ubuntu 的 Windows installer 預設是安裝 32 bit 版本. 所以要先下載 64 bit (amd64) 版, 然後手動選取 iso 檔.

如果一定要用 ubuntu 32 bit 版本, 請參考這一篇 [註 0].

1. 在 ubuntu 上安裝以下的套件, 修改的地方用紅色, 並新增第四行.

sudo apt-get install git-core flex bison gperf libesd0-dev zip

sudo apt-get install libwxgtk2.8-dev zlib1g-dev build-essential libstdc++5

sudo apt-get install tofrodos  x-dev libx11-dev lib32ncurses5-dev xsltproc

sudo apt-get install gcc-multilib g++-multilib libc6-dev-i386 ia32-libs x11proto-core-dev lib32readline-gplv2-dev lib32z1-dev [註 1]

如果 apt-get 失敗, 請參考這篇 “回覆: 最近在安裝新的10.10無法更新


接下來就是 Java 了, 基本上 Java 套件會找不到. 所以要先讓 ubuntu 可以安裝過期軟體 [註 2].

apt-add-repository “deb http://old-releases.ubuntu.com/ubuntu/ jaunty multiverse"
apt-add-repository “deb http://old-releases.ubuntu.com/ubuntu/ jaunty-updates multiverse"

此時在 /etc/apt/sources.list 的最後四行會看到:

deb http://old-releases.ubuntu.com/ubuntu/ jaunty multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ jaunty multiverse
deb http://old-releases.ubuntu.com/ubuntu/ jaunty-updates multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ jaunty-updates multiverse

接著就可以更新 source list.

sudo apt-get update

sudo apt-get install sun-java6-jdk


再來就可以安裝 repo.

cd ~/bin

curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo

chmod a+x ~/bin/repo

PATH=~/bin:$PATH


再來取得 Android source code.

repo init -u https://android.googlesource.com/platform/manifest.git

repo sync

經過了不知道多久….

接著做設定

lunch

畫面出現

You’re building on Linux

Lunch menu… pick a combo:
     1. full-eng
     2. full_x86-eng
     3. vbox_x86-eng
     4. full_mips-eng
     5. full_grouper-userdebug
     6. full_tilapia-userdebug
     7. mini_armv7a_neon-userdebug
     8. mini_armv7a-userdebug
     9. mini_mips-userdebug
     10. mini_x86-userdebug
     11. full_phantasm-userdebug
     12. full_mako-userdebug
     13. full_maguro-userdebug
     14. full_manta-userdebug
     15. full_toroplus-userdebug
     16. full_toro-userdebug
     17. full_panda-userdebug

Which would you like? [full-eng]

預設就是第一項 full-eng.

make

如果 64 bits 編譯工具沒弄好, 可能看到錯誤訊息:

prebuilts/tools/gcc-sdk/gcc: line 40: prebuilts/tools/gcc-sdk/../../gcc/linux-x86/host/i686-linux-glibc2.7-4.6/bin/i686-linux-gcc:

用了這招可以修好 [註 3]

cd prebuilts/tools ; git reset –hard HEAD^
cd external/qemu ; git reset –hard d4f5a3ae87a7246613188940c1667bf2880da402

如果看到

/bin/bash: prebuilt/linux-x86/sdl/bin/sdl-config: No such file or directory
/bin/bash: prebuilt/linux-x86/sdl/bin/
sdl-config: No such file or directory

可能是 repo init 時設錯. 我發現我是設錯 username, 此時用

repo init –config-name 重設一次 username 和 email address


錦上添花的設定:

1. 減少不必要的編譯.

export USE_CCACHE=1

2. 設定 USB 設備:

sudo vim /etc/udev/rules.d/51-android.rules
加入設定指令, 讓 Android user 可以直接使用 USB 設備, 忽略到 OWNER 就變成是 root 才能訪問.

# adb protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1″, ATTR{idProduct}=="4e12″, MODE="0600″, OWNER="<username>"
# fastboot protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4″, ATTR{idProduct}=="0fff", MODE="0600″, OWNER="<username>"
# adb protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1″, ATTR{idProduct}=="4e22″, MODE="0600″, OWNER="<username>"
# fastboot protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1″, ATTR{idProduct}=="4e20″, MODE="0600″, OWNER="<username>"
# adb protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="22b8″, ATTR{idProduct}=="70a9″, MODE="0600″, OWNER="<username>"
# fastboot protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1″, ATTR{idProduct}=="708c", MODE="0600″, OWNER="<username>"
# adb protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8″, ATTR{idProduct}=="6860″, MODE="0600″, OWNER="<username>"
# fastboot protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1″, ATTR{idProduct}=="4e30″, MODE="0600″, OWNER="<username>"
# adb protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451″, ATTR{idProduct}=="d101″, MODE="0600″, OWNER="<username>"
# fastboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451″, ATTR{idProduct}=="d022″, MODE="0600″, OWNER="<username>"
# usbboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451″, ATTR{idProduct}=="d010″, MODE="0600″, OWNER="<username>"

sudo chmod a+rx /etc/udev/rules.d/51-android.rules


[註 0] ubuntu 11.10(32位系统)下编译android源码

[註 1] Ubuntu 64 bit 编译 Android

[註 2] ubuntu安裝sun-java5-jdk

[註 3] wrappers for 32/64-bit using wrong path?

[註 4] [Linux]ubuntu 11.04(64 bit)抓取android4.0.4原始碼跟編譯source code/SDK/kernel

Render Script 小檔案

因為 Render Script 的重要性似乎比我原先想像地還要厲害, 故整理 Render Script 的用法如下. 主要參考 Google 的文件 [註1].

1. Off line Compile:

以 llvm-rs-cc compile 一個 render script (rs) 檔案, 產生 bit code (bc) 檔案, 例如底下的 foo.bc. 如果不是編成 bit code, 也可以和其他的 Java 檔編成 .Java. 這個過程可以使用 Java Reflection 的概念.

Java Reflection 能夠分析未知的 class, 把新 class 裡面的 name of the constructors, declared fields 和 methods 都抓出來. 換言之, 我們原先所寫的 .rs 檔透過 Java Reflection 取得正確的 Java API 資訊, 產生確實可用的 Java code. 而不會在 run time 才發生錯誤. 包括 Python 也是這類的 script, 而 C# 也支援 reflection, 但 C++ 沒有這個觀念. 

2.  On Line JIT Flow

等到 .bc 檔和 Java 檔都準備好之後, .bc 檔進入到 Android 所支持的 libbcc, 而 Java code 進入到 Android 的 Dalvik JIT, 跑在 DVM 上. 由下圖可以看得出來, 只有 .bc 可以用 GPU 或 DSP 來執行, 而 Java 不能. 這就是 render script 大有前途的地方.

特別值得提的是 llvm-rs-cc 會做很多大量的優化, 以便產生可移植的 .bc 檔. 而 libbcc 就是一個輕量級的 compiler, 目標只是針對本地平台已知的特性優化.

上次提到 HoneyComb 首先釋出 rs 的 API, 此時它還沒有用到平行處理. 在 ICS 版, 有個 rsForEach() 把每個 reflected Java helper 都叫起來.

RS 的範例如下:

從參數我們可以得知, 它在計算 luminance = 0.299 red + 0.587 green + 0.114 blue, 不愧是 C99 like.

[註 1] http://llvm.org/devmtg/2011-11/Hines_AndroidRenderscript.pdf

 

阿淘哥詏館半日遊

因為 Facebook 上說, 阿淘哥 – 陳永淘要在峨眉的詏館辦個辯論, 所以老婆叫我載她去找素不相識的阿淘哥, 以便徵詢他對歌曲授權的意見.

詏館就是辯論的地方. 說是辯論, 但大家都是阿淘哥的粉絲, 所以我看到只有正方, 而沒有反方. 阿淘哥一面講他的理念, 一面隨興地唱歌. “釣魚台是屬於太平洋的, 是屬於燕鷗的…". “牽妳、牽我、牽牛花…." (太陽花的歌詞).

阿淘哥有時候說國語、有時候說客家話. 我對客家話算是 “略知二一", 也就是快要當掉二分之一的程度, 但還算能跟得上他說話的內容. 大概是海陸口音我比較熟悉的關係.

阿淘哥歌聲真的不錯, 有自己的想法和理念, 對人也很親切有禮, 難怪能夠吸引那麼多粉絲. 詏館這邊養狗養貓養雞養鴨又養豬, 有沒有養魚是不看出來, 但是有一個超大的池塘 (下圖左上方). 阿淘哥說他深愛大自然, 誠哉斯言.

唱歌告一段落之後, 阿淘哥餓了, 於是招呼大家吃飯. 客家話說 “詏又冇好食", 意思是說人不要好辯, 爭辯又不能當飯吃. 但遠很氣的阿淘哥偏偏讓大家辯論完後有得吃 – “詏有好食" (下圖右上方有三個竈). 至於餐費則是自由樂捐的, 讓我聯想到以前曾經拜訪過的麵包傀儡劇場 – 他們演完戲後一定會有麵包吃, 因為看戲和吃飯都很重要.

今天的主食是菜頭苦瓜白菜加鹹蛋湯 (右下圖), 不知道每次是否菜色都相同? 哈! 肚子餓的人也會添一大碗白飯 (左下圖那一大鍋就是飯), 不過我剛吃完 Lunner (Lunch+Dinner) 才來的, 沒有那麼大的胃口. 只見二三十人或站或坐地吃著大鍋飯和大鍋菜, 感覺有點人民公社或是嬉皮聚會的味道.

雖然我也很想在 A Cut 打卡讓 FB 上的朋友羨慕, 不過在詏館聽歌、吃大鍋飯也是別有一番風味.

Bitcode 與 Bytecode

大家都知道 Android 裡面有 Java virtual machine (JVM), 而 JVM 上面執行的就是 Java 的 byte code. Byte code 具有跨平台的性質, 所以 Java 可以 compile once, execute everywhere. 但 Android 裡面還有一個 bit code 就太為人所知.

Bit code 的功能和 byte code 一樣, 但是它不僅限於 Java 語言. 根據伊利諾大學的 LLVM (Low Level Virtual Machine) 計畫, front end 的 compiler 可以是 GCC, 而支援的語言包括 Ada, C, C++, D, Fortran, 和 Objective-C 等等. 這些高階語言被編成 LLVM IF (intermediate form), 然後被放在 virtual machine 上執行. 當然, 從 IF 也可以直接再編成可執行檔.

LLVM 的官網似乎都是用 LLVM IR (intermediate representation) 來代替 IF (WIKI 用語) 一詞, 而這個 LLVM Bitcode File Format 在他們的官網就可以找得到. 

Bit code 除了跨平台之外, 還有什麼好處呢?Google 在推的 RenderScript Compute 就是其中一個應用.  使用者可以先寫好 script, 然後交給 LLVM compiler 去翻譯成對平台最有利的 binary. 比方說這個平台的 GPU (Graphic processor unit) 很弱, 那麼某些 code 在 just in time compile 的時候就會讓 CPU 多分擔一點工作. 從 Android 3.0 的 Honeycomb 開始就支援 LLVM compiler 的 API, 放在 /system/lib/libbcc.so.

蟹老闆, 我又回來了!

我又回到螃蟹家族了.

去年離開瑞昱, 加入擎展科技這家未上市公司的時候, 想說公司剛剛增資到 10 億元, 應該可以撐個三年左右. 如此一來, 絕對足夠我培養完整的 ARM SOC 經驗, 將來就算退出工程師界也可以畫下完美的句點.

今天 7 月 11 日 SV8870 IC 回來, 算是 first cut  works. 它具有 Cortex A9 dual core 1GHz, SGX540 graphics engine, 1080@60fps encode / decode, 與 security engine 等功能. 後續在軟體方面也有所進展: 像是 Android 4.1.1, 4 路 720P video transcoding + DMS, multi-windows (即 Android frame 與 HDMI RX, video playback 同時) 也做好了. 

然而, 天有不測風雲, 公司迅速把錢燒完了, 距離 IC 回來還不到 4 個月. 關於公司裡發生了哪些事情? 大家可以去看一下"壽司幹嘛轉來轉去"的第三彈, 公司經營遇到的問題不外乎是那些. 而我從這本書中得到的領悟就是:管理不在於胡蘿蔔或是鞭子的運用, 因為這些都是作用在馬的身上. 馬車跑得不好, 不能全怪 “馬" – 呃, 台灣的問題也是一樣. 管理上最重要的地方在於乘客、車伕、和馬兒想法是否一致.

本來我打算在工程領域做到 50 歲, 我的三年計畫也是這麼來的. 畢竟, 人們對於老工程師的觀感和面對老醫生是不能比的. 醫生工作的平台 (也就是人體啦!) 數百萬年不變, 老醫生病例看得愈多就愈厲害, 頂多再去進修一些新的工具和手法. 其實, 就算只會一招走天下, 儀器/手法都用最舊的, 也還是有生意上門. 更別說相傳 5000 年的中醫療法都還管用, 有些病人甚至還特別喜歡中醫, 認為西醫西藥不行. 至於工程師天天看 bug list 的話, 大家都知道它對經驗值的提升有限.

匆匆忙忙地幫公司資遣了我手下的 26 個工程師之後, 當然就該想想自己也被資遣的這個問題了. 既然在未上市公司的夢想已經破滅, 我該何去何從呢? 雖然市場上有幾個工作我還挺有興趣的, 但是再次轉換到新環境, 可能又要花點時間才能看出績效. 與其另闢戰場, 不如回到當初培養我的地方吧! 所以, 聽說我的老闆用 super hot run 跑完用人流程, 在我失業 9 天之後, 又回到了前前公司.

[註] 政府規定要在登記後兩週都沒有工作才算失業, 這段期間內面談過兩家都被拒才能夠領失業給付. 新竹市規定要面談三家, 其中一家必須是就業服務站推薦的, 自己找的要兩家以上.

雖然我們原來的 DMP 產品線在我離開之後分家成了 DHC 和 TV 兩個部分, 不過畢竟我才離開一年的時間, 大部分的人事物都和從前差不多. 有些結婚了、有些懷孕了、也有只是單純變胖變老的, 像我自己就是. 回想當初帶著 MIPS/Linux 架構下的韌體經驗去擎展, 又帶著 ARM/Android 的經驗回來瑞昱, 好像是上了短期的補習班. 對螃蟹公司來說, 塞翁失馬, 焉知非福?

聽說正常的螃蟹一生只換三、四次殼. 但商人為了量產軟殼蟹, 會把螃蟹的腳全部拔掉, 以逼迫牠們提早換殼, 讓大家很容易就可以吃到以往相當罕見的軟殼蟹. 公司的組織異動, 大概就算是拔掉蟹腳的過程吧! 只要蟹身還是健康的, 換完殼應該會變得更大隻. 嗯…希望變大的是業績, 而不是組織規模. 這一年來畢竟自己也成長不少, 希望可以為螃蟹家族帶來一些成長的力道!