2010年10月16日 星期六

How to Use ADB over TCP/IP?

對於 Android 的開發,Android Debug Bridge (ADB) 是一個相當實用的工具。再且多數的 ARM 開發板都具有乙太網路介面,若透過 TCP/IP 來使用 ADB 其實是相當容易的。

首先,假設將電腦和 ARM 開發板直接用網路線連接起來,將電腦的 IP 位址設定為 192.168.1.200,而 ARM 開發板則設為 192.168.1.202。

那麼,在 ARM 開發板這端需要指定 service.adb.tcp.port 這個變數,並重啟 adbd (ADB Daemon)。

stop adbd
setprop service.adb.tcp.port 5555
start adbd

在電腦端,確認 Android SDK 裡的 adb 版本至少為 1.0.25 或更新版本後,開啟一個 DOS 終端,然後利用 adb connect [IP]:[PORT] 連接 ADB Daemon。

adb kill-server
adb connect 192.168.1.202:5555

這樣就 OK 了。

所以,如果在移植 Android 時,加上這個 patch,在使用就稍微方便些了。

diff -Naur old/system/core/rootdir/etc/init.goldfish.sh new/system/core/rootdir/etc/init.goldfish.sh
--- old/system/core/rootdir/etc/init.goldfish.sh 2010-09-09 02:24:32.318070299 +0000
+++ new/system/core/rootdir/etc/init.goldfish.sh 2010-09-09 02:26:18.598160293 +0000
@@ -1,7 +1,10 @@
#!/system/bin/sh

-#ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up
-#route add default gw 10.0.2.2 dev eth0
+ifconfig eth0 192.168.1.202 netmask 255.255.255.0 up
+route add default gw 192.168.1.1 dev eth0

diff -Naur old/system/core/rootdir/init.rc new/system/core/rootdir/init.rc
--- old/system/core/rootdir/init.rc 2010-09-09 02:22:45.189174370 +0000
+++ new/system/core/rootdir/init.rc 2010-09-09 02:23:15.899741002 +0000
@@ -270,9 +270,11 @@

# adbd on at boot in emulator
on property:ro.kernel.qemu=1
+ setprop service.adb.tcp.port 5555
start adbd

on property:persist.service.adb.enable=1
+ setprop service.adb.tcp.port 5555
start adbd

on property:persist.service.adb.enable=0

此外,若再從 system/core/adb/adb.c 這個檔案第 921 行處的程式碼來看,大約就更可以瞭解為什麼設定 service.adb.tcp.port 之後就可以由 TCP/IP 使用 ADB 了。

    /* for the device, start the usb transport if the
** android usb device exists and the "service.adb.tcp.port" and
** "persist.adb.tcp.port" properties are not set.
** Otherwise start the network transport.
*/
property_get("service.adb.tcp.port", value, "");
if (!value[0])
property_get("persist.adb.tcp.port", value, "");
if (sscanf(value, "%d", &port) == 1 && port > 0) {
// listen on TCP port specified by service.adb.tcp.port property
local_init(port);
} else if (access("/dev/android_adb", F_OK) == 0) {
// listen on USB
usb_init();
} else {
// listen on default port
local_init(ADB_LOCAL_TRANSPORT_PORT);
}

延伸閱讀:

2010年9月14日 星期二

如何將 busybox 加到 Android 的 system.img 裡

根據上一篇文章的作法,如果要將預先編譯好的 busybox 加到 Android 裡,其實方法也同樣簡單。

首先下載 Busybox 的源碼,並以「靜態連結」的方式編譯,並將 busybox 這個可執行檔取出來。

然後在下載回來的 AOSP 源碼裡建立一個適當的目錄:

mkdir -p prebuilt/android-arm/busybox

接著將剛才編譯出來的 busybox 可執行檔複製到 prebuilt/android-arm/busybox 這個路徑下。

接著再於 prebuilt/android-arm/busybox 這個路徑下編寫一個 Android.mk 文件,內容為:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

# Explicitly mark busybox as "eng" so that it doesn't
# get included in user or SDK builds. (GPL issues)
#
LOCAL_SRC_FILES := busybox
LOCAL_MODULE := busybox
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := debug
include $(BUILD_PREBUILT)

# Any prebuilt files with default TAGS can use the below:
prebuilt_files :=

$(call add-prebuilt-files, EXECUTABLES, $(prebuilt_files))

最後,執行 make 得到的 system.img 就會包含 busybox 了。

如何將 bash 加到 Android 的 system.img 裡

也許我還是較習慣 bash 吧!所以也就嘗試將預先編譯好的 bash 加到 Android 裡。

其實方法並不難。

首先,參考之前這篇文章以靜態連結的方式編譯出 bash 的可執行檔。

然後在下載回來的 AOSP 源碼裡建立一個適當的目錄:

mkdir -p prebuilt/android-arm/bash

接著將剛才編譯出來的 bash 可執行檔複製到 prebuilt/android-arm/bash 這個路徑下。

接著再於 prebuilt/android-arm/bash 這個路徑下編寫一個 Android.mk 文件,內容為:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

# Explicitly mark bash as "eng" so that it doesn't
# get included in user or SDK builds. (GPL issues)
#
LOCAL_SRC_FILES := bash
LOCAL_MODULE := bash
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := debug
include $(BUILD_PREBUILT)

# Any prebuilt files with default TAGS can use the below:
prebuilt_files :=

$(call add-prebuilt-files, EXECUTABLES, $(prebuilt_files))

最後,執行 make 得到的 system.img 就會包含 bash 了。

2010年8月16日 星期一

移植 bash 到 ARM 開發板

http://www.gnu.org/software/bash/ 下載 bash-4.1.tar.gz。

解開下載的 bash-4.1.tar.gz,然後選擇一個適當的 cross compiler,並執行 configure。

CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-linux \
--target=arm-none-linux-gnueabi --enable-static-link \
--enable-history --without-bash-malloc

原則上執行完 configure 就可以執行 make 編譯了。若想得到靜態編譯的 bash 可執行檔,則再對 Makefile 稍作修改即可。

diff -Naur old/Makefile new/Makefile 
--- old/Makefile 2010-08-15 15:34:58.489728811 +0000
+++ new/Makefile 2010-08-15 15:35:34.877136059 +0000
@@ -120,7 +120,7 @@
# with gprof, or nothing (the default).
PROFILE_FLAGS=

-CFLAGS = -g -O2
+CFLAGS = -g -O2 -static
CFLAGS_FOR_BUILD = -g -DCROSS_COMPILING
CPPFLAGS =
CPPFLAGS_FOR_BUILD =

2010年8月15日 星期日

在 Debian / Ubuntu 使用 gitosis 架設 GIT server

首先自套件庫安裝 python-setuptools。

sudo aptitude install python-setuptools

然後自 eagain.net 下載 gitosis 的程式碼。

git clone git://eagain.net/gitosis.git

接著將下載回來的 gitosis 搬移到 /opt 目錄,再到該目錄執行安裝動作。

sudo mv gitosis/ /opt/
cd /opt/gitosis/
sudo python setup.py install

安裝完畢後。接著建立一個使用者 git 以存取 repository。

sudo adduser --system --shell /bin/sh \
--gecos 'git version control' --group \
--disabled-password --home /home/git git

接著以平時使用的帳號產生一組 SSH 的 key。

ssh-keygen -t rsa

再使用這個 SSH key 初始化 Git Server。

sudo -H -u git gitosis-init < /tmp/id_rsa.pub
sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update

接著透過 git 下載 gitosis-admin.git。

git clone git@YOUR_SERVER_HOSTNAME:gitosis-admin.git

進入下載回來的 gitosis-admin 目錄後,會有一個 gitosis.conf 檔案和一個 keydir 目錄,其中要新增存取 git server 的使用者時,將 SSH key 添加到 keydir 目錄;而 gitosis.conf 則可以用來建立專案。

例如修改 gitosis.conf,添加一個叫 hello 的專案。

--- old/gitosis.conf   2010-08-12 23:08:13.684510792 +0800
+++ new/gitosis.conf 2010-08-12 23:10:55.504778775 +0800
@@ -4,3 +4,7 @@
writable = gitosis-admin
members = online@local

+[group]
+writable = hello
+members = online@local

接著將它送回 git repository,

git commit -a -m "Added a new project \"hello\""
git push

然後就可以開始建立 hello 這個專案了。

mkdir hello
cd hello/
git init
touch README
git add .
git commit -a -m 'Initial import'
git remote add origin git@YOUR_SERVER_HOSTNAME:hello.git
git push origin master

2010年6月22日 星期二

自製 MP-300 供電器

前陣子入手了一個 MP-300,至於開箱文嘛……其實網路上文章很多,就省下來吧!

寫這篇文章的重點是……MP-300 的電池用的是 CR2,這是屬於相機專用電池,而且不怎麼便宜。最傷腦筋的是,它竟然還一次得餵兩顆電池耶!

幸好 MP-300 還提供了 DC 電源的供電方式,不過……我總不能去弄個 DC Adapter 吧!畢竟 MP-300 就是可以方便地帶著跑了,那搞個 DC Adapter 怎麼帶著跑呀?

所以……一個簡易的自製電源就這麼產生了。首先到材料行買一個 DC 插頭,由於不確定它的尺寸,所以就帶著 MP-300 到材料行試試。

嘿!看到這篇文章的網友就不用這麼麻煩了,請直接拿 1.7mm 的 DC 插頭吧!

然後準備 3 號電池盒,這麼一來可以和閃燈共用充電電池,多棒呀!由於兩顆 CR2 電池一共是 6V 的電壓,雖然 DC Adapter 輸入是 5V 就可以使用,但那可是「穩定」的 5V 耶!由於我現在打算使用充電式電池,每顆是 1.2V,所以建議弄一組可裝 5 顆的電池盒。

注意一下,由於 DC 插頭的內圈必須是正極 (VCC),而外圈是負極 (GND),所以如果網友也買到像我使用這種沒有標示的 DC 插頭時,焊線前先用電表確認一下吧!

做好的成品就像下面這張相片。哈!不過,接下來就花點心思將它美化一下吧!不然這樣也不好攜帶呢!

2010年3月31日 星期三

移植 rz / sz 公用程式到 BeagleBoard

使用 rz / sz 這兩支公用程式可以藉由 zmodem 協議將檔案在 PC 和 BeagleBoard 之間傳遞。雖然速率並不快,但對於一些小檔案偶爾還是很方便的。

移植時,我還是選擇 CodeSourcery Sourcery G++ Lite Edition 2009q3 這個 cross compiler。

首先下載 rzsz-3.48.tar.gz 這個源碼包。

wget -c http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz 

解開之後,修改它的 Makefile,先將 compiler 指定如下:

CC = arm-none-linux-gnueabi-

接著修改 sz.c 及 rz.c,均加入以下這行:

#define REGISTERED

或是將修改 Makefile 如下:

OFLAG = -O -DREGISTERED

最後,編譯完成取用 rz 及 sz 兩支公用程式即可。

make posix

2010年3月7日 星期日

2010 Android Developer Lab, Taipei

其實這篇文章應該在 3 月 3 日當天晚上就想張貼了,不過最後還是在稍微平靜下來後再來張貼文章。我幾乎是在一得知 Google 要在台北舉辦 Android Developer Lab 就填了報名表,運氣很好,在過年前收到了邀請函,挺令人開心的一個年前小禮。

3 月 3 日當天我也是一早就從台中搭高鐵北上了,因為距離議程開始的 12 點 30 分還早,所以我也就背著相機搭捷運隨意逛逛、拍幾張相片。

12 點左右,在悠閒地吃完午餐,就前往六福皇宮會場了。

這是 Android Developer Lab 的入場卷,而且憑卷兌換禮物乙份!

(ps. Alpha 是我在公司裡使用的英文名字,主要是因為同事之間敲 Skype 時方便,所以我乾脆弄個簡單、好記的名字~~~哈!)

當天的議程前半段介紹了 GTUG Taipei、Android 手機與 Android Market 的現狀。後半段則是偏重開發經驗分享,CodeLab 練習的題目是動態桌面的製作,講師也提供了習作的範例,可以在 http://sites.google.com/site/androidcodelabs/assignments/live-wallpaper 下載。

當天最 High 的是領到 Google 贈送的 Nexus One,太開心了!

延伸閱讀:

2010年1月24日 星期日

如何建立 patch

假設要製作 Linux kernel 原始碼中 arch/arm/boot/Makefile 的 patch。首先準備好修改前後的檔案,例如 Makefile 及 Makefile.orig。然後使用 diff 指令產生兩個檔案的差異,指令如下:

LC_ALL=C TZ=UTC0 diff -up Makefile.orig Makefile > arch_arm_boot_makefile.patch

這時會得到以下的內容:

--- Makefile.orig 2010-01-14 01:26:36.000000000 +0000
+++ Makefile 2010-01-24 11:16:04.848551840 +0000
@@ -17,6 +17,16 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif

+SEC_OUTDIR := $(shell if [ -f /etc/inetd.conf ]; then \
+ cat /etc/inetd.conf | grep in.tftpd | awk '{print $$8}'; \
+ elif [ -f /etc/xinetd.d/tftp ]; then \
+ cat /etc/xinetd.d/tftp | grep server_args | \
+ sed 's/^.*-s //g'; \
+ elif [ -f /etc/default/tftpd-hpa ]; then \
+ cat /etc/default/tftpd-hpa | grep OPTIONS | \
+ sed 's/^.*-s //g' | sed 's/\".*$//g'; \
+ fi)
+
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -56,8 +66,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
- cp -f arch/arm/boot/zImage /tftpboot/
- @echo ' Kernel: $@ is ready'
+ $(shell if [ -d $(SEC_OUTDIR) ]; then \
+ cp -f arch/arm/boot/zImage $(SEC_OUTDIR); fi)
+ @echo ' Kernel: $@ is also ready at $(SEC_OUTDIR)'

endif

但由於避免使用 *.orig 這類的名稱,且可以在最前面加上產生 patch 的指令,因此修改成如下:

diff -up old/arch/arm/boot/Makefile new/arch/arm/boot/Makefile
--- old/arch/arm/boot/Makefile 2010-01-14 01:26:36.000000000 +0000
+++ new/arch/arm/boot/Makefile 2010-01-24 11:16:04.848551840 +0000
@@ -17,6 +17,16 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif

+SEC_OUTDIR := $(shell if [ -f /etc/inetd.conf ]; then \
+ cat /etc/inetd.conf | grep in.tftpd | awk '{print $$8}'; \
+ elif [ -f /etc/xinetd.d/tftp ]; then \
+ cat /etc/xinetd.d/tftp | grep server_args | \
+ sed 's/^.*-s //g'; \
+ elif [ -f /etc/default/tftpd-hpa ]; then \
+ cat /etc/default/tftpd-hpa | grep OPTIONS | \
+ sed 's/^.*-s //g' | sed 's/\".*$//g'; \
+ fi)
+
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -56,8 +66,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
- cp -f arch/arm/boot/zImage /tftpboot/
- @echo ' Kernel: $@ is ready'
+ $(shell if [ -d $(SEC_OUTDIR) ]; then \
+ cp -f arch/arm/boot/zImage $(SEC_OUTDIR); fi)
+ @echo ' Kernel: $@ is also ready at $(SEC_OUTDIR)'

endif

那麼怎麼使用這個 patch 呢?指令很簡單,如下:

patch -d $PWD/s3c6410-linux-2.6.27 -p1 < arch_arm_boot_makefile.patch

就可以用這個 patch 去修改 $PWD/s3c6410-linux-2.6.27/arch/arm/boot/Makefile 了。

延伸閱讀:

2010年1月22日 星期五

網路評論員?五毛黨?

最近看到「五毛黨」這個名詞,一時還想不出來是什麼,於是上網查了查,原來所謂「五毛黨」,指得就是網路評論員,是由政府部門聘雇在網路上發表評論的一群人。任務是主動導帖、積極跟帖、適時轉帖,特別是在發生突發事變的關鍵時刻,他們更肩負著引導網上輿論的重責大任。

在中時電子報對「五毛黨」的報導中提到:

根據網傳的「五毛黨」工作方法,他們日常工作是按照網站區分小組,並主要入侵熱門網站,對於某些人氣不錯的論壇,網友信用度比較高,這時「首先要做的是製造一種混亂,通過似是而非的文章進行干涉,跟帖做非理性的故意曲解、製造誤會和爭辯,轉移網民的注意力。」

在維基百科也可以找到以下這段說明:

在中國大陸,「網路評論員」最早出現南京大學官方BBS——南京大學BBS上。在小百合BBS拒絕按照官方命令進行整改,宣布關站之後,南京大學校方在原有域名上開設官方版本的南京大學BBS,指令學生會幹部及一部分熱心上進人士為「網評員」,「納入學校勤工助學體系,根據每月的考評結果發給適當的勤工助學補助」。這些網評員的主要職責是,「南京大學電子論壇通過發帖發布正面信息,跟帖回應抵制消除負面信息,營造積極健康的校園網路環境,同時對校內外網站上有關學校的重要信息及時上報學校網路管理工作領導小組辦公室」。隨後各個學校紛紛招聘網路評論員。

哈!原來如此,講白了不過就是中共當局用來控制、導引人民思想的一個棋子嘛!

延伸閱讀: