RFC 2119 小整理

RFC (Request For Comments) 是指網路上標準的討論草案. 每個編號都代表一個獨立的文件, 像是 RFC3261 專門講 SIP (Session Initiation Protocol) 的規範等等. 發行 RFC 的單位是 IETF (Internet Engineering Task Force). 由於 IETF 只是一個鬆散的組織, 背後由 The Internet Society 提供支援. 因此 RFC 文件的 copyright 屬於 The Internet Society 所擁有.

相較於每份標準要賣百塊瑞士法郎的 ISO/IEEE, The Internet Society 的文件都可以免費地由網站上取得. 其中 RFC2119 很特別地不是講技術, 而是講規格中幾個常用詞的定義. SHALL 可以例外嗎? MAY 到底是有規定還是沒規定?

如果我們以光譜來看, 最左邊是一定要, 最右邊是一定不要. MUST 和 SHALL 都是同級的, 表示最強烈的意思. 退而求其次就是 SHOULD, 它允許有例外. MAY 的話, 就有點不置可否了. 很有趣地, RFC 2119 這本規格就只講了這些.

絕對肯定 —————————————————————————————絕對否定
MUST

REQUIRED

SHALL

SHOULD

RECOMMENDED

MAY

OPTIONAL

SHOULD NOT

NOT RECOMMENDED

MUST NOT

SHALL NOT

絕對要 一般要, 可以有例外 可以做, 也可以不做 一般不可以, 可以例外 絕對不可以

不能備份 Windows 的問題

先前試了幾次, 好像都沒辦法按照 Windows  提供的步驟完成備份. 啟用光碟和憑證的備份倒是都順便生出好幾份了. 本來我猜測 Windows 有 2TB 的大小限制, 否則為何每次失敗的訊息都一樣. 所以上次重灌時, 我還特地把 Windows 灌到小小的 SSD 上面. 結果還是不行! 因為那顆 SSD 太小了, 放不下的 program files 還是得安裝在大顆硬碟那邊, 大硬碟的問題依然存在.

前陣子不死心地又找了一下錯誤碼, 才知道中文版的解答很少, 但是有英文版的. Error 0X807800B4 not able to backup files in Windows 7. 和 Backup fails in Windows 7 when trying to create a system image.

前者不能備份是因為磁碟有問題. 按照此連結上面的說明, 首先要叫出 “系統檔案檢查員". 使用 「 系統檔案檢查員 」 工具 (SFC.exe) 來判斷哪些檔案造成這個問題, 接著以正確的檔案取代壞掉的檔案。

  1. 在命令提示字元中,輸入下列命令,並按 ENTER:
    sfc /scannow
  2.  如果 sfc 發現問題, 參考上面的連結可以解決此問題.

但是如果完全沒有發現問題呢? 大概就是第二個連結所講的: Microsoft 的限制. Windows 最多只認得 2TB 的虛擬硬碟 (virtual hard disk), 而其實際容量只有 2097152MB – 2MB – 8192MB = 2088958 MB, 這就是上面錯誤訊息視窗上所寫的數字. 把任何大於 2088958MB 的東西拿來備份都會失敗.

當我在設定備份內容時, 如果勾選了製作系統映像 (system image), Windows 就會認為它要還原整個硬碟. 即便是沒有勾選所有的目錄, 只要勾到左下角那個紅圈圈的 box 就算.

當然, 把映像存起來, 未來才可以完整地還原電腦. 若是這裡不圈選, 就等於只備份了檔案. 想要完整地備份大於 2TB 的系統, 唯一的方法是把大硬碟切小. 內容參考這篇 Shrink a Basic Volume. 基本上它講到如何用 Windows 介面或是命令列去修改 partition. 不過用第三方的免費軟體或許還比較可靠.

總之, 2TB 的限制的確存在. 想要做系統映像檔, 必須先把開機硬碟切到 2088958 MB 以下.

LCD 螢幕小整理

本來這個禮拜要把手邊的幾本書都讀完, 不過昨天發生一個悲劇 – 我的電腦螢幕壞了, 只好花時間研究一下 LCD 螢幕怎麼買?這個三隻小鳥牌的螢幕在臨終之前, 常常有不能從休眠中喚醒的症狀. 近來它被喚醒的難度愈來愈高, 終至昨天為了一時想省電而把它 power off, 哪知它再也醒不來了.  

正好現在資訊月開跑, 3C 產品的價位應該會比較便宜吧!上網查了一下, 我原來那台螢幕的價錢已經可以買到 27 吋了. 既然科技日新月異, 我也要先惡補相關資訊, 以免買錯.

首先, 應該要買 LED 背光的產品, 取代傳統的冷陰極螢光燈 (CCFL) 背光. 基本上廠商自己會進版, LED 具備省電, 壽命長等諸多優點, 我們非買不可.

其次是 LCD 技術, 大致上它分為 TN, VA, 和 IPS 三大類. TN (Twisted Nematic) 是最舊的技術, 不過現在很多螢幕還是走 TN, 包括定位較高階的 27" 產品, 原因是 TN 技術的價格低廉. VA (Vertical Alignment) 是比 TN 優秀的技術, 特色是對比明顯加大, 亮點機率降低, 但可能會有暗點. VA 有很多衍生的技術, 像是富士的 MVA (Multi-domain Vertical Alignment), 友達的 AMVA  (Advanced MVA), 奇美的SMVA (Super MVA). 最昂貴的一種技術則是 IPS (In Plane Switching).

傳統的 TN 在無電壓的時候, 液晶略微平躺, 此時是亮的; 有電壓時, 液晶會慢慢站起來, 此時是暗的. 因此沒吃到電的壞液晶會變成亮點, 短路是暗點. 反之, VA 在沒電壓的站著, 有電壓是倒下去, 故壞的液晶多數是暗點.  當液晶都還站著的時候, 只要把偏光板設為全黑, 光線就一點也不能通過. 這使得 VA 的對比好過 TN 與 IPS, 勇奪第一.

初期 VA 的可視角不好, 但在 MVA 發明之後就解決了這個問題, 甚至超越的 TN + film (薄膜). 最好的可視角要算是 IPS 技術. IPS 的特點是不讓液晶站了又倒, 倒了又站. 大家一直都平躺的, 只是在原地打轉. 由於 IPS 液晶轉圈的速度比不上站起或是倒下, 因此它的反應速度最慢, 耗電又最多.不過就像 VA 之後有了 MVA, IPS 也有了 S-IPS (Super IPS), AH-IPS(Advanced High Performance IPS) 等等的改進方法, 雖然對比不行, 但是反應速度/透光度或是耗電都有了改善. 它的最大優勢在於可視角在 170 度以上, VA 頂多就是做到 170 度.

在反應速度上, 通常標示為灰階或是 G2G (graylevel to graylevel)  而非全黑到全白. 目前 IPS 的反應速度可以寫到 6ms (acer S275HL). VA大約是 4ms (BenQ GW2750HM), TN 是 2 ms (Samsung S27B350H). 所以 TN 的螢幕都會強調 "激速". 上面的數據看似 VA 比 IPS 更快, 但 VA 正常的速度應該是 12ms (Envision H2776MHA, Philips 273P3QPYEB), BenQ 比較快是因為開了獨家的 AMA (Advanced Motion Accelerator Technology) mode 讓液晶加速翻身. 

附帶一提, 如果大家去百度查資料的話, 大家都說 IPS 比 VA 快, 在理論上這是不正確的. 如果拿同一代的技術相比, VA 應該不會輸給 IPS. 我想這就是 acer 號稱 6ms, LG (LG IPS277L-BN) 號稱 5ms, 而 BenQ 號稱 4 ms 的原因. 

另外 IPS 的面板是硬的; TN 和 VA 的面板都是軟的. 以前我很怕同事跑討論事情的時候在螢幕上指指點點的, 只要手指按下去, 整塊區域都會出現彩虹. 不管是自己的螢幕或是別人的螢幕, 感覺它都受了內傷. 想必 IPS 可以徹底解決此一問題.

IPS 面板上分布了很多電極, 他們都是住平房, 而不是住樓上下. 因此透光度比較差, 需要更多的背光燈管. 燈管一多, 除了前面提到的耗電問題之外, 黑的地方就不如 VA 黑, 對比範圍因此降低. 對比的數字有兩種, 一種是幾百千萬起跳的動態對比 (contrast ratio max); 另外一種是數字幾千的真實對比 (contrast ratio native). 在真實比對方面VA 大概寫  3000:1~5000:1, IPS 大概是 1000:1, TN 不是不寫, 就是寫動態對 2,000 萬:1. 如果 IPS 要寫動態對的話是 10, 000 萬 :1.

再來就是 LED 燈管的安排有直下式和側照式兩種. 不好的螢幕會有漏光的現象, 開到全黑畫面時, 會看到某一區是亮的. 因此也有些螢幕會標示零漏光. 至於會漏光的螢幕也不是瑕疵品, 而是規格本就如此. 網路上有一些測亮點和漏光的程式可以下載, 如果是新買的螢幕還來得及退換貨的話, 可以測試一下. 否則直接看網路評價應該就可以了.

然後是 bit 數, 有的是 6 bit, 有的是 8 bit, 10bit, 甚至 12 bit (DELL U2711). 6 bit 唯一的好處就是處理的速度比 8 bit 更快. 一般 8 bit 螢幕就會標示為 16.7M (2 (8 x 3)) 色, 只有 VA 和 IPS 可以做到每個原色完整呈現 8 bit, TN 頂多到 16.2M. 16.2M 和 16.7M 看起來差沒有多少, 但 TN 在這一關就是輸了. 

當然, 更厲害的人會關心色偏 (color shift). 這個部分我另外再研究.

至於輸入的接頭也很重要, 如果只有 HDMI 接頭而沒有 DVI 接頭, 那麼需要買 DVI 轉 HDMI 的這條線, 大概幾百塊可以搞定. 若是多一兩組 HDMI, 這又可以接播放機來看電影而不用開電腦. 最後就是有支援 PIP/PBP 的螢幕, 這樣一來價錢難免就破萬元了, 好處是它可以一面打電腦一面看電視. 然而到了這種價位, 難免會想要直接買 26" 的電視而不是 27" 的電腦螢幕. 買 PIP 螢幕, 唯一能省下的就是不用買一個支援 PIP 的電視盒, 而是一個普通的電視盒.

考慮到改為買電視的話, 少數機種還支援 MHL, 這樣就可以用手機看大螢幕而不用再幫手機充電. 螢幕的部分有 LG IPS277L-BN, AOC i2757FM, 三星 S27B970D 可選. 當然電視或是螢幕不支援 MHL 也沒關係, 只要手機或平板支援 MHL, 再買一條可以充電的 MHL + power 線, 同樣可以在螢幕上玩 APP, 看網路影片. 這條線在價格方面也是幾百元, 買到 HDMI 公的就可以直接用, 若是買到 HDMI 母的又需要多買一條 HDMI 線.

總之, VA 的性價比較好, IPS 當電視最佳. TN 也可以用, 畢竟這是桌上型電腦螢幕而不是電視, 視角小一點並沒有影響, 只要螢幕腳架可以調整高低就 OK 了. HDMI 也是愈多愈好, 有沒有 3D, USB 或是喇叭無所謂, 大概就是這樣了. 

[REF]

1. 簡述 TN、VA、IPS 液晶色彩 與 影像品質

2. LED背光液晶顯示電視

3. 薄膜電晶體液晶顯示器

4.  LCD Color: 8-Bit vs. 6-Bit

5. 螢幕面板怎麼挑?TN、MVA、IPS 各有什麼特色與優點

«深入淺出 – 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