2013年4月28日 星期日

[Linux] 計算程式運行的最低需求(Code size & Shared libraries) @ Ubuntu 12.04

這幾個月處理一些跑在 Embedded System 的小工具、小服務,每次 porting 後,總要計算一下程式的大小,這時計算的原理就是用 ldd、objdump 或 readelf 看一下呼叫了哪些 shared library,把他們加一加就差不多了。然而,需要留意的則是 shared library 還會在 link 其他 shared library,所以用到的 shared library 也要一併挑出來查看一下才行。


不知不覺就寫了 script 來處理,原理就是建 hash 來判斷 shared library 判斷過了沒。


$ git clone https://github.com/changyy/resource-calculator.git
$ ./resource-calculator/resource-calculator.sh
Usage> ./resource-calculator.sh -v -r path_bin_readelf -s path_bin_strip -o output_dir -l path_for_library_finding  [ BIN_FILE | BIN_DIR | LIB_FILE | LIB_DIR ] ...


其中 -r 是吃 readelf 工具位置,可以用 -r `which armv6-linux-gnueabi-readelf`;-s 是指定 strip 位置,也就是產出時順便 strip 一下;-o 則是輸出到指定輸出目錄;-l 是指定讀取 shared library 位置,如 cross compiler 的 library 位置、platform sysroot/lib 位置和第三方 shared library 位置等;最後的參數則是要驗證的 tool 或 library ,若接目錄則是進去撈 bin 或 so 出來。


實例 (已在 PATH 環境變數中加入 cross compiler 的搜尋位置):


$ ./resource-calculator/resource-calculator.sh -o /tmp/output -r `which armv6-linux-gnueabi-readelf` -s `which armv6-linux-gnueabi-strip` -l /path/armv6-linux-gnueabi/compiler/lib -l /path/armv6-linux-gnueabi/platform/sysroot/lib -l /path/armv6-linux-gnueabi/3rd-party/lib /path/imagemagick-convert

[INFO] READELF: /path/armv6-linux-gnueabi-readelf
[INFO] STRIP: /path/armv6-linux-gnueabi-strip
[INFO] OTHER LIB: /path/armv6-linux-gnueabi/compiler/lib /path/armv6-linux-gnueabi/platform/sysroot/lib /path/armv6-linux-gnueabi/3rd-party/lib
[INFO] TARGET: /path/imagemagick-convert
[INFO] OUTPUT: /tmp/output/lib /tmp/output/bin /tmp/output/slib
-------------
..............*...............*
All:
       libdl.so.2 libm.so.6 librt.so.1 libpthread.so.0 libMagickWand-6.Q8.so.1 libgcc_s.so.1 libjpeg.so.62 libpng10.so.0 libtiff.so.5 libz.so.1 libMagickCore-6.Q8.so.1 libc.so.6 ld-linux.so.3 libxml2.so.2 libgomp.so.1

$ du -h /tmp/output/
6.7M    /tmp/output/lib
1.9M    /tmp/output/slib
12K     /tmp/output/bin
8.5M   /tmp/output/

$ ls -R /tmp/output/
/tmp/output/:
bin  lib  slib

/tmp/output/bin:
convert

/tmp/output/lib:
libdl.so.2     libMagickCore-6.Q8.so.1  libtiff.so.5
libgomp.so.1   libMagickWand-6.Q8.so.1  libxml2.so.2
libjpeg.so.62  libpng10.so.0            libz.so.1

/tmp/output/slib:
ld-linux.so.3  libc.so.6  libgcc_s.so.1  libm.so.6  libpthread.so.0  librt.so.1


故程式運行時所需的 size 是 8.5MB ,但其中有 sysroot libraries 為 1.9MB ,所以移植到板子上的程式碼大小 = 8.5MB - 1.9MB。


2013年4月25日 星期四

[Linux] 關於 Camera Orientation 問題 @ Ubuntu 12.04

得知隔壁 Team 碰到照片 Orientation 問題就稍微研究一下,舉個例來說,跨年時常看到有人用手機拍下 101 煙火影片,結果擺到電腦上要觀看時,頭則要旋轉 90 度才可以看 Orz


關於照片部分,在 JPEG 裡頭有 Exif Orientation Tag 資訊可以查看,簡易地用 iPad 2 with iOS 6.1.2 ,分別轉動 90 度拍下四張照片,並利用網路資源 jpegexiforient.c 查看:


$ mkdir ~/tmp 
$ wget http://sylvana.net/jpegcrop/jpegexiforient.c -O ~/tmp/jpegexiforient.c
$ cd ~/tmp
$ gcc jpegexiforient.c

$ find /path/photo -name "*.JPG" | -exec ~/tmp/a.out {} \;
3
8
6
1


由此 jpegexiforient.c 可知:


 * Value | 0th Row     | 0th Column
* ------+-------------+-----------
* 1 | top | left side
* 2 | top | right side
* 3 | bottom | right side
* 4 | bottom | left side
* 5 | left side | top
* 6 | right side | top
* 7 | right side | bottom
* 8 | left side | bottom

至於解法嘛,有的是靠 Photo Reader 處理,例如在 Windows 8 顯示仍一切正常,但有的沒處理時,顯示則會出錯,故最後手段就是用程式處理一下,給它轉個 90度、180度、270度吧!產生照片的過程說誰錯也不對,只能說對使用者不方便就是程式設計師的錯吧 XD


[Linux] 確認 Tools 和 Shared Library 的 CPU 架構 @ Ubuntu 12.04

最近在移植一些工具,需要確認編譯出來的程式跟函式庫是不是板子可跑的,或是碰到程式不能跑時,該怎樣確認。


這時就可以用簡易的 file 指令來驗證:


$ file spawn-fcgi
spawn-fcgi: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.27, stripped


$ file lib/libjpeg.so.62
lib/libjpeg.so.62: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped


驗證所需函式庫(有些 shared object 還會再 link 其他 shared objects):


$ armv6-linux-gnueabi-readelf -a bin/spawn-fcgi | grep Shared
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]


$ armv6-linux-gnueabi-readelf -a lib/libjpeg.so.62 | grep Shared
Type: DYN (Shared object file)
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]


有時雖然已經是 ARM 架構,但丟上去就是不能跑,顯示 format 錯誤的訊息,這時有可能是板子雖然是 ARM 架構,但是 CPU 指令集不支援,例如在 ARMv6 的板子執行 ARMv7 編譯出來的程式,此時就需要判斷程式或函式庫是用哪個 compiler 編的:


$ armv6-linux-gnueabi-readelf -a modules/fuse.ko | grep -i CPU
Tag_CPU_name: "6"
Tag_CPU_arch: v6


 


2013年4月18日 星期四

把玩 TideSDK - 跨 PC 平台的 Desktop App 整合方案(HTML5/CSS3/JS + PHP/Python/Ruby)


最近有打算做 pc app ,想說一口氣做一個跨平台的程式,在找資料的過程中,除了 QT 方案外,被 TideSDK 吸引到!簡單說,若曾聽過 PhoneGap 的話,那對於 TideSDK 就不會陌生,皆是一樣的架構:


Plaftform framework (Support Ruby/Python/PHP) + Browser + HTML5  


接著還能幫你打包成個平台的安裝程式!真是佛心來的 Open Source 啦!操作上需下載 TideSDK 和 TideSDK Developer 套件,將 SDK 依系統擺在指定的位置上即可,更多細節請參考官方教學文件,本次在 Mac 10.8.2 跟 Windows 8 測試。


直接說測試結果好了...嗯...跨平台的事沒那麼簡單,光要跨平台就會面臨 browser rendering engine 的問題,所以我測試的結果是光 mac 跟 windows 的 TideSDK-Webkit 行為就不一樣 :P 簡單的說,原本的概念想說從 IE/Chrome/Firefox 多種瀏覽器支援,降到至少只要維護 TideSDK-Webkit 一個版本就好,用了之後反而變成要多支援數個瀏覽器版本(TideSDK-Webkit @ Windows, TideSDK-Webkit @ Mac),故:


!!平台不是這麼容易跨的!!


所幸的,逛了一下 TideSDK API 中,有看到開啟系統內建瀏覽器的用法,或許急用的話就用這招吧!


Ti.Platform.openURL : Open the given URL in the system's default browser. ...


除此之外,這還是挺不錯的!還可以用 PHP/Ruby/Python 唷!


2013年4月16日 星期二

更換 ACER 筆電鍵盤

ACER NB KEYBOARD


這是一台 2009 年購買的 ACER 的筆電,但其實購買沒半年,鍵盤就開始出現某些按鍵無效(6,8,9鍵),除了人在外地很懶得去更換外,另一個主因是時好時壞,有時要 demo 給別人看也不見得好 demo ,就這樣撐到了 2013 年,基本上已經邁入完全外接鍵盤的用法了。在上個週末閒來無事順便找一下如何拆鍵盤,就默默地學會拆鍵盤,接著去露天找筆電型號,又找到還有人在賣這型號鍵盤,就賭了一把給它下標了!


幸運地,一切正如所料,換了鍵盤就好了 :P 再也不用外接鍵盤啦!不過當初拆建盤的主因是有人說只要重接鍵盤說不定會好,但此例是仍不ok啦,且事實上也有可能是內部接頭的問題,故沒拿去給別人檢驗而自己買零件來換是有風險的,需自己評估勇氣 XD


ACER NB keyboard


 


這台筆電分別在 ESC, F4, F8, F12, Del 上有個卡榫,往邊框(往螢幕那個方向)壓後就可以慢慢把鍵盤拆掉


anyway, 這台筆電又重生了!外加再找拆卸的工具時,發現之前有兩條替換 MBP 的記憶體默默地被收藏著,於是順手又把這台筆電升到 4GB 囉!還是要提一下,若保固內還是趕緊拿去換修,之前查文章的結果,給原廠修似乎要價 2500 元!真的不便宜,這次買露天的(可能是副廠做的),含運花費不用 550 元,所以才賭了一把 :)


[OSX] 架設 NFS server @ Mac OS X 10.8 Server

架設 NFS 最方便之處莫過對一般人提供多台主機登入後,仍共用同樣的家目錄,所以,這次 NFS service 著重在家目錄的設定。


首先,先介紹一下 OSX Server 的環境,共有兩顆硬碟分別都是 750GB 的容量,目前切割為系統槽、490GB、750GB 共三份,故規劃把家目錄擺在 750GB 中,並備份到 490GB位置上(備份到另一顆硬碟)。另外一提的,要留意 OSX 預設檔案系統是 case insensitive (不分大小寫),若要給 Linux client 等的還是先格式化為 case sensitive 吧


工作方向:



  1. 處理 /User 移位

  2. 啟動 NFS server 設定

  3. 讓其他主機掛載進來

  4. 處理 uid/gid 不對應問題


將 /User 目錄移動到 750GB 中:


原先家目錄是在第一顆硬碟中,為了以後方便備份,所以嘗試用 rsync 搬移它到另一顆硬碟


$ sudo ln -s /Volumes/750GB /data
$ sudo mkdir /data/SYSTEM
$ sudo rsync -a /Users/ /data/SYSTEM/Users
$ sudo mv /Users /Users-Bak
$ sudo ln -s /data/SYSTEM/Users /Users
$ sudo chown root:admin /Volumes/750GB/SYSTEM/


設定 NFS Server:


$ sudo vim /etc/exports
/Volumes/750GB/SYSTEM -maproot=root:wheel -network 192.168.168.168 -mask 255.255.255.0
/Volumes/490GB -maproot=root:wheel 192.168.168.168


代表存其他 NFS client 存取 /data/SYSTEM/Users 僅限 192.168.168.* 機器位置,而 /Volumes/490GB 僅限 192.168.168.168 這台機器。存檔後,nfsd 也會自動啟動了,可以用以下指令強制啟動、更新等:


$ sudo nfsd disable
$ sudo nfsd enable
$ sudo nfsd udpate
(更新 /etc/exports 後,可以用 $ sudo nfsd update 來更新)


$ showmount -e
Exports list on localhost:
/Volumes/490GB 192.168.168.168
/Volumes/750GB/SYSTEM/Users 192.168.168.168


如果看不到清單,有可能是 /etc/exports 有寫錯,或是 export 的目錄權限有誤,例如 $ sudo chown root:admin /Volumes/750GB/SYSTEM,不然無法正常顯示


在 Linux client 中啟用:


$ sudo apt-get install nfs-common
$ showmount -e NFS_Server_IP
Export list for NFS_Server_IP:
/Volumes/750GB/SYSTEM/Users NFS_Server_IP
$ sudo mkdir -p /mnt/NFSHome


手動掛載:


$ sudo mount -t nfs NFS_Server_IP:/Volumes/750GB/SYSTEM/Users /mnt/NFSHome


自動掛載:


$ sudo vim /etc/fstab
NFS_Server_IP:/Volumes/750GB/SYSTEM/Users /mnt/NFSHome nfs defaults 0 0


處理 uids/gids 不對應問題:


處理這類問題的最佳解是用 NIS 服務,有空在來嘗試 map_static 用法。


2013年4月13日 星期六

[Linux] Nginx、ARM 與 CMake @ Ubuntu 12.04

   +   


Nginx 是這幾年開始火紅的 Web server,而 ARM Device 則有過之而無不及!這兩個合在一起,就可以創作出許多 web app on ARM device 的熱情。最近抽空用 CMake 整了一下安裝流程,當然是偽 CMake 用法 XD 把 CMake 當做 script 的用法 :P 整合過程中,就依樣畫葫順便做了 libssl-cmakelibz-cmake,測試環境:



  • 在 Ubuntu 12.04 64Bit 環境,編譯給自身用的服務

  • 在 Ubuntu 12.04 64Bit 環境,透過 cross complier 編譯給 ARM Device (ARM6)

  • 在 Mac OSX 12.08 Server 版,編譯給自身用的服務


如此一來,終於可以接近 "一鍵" 完成 cross compile 給 ARM Device 跑的服務啦 :P


需提一下,由於在 nginx configure 的過程中,會去測試裝置所用的 int size、syserr_no 等資訊,作法就是編譯片段程式,丟到裝置上跑完來得知結果,故在 cross compile 的流程中,導入 ssh/scp 的機制,將編譯好的程式丟到裝置上執行,所以裝置必須支援 ssh/scp 以及 key-pair 的登入方式(可參考 dropbeardropbear-cmake )。


如此一來方可完成 cmake .. && make 等輕鬆愉快的體驗 XD 在此感謝同事 YangAcer 以及 Ali's blog: Cross-compile nginx 1.3.6 的分享 :D 


一般使用:


$ git clone --recursive https://github.com/changyy/nginx-cmake.git
$ cd nginx-cmake
$ mkdir build
$ cd build
$ cmake ..
$ make
$ ./nginx-out/sbin/nginx -p ./nginx-out/


裝置編譯(此例裝置 IP 為 192.168.168.168,並且可用 root@192.168.168.168 遠端登入及 scp 檔案):


$ git clone --recursive https://github.com/changyy/nginx-cmake.git
$ cd nginx-cmake
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/toolchain-arm6.cmake
...
CMake Error at CMakeLists.txt:14 (message):
Please use -DREMOTE_DEVICE_SSH_LOGIN='account@remote_device_ip' again (need
sshd & scp service)
...
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/toolchain-arm6.cmake -DREMOTE_DEVICE_SSH_LOGIN='root@192.168.168.168'
$ make
$ scp -r ./nginx-out root@192.168.168.168:/tmp
$ ssh root@192.168.168.168 "/tmp/nginx-out/sbin/nginx -p /tmp/nginx-out/"

註:跑 nginx 還須處理 shared library,可以用 objdump 或 readelf -a sbin/nginx | grep Shared 確認


2013年4月8日 星期一

[Windows] 使用 VNC 遠端登入 Mac OS X Server 10.8 @ Windows 7

螢幕共享


剛收到一台 Mac mini server 版,原先很擔心無法多人登入,試了一下還滿 ok 的 :) 簡單的說,只需打開 VNC 設定即可搞定!若沒開 VNC 反而會一直說使用的加密連線不合。


vnc_osx


最後,透過 VNC client 登入時,無論你的 mac account 是否已登入,一律都會顯示這個登入畫面,我覺得這點挺讚的!一律要再登入一次,才能看到 remote desktop。


補充:



  • 第一位登入者,此時 osx console 端則是該會使用者的畫面,無論該此用者 remote 切掉或如何,在 console 端一樣會顯示目前已登入的畫面,故最後我選擇建一個帳號,用來第一次使用後來鎖住營目,如此一來可以避免 console 端的資安問題

  • 拖拉事件無法使用,也就是說,假設你在開發 iOS app 時,如 Storyboard 操作上會常常需要按著 ctrl 後,拖拉到其他 view controller 的行為,會因為拖拉事件無法遠端傳進去而無法使用


2013年4月6日 星期六

房貸試算

principal+ interest


每次跟別人聊天時,都會需要列一張表來勸退這個話題 XD 所以,就乾脆寫一下 script 粗算一下吧 :P





















總貸款額度
(萬)
償還年限
(年)
年利率
(%)
每年償還本金
(萬)
每年償還利息
(萬)
每月還款總額
(元)

註:灰色是可輸入的,輸入完按 tab 或把滑鼠點擊其他空白處則會重新計算





2013年4月4日 星期四

Dropbear SSH - dropbear 與 cmake @ Ubuntu 12.04 64Bit

Dropbear SSH 是一套很常見的嵌入式 SSHD、SSH、SCP 替代方案


然而,最近使用 dropbear 時卻被一開始的編譯變數給影響到:


#define _PATH_SSH_PROGRAM "/usr/bin/dbclient"


所以就把它弄成可以在 compiler time 去定義一下,不然這個資訊會影響到 scp 的操作行為,最後就手動建個偽 cmake 用法 :P


$ git clone https://github.com/changyy/dropbear-cmake.git
$ cd dropbear-cmake
$ mkdir build
$ cd build
$ cmake .. -D_PATH_SSH_PROGRAM=/tmp/your/dbclient
$ make
$ ./bin/scp
Use ssh_program: /tmp/your/dbclient
usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
...


徬徨時程

2013/03/31 walking


當了 leader 後,常常「時程」二字在耳邊懸繞,難得長假又回到老家,反而想起家人的幸福時程,安排了沒?總是被這偷閒的甜蜜給徬徨到...


接著就像上班族一樣,下了班不是想要買醉就是購物 XD 倒也想起了國中看過的字句:「人就是因為不完美,才會不斷地招攬完美的事物。」我想,我回家的頻率太少,導致一直想買點東西犒賞家人,只是,理性又告訴我,家人不會因為這些東西而感到幸福,這只是另一種贖罪心態吧 :P


這一年來心境轉變很大,一來是角色的轉換太快,二則是面對的事件增加太快,讓我損失了不少衝勁,不再像學生時代,熬夜衝一下就能解決啥似的,看來,我還真的是嫩的可以。


2013年4月3日 星期三

wpa_cli 筆記

玩嵌入式時,有時就是需要手動從 command 去指定 wifi ap,試了一會終於找到就順手記一下吧


在此用的 wifi ap 是走 WPA2 TKIP 加密的,其他加密或不加密的方式可以參考這篇討論串 'SET_NETWORK 0 psk "1234567890"' command timed out


# wpa_cli scan
# wpa_cli scan_result
Selected interface 'wlan0'
bssid / frequency / signal level / rate / protocol caps / flags / ssid
xx:xx:xx:xx:xx:xx 2412 -45 54M 802.11b/g BW20 [WPA2-PSK-TKIP][ESS] MyWifiAP


# wpa_cli -i wlan0 remove_network 0
# wpa_cli -i wlan0 add_network
0
# wpa_cli -i wlan0 set_network 0 ssid '"MyWifiAP"'
# wpa_cli -i wlan0 set_network 0 key_mgmt WPA-PSK
# wpa_cli -i wlan0 set_network 0 psk '"Password"'
# wpa_cli -i wlan0 set_network 0 pairwise TKIP
# wpa_cli -i wlan0 set_network 0 group TKIP
# wpa_cli -i wlan0 set_network 0 proto RSN
# wpa_cli -i wlan0 enable_network 0
# wpa_cli -i wlan0 select_network 0
# wpa_cli -i wlan0 status


如果碰到 IP address 未更新,那就再直接叫 dhcp client (如udhcpc等) 去更新 ip 即可