2012年7月31日 星期二

試玩 X86 版本的 Android 4.0.4 (Ice Cream Sandwich branch)

根據 "ReleaseNote 4.0-RC2" 這篇文章,下載 Ice Cream Sandwich 的程式碼:

$ repo init -u http://git.android-x86.org/manifest -b ics-x86
$ repo sync 

編譯:

$ lunch eeepc-eng
$ make iso_img 

接著請耐心等待它編譯完成。

編譯完成後,可以得到 out/target/product/eeepc/eeepc.iso 這個檔案。接著,可以利用 VMware Player 或 Virtualbox 建立一個虛擬機器,並執行這個 ISO 檔。

順利載入 Android 的第一個畫面:

接下來,要先設定它的網路,能上網才方便繼續玩耍下去呀!先找到 Terminal 程式,然後執行 su 這個指令,它會取得 root 權限:

接著就可以設定網路裝置了。我在 VMware Player 裡設定網路使用 NAT 模式,所以可以讓 eth0 藉由 DHCP 取得 IP,不過 DNS 仍然要手動鍵入,因此執行以下的指令:

# netcfg eth0 dhcp
# setprop net.dns1 8.8.8.8 

打開瀏覽器看看,可以上網囉!

2012年7月17日 星期二

sfdisk: The Scriptable fdisk

在玩 Beagleboard 時接觸到 sfdisk 這個指令,一開始還沒怎麼弄明白,不過爬了些文章後,試了試發現 sfdisk 這指令真的很有意思。只要將想建立的 partition 資訊「餵」給它,就會將磁碟建立出對應的 partition。所以,可以在腳本裡利用 echo 和 sfdisk 配合,來建立需要的 partition。

在反覆試了幾次,我試著改了一個 mkmmc.sh 的腳本出來:

#!/bin/bash

echo "[Unmounting all existing partitions on the device ]"
umount $1*

echo "[Partitioning $1...]"

DRIVE=$1
SIZE=`fdisk -l $DRIVE | grep Disk | awk '{print $5}'`
  
echo DISK SIZE - $SIZE bytes
 
CYLINDERS=`echo $SIZE/255/63/512 | bc`
 
echo CYLINDERS - $CYLINDERS
{
 echo ,17,0x0C,*
 echo ,130,,-
 echo ,130,,-
 echo ,,0x0C,-
} | sfdisk -D -H 255 -S 63 -C $CYLINDERS $DRIVE &> /dev/null

echo "[Making filesystems...]"

mkfs.vfat -F 32 -n boot "$1"1 &> /dev/null
mkfs.ext3 -L rootfs "$1"2 &> /dev/null
mkfs.ext3 -L extend "$1"3 &> /dev/null
mkfs.vfat -F 32 -n data "$1"4 &> /dev/null 

經過這個腳本,可以建立出如下的 partition:

Disk /dev/sdb: 3965 MB, 3965190144 bytes
255 heads, 63 sectors/track, 482 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1          17      136521    c  W95 FAT32 (LBA)
/dev/sdb2              18         147     1044225   83  Linux
/dev/sdb3             148         277     1044225   83  Linux
/dev/sdb4             278         482     1646662+   c  W95 FAT32 (LBA)

延伸閱讀:

  1. sfdisk: The Scriptable fdisk

2012年5月12日 星期六

在少於 2GB 記憶體的虛擬機裡編譯 Android 4.0 (ICS)

先前偶爾會在虛擬機器裡編譯 Android,這兩天也試在稍早安裝的 Debian (32bit) 上嘗試編譯 Android 4.0 (ICS),首先遇上的問題是記憶體的部份。首先我將虛擬機器裡的記憶體設定成 1GB,所以編譯時遇上了這個問題:

target Dex: core
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
make: *** [out/target/common/obj/JAVA_LIBRARIES/core_intermediates/noproguard.classes-with-local.dex] Error 1 

這個容易處理,修改 core/definitions.mk 這個檔案是可以解決的,修改方式如下:

diff --git a/core/definitions.mk b/core/definitions.mk
index b678158..b83b299 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1525,7 +1525,7 @@ define transform-classes.jar-to-dex
 @echo "target Dex: $(PRIVATE_MODULE)"
 @mkdir -p $(dir $@)
 $(hide) $(DX) \
-    $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx2048M) \
+    $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx1024M) \
     --dex --output=$@ \
     $(incremental_dex) \
     $(if $(NO_OPTIMIZE_DX), \ 

但,最後卻在編譯 qemu 時又出現錯誤,爬了文之後,在 "Build android ICS on ubuntu 32 bits" 這串討論文章裡看到以下這麼一段:

Indeed, with the emulator moving to 64-bit, building on 32-bit hosts is not an option any more (not even unsupported).

噗~~~既然我主要的環境都是 64 位元,而且在 32 位元的 Debian GNU/Linux 上也只是順手試試,那麼就先暫時到這裡吧! XD

2012年5月8日 星期二

讓 Ubuntu 12.04 的 ibus 倉頡五代輸入法預設使用繁體語系

日前安裝了 Ubuntu 12.04 後,在使用 ibus 裡的「倉頡五代輸入法」打字時發現似乎預設採用了簡體語系。於是爬文找了一下,原來這狀況在之前的版本裡已經存在了,便參考了這篇文章修改一下。

修改方法不難,使用任何一個編輯器開啟 /usr/share/ibus-table/engine/table.py 這個檔案,然後找到第 96 行到第 129 行這段:

  96         # self._chinese_mode: the candidate filter mode,
  97      #   0 is simplify Chinese
  98      #   1 is traditional Chinese
  99      #   2 is Big charset mode, but simplify Chinese first
 100      #   3 is Big charset mode, but traditional Chinese first
 101      #   4 is Big charset mode.
 102      # we use LC_CTYPE or LANG to determine which one to use
 103      self._chinese_mode = self._config.get_value (
 104              self._config_section,
 105              "ChineseMode",
 106              self.get_chinese_mode())
 107
 108  def get_chinese_mode (self):
 109      '''Use LC_CTYPE in your box to determine the _chinese_mode'''
 110      try:
 111          if os.environ.has_key('LC_CTYPE'):
 112              __lc = os.environ['LC_CTYPE'].split('.')[0].lower()
 113          else:
 114              __lc = os.environ['LANG'].split('.')[0].lower()
 115
 116          if __lc.find('_cn') != -1:
 117              return 0
 118          # hk and tw is should use tc as default
 119          elif __lc.find('_hk') != -1 or __lc.find('_tw') != -1\
 120                  or __lc.find('_mo') != -1:
 121              return 1
 122          else:
 123              if self.db._is_chinese:
 124                  # if IME declare as Chinese IME
 125                  return 1
 126              else:
 127                  return -1
 128      except:
 129          return -1 

get_chinese_mode 裡會依 locale 的 LC_CTYPE 來判斷,但由於我將 LC_CTYPE 設定成 en_US.UTF-8,原本在第 125 行就會返回 0 這個值,但依據第 96 行到第 101 行的註解,當返回 0 時則採用簡體中文語系。

所以,修改方式就是將第 125 行的返回值改成 1,這麼一來就可以直接使它使用繁體中文語系了。

2012年4月18日 星期三

Configuring USB Access under GNU/Linux

根據 http://source.android.com/source/initializing.html 這個網頁的說明,在 GNU/Linux 下只要設定好 /etc/udev/rules.d/51-android.rules 這個檔案,就可使用 ADB 工具連接 Android 手機了。同時,在網頁上也提供了一個範例:

# 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>" 

於是,我便拿自己的 Nexus One 來試了一下。

因為我將 Nexus One 接在筆電上,並啟用讓筆電透過 3G 上網,因此執行 lsusb 查看 Vendor ID 及 Product ID 時顯示如下:

Bus 001 Device 008: ID 18d1:4e14 Google Inc.  

所以,我將 cat /etc/udev/rules.d/51-android.rules 這個檔案改成如下:

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

存檔後,我將手機重新連接到筆電上,並重新載入 GNU/Linux 的 udev,也真的可以透過 ADB 工具連接到手機耶!

sudo service udev restart
sudo killall adb
adb devices 

以下是執行 adb devcies 後的訊息:

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached 
HT02Rxxxxxxx device 

延伸閱讀:

2012年4月8日 星期日

Build Android Gingerbread with GCC 4.6

這兩天將 Debian 升級到 testing 版本後,沒想到編譯 Android 2.3 (Gingerbread) 時卻遇到了這樣的錯誤訊息:
host C++: libutils <= frameworks/base/libs/utils/RefBase.cpp
frameworks/base/libs/utils/RefBase.cpp: In member function ‘void android::RefBase::weakref_type::trackMe(bool, bool)’:
frameworks/base/libs/utils/RefBase.cpp:483:67: error: passing ‘const android::RefBase::weakref_impl’ as ‘this’ argument of ‘void android::RefBase::weakref_impl::trackMe(bool, bool)’ discards qualifiers [-fpermissive]
host C++: libutils <= frameworks/base/libs/utils/ResourceTypes.cpp
make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libutils_intermediates/RefBase.o] Error 1
make: *** Waiting for unfinished jobs....
frameworks/base/libs/utils/ResourceTypes.cpp: In member function ‘void android::ResTable::print(bool) const’:
frameworks/base/libs/utils/ResourceTypes.cpp:4369:84: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
frameworks/base/libs/utils/ResourceTypes.cpp:4375:43: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
這是由於 GCC 也一併升級為 4.6 版引起的,在用了下面這個 patch 後就搞定了:
diff -Naur old/frameworks/base/libs/utils/Android.mk new/frameworks/base/libs/utils/Android.mk
--- old/frameworks/base/libs/utils/Android.mk 2011-05-05 09:42:48.000000000 +0000
+++ new/frameworks/base/libs/utils/Android.mk 2012-04-07 15:45:40.738996228 +0000
@@ -57,7 +57,7 @@
 
 LOCAL_MODULE:= libutils
 
-LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -fpermissive
 LOCAL_C_INCLUDES += external/zlib
 
 ifeq ($(HOST_OS),windows)
延伸閱讀: