<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-59345686725815191</id><updated>2012-02-14T19:00:03.448+08:00</updated><category term='Python'/><category term='setup'/><category term='MantainLog'/><category term='backup_restore'/><category term='SQL'/><category term='bootloader'/><category term='cellphone'/><category term='software_package'/><category term='MINGW'/><category term='Info'/><category term='Kernel'/><category term='Windows'/><category term='command'/><category term='application'/><category term='Graphic'/><category term='工作的備worklog'/><category term='Configuration'/><category term='Gentoo'/><category term='GCC'/><category term='make'/><category term='翻譯'/><category term='SDL'/><category term='browser'/><category term='memo'/><category term='Virtualization'/><category term='OpenCL'/><category term='hibernation'/><category term='hardware'/><category term='Filesystem'/><category term='VersionControl'/><category term='EFL'/><category term='driver'/><category term='debug'/><category term='tool'/><category term='programming'/><category term='ffmpeg'/><category term='language'/><category term='django'/><category term='ker'/><category term='VLC'/><category term='life'/><category term='iMX51'/><category term='editor'/><category term='bluetooth'/><category term='android'/><category term='Install'/><category term='administration'/><category term='bookmark'/><category term='自言自語'/><category term='ProblemAndSolve'/><category term='archlinux'/><category term='network'/><category term='ToDo'/><category term='MCU_P'/><category term='google'/><category term='OS'/><title type='text'>R40eUbuntu-Sempron26Debian</title><subtitle type='html'>ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default?start-index=101&amp;max-results=100'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>536</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6278949646819077235</id><published>2012-02-14T14:41:00.003+08:00</published><updated>2012-02-14T19:00:03.474+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Install'/><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><title type='text'>D-Link HSPDA Dongle - DWN-156</title><content type='html'>會先出現 cd rom，然後要切 modeswitch，才會出現 serial port。&lt;br&gt;
在 windows 上會出現三個 serial port (其中一個是 USB Modem):
&lt;ol&gt;
&lt;li&gt; D-Link HSPDA DataCard Diagnostics Interface&lt;li&gt;
&lt;li&gt; D-Link HSPDA DataCard NMEA Device&lt;/li&gt;
&lt;li&gt; D-Link HSPDA DataCard Propertiery USB Modem&lt;/li&gt;
&lt;/ol&gt;&lt;br&gt;
這又是一個 有 usb cdrom 模式的 3g dongle。&lt;br&gt;
剛插入系統，會是 cd rom。&lt;br&gt;
要先 switch 到 modem 後，才會出現 usb serial。&lt;br&gt;
&lt;br&gt;
剛插入時，vid , pid 是：
&lt;pre&gt;New USB device found, idVendor=07d1, idProduct=a804&lt;/pre&gt;
mount 再 umount 後，vid, pid 是：
&lt;pre&gt;New USB device found, idVendor=07d1, idProduct=7e11&lt;/pre&gt;
但是這時後也沒有出現 usb serial port。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
大概用兩個步驟：
&lt;ol&gt;
&lt;li&gt; usb-modeswitch, 切換到 modem mode&lt;/li&gt;
&lt;li&gt; 手動 load usb-serial ，指定 vid, pid&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
usb-modeswitch:&lt;br&gt;
&lt;br&gt;
debian 已經有安裝，但是 /etc/usb_modeswitch.d/ 下面沒有 07d1:a804 的設定檔，&lt;br&gt;
所以要寫 /etc/usb_modeswitch.d/ 下的 vid:pid 檔：&lt;br&gt;
&lt;code&gt;sudo vi /etc/usb_modeswitch.d/07d1:a804

######################################################## 
# D-Link DWM-156 HSUPA 3.75G USB Modem 

DefaultVendor= 0x07d1
DefaultProduct=0xa804

TargetVendor=  0x07d1
TargetProduct= 0x7e11

MessageContent="5553424312345678000000000000061b000000020000000000000000000000"

CheckSuccess=20
&lt;/code&gt;
寫好就可以用 usb_modeswitch 來切了..&lt;br&gt;
&lt;br&gt;
先插入 dwn-156, dmesg 內容是：
&lt;code&gt;[25387.281621] usb 2-1.1.4.2: new high speed USB device using ehci_hcd and address 19
[25387.391940] usb 2-1.1.4.2: New USB device found, idVendor=07d1, idProduct=a804
[25387.391946] usb 2-1.1.4.2: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[25387.391950] usb 2-1.1.4.2: Product: D-Link WCDMA Technologies MSM
[25387.391954] usb 2-1.1.4.2: Manufacturer: D-Link,Incorporated
[25387.391957] usb 2-1.1.4.2: SerialNumber: MF112DDLKD010000
[25387.392114] usb 2-1.1.4.2: configuration #1 chosen from 1 choice
[25387.394534] scsi16 : SCSI emulation for USB Mass Storage devices
[25387.394655] usb-storage: device found at 19
[25387.394659] usb-storage: waiting for device to settle before scanning
[25392.392130] usb-storage: device scan complete
[25392.392810] scsi 16:0:0:0: CD-ROM            HSPA     USB SCSI CD-ROM  2.31 PQ: 0 ANSI: 2
[25392.397282] sr1: scsi-1 drive
[25392.397481] sr 16:0:0:0: Attached scsi CD-ROM sr1
[25392.397632] sr 16:0:0:0: Attached scsi generic sg4 type 5
&lt;/code&gt;
用 usb_modeswitch 來切換 mode:
&lt;code&gt;
$ sudo usb_modeswitch -c /etc/usb_modeswitch.d/07d1:a804


Looking for target devices ...
 No devices in target mode or class found
Looking for default devices ...
 Found devices in default mode or class (1)
Accessing device 022 on bus 002 ...
Using endpoints 0x01 (out) and 0x81 (in)
Using endpoints 0x01 (out) and 0x81 (in)
Inquiring device details; driver will be detached ...
Looking for active driver ...
 OK, driver found ("usb-storage")
 OK, driver "usb-storage" detached

SCSI inquiry data (for identification)
-------------------------
  Vendor String: HSPA    
   Model String: USB SCSI CD-ROM 
Revision String: 2.31
-------------------------

USB description data (for identification)
-------------------------
Manufacturer: D-Link,Incorporated
     Product: D-Link WCDMA Technologies MSM
  Serial No.: MF112DDLKD010000
-------------------------
Setting up communication with interface 0 ...
Using endpoint 0x01 for message sending ...
Trying to send message 1 to endpoint 0x01 ...
 OK, message successfully sent
Resetting response endpoint 0x81
Resetting message endpoint 0x01

Checking for mode switch (max. 20 times, once per second) ...
 Waiting for original device to vanish ...
 Waiting for original device to vanish ...
 Original device can't be accessed anymore. Good.
 Searching for target devices ...
 Found correct target device

Mode switch succeeded. Bye.
&lt;/code&gt;&lt;br&gt;
看一下 dmesg:
&lt;code&gt;[38715.226573] usb 2-1.1.4.2: new high speed USB device using ehci_hcd and address 23
[38715.337316] usb 2-1.1.4.2: New USB device found, idVendor=07d1, idProduct=7e11
[38715.337321] usb 2-1.1.4.2: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[38715.337324] usb 2-1.1.4.2: Product: D-Link WCDMA Technologies MSM
[38715.337327] usb 2-1.1.4.2: Manufacturer: D-Link,Incorporated
[38715.337329] usb 2-1.1.4.2: SerialNumber: MF112DDLKD010000
[38715.337460] usb 2-1.1.4.2: configuration #1 chosen from 1 choice
&lt;/code&gt;&lt;br&gt;
已經切換了。&lt;br&gt;
&lt;br&gt;
然後動 load usb-serial module，指定 vid,pid
&lt;code&gt;sudo modprobe usbserial vendor=0x07d1 product=0x7e11
&lt;/code&gt;&lt;br&gt;
dmesg 可以看到 ttyUSB 出現：
&lt;code&gt;[38715.339951] usbserial_generic 2-1.1.4.2:1.0: generic converter detected
[38715.340069] usb 2-1.1.4.2: generic converter now attached to ttyUSB0
[38715.340178] usbserial_generic 2-1.1.4.2:1.1: generic converter detected
[38715.340280] usb 2-1.1.4.2: generic converter now attached to ttyUSB1
[38715.340537] scsi20 : SCSI emulation for USB Mass Storage devices
[38715.340695] usb-storage: device found at 23
[38715.340699] usb-storage: waiting for device to settle before scanning
[38715.340788] usbserial_generic 2-1.1.4.2:1.3: generic converter detected
[38715.340889] usb 2-1.1.4.2: generic converter now attached to ttyUSB2
[38720.337127] usb-storage: device scan complete
&lt;/code&gt;&lt;br&gt;
&lt;hr&gt;
這時候，在 panel 的 network widget 就可以看到 "Chungwha Telecom.."，&lt;br&gt;
打勾 就可以連上了。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
ref: &lt;a href="http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=817&amp;sid=e08d0632f3a91e6379a0367bd258809c"&gt;http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=817&amp;sid=e08d0632f3a91e6379a0367bd258809c&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6278949646819077235?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6278949646819077235/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6278949646819077235' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6278949646819077235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6278949646819077235'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/d-link-hspda-dongle-dwn-156.html' title='D-Link HSPDA Dongle - DWN-156'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1522517244188369846</id><published>2012-02-09T15:46:00.002+08:00</published><updated>2012-02-10T17:50:11.158+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Set System Time.</title><content type='html'>/framework/base/libs/utils/SystemClock.cpp: &lt;br&gt;
&lt;code&gt;#if HAVE_ANDROID_OS
    fd = open(&amp;quot;/dev/alarm&amp;quot;, O_RDWR);
    if(fd &amp;lt; 0) {
        LOGW(&amp;quot;Unable to open alarm driver: %s\n&amp;quot;, strerror(errno));
        return -1;
    }
    ts.tv_sec = tv.tv_sec;
    ts.tv_nsec = tv.tv_usec * 1000;
    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &amp;amp;ts);
    if(res &amp;lt; 0) {
        LOGW(&amp;quot;Unable to set rtc to %ld: %s\n&amp;quot;, tv.tv_sec, strerror(errno));
        ret = -1;
    }
    close(fd);
#else
    if (settimeofday(&amp;amp;tv, NULL) != 0) {
        LOGW(&amp;quot;Unable to set clock to %d.%d: %s\n&amp;quot;,
            (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
        ret = -1;
    }
#endif
&lt;/code&gt;
可以看到 Android 設定系統時間，用 ioctl，不能直接 call settimeofday.&lt;br&gt;
&lt;br&gt;
settimeofday ，系統時間會改，但是 RTC 不會改， 所以 system reboot 後，時間還是沒變更。&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;hr&gt;&lt;br&gt;
手動設會有
&lt;code&gt;D/SystemClock( 2399): Setting time of day to sec=31622433
D/        ( 2269): enter Cmd: L 
D/dalvikvm( 2269): GC_CONCURRENT freed 1061K, 45% free 2224K/3971K, external 3688K/4325K, paused 3ms+3ms
D/AlarmManagerService( 2269): Kernel timezone updated to -540 minutes west of GMT
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1522517244188369846?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1522517244188369846/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1522517244188369846' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1522517244188369846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1522517244188369846'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/frameworkbaselibsutilssystemclock.html' title='Android Set System Time.'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7745149940498754145</id><published>2012-02-09T14:28:00.000+08:00</published><updated>2012-02-10T11:26:36.253+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Time Sync with GPS</title><content type='html'>Time Sync with GPS&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;設定 enable/disable 放在 Settings.system 中&lt;/li&gt;
&lt;li&gt;應該由 Location Service 讀取內容，負責動作。&lt;/li&gt;
&lt;/ol&gt;
Location Service 和 hardware gps 的分層負責就因人而異了。&lt;br&gt;
&lt;br&gt;
可以增加　interface (?)，讓 service 告知  gps driver 收到 gps time nmea data 時，set system time。&lt;br&gt;
也可以 service 自己作，當取得 nmea time data 時，依照 Setting 內容決定。&lt;br&gt;
&lt;br&gt;
要sync system time 的時機：
&lt;ol&gt;
&lt;li&gt;改 Auto Sync 設定時&lt;/li&gt;
&lt;li&gt;GPS lock 時&lt;/li&gt;
&lt;/ol&gt;
所以要寫在兩個地方，互相 check 對方。&lt;br&gt;
&lt;br&gt;
但是要確認 gps driver , check lock 的時間，要比 server 啟動, check system setting 的後面才行。&lt;br&gt;
否則就會不同步。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
直接把 GPS NMEA Channel cat 出來.. (只列出 GPRMC)..並且修改 location data.. (所以 checksum 是錯的)
&lt;code&gt;
$GPRMC,080058.000,A,2502.9061,N,14122.4832,E,0.00,0.00,090212,,,A*6x
$GPRMC,080100.000,A,2502.9061,N,14122.4832,E,0.00,0.00,090212,,,A*6x
$GPRMC,080101.000,A,2502.9061,N,14122.4832,E,0.00,0.00,090212,,,A*6x
$GPRMC,080102.000,A,2502.9061,N,14122.4832,E,0.00,0.00,090212,,,A*6x
&lt;/code&gt;
GPRMC format : (&lt;a href="http://aprs.gids.nl/nmea/#rmc"&gt;http://aprs.gids.nl/nmea/#rmc&lt;/a&gt;)&lt;br&gt;
&lt;pre&gt;eg1. $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68


           225446       Time of fix 22:54:46 UTC
           A            Navigation receiver warning A = OK, V = warning
           4916.45,N    Latitude 49 deg. 16.45 min North
           12311.12,W   Longitude 123 deg. 11.12 min West
           000.5        Speed over ground, Knots
           054.7        Course Made Good, True
           191194       Date of fix  19 November 1994
           020.3,E      Magnetic variation 20.3 deg East
           *68          mandatory checksum
&lt;/pre&gt;
GPS FIX 的資料是在  $GPGGA - Global Positioning System Fix Data  (h&lt;a href="http://aprs.gids.nl/nmea/"&gt;ttp://aprs.gids.nl/nmea/&lt;/a&gt;)&lt;br&gt;
&lt;pre&gt;eg2. $--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx

hhmmss.ss = UTC of position 
llll.ll = latitude of position
a = N or S
yyyyy.yy = Longitude of position
a = E or W 
x = GPS Quality indicator (0=no fix, 1=GPS fix, 2=Dif. GPS fix) 
xx = number of satellites in use 
x.x = horizontal dilution of precision 
x.x = Antenna altitude above mean-sea-level
M = units of antenna altitude, meters 
x.x = Geoidal separation
M = units of geoidal separation, meters 
x.x = Age of Differential GPS data (seconds) 
xxxx = Differential reference station ID 
&lt;/pre&gt; 其中 'GPS Quality indicator' 就是 FIX 的狀態..&lt;br&gt;
實際的資料： (pull-out gps antenna):
&lt;code&gt;
$GPGGA,000935.066,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*4C
$GPGGA,000936.064,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*4D
$GPGGA,000938.066,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*41
$GPGGA,000940.075,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*4C
$GPGGA,000941.065,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*4C
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7745149940498754145?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7745149940498754145/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7745149940498754145' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7745149940498754145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7745149940498754145'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/time-sync-with-gps-enabledisable.html' title='Time Sync with GPS'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7867739171788314135</id><published>2012-02-08T17:00:00.001+08:00</published><updated>2012-02-08T17:11:34.491+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>moveTaskToFront, moveTaskToBack ..</title><content type='html'>要作一個 toggle 功能的 hot-key:  按一下開啟，按一下關閉。&lt;br&gt;
&lt;br&gt;
關閉還不能真的關，只能把他擺到後面..&lt;br&gt;
&lt;br&gt;
所以用 moveTaskToBack, moveTaskToFront 來作。&lt;br&gt;
&lt;br&gt;
Hotkey 的implement 在 PhoneWindow.java &lt;br&gt;
&lt;br&gt;
所以在 onKeyDown( ) 的 case 特殊 Key，作
&lt;code&gt;
public class PhoneWindow extends Window implements MenuBuilder.Callback {
              String packageName = "com.android.calculator2";
              String className   = "com.android.calculator2.Calculator";

              ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
              List&amp;gt;ActivityManager.RunningTaskInfo&amp;gt; taskInfo = am.getRunningTasks(20);
              for(int i=0;i&amp;lt;taskInfo.size();i++) {
                      Log.d("current task:", "CURRENT Activity ::" + taskInfo.get(i).topActivity.getClassName() + ", id: " + taskInfo.get(i).id);
                      Log.d("Package Name:", " "                   + taskInfo.get(i).topActivity.getPackageName());
                        if(taskInfo.get(i).topActivity.getPackageName().equals(packageName) == true){
                              Log.d(TAG,"Found!" + packageName + " in " + i);
                              if(i!=0) {
                                      try {
                                              ActivityManagerNative.getDefault().moveTaskToFront(taskInfo.get(i).id);
                                      }catch (RemoteException e) {
                                              Log.d(TAG,"Failed !! moveTaskToFront");
                                      }
                              }else{
                                      try {
                                              ActivityManagerNative.getDefault().moveTaskToBack(taskInfo.get(i).id);
                                      } catch (RemoteException e) {
                                              Log.d(TAG,"Failed !! moveTaskToBack");
                                      }       
                                      Log.d(TAG,"Calc is on top");
                              }       
                              return true;
                      }
              }
              // calculator not launched.
              Log.d(TAG," " + packageName + " not running");
              Intent intent = new Intent();
              intent.setClassName(packageName,className);
              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
              try {
                      getContext().startActivity(intent);
              }catch( ActivityNotFoundException e){
                      Log.d(TAG,"Activity Not Found");
              }
       }
&lt;/code&gt;
.. 找特定 packagename，如果是 0 (top), move to back.&lt;br&gt;
如果不是 0 (background), move to front&lt;br&gt;
&lt;br&gt;
如果找不掉 -- startActivity 啟動他&lt;br&gt;
&lt;br&gt;
用 eclipse 的 hierarchy viewr 可以看到這個動作。&lt;br&gt;
&lt;br&gt;
但是某 app，本身就具有 "避免重複啟動" , back , home key, keeps running in background 功能。&lt;br&gt;
在 move to front 後，沒有動作。&lt;br&gt;
看 hierarachy view ，好像沒有取得 focus。&lt;br&gt;
&lt;br&gt;
所以只好改成：&lt;br&gt;
if on top ==&amp;gt; move to back&lt;br&gt;
if not top ==&amp;gt; startActivity&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
這要動作。系統要拿掉 GET_TASKS, moveTaskToFront, moveTaskToBack 的 permission check&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7867739171788314135?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7867739171788314135/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7867739171788314135' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7867739171788314135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7867739171788314135'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/movetasktofront-movetasktoback.html' title='moveTaskToFront, moveTaskToBack ..'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5497088871031555542</id><published>2012-02-07T16:27:00.000+08:00</published><updated>2012-02-07T16:27:23.181+08:00</updated><title type='text'></title><content type='html'>ViewRoot 的 getpermission 用到 ActivityManagerNative:
&lt;code&gt;                return ActivityManagerNative.getDefault().checkPermission(
                        permission, Binder.getCallingPid(), Binder.getCallingUid());
&lt;/code&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5497088871031555542?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5497088871031555542/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5497088871031555542' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5497088871031555542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5497088871031555542'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/viewroot-getpermission.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2959119162646003711</id><published>2012-02-07T13:43:00.001+08:00</published><updated>2012-02-07T16:34:29.319+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>getTopActivity &amp; GET_TASKS permission check</title><content type='html'>要知道目前 最前面的 activity 是什麼，可以用:
&lt;code&gt;
import java.util.List;
import android.app.ActivityManager;

                ...
                
                        ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
                        List&amp;lt;ActivityManager.RunningTaskInfo&amp;gt; taskInfo = am.getRunningTasks(1);
                        Log.d("current task:", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
                        Log.d("Package Name:", " "                   + taskInfo.get(0).topActivity.getPackageName());


                
&lt;/code&gt;&lt;br&gt;

但是 getRunningTasks( ) 需要 GET_TASKS 權限
&lt;code&gt;
android.permission.GET_TASKS
&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
getRunningTasks( ) 實際上是 call IActivityManager 的 getTasks():
&lt;code&gt;    public List&amp;lt;RunningTaskInfo&amp;gt; getRunningTasks(int maxNum, int flags, IThumbnailReceiver receiver)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().getTasks(maxNum, flags, receiver);
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
            return null;
        }
    }

&lt;/code&gt;&lt;br&gt;

&lt;hr&gt;
&lt;br&gt;
配合 Hotkey 的動作，如果要作到：&lt;b&gt;依照目前操作的 程式，決定 Hotkey 要 launch 的程式&lt;/b&gt;，就要改 framework 裡，hotkey 的 code。&lt;br&gt;
&lt;br&gt;
因為這段 code 實際上是在每一個 vm 中 run 的，&lt;br&gt;
所以，要是 這個 package 沒有 GET_TASKS 權限， framework 的 getRunningTasks 就會 fail。&lt;br&gt;
&lt;br&gt;
只好.... bypass GET_TASKS 的 permission check!! &lt;br&gt;
&lt;br&gt;
修改 ActivityManagerService.java:
&lt;code&gt;public List getTask(int maxNum ....
   ...

            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
                    != PackageManager.PERMISSION_GRANTED) {
            ..
&lt;/code&gt;把這段 check comment 掉..&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
ref:
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://qtcstation.com/2011/01/getting-info-about-your-currently-running-activities/"&gt;http://qtcstation.com/2011/01/getting-info-about-your-currently-running-activities/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2959119162646003711?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2959119162646003711/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2959119162646003711' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2959119162646003711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2959119162646003711'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/gettopactivity-gettasks-permission.html' title='getTopActivity &amp; GET_TASKS permission check'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-861113332600825311</id><published>2012-02-06T18:30:00.002+08:00</published><updated>2012-02-06T18:39:06.081+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>shortcut - Camera</title><content type='html'>CAMERA 按鍵在 android framework 中，要長按才會啟動，&lt;br&gt;
&lt;br&gt;
順便可以看一下 LongPress 的 detection:
&lt;code&gt;               if (event.getRepeatCount() == 0) {
                    dispatcher.startTracking(event, this);
                } else if (event.isLongPress() &amp;&amp; dispatcher.isTracking(event)) {
                    dispatcher.performedLongPress(event);
                    mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                    sendCloseSystemWindows();
                     Broadcast an intent that the Camera button was longpressed
                    Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
                    intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
                    getContext().sendOrderedBroadcast(intent, null);
                }
&lt;/code&gt;
大概就是... 第一次 down event (repeat()=0) 時，call startTracking( ) 叫 Input manager(?) tracking 這個 key。&lt;br&gt;
這樣 input manager 就會持續嗔測 CAMERA Key， timeout 時 再送一個 down event，並且 event.isLongPress() 會是 1&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
在 ViewRoot.java 有關 CAMERA Key 的一段 code:
&lt;code&gt;    private void dispatchKey(KeyEvent event, boolean sendDone) {
        //noinspection ConstantConditions
        if (false &amp;&amp; event.getAction() == KeyEvent.ACTION_DOWN) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) {
                if (Config.LOGD) Log.d("keydisp",
                        "===================================================");
                if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:");
                debug();

                if (Config.LOGD) Log.d("keydisp",
                        "===================================================");
            }
        }
        ....
&lt;/code&gt;
如果把 false 拿掉，會印出有趣的 debug message,,,
&lt;br&gt;
&lt;code&gt;D/keydisp ( 2642): ===================================================
D/keydisp ( 2642): Focused view Hierarchy is:
D/View    ( 2642):   + com.android.internal.policy.impl.PhoneWindow$DecorView@2ac72cc0
D/View    ( 2642):       frame={0, 0, 800, 480} scroll={0, 0}
D/View    ( 2642):       mMeasureWidth=800 mMeasureHeight=480
D/Debug   ( 2642):       Contents of WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#790303 fmt=-2 wanim=0x1030001}:
D/Debug   ( 2642): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }
D/Debug   ( 2642): WindowManager.LayoutParams={title=com.android.deskclock/com.android.deskclock.DeskClock}
D/View    ( 2642):       flags={}
D/View    ( 2642):       privateFlags={IS_ROOT_NAMESPACE HAS_BOUNDS DRAWN}
D/View    ( 2642):       {
D/View    ( 2642):       + android.widget.FrameLayout@2ac73900 (id=16908290)
D/View    ( 2642):           frame={0, 0, 800, 480} scroll={0, 0}
D/View    ( 2642):           mMeasureWidth=800 mMeasureHeight=480
D/View    ( 2642):           ViewGroup.LayoutParams={ width=match-parent, height=match-parent }
D/View    ( 2642):           flags={}
remain 0 unprocessed.
D/View    ( 2642):           privateFlags={HAS_BOUNDS DRAWN}
D/View    ( 2642):           {
D/View    ( 2642):           + android.widget.FrameLayout@2ac74548
D/View    ( 2642):               frame={0, 0, 800, 480} scroll={0, 0}
D/View    ( 2642):               mMeasureWidth=800 mMeasureHeight=480
D/View    ( 2642):               ViewGroup.LayoutParams={ width=match-parent, height=match-parent }
D/View    ( 2642):               flags={}
D/View    ( 2642):               privateFlags={HAS_BOUNDS DRAWN}
D/View    ( 2642):               {
D/View    ( 2642):               + android.widget.LinearLayout@2ac74bc0 (id=2131492882)
D/View    ( 2642):                   frame={0, 0, 800, 480} scroll={0, 0}
D/View    ( 2642):                   padding={0, 38, 0, 0}
D/View    ( 2642):                   mMeasureWidth=800 mMeasureHeight=480
D/View    ( 2642):                   ViewGroup.LayoutParams={ width=match-parent, height=match-parent }
&lt;/code&gt;可以出來，目前的 Focuse App 是 com.android.deskclock/com.android.deskclock.DeskClock&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-861113332600825311?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/861113332600825311/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=861113332600825311' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/861113332600825311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/861113332600825311'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/shortcut-camera.html' title='shortcut - Camera'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2992783050428802425</id><published>2012-02-03T16:57:00.000+08:00</published><updated>2012-02-03T16:57:17.431+08:00</updated><title type='text'></title><content type='html'>Task :
&lt;pre&gt;A task is a collection of activities that users interact with when performing a certain job. &lt;/pre&gt;
 &lt;a href="http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html"&gt;http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html&lt;/a&gt;
所以task 是一堆 activity 的集合。&lt;br&gt;

Application 是 apk.&lt;br&gt;
application 裡面是一堆 component (Activity, Service, BroadcastReceiver...)。&lt;br&gt;
當這個 application 的 component 被叫起來時， android 就會啟動這個 application。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2992783050428802425?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2992783050428802425/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2992783050428802425' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2992783050428802425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2992783050428802425'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/task-task-is-collection-of-activities.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7945534049325238995</id><published>2012-02-03T11:23:00.000+08:00</published><updated>2012-02-03T15:13:14.661+08:00</updated><title type='text'></title><content type='html'>做出 Launcher 長壓 HOME Key 的動作：&lt;br&gt;
列出 N 個 recent task，按下後開啟該 task。&lt;br&gt;
&lt;br&gt;
或先測試一下這用 "長按 HOME" 來切換 task 的方式，和不合用。&lt;br&gt;
再作決定。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
HomeLongPress 在 PhoneWindowManager.java
&lt;code&gt;    Runnable mHomeLongPress = new Runnable() {
        public void run() {
            mHomePressed = false;
            performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
            showRecentAppsDialog(); 
        }
    };
&lt;/code&gt;&lt;br&gt;
的 showRecentAppsDialog:
&lt;code&gt;
    void showRecentAppsDialog() {
        if (mRecentAppsDialog == null) {
            mRecentAppsDialog = new RecentApplicationsDialog(mContext);
        }
        mRecentAppsDialog.show();
    }       
&lt;/code&gt;
&lt;br&gt;
所以實做就是在 RecentApplicationDialog( )&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7945534049325238995?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7945534049325238995/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7945534049325238995' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7945534049325238995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7945534049325238995'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/launcher-home-key-n-recent-task-task.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5099534404654563845</id><published>2012-02-02T16:01:00.001+08:00</published><updated>2012-02-02T16:25:46.062+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>3g modem, rild &amp; pppd</title><content type='html'>init.rc 啟動 rild 和 pppd:
&lt;code&gt;service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
    socket rild-ppp stream 660 radio system
    user root
    group radio cache inet misc audio

service pppd_gprs /etc/init.gprs-pppd
    user root
    group radio cache inet misc
    disabled
    oneshot
&lt;/code&gt;
rild 的部份是直接 run rild (實際是去 run libreference-ril.so 的 Init)&lt;br /&gt;
&lt;br /&gt;
rild 負責 modem 的初始化，語音撥撥號，接聽，modem 連線狀態維護 (連線中, operator, signal strength.. etc)。&lt;br&gt;
pppd 則負責 ppp protocol，並形成 ppp0 這個　network interface&lt;br&gt;
&lt;br&gt;
pppd 是 run script : /etc/init.gprs-pppd:
&lt;code&gt;PPPD_PID=

/system/bin/setprop "net.gprs.ppp-exit" ""

/system/bin/log -t pppd "Starting pppd"


#/system/xbin/pppd $*
# pppd was put into /system/bin instead of /system/xbin after SDK1.6
if ls /dev/ttyUSB0 &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
    /system/bin/pppd connect 'chat -f "/etc/3gdata.conf"' /dev/ttyUSB3 115200 mru 1280 mtu 1280 nodetach debug dump defaultroute usepeerdns novj novjccomp noipdefault ipcp-accept-local ipcp-accept-remote connect-delay 5000 linkname ppp0
else
    /system/bin/pppd ttyACM0 921600 nodetach noauth noipdefault defaultroute usepeerdns linkname ppp0 connect "chat -v '' AT OK ATD*99***1# CONNECT" debug
fi

PPPD_EXIT=$?
PPPD_PID=$!

/system/bin/log -t pppd "pppd exited with $PPPD_EXIT"

/system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT"
&lt;/code&gt;
.. 這個 file 在 /system/core/rootfs/etc/ &lt;br /&gt;
&lt;br /&gt;
script 是啟動 pppd ，在參數指定連接的動作，使用 chat:
&lt;code&gt; connect 'chat -f "/etc/3gdata.conf" '&lt;/code&gt;
這樣寫是要 chat 使用 3gdata.conf 作 連線參數。&lt;br /&gt;
&lt;code&gt; connect "chat -v ''AT OK ATD*99***1# CONNECT" &lt;/code&gt;
這樣寫是使用簡單是 chat 設定，所以直接寫出來。&lt;br /&gt;
&lt;br /&gt;
chat 是一種 send - reply 對應的程式，會依照config 送 string，並且依照 config 檢查回應的string。&lt;br&gt;
&lt;br&gt;
pppd 的 help 中，connet 的說明是：
&lt;code&gt;connect &amp;lt;p&amp;gt;     Invoke shell command &amp;lt;p&amp;gt; to set up the serial line &lt;/code&gt;
就是另外 run script 'p' 來作建立連線的動作 (撥號)。&lt;br&gt;
&lt;br&gt;
啟動 pppd 還要給的就是 pppd 對應的 3g modem data port number，一般會是　/dev/ttyUSB? &lt;br&gt;
&lt;br&gt;
3g modem 會提供很多 ttyUSB port，每個有不同的功能
&lt;ol&gt; 
&lt;li&gt;AT Command 語音撥號&lt;/li&gt;
&lt;li&gt;ppp 資料&lt;/li&gt;
&lt;li&gt;AT Command 系統狀態&lt;/li&gt;
&lt;/ol&gt;
每一個廠家的port 對應都不一樣，所以要告訴 pppd 對哪一個 port 動作。&lt;br&gt;
&lt;br&gt;
同理，撥號也一樣，如果撥號和 ppp 通訊在同一個，就可以寫在 這裡，叫 pppd 撥號。&lt;br&gt;
如果 撥號 和 ppp 通訊在不同的　port，就不能請 pppd 做了 (也就沒有 connect 這個 參數)&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
 port 是 支援 3g modem 時最麻煩的東西。&lt;br&gt;
不同的 modem 有不同的 port 指定。&lt;br&gt;
不僅 pppd 要知道對哪一個 port 動作， rild 也要知道。&lt;br&gt;
&lt;br&gt;
舊版的 android，是把 port number 直接寫在 init.rc 的 啟動命令參數，所以要同時支持多個 3g modem 是不可能的。&lt;br&gt;
&lt;br&gt;
新版修改了 rild reference-ril，會由 3g modem 的 vid, pid 知道是哪一個 modem，然後有一個內建的　table，決定 port。&lt;br&gt;
所以只要有在 vid. pid table 中的 3g modem， rild 都可以正確動作。&lt;br&gt;
&lt;br&gt;
* 但是這樣只有作半套...
&lt;br&gt;
pppd 的 port 還是由 init.rc 寫死，所以沒辦法依照 vid.pid 來決定。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5099534404654563845?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5099534404654563845/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5099534404654563845' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5099534404654563845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5099534404654563845'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/init.html' title='3g modem, rild &amp; pppd'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1860580352784512342</id><published>2012-02-02T14:15:00.003+08:00</published><updated>2012-02-02T14:15:28.613+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iMX51'/><title type='text'>iMX51 的 DDR D0-D31 driving strength setting</title><content type='html'>&lt;ol&gt;
&lt;li&gt;IOMUXC_SW_PAD_CTL_GRP_DRAM_B0 (08A4) : DRAM_D0-- D7&lt;/li&gt;
&lt;li&gt;IOMUXC_SW_PAD_CTL_GRP_DRAM_B1 (08AC) : DRAM_D8-- D15&lt;/li&gt;
&lt;li&gt;IOMUXC_SW_PAD_CTL_GRP_DRAM_B2 (08B8) : DRAM_D16- D23&lt;/li&gt;
&lt;li&gt;IOMUXC_SW_PAD_CTL_GRP_DRAM_B4 (082C) : DRAM_D25- D31&lt;/li&gt;
&lt;/ol&gt;
最後 bit 2.1 是 driving strength
&lt;ol&gt;
&lt;li&gt;0.0 : Low&lt;/li&gt;
&lt;li&gt;0.1 : Medium&lt;/li&gt;
&lt;li&gt;1.0 : High&lt;/li&gt;
&lt;li&gt;1.1 : Max&lt;/li&gt;
&lt;/ol&gt;

memory 的相關設定都是在 bootloader 做的，所以是在
&lt;code&gt;board/freescale/imx51_bbg/flash_header.S


MXC_DCD_ITEM(11,4, IOMUXC_BASE_ADDR + 0x8a4, 0x004)
MXC_DCD_ITEM(12,4, IOMUXC_BASE_ADDR + 0x8ac, 0x004)
MXC_DCD_ITEM(13,4, IOMUXC_BASE_ADDR + 0x8b8, 0x004)
MXC_DCD_ITEM(14,4, IOMUXC_BASE_ADDR + 0x82c, 0x004)
&lt;/code&gt;
都改最小的話，就是 0x000&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1860580352784512342?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1860580352784512342/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1860580352784512342' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1860580352784512342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1860580352784512342'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/02/imx51-ddr-d0-d31-driving-strength.html' title='iMX51 的 DDR D0-D31 driving strength setting'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8582752649020105153</id><published>2012-01-30T19:00:00.000+08:00</published><updated>2012-01-30T19:00:12.120+08:00</updated><title type='text'></title><content type='html'>&lt;code&gt;
*** Forcing "make installclean"...
*** rm -rf 
out/target/product/CV/data/* 
out/target/product/CVdata-qemu/* 
out/target/product/CV/userdata-qemu.img 
out/host/linux-x86/obj/NOTICE_FILES out/host/linux-x86/sdk 
out/target/product/CV/*.img 
out/target/product/CV/*.txt 
out/target/product/CV/*.xlb 
out/target/product/CV/*.zip 
out/target/product/CV/data 
out/target/product/CV/obj/APPS 
out/target/product/CV/obj/NOTICE_FILES 
out/target/product/CV/obj/PACKAGING 
out/target/product/CV/recovery 
out/target/product/CV/root 
out/target/product/CV/system 
out/target/product/CV/dex_bootjars 
out/target/product/CV/obj/JAVA_LIBRARIES
*** Done with the cleaning, now starting the real build.
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8582752649020105153?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8582752649020105153/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8582752649020105153' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8582752649020105153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8582752649020105153'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/forcing-make-installclean.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-334951259291104193</id><published>2012-01-30T18:26:00.001+08:00</published><updated>2012-01-30T18:26:24.289+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>root fs copy-to, file attribute</title><content type='html'>要在 root fs 中加東西，結果 copy 過去後，file attr 變了。&lt;br&gt;
這部份有點糟。&lt;br&gt;
除了要把 file 寫在 /system/core/rootfs/Android.mk 裡，&lt;br&gt;
還要修改 /system/core/include/private/android_filesystem_config.h &lt;br&gt;
像：
&lt;code&gt;static struct fs_path_config android_files[] = {
    { 00440, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.sh" },
    ..
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-334951259291104193?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/334951259291104193/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=334951259291104193' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/334951259291104193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/334951259291104193'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/root-fs-copy-to-file-attribute.html' title='root fs copy-to, file attribute'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8996192296560167082</id><published>2012-01-30T15:21:00.000+08:00</published><updated>2012-01-30T15:21:09.005+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>INSTALL_FAILED_SHARED_USER_INCOMPATIBLE</title><content type='html'>使用 vendor 的 apk, install 後，無法再 uninstall，在系統中也找不到 apk，所以無法刪除。&lt;br&gt;
install 會出現：
&lt;code&gt;INSTALL_FAILED_SHARED_USER_INCOMPATIBLE&lt;/code&gt;
後來在 logcat 中找到 unpack native ... 的 message，原來apk 解開後，安裝到 /data/app 下，並且是以 package name 而不是 filename存在。&lt;br&gt;
rm 後 install 還是 fail，但是這次error是 
&lt;code&gt;Attempt to re-install xxx.xxx.xxx without first uninstalling.&lt;/code&gt;
所以 uninstall xxx.xxx.xxx 後，再 install 一次就 OK 了。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8996192296560167082?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8996192296560167082/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8996192296560167082' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8996192296560167082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8996192296560167082'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/installfailedshareduserincompatible.html' title='INSTALL_FAILED_SHARED_USER_INCOMPATIBLE'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8967701006472988825</id><published>2012-01-30T14:02:00.002+08:00</published><updated>2012-01-30T14:02:52.740+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><category scheme='http://www.blogger.com/atom/ns#' term='MantainLog'/><category scheme='http://www.blogger.com/atom/ns#' term='driver'/><title type='text'>dell N4010 : enable bluetooth</title><content type='html'>Dell N4010 的 bluetooth 是 
&lt;code&gt;Bus 001 Device 008: ID 413c:8160 Dell Computer Corp. Wireless 365 Bluetooth
&lt;/code&gt;
但是不知道為什麼，在 ubuntu 下 lsusb 沒有出現，只有出現 他的 usb hub :
&lt;code&gt;Bus 001 Device 003: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
&lt;/code&gt;
猜是沒有 enable，但是 bluetooth enable 。&lt;br&gt;
而且 debian 的 dell hotkey 沒有 support wireless (wifi, bt) 的 switch。&lt;br&gt;
&lt;br&gt;
所以，只好..&lt;br&gt;
&lt;br&gt;
開到 windows 7 下， enable bluetooth，重新開到 debian ...&lt;br&gt;
&lt;br&gt;
bluetooth 出現了... &lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8967701006472988825?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8967701006472988825/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8967701006472988825' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8967701006472988825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8967701006472988825'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/dell-n4010-enable-bluetooth.html' title='dell N4010 : enable bluetooth'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5004295422871388231</id><published>2012-01-13T18:16:00.000+08:00</published><updated>2012-01-13T18:16:17.294+08:00</updated><title type='text'></title><content type='html'>&lt;code&gt;diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index f0f2ecb..940bd24 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1712,21 +1712,6 @@ public final class Telephony {
 
         public static final String TYPE = "type";
 
-        /**
-         * The protocol to be used to connect to this APN.
-         *
-         * One of the PDP_type values in TS 27.007 section 10.1.1.
-         * For example, "IP", "IPV6", "IPV4V6", or "PPP".
-         */
-        public static final String PROTOCOL = "protocol";
-
-        /**
-          * The protocol to be used to connect to this APN when roaming.
-          *
-          * The syntax is the same as protocol.
-          */
-        public static final String ROAMING_PROTOCOL = "roaming_protocol";
-
         public static final String CURRENT = "current";
     }
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5004295422871388231?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5004295422871388231/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5004295422871388231' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5004295422871388231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5004295422871388231'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/diff-git-acorejavaandroidproviderteleph.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2836635208576358724</id><published>2012-01-11T17:40:00.000+08:00</published><updated>2012-01-30T09:57:28.935+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android code trace : at command engine</title><content type='html'>response 都是 char *&lt;br&gt;
有可能是很多個 reponse ，所以用一個 ATLine 來包裝，&lt;br&gt;
ATLine 是一個 char * 的 linking list:
&lt;code&gt;typedef struct ATLine  {      
    struct ATLine *p_next;
    char *line;
} ATLine;
&lt;/code&gt;
reponse 是用addIntermediate(const char *line) 來填入資料：
&lt;code&gt;    ATLine *p_new;

    p_new = (ATLine  *) malloc(sizeof(ATLine));

    p_new-&gt;line = strdup(line);
    
    /* note: this adds to the head of the list, so the list
       will be in reverse order of lines received. the order is flipped
       again before passing on to the command issuer */
    p_new-&gt;p_next = sp_response-&gt;p_intermediates;
    sp_response-&gt;p_intermediates = p_new;
&lt;/code&gt;
對於 singleline response 的處理：
&lt;code&gt;        case SINGLELINE:
            if (sp_response-&gt;p_intermediates == NULL
                &amp;&amp; strStartsWith (line, s_responsePrefix)
            ) {
                addIntermediate(line);
            } else {
                /* we already have an intermediate response */
                handleUnsolicited(line);
            }
            break;
&lt;/code&gt;
所以拿到的 reponse，其中的 ATLine-&amp;gt;line 才是 char* 的內容。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
reference-ril/at_tok.c 是 response 的字串處理 function。&lt;br&gt;
&lt;br&gt;
at_tok_start(char*) : 找到 ':' 後面的位置，通常是回應的內容的開始。&lt;br&gt;
&lt;br&gt;
所以要處理 available network 的 ( )，要增加 function..&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2836635208576358724?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2836635208576358724/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2836635208576358724' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2836635208576358724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2836635208576358724'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/response-char-reponse-atline-atline.html' title='android code trace : at command engine'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-3416512381472363539</id><published>2012-01-11T15:16:00.000+08:00</published><updated>2012-01-30T10:25:52.673+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android code trace -- rild. reference-ril</title><content type='html'>從前一篇，可以知道，rild daemon ，處理 command 的部份是libril/ril.cpp 的 processCommandCallback&lt;br&gt;
其中的 processCommandBuffer( )&lt;br&gt;
&lt;br&gt;
Command 的內容格式 (protocol) 好像是 Parcel 這個 structure。&lt;br&gt;
分為 request, token。&lt;br&gt;
request 就是 command 的 id。&lt;br&gt;
&lt;br&gt;
然後簡單由查表找出 request command id 對應的 function 是 ? &lt;br&gt;
然後去執行他。&lt;br&gt;
&lt;br&gt;
這個 table 就是
&lt;code&gt;static CommandInfo s_commands[] = {
#include "ril_commands.h"
};&lt;/code&gt;
&lt;hr&gt;
&lt;br&gt;
trace 一下，以 QUERY_AVAILABLE_NETWORKS.&lt;br&gt;
&lt;br&gt;
在 ril_commands.h 裡，有 
&lt;code&gt;    {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings},T&lt;/code&gt;
所以，是 call dispatchVoid()，然後 response 送到 reponseStrings( )。&lt;br&gt;
&lt;br&gt;
dispatchVoid( ) 實際 call s_callbacks.onRequest( )。&lt;br&gt;
s_callbacks 是：
&lt;code&gt;static const RIL_RadioFunctions s_callbacks = {
    RIL_VERSION,
    onRequest,
    currentState,
    onSupports,
    onCancel,
    getVersion
};
&lt;/code&gt;
所以 call 的是 onRequest (reference-ril.c)&lt;br&gt;
&lt;br&gt;
rild support 的 command 就寫在 onRequest。&lt;br&gt;
.. 裡面沒有 implement AVAILABLE_NETWORK..&lt;br&gt;
&lt;br&gt;
... 難怪每一家 modem vendor 都不願意給 source，都給so.&lt;br&gt;
&lt;br&gt;
AVAILABLE_NETWORK 的 AT COMMAND 是
&lt;code&gt;at+cops=?&lt;/code&gt;
response 是 一行：&lt;br&gt;
 ref: &lt;a href="http://r40eubuntu.blogspot.com/2012/01/modem-at-command-cops-operator.html"&gt;http://r40eubuntu.blogspot.com/2012/01/modem-at-command-cops-operator.html&lt;/a&gt; &lt;br&gt;
&lt;br&gt;
所以送的 at_command 應該用 SINGLELINE。
&lt;code&gt;at_send_command_singleline&lt;/code&gt;
reponse 也是以 COPS: 開始，所以送command 應該是：
&lt;code&gt;err = at_send_command_singleline("AT+COPS=?","+COPS:",&amp;p_response);&lt;/code&gt;
&lt;br&gt;
response 的部份可以參考 CM 的 android_hardware_ril 為了 htc 的 reference-ril.so 的修改：
 &lt;a href="https://github.com/CyanogenMod/android_hardware_ril/commit/90102813ee766b658c9d11f47bfffa785a98b6cd"&gt;https://github.com/CyanogenMod/android_hardware_ril/commit/90102813ee766b658c9d11f47bfffa785a98b6cd &lt;/a&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-3416512381472363539?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/3416512381472363539/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=3416512381472363539' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3416512381472363539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3416512381472363539'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/rild-daemon-command-librilril.html' title='android code trace -- rild. reference-ril'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6228628216941738697</id><published>2012-01-11T13:15:00.001+08:00</published><updated>2012-01-30T10:26:35.221+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android code trace : rild, service socket</title><content type='html'>&lt;ol&gt;
&lt;li&gt;s_listen_event : processCommandsCallback, listenCallback, &lt;/li&gt;
&lt;li&gt;s_commands_event : listenCallback&lt;/li&gt;
&lt;li&gt;s_wakeupfd_event : eventLoop&lt;/li&gt;
&lt;li&gt;s_debug_event : RIL_register&lt;/li&gt;
&lt;/ol&gt;
其中 各 event 對應的 socket, callback function:
&lt;ol&gt;
&lt;li&gt;s_listen_event : s_fdListen, listenCallback&lt;/li&gt;
&lt;li&gt;s_commands_event : s_fdCommand, processCommandsCallback&lt;/li&gt;
&lt;li&gt;s_wakeupfd_event : s_fdWakeupRead, processWakeupCallback&lt;/li&gt;
&lt;li&gt;s_debug_event : s_fdDebug, debugCallback&lt;/li&gt;
&lt;/ol&gt;

s_wakeupfd_event 是用 pipe implement，只是為讓 event loop 跳出 select( ) 的 blocking 狀態。&lt;br&gt;
所以內容很無聊。&lt;br&gt;
正如變數名稱所說：只是為了 wakeup event loop。&lt;br&gt;
&lt;br&gt;


s_debug_event 提供 socket : SOCKET_NAME_RIL_DEBUG 供額外控制 ril 的介面。&lt;br&gt;
&lt;br&gt;
s_listen_event 是 Rild 的主要 service socket : SOCKET_NAME_RIL。&lt;br&gt;
&lt;br&gt;
這兩個 socket:
&lt;code&gt;
#define SOCKET_NAME_RIL "rild"
#define SOCKET_NAME_RIL_DEBUG "rild-debug"
&lt;/code&gt;都是在 init.rc 中 create 好:&lt;br&gt;
&lt;code&gt;
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
&lt;/code&gt;
所以在 rild 中只要經過 android_get_control_socket() 從環境變數中取出 socket id 就可以，不用自己 create (bind)。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
rild 是一對多的 server，所有的 client 經過 SOCKET_RIL 向 rild 取得命令通道，之後就可以和 rild 溝通。&lt;br&gt;
&lt;br&gt;
rild 從 s_fdListen 得到 client 的連線 (accept)，就keep 這個 connection : s_command_event。&lt;br&gt;
同時，繼續 s_fdListen 的 listen( )，等待另一個 client 的連線。&lt;br&gt;
==&gt; 一般 network server 的作法。&lt;br&gt;
&lt;br&gt;
這個 socket base , event callback 的架構中心，就是 libril/ril_event.cpp 的 ril_event_loop().&lt;br&gt;
&lt;br&gt;
ril_event_loop 是一個一般化的 event callback loop，就是select block，return if data available&lt;br&gt;
然後call 對應的 callback。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6228628216941738697?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6228628216941738697/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6228628216941738697' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6228628216941738697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6228628216941738697'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/slistenevent-processcommandscallback.html' title='android code trace : rild, service socket'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1423630325862447356</id><published>2012-01-10T15:01:00.000+08:00</published><updated>2012-01-30T10:29:39.036+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android code trace : gsm service</title><content type='html'>&lt;code&gt;base/telephony/java/android/telephony/ServiceState.java&lt;/code&gt;
是 3G Modem 的狀態。&lt;br&gt;
用來表示 3G Service State。&lt;br&gt;
&lt;br&gt;
因為 3G State 不是單純的 OK, fail。&lt;br&gt;
所以些class 來存放 Service state。&lt;br&gt;
&lt;br&gt;
ServiceState 裡面包含的資料有：
&lt;code&gt;    private int mState = STATE_OUT_OF_SERVICE;
    private boolean mRoaming;
    private String mOperatorAlphaLong;
    private String mOperatorAlphaShort;
    private String mOperatorNumeric;
    private boolean mIsManualNetworkSelection;

    private boolean mIsEmergencyOnly;

    //***** CDMA
    private int mRadioTechnology;
    private boolean mCssIndicator;
    private int mNetworkId;
    private int mSystemId;
    private int mCdmaRoamingIndicator;
    private int mCdmaDefaultRoamingIndicator;
    private int mCdmaEriIconIndex;
    private int mCdmaEriIconMode;
&lt;/code&gt;
System Setting  和 Status 的大部分資料都是從 SeviceState 這個 object 來的。&lt;br&gt;
&lt;br&gt;
在 TelephonyRegistry.java : 有一堆 BroadcastXXXChange(xxx)。&lt;br&gt;
這些 function  都會 呼嘯 fillInNotifierBundle( )，把 Bundle 放到 intent 的 extra，然後再 broadcast 。&lt;br&gt;
&lt;br&gt;
以 ServiceStateChanged( ) 來看。&lt;br&gt;
&lt;code&gt;
notifyServiceState
 broadcastServiceStateChanged&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1423630325862447356?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1423630325862447356/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1423630325862447356' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1423630325862447356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1423630325862447356'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/basetelephonyjavaandroidtelephonyservic.html' title='android code trace : gsm service'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6134818127792706986</id><published>2012-01-10T13:23:00.000+08:00</published><updated>2012-01-30T10:29:50.026+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cellphone'/><title type='text'>Modem AT Command : COPS -- 與 operator 相關</title><content type='html'>&lt;code&gt;AT+COPS&lt;/code&gt;  這個 command 跟 operator 相關。&lt;br&gt;
可以用來：
&lt;ol&gt;
&lt;li&gt; 顯示目前註冊的operator&lt;/li&gt;
&lt;li&gt; 選擇 operator 的方法：自動，手動&lt;/li&gt;
&lt;li&gt; 列出所有搜尋到的 operator&lt;/li&gt;
&lt;/ol&gt;
例如：
&lt;code&gt;at+cops=?
+COPS: 
(2,"Chunghwa Telecom","Chunghwa","46692",2),
(1,"Chunghwa Telecom","Chunghwa","46692",0),
(3,"VIBO","VIBO","46689",2),
(3,"Far EasTone","FET","46601",0),
(3,"TW Mobile","TWM","46697",0),
(3,"TW Mobile","TWM","46697",2),
(3,"Far EasTone","FET","46601",2),
,(0,1,2,3,4),(0,1,2)
&lt;/code&gt;
-- 實際上是連在一起，為好看，我加上分行。&lt;br&gt;
&lt;br&gt;
每個 (  ) 代表一個 operator, 各攔的意思是：&lt;br&gt;
&lt;code&gt;
( state, operator name - long, operator name -short, operator id,  rate )
&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;state : operator 的狀態。&lt;br&gt;0 : unknown,&lt;br&gt;1 : 可用&lt;br&gt;2 : 目前註冊的 operator&lt;br&gt;3 : 禁止使用&lt;/li&gt;
&lt;li&gt; operator name , long, short, id : 分別是 operator 的三種表示法&lt;/li&gt;
&lt;li&gt; rate : 網路型態：&lt;br&gt;0 : GSM/GPRS&lt;br&gt; 2: WCDMA&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6134818127792706986?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6134818127792706986/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6134818127792706986' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6134818127792706986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6134818127792706986'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/modem-at-command-cops-operator.html' title='Modem AT Command : COPS -- 與 operator 相關'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6990665936572008215</id><published>2012-01-05T10:20:00.001+08:00</published><updated>2012-01-30T10:28:49.364+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='memo'/><category scheme='http://www.blogger.com/atom/ns#' term='cellphone'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>3gdongle on linux &amp; android, some notes</title><content type='html'>中華電信的某種 帳戶 服務 ，在 android 上有點奇怪。&lt;br&gt;&lt;br&gt;
APN 只能使用 "internet" 的 simcard。&lt;br&gt;
&lt;br&gt;
一旦設定使用 "emome" 這個 apn name，data channel 無法連上 (這是當然的)，&lt;br&gt;
但是把 apn 改回 internet，也是一樣無法連上，&lt;br&gt;
重開機也一樣。&lt;br&gt;
&lt;br&gt;
結果是用 3g dongle，接上 linux，手動撥接..&lt;br&gt;
第一次：撥接 OK，但是ppp 連線，取得 dns 位址時，一直得到 fake 的 10.11.12.13 和 14，&lt;br&gt;
pppd keep retry，還是一樣。&lt;br&gt;
... 猜 android 手機大概是維持在這個狀態。&lt;br&gt;
&lt;br&gt;
之後m，再差拔一次 3g dongle，&lt;br&gt;
再 撥接一次才OK。&lt;br&gt;
&lt;br&gt;
之後，放在 android 手機上也 OK 了。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;手機是 nexus S&lt;/li&gt;
&lt;li&gt;在改apn name 為 emome ，無法連線，之後有作一次 "恢復 default setting" 的 apn setting&lt;/li&gt;
&lt;li&gt;還有作過 "搜尋可用網路"，也無效&lt;li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6990665936572008215?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6990665936572008215/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6990665936572008215' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6990665936572008215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6990665936572008215'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/android-apn-internet-simcard-emome-apn.html' title='3gdongle on linux &amp; android, some notes'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6352568272343944770</id><published>2012-01-03T12:13:00.000+08:00</published><updated>2012-01-30T10:29:17.811+08:00</updated><title type='text'>android code trace : rild</title><content type='html'>&lt;code&gt;
mainLoop(){
  for(;;){
     open /dev/ttyXXX
     at_open( );   // 設定好 at command 的 read back thread.
     
     RIL_requestTimedCallback(initializeCallback, NULL, &amp;TIMEVAL_DELAYINIT);  // delay 一段時間， call initializeCallback
     
     waitForClose();  // 會停在這，一直到 device 被關掉，發出 signal
  }
}
&lt;/code&gt;
這個 mainLoop( ) 就是 rild 的主體。&lt;br&gt;
&lt;br&gt;
initializeCallback() 負責送出 modem 的初始化 at command  (有一堆)。&lt;br&gt;
&lt;br&gt;
所以 at_open( ) 會先執行，然後才是 modem initialize commands。&lt;br&gt;
&lt;br&gt;
at_open 實際呼叫時： at_open(fd,onUnsolicited)&lt;br&gt;
&lt;br&gt;
這裡的 onUnsolicited 是 function : 負責處理 還沒送出 initialize command 前， modem 自己送回來得 command。&lt;br&gt;
 -- 所以一定是 unsolicited&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
Service 的 socket interface 部份。&lt;br&gt;
&lt;br&gt;
在RIL_register( ) 開始。&lt;br&gt;
這是在 mainLoop() 前就執行的。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;hr&gt;
ril 好像有兩種啟動方法：
&lt;ol&gt;
&lt;li&gt; 直接由 reference-ril 的 main 啟動&lt;/li&gt;
&lt;li&gt; 由 rild 呼叫 RIL_Init( ) 啟動&lt;/li&gt;
&lt;/ol&gt;
在 init.rc 中好像是用 rild 呼叫 RIL_Init 。&lt;br&gt;
&lt;br&gt;
這樣的話..&lt;br&gt;
RIL_Init ( ) 只做：
&lt;ol&gt;
&lt;li&gt;start uevent monitor -- probe usb device..&lt;/li&gt;
&lt;li&gt; 取得 device, data port，開啟 mainLoop( ) thread.&lt;/li&gt;
&lt;li&gt; 執行 RIL_register&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6352568272343944770?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6352568272343944770/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6352568272343944770' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6352568272343944770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6352568272343944770'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/mainloop-for-open-devttyxxx-atopen-at.html' title='android code trace : rild'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-511654944263599311</id><published>2012-01-02T17:30:00.000+08:00</published><updated>2012-01-02T17:30:40.028+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>rild AT_DUMP 的陷阱</title><content type='html'>android 的 ril。&lt;br&gt;
AT_DUMP( ) 原先應該是要 dump 到 file (ref comment)。&lt;br&gt;
但是好像是沒有implement，所以用 LOGD，但是又不一樣。所以把 AT_DEBUG set 1，不會動作。&lt;br&gt;
&lt;br&gt;
不能用 LOGD("%s",buff) 直接輸出的原因是 buff 有可能是部份的 AT string，還沒到 ending，所以沒有 ending null。&lt;br&gt;
&lt;br&gt;
所以 AT_DUMP( )的 argument 有 len。&lt;br&gt;
&lt;br&gt;
但是要注意，如果想改用 memcpy( ) copy 到 tmp 後加上 ending null 再印出去，run 起來會 exception。&lt;br&gt;
因為在reference-ril.c 有這樣呼叫的：
&lt;code&gt;static void *
mainLoop(void *param)
{
    ....
    AT_DUMP("== ", "entering mainLoop()", -1 );
    ....
&lt;/code&gt;
.. len 是 -1.&lt;br&gt;
&lt;br&gt;
所以真的要改 AT_DUMP( ) 的話，要針對 len -1 作處理。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-511654944263599311?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/511654944263599311/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=511654944263599311' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/511654944263599311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/511654944263599311'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/rild-atdump.html' title='rild AT_DUMP 的陷阱'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2800322677388174463</id><published>2012-01-02T14:08:00.000+08:00</published><updated>2012-01-02T14:08:04.174+08:00</updated><title type='text'></title><content type='html'>signal() 會直接送出 signal。&lt;br&gt;
alarm(n) 就是 delay n sec 後送出 alarm signal。&lt;br&gt;
&lt;br&gt;
兩個 function 都是 none-block (呼叫後會繼續執行)。&lt;br&gt;
&lt;br&gt;
因為都是 signal，所以使用上要設定 signal handler，當signal 發生後 (馬上或是 n 秒後)。&lt;br&gt;
signal handler 會被呼叫。x&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2800322677388174463?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2800322677388174463/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2800322677388174463' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2800322677388174463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2800322677388174463'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2012/01/signal-signal-alarmn-delay-n-sec-alarm.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2770599347252738464</id><published>2011-12-29T18:29:00.000+08:00</published><updated>2011-12-29T18:29:42.723+08:00</updated><title type='text'>microcom : busybox version minicom</title><content type='html'>Busybox 提供一個 serial port 通訊程式，類似 minicom。&lt;br&gt;
&lt;br&gt;
&lt;code&gt;microcom -d 1200 -s 115200 /dev/ttyUSB3&lt;/code&gt;
: 設定 character timeout 是 1200ms，baudrate 是 115200，對 /dev/ttyUSB3 動作。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2770599347252738464?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2770599347252738464/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2770599347252738464' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2770599347252738464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2770599347252738464'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/microcom-busybox-version-minicom.html' title='microcom : busybox version minicom'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7295038642271167056</id><published>2011-12-29T08:34:00.001+08:00</published><updated>2011-12-29T08:34:15.513+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android root fs file,dir attribute</title><content type='html'>android root 的directory, file attribute 是在製作 root image 時就設定的。&lt;br&gt;
permission 的設定是在
&lt;code&gt;system/core/include/private/android_filesystem_config.h&lt;/code&gt;
實際reference ，使用的是：
&lt;code&gt;system/core/cpio/mkbootfs.c&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7295038642271167056?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7295038642271167056/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7295038642271167056' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7295038642271167056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7295038642271167056'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/android-root-fs-filedir-attribute.html' title='android root fs file,dir attribute'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-899592795154719629</id><published>2011-12-28T11:02:00.000+08:00</published><updated>2011-12-29T18:19:02.067+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><title type='text'>CHT E180 (Huawei) 3G dongle in Debian</title><content type='html'>中華電信的 E180 3G dongle ，實際插入後看 VID, PID 不是 E180。&lt;br&gt;
&lt;code&gt;idVendor=12d1, idProduct=140c&lt;/code&gt;
但是和網路上 140C 的 Huawei dongle 不一樣的是，這個(fake) E180 是同時有 3G modem, CD ROM + card reader 三種 device profile 同時啟動。&lt;br&gt;
所以不必用 usb modeswitch 來切換到 usb serial mode。&lt;br&gt;
&lt;br&gt;
插入後會看到 6 個裝置：
&lt;ol&gt;
&lt;li&gt;ttyUSB0-3&lt;/li&gt;
&lt;li&gt;CD-ROM&lt;/li&gt;
&lt;li&gt;Direct Access ,SD Storage&lt;/li&gt;
&lt;/ol&gt;
插入後，用 debian 內建的 network manager 就可以，&lt;br&gt;
依照 SIM card 選 Taiwan, CHT (emome) 就會設定好 APN, dial number..&lt;br&gt;
&lt;br&gt;
然後就可以上網了。&lt;br&gt;
&lt;br&gt;
Network manager 一旦關閉掉這個 mobile 連線 後，要再重新插拔一次dongle 才會出現..(很慢，大約要 15 sec)。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
寄一下這個 sim card 的 default gw 是：&lt;code&gt;10.64.64.64&lt;/code&gt;
route :
&lt;code&gt;Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.64.64.64     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ppp0
0.0.0.0         10.64.64.64     0.0.0.0         UG    0      0        0 ppp0
&lt;/code&gt;&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
ttyUSB3 好像是 control port，但是一上電，會自動，定期送：
&lt;code&gt;^BOOT:32614906,0,0,0,20
^SRVST:1
^MODE:5,4
^STIN:0,0,0
^RSSI:13
^RSSI:13
..
&lt;/code&gt;
依照 這一篇(&lt;a href="http://forum.huawei.com/jive4/thread.jspa?threadID=328818"&gt;http://forum.huawei.com/jive4/thread.jspa?threadID=328818&lt;/a&gt;) 的說法，下
&lt;code&gt;AT^CURC=0&lt;/code&gt;
就可以停止這些 unsolicied response.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-899592795154719629?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/899592795154719629/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=899592795154719629' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/899592795154719629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/899592795154719629'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/cht-e180-huawei-3g-dongle-in-debian.html' title='CHT E180 (Huawei) 3G dongle in Debian'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-321647275750014320</id><published>2011-12-26T09:18:00.000+08:00</published><updated>2011-12-26T09:39:35.379+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>usb ethernet -- android &amp; linux</title><content type='html'>開啟 USB Tethering 後...可以參考&lt;a href="http://support.google.com/mobile/bin/answer.py?hl=en&amp;answer=182134"&gt;http://support.google.com/mobile/bin/answer.py?hl=en&amp;answer=182134&lt;/a&gt; &lt;br&gt;
文章是說明 XP 的，沒有Linux 的原因是，linux native support ..(?)&lt;br&gt;
&lt;br&gt;
實際插入後，dmesg 看..
&lt;code&gt;[ 3322.275837] usb 2-1.1.4.3: new high speed USB device using ehci_hcd and address 7
[ 3322.385272] usb 2-1.1.4.3: New USB device found, idVendor=0fce, idProduct=014f
[ 3322.385277] usb 2-1.1.4.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3322.385280] usb 2-1.1.4.3: Product: SEMC HSUSB Device
[ 3322.385282] usb 2-1.1.4.3: Manufacturer: SEMC
[ 3322.385285] usb 2-1.1.4.3: SerialNumber: XXXXXXXXXXXX
[ 3322.385429] usb 2-1.1.4.3: configuration #1 chosen from 1 choice
[ 3360.185459] usb 2-1.1.4.3: USB disconnect, address 7
[ 3360.404499] usb 2-1.1.4.3: new high speed USB device using ehci_hcd and address 8
[ 3360.513935] usb 2-1.1.4.3: New USB device found, idVendor=0fce, idProduct=714f
[ 3360.513939] usb 2-1.1.4.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3360.513942] usb 2-1.1.4.3: Product: SEMC HSUSB Device
[ 3360.513945] usb 2-1.1.4.3: Manufacturer: SEMC
[ 3360.513947] usb 2-1.1.4.3: SerialNumber: XXXXXXXXXXXX
[ 3360.514069] usb 2-1.1.4.3: configuration #1 chosen from 1 choice
[ 3360.582488] usbcore: registered new interface driver cdc_ether
[ 3360.587738] usb0: register 'rndis_host' at usb-0000:00:1d.0-1.1.4.3, RNDIS device, XX:XX:XX:XX:XX:XX
[ 3360.587786] usbcore: registered new interface driver rndis_host
[ 3371.666534] usb0: no IPv6 routers present
&lt;/code&gt;
所以host 要 support，要 enable cdc_ether ，還有 rndis_host。&lt;br&gt;
&lt;br&gt;
在 driver/net/usb/Makefile 有：
&lt;code&gt;obj-$(CONFIG_USB_NET_CDCETHER)  += cdc_ether.o

obj-$(CONFIG_USB_NET_RNDIS_HOST)        += rndis_host.o
&lt;/code&gt;&lt;br&gt;
有關 USB_NET_CDCETHER :
&lt;code&gt;config USB_NET_CDCETHER
        tristate "CDC Ethernet support (smart devices such as cable modems)"
        depends on USB_USBNET
        default y
&lt;/code&gt;&lt;br&gt;
所以要 enable USB_USBNET:
&lt;code&gt;config USB_USBNET
        tristate "Multi-purpose USB Networking Framework"
        select MII
&lt;/code&gt;
還有，這些是屬於...
&lt;code&gt;menu "USB Network Adapters"
        depends on USB &amp;&amp; NET
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-321647275750014320?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/321647275750014320/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=321647275750014320' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/321647275750014320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/321647275750014320'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/usb-ethernet-android-linux.html' title='usb ethernet -- android &amp; linux'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4039769617362042990</id><published>2011-12-23T15:26:00.001+08:00</published><updated>2011-12-23T15:38:28.099+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MantainLog'/><title type='text'>Use wlan &amp; in-office nic</title><content type='html'>大概就是
&lt;ol&gt;
&lt;li&gt; 公司內部的server ，用 eth0&lt;/li&gt;
&lt;li&gt; 外部，用 wireless&lt;/li&gt;
&lt;/ol&gt;
因為wireless 用 3G-Ap，沒有鎖 port, site。&lt;br&gt;
&lt;br&gt;
方法： &lt;br&gt;
&lt;br&gt;
就是改 route table，把公司的 ip 導到 eth0，其他都是 wlan0&lt;br&gt;
&lt;br&gt;
wireless, ethernet 都接上後， route :
&lt;code&gt;$sudo route -n

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.43.0    0.0.0.0         255.255.255.0   U     2      0        0 wlan0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 wlan0
0.0.0.0         192.168.43.1    0.0.0.0         UG    0      0        0 wlan0
&lt;/code&gt;
公司內部又分很多 sub network，我的ethernet 好像是在 192.168.144.0 網段，&lt;br&gt;
所以仙家一下：
&lt;code&gt;$sudo route add -net 192.168.144.netmask 255.255.255. dev eth0&lt;/code&gt;
然後加上要 access 的 server:
&lt;code&gt;$sudo route add -host 191.168.147.233 gw 192.168.144.254 dev eth0&lt;/code&gt;
因為公司有分很多 sub net， 144 網段的 gateway 是 254。&lt;br&gt;
&lt;br&gt;
 這樣就可以了， &lt;br&gt;
 -- check 一下 default gw，要是 wireless 的 192.168.43.1。&lt;br&gt;
如果有新增加eth 的 gw，要刪除掉。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
還有接上外部網站變慢是 dns 的關係，注意要把 dns 加到 route path 中：
&lt;code&gt;sudo route add -host 192.168.147.15 gw 192.168.144.254 dev eth0&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;&lt;br&gt;
一個一個加很白痴，就設 192.168.147.0 的 gw 是 192.168.144.254 就好..&lt;br&gt;
&lt;code&gt;sudo route add -net 192.168.147.0 netmask 255.255.255.0 gw 192.168.144.254 dev eth0&lt;/code&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4039769617362042990?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4039769617362042990/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4039769617362042990' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4039769617362042990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4039769617362042990'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/use-wlan-in-office-nic.html' title='Use wlan &amp; in-office nic'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8020092137922034802</id><published>2011-12-23T14:36:00.003+08:00</published><updated>2011-12-23T14:36:45.649+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><category scheme='http://www.blogger.com/atom/ns#' term='MantainLog'/><title type='text'>enable dell inspiron N4010 wireless module</title><content type='html'>先 lspci 看一下 wireless module 是..
&lt;code&gt;04:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g/n Wireless LAN Controller (rev 01)
&lt;/code&gt;
或是用 lshw --class network 看
&lt;code&gt;  *-network               
       description: Wireless interface
       product: BCM4313 802.11b/g/n Wireless LAN Controller
       vendor: Broadcom Corporation
       physical id: 0
       bus info: pci@0000:04:00.0
       logical name: wlan0
       version: 01
       serial: 5c:ac:4c:98:d7:59
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress bus_master cap_list ethernet physical wireless
       configuration: broadcast=yes driver=brcm80211 ip=192.168.43.230 latency=0 multicast=yes wireless=IEEE 802.11bgn
       resources: irq:17 memory:f0300000-f0303fff
&lt;/code&gt;
知道是 BCM4313&lt;br&gt;
&lt;br&gt;
然後　google 到這一篇：&lt;a href="http://wiki.debian.org/brcm80211"&gt;http://wiki.debian.org/brcm80211&lt;/a&gt; &lt;br&gt;
照著作，安裝 firmware-brcm80211，然後 modprobe..&lt;br&gt;
 -- 奇怪我第一次 modprobe 沒效， -r 後再 一次才 iwconfig OK.&lt;br&gt;
&lt;br&gt;
裝進去後，就可以在 GUI networkmanager applet看到...&lt;br&gt;
... 就可以操作了..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8020092137922034802?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8020092137922034802/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8020092137922034802' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8020092137922034802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8020092137922034802'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/enable-dell-inspiron-n4010-wireless.html' title='enable dell inspiron N4010 wireless module'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2870003623186035704</id><published>2011-12-20T08:59:00.004+08:00</published><updated>2011-12-20T18:03:40.708+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>3G 開通紀錄</title><content type='html'>紀錄一下，3G 開通。&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-IJ-Vp0u2K5M/TvAhvWvJmlI/AAAAAAAAF6o/wBCapjIMjYY/s1600/DSC00976.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-IJ-Vp0u2K5M/TvAhvWvJmlI/AAAAAAAAF6o/wBCapjIMjYY/s320/DSC00976.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2870003623186035704?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2870003623186035704/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2870003623186035704' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2870003623186035704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2870003623186035704'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/3g.html' title='3G 開通紀錄'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-IJ-Vp0u2K5M/TvAhvWvJmlI/AAAAAAAAF6o/wBCapjIMjYY/s72-c/DSC00976.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8077721901689003903</id><published>2011-12-15T13:26:00.003+08:00</published><updated>2011-12-15T13:26:53.092+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Activity Stack  只留一個 app (act)</title><content type='html'>其實就是 setAlwaysFinish 就可以。&lt;br&gt;
-- 如果可以把 system setting 的 default 就設 enable 應該比較漂亮。&lt;br&gt;
&lt;br&gt;
不然就在 Code 中：
&lt;code&gt;import android.app.ActivityManagerNative;
import android.util.Log;


    try {
            ActivityManagerNative.getDefault().setAlwaysFinish(true);
    } catch (RemoteException ex) {
            Log.d(TAG,"setAlwaysFinish failed!!");
    }
&lt;/code&gt;

結果可以用 adk 的 hierarchyviewer 來看。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8077721901689003903?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8077721901689003903/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8077721901689003903' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8077721901689003903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8077721901689003903'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/activity-stack-app-act.html' title='Activity Stack  只留一個 app (act)'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6651714189518767186</id><published>2011-12-14T17:16:00.002+08:00</published><updated>2011-12-14T17:45:25.788+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>use sqilt3 command to show the system settings</title><content type='html'>android 的 system settings 存放在 sqilt3 database 裡。&lt;br&gt;
所以可以用 sqilt3 command 來檢視/變更。&lt;br&gt;
&lt;br&gt;
先開啟 database:
&lt;code&gt;#sqilt3 /data/data/com.android.providers.settings/database/settings.db
&lt;/code&gt;
顯示 所有內容：
&lt;code&gt;sqilte&gt;select * from system;

1|volume_music|12
2|volume_ring|5
3|volume_system|7
4|volume_voice|4
5|volume_alarm|6
6|volume_notification|5
7|volume_bluetooth_sco|7
8|mode_ringer|2
9|vibrate_on|4
10|mode_ringer_streams_affected|166
11|mute_streams_affected|46
12|dim_screen|1
13|stay_on_while_plugged_in|0
14|screen_off_timeout|-1
15|emergency_tone|0
16|xec_dls_control|0
17|call_auto_retry|0
18|dtmf_tone_type|0
19|hearing_aid|0
20|tty_mode|0
21|airplane_mode_on|0
22|airplane_mode_radios|cell,bluetooth,wifi
23|airplane_mode_toggleable_radios|bluetooth,wifi
24|auto_time|1
25|screen_brightness|255
26|screen_brightness_mode|0
27|window_animation_scale|1.0
28|transition_animation_scale|1.0
29|accelerometer_rotation|1
30|haptic_feedback_enabled|1
31|notification_light_pulse|1
32|set_install_location|0
33|default_install_location|0
34|power_sounds_enabled|1
35|low_battery_sound|/system/media/audio/ui/LowBattery.ogg
36|dock_sounds_enabled|0
37|desk_dock_sound|/system/media/audio/ui/Dock.ogg
38|desk_undock_sound|/system/media/audio/ui/Undock.ogg
39|car_dock_sound|/system/media/audio/ui/Dock.ogg
40|car_undock_sound|/system/media/audio/ui/Undock.ogg
41|lockscreen_sounds_enabled|0
42|lock_sound|/system/media/audio/ui/Lock.ogg
43|unlock_sound|/system/media/audio/ui/Unlock.ogg
44|vibrate_in_silent|1
45|notifications_use_ring_volume|1
46|next_alarm_formatted|
47|alarm_alert|content://media/internal/audio/media/1
48|notification_sound|content://media/internal/audio/media/2
49|ringtone|content://media/internal/audio/media/3
50|pointer_location|0
52|ServiceIntentActionToResumeSD|
69|MediaPlaybackPath|content://media/external/audio/media/131076
70|always_finish_activities|1
sqlite&gt; 
&lt;/code&gt;
default 沒有 show 欄位名稱，可以用：
&lt;code&gt;sqlite&gt;.header on&lt;/code&gt;
打開，然後再顯示一次..
&lt;code&gt;sqlite&gt; select * from system;
_id         name          value     
----------  ------------  ----------
1           volume_music  12        
2           volume_ring   5         
3           volume_syste  7         
4           volume_voice  4         
5           volume_alarm  6         
6           volume_notif  5         
7           volume_bluet  7         
8           mode_ringer   2     
...
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6651714189518767186?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6651714189518767186/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6651714189518767186' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6651714189518767186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6651714189518767186'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/use-sqilt3-command-to-show-system.html' title='use sqilt3 command to show the system settings'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4927714141225766440</id><published>2011-12-14T15:22:00.000+08:00</published><updated>2011-12-14T17:04:08.951+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>limit max process &amp; immediately destroy activity</title><content type='html'>限制 max activity 的code 是在./services/java/com/android/server/am/ActivityManagerService.java &lt;br&gt;
其中的trimApplication()&lt;br&gt;
&lt;br&gt;
call trimApplication 的有：
&lt;ol&gt;
&lt;li&gt;activityStopped&lt;/li&gt;
&lt;li&gt;unregisterReceiver&lt;/li&gt;
&lt;li&gt;finishReceiver&lt;/li&gt;
&lt;/ol&gt;
另外，還有./services/java/com/android/server/am/ActivityStack.java 的&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;activityIdleInternal&lt;/li&gt;
&lt;/ol&gt;
是在handleMessage( ) 中呼叫。&lt;br&gt;
呼叫的時機：
&lt;ol&gt;
&lt;li&gt;IDLE_TIMEOUT_MSG&lt;/li&gt;
&lt;li&gt;IDLE_NOW_MSG&lt;/li&gt;
&lt;/ol&gt;
還有 ./services/java/com/android/server/am/ActivityManagerService.java 的 &lt;br&gt;
activityIdle&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
除了以上的code，在 trimApplication( ) 中可以看到，mProcessLimit 也可以用來限制 activity 的數量。&lt;br&gt;
&lt;br&gt;
mProcessLimit  的存取 方法是：
&lt;ol&gt;
&lt;li&gt;setProcessLimit&lt;/li&gt;
&lt;li&gt;getProcessLimit&lt;/li&gt;
&lt;/ol&gt;
這個 SET_PROCESS_LIMIT 好像也是 app 的 permission。&lt;br&gt;
&lt;br&gt;
在 developement Setting 的 writeProcessLimitOptions( ) 使用到&lt;br&gt;
&lt;br&gt;
這個就是 Immediately Destroy Activity 的上一個選項 max process limit (?)&lt;br&gt;
&lt;br&gt;
但是實際測試， max process limit=1，和 immediately destroy activity 好像效果不一樣。&lt;br&gt;
以 播放影片的 Gallery 為例：&lt;br&gt;
程式進入，是 GalleryPicker， 選好 folder 後，再開啟 ImageGallery。&lt;br&gt;
&lt;br&gt;
當 enable immediately destroy activity 時，可以正常動作。&lt;br&gt;
但是 set max process limit=1 卻不行，要開啟 ImageGallery 時，就 fail 回到GalleryPicker。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4927714141225766440?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4927714141225766440/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4927714141225766440' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4927714141225766440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4927714141225766440'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/max-activity-code.html' title='limit max process &amp; immediately destroy activity'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1513681815977804568</id><published>2011-12-14T14:42:00.000+08:00</published><updated>2012-02-08T15:57:37.644+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>activity hierarchy</title><content type='html'>android 的 activity 是像 stack 一樣堆疊起來。&lt;br&gt;
android sdk 提供一個 tool，讓你看activity stack 的狀態：
&lt;code&gt;hierarchyviewer&lt;/code&gt;
是 GUI 介面，會自動 update。&lt;br&gt;
用這個 tool，可以看到 stack 的狀態。&lt;br&gt;
&lt;br&gt;
實際測試，可以知道 在 app 中按下 HOME key，只是把 launcher 叫出來，原app 被 push 到 stack。&lt;br&gt;
&lt;br&gt;
要在該 app 按 BACK，才會從 activity stack 中剔除。&lt;br&gt;
&lt;br&gt;
另外，配合上一篇的內容。&lt;br&gt;&lt;br&gt;
當 enable "Immediately destroy activies" 的話。&lt;br&gt;
 activity stack 只會留最上面的 app，一旦被推到後面的 app，會從 stack 中移除。&lt;br&gt;
 -- 就像按下 BACK 一樣。&lt;br&gt;
&lt;br&gt;
但是這只限於 activity。&lt;br&gt;
app 中的 service 並不受影響。&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
hierarchyviewer 有兩個，一個是 eclipse 的 perspective view，另一個在 out/host/linux-x86/bin 下。&lt;br&gt;
這邊用的是 eclipse 的&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1513681815977804568?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1513681815977804568/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1513681815977804568' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1513681815977804568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1513681815977804568'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/activity-hierarchy.html' title='activity hierarchy'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1059151153396603667</id><published>2011-12-14T13:30:00.001+08:00</published><updated>2011-12-14T13:30:33.639+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software_package'/><category scheme='http://www.blogger.com/atom/ns#' term='MantainLog'/><title type='text'>update flashplayer 11 for debian squeeze</title><content type='html'>最近 squeeze 的 chrom 一直 complain flash player plugin 太舊，所以不執行。&lt;br&gt;
&lt;br&gt;
所以到 adobe 網站去download，但是沒有 debian 的版本。&lt;br&gt;
只好 download tar.gz 版，自己解開。&lt;br&gt;
&lt;br&gt;
google 一下手動安裝。&lt;br&gt;
好像就是把 libflashplayer.so copy  到某個目錄就可以。&lt;br&gt;
其他 /usr /,... 的，大概是因為原來就有 install none-free 版的 rev 10，所以不必用。&lt;br&gt;
&lt;br&gt;
這樣，就只要把解開的 libflashplayer.so 覆蓋掉 /usr/lib/flashplugin-nonfree/libflash.so &lt;br&gt;
然後重開 chrome 就可以..&lt;br&gt;
&lt;br&gt;
至少沒有 complain，然後 youtube 播放 OK。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1059151153396603667?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1059151153396603667/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1059151153396603667' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1059151153396603667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1059151153396603667'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/update-flashplayer-11-for-debian.html' title='update flashplayer 11 for debian squeeze'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7863337146694722431</id><published>2011-12-14T11:58:00.000+08:00</published><updated>2011-12-14T11:58:15.341+08:00</updated><title type='text'>test android app state</title><content type='html'>看看 app 內部的變數，會因為 HOME, BACK 後重啟動而有不同嗎？&lt;br&gt;
test app 就是用 一個 button，按一下 increase 一次 counter，然後看每次啟動 counter 是否被 reset。&lt;br&gt;
&lt;br&gt;
&lt;code&gt;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.view.View;

public class testAndroidActivity extends Activity implements View.OnClickListener
{
    final String TAG = "testAndroid";
    LinearLayout layout;
    Button btn;
    int clickcnt = 0;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);

        layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        btn = new Button(this);
        btn.setText(Integer.toString(clickcnt));
        btn.setOnClickListener(this);

        layout.addView(btn,150,100);

        setContentView(layout);
        Log.v(TAG,"onCreate");
    }

    public void onClick(View v) {
            Log.v(TAG, "onClick");
            clickcnt++;
            btn.setText(Integer.toString(clickcnt));
    }
&lt;/code&gt;
結果..&lt;br&gt;&lt;br&gt;
啟動 app，按button 3 次後， button 顯示 3，然後：
&lt;ol&gt;
&lt;li&gt; 按下 HOME 後再重新啟動：一樣是 3&lt;/li&gt;
&lt;li&gt; 按下 BACK 後再重新啟動：顯示 0 (被 reset)&lt;/li&gt;
&lt;/ol&gt;
所以 HOME key 並不會destroy app... back 才會。&lt;br&gt;
&lt;br&gt;
實際上， HOME 沒有 destroy app 的說法不一定成立。&lt;br&gt;
.. 到 development setting，設定 "immediately destroy activity"&lt;br&gt;
這樣按 HOME key 每次都會 destroy app..&lt;br&gt;
&lt;br&gt;
看 logcat message... enable "immediately destroy activity" 時，&lt;br&gt;
按下 HOME key 的行為就像按下 BACK 一樣 (對單一 activity 的 app 而言)。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7863337146694722431?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7863337146694722431/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7863337146694722431' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7863337146694722431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7863337146694722431'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/test-android-app-state.html' title='test android app state'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-241798685166790759</id><published>2011-12-14T11:23:00.002+08:00</published><updated>2011-12-14T11:23:37.200+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android app, input</title><content type='html'>android 的每個 app 好像都是一個包含完整的 framework 程式。&lt;br&gt;
舉例來說：&lt;br&gt;
framework 的 keyinput 機制，包含在每個 app 中。&lt;br&gt;
所以當按下 HOME 鍵，會因為 app 中的 input framework 會收到 KEYCODE_HOME。&lt;br&gt;
&lt;br&gt;
因為 framework 的 input framwework 有處理 HOME key，並且寫好了對 KEYCODE_HOME 的動作： sent intent to HOME。&lt;br&gt;
所以會叫起 Launcher。&lt;br&gt;
....&lt;br&gt;
也就是說，按HOME 鍵，其實是 app 處理 (並沒有一個 處理 home key 的 server process)。
app 裡的 input framework code ，叫起 HOME launcher。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-241798685166790759?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/241798685166790759/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=241798685166790759' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/241798685166790759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/241798685166790759'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/android-app-input.html' title='android app, input'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2710624599176161803</id><published>2011-12-14T10:55:00.002+08:00</published><updated>2011-12-14T10:55:28.077+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>create button without using xml</title><content type='html'>完全寫在 code 裡的方法， layout 和 button 都不用 xml 定義。&lt;br&gt;
from : &lt;a href="http://toimy.blogspot.com/2010/07/android.html"&gt;http://toimy.blogspot.com/2010/07/android.html&lt;/a&gt; &lt;br&gt;
&lt;code&gt;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.view.View;

public class testAndroidActivity extends Activity implements View.OnClickListener
{
    final String TAG = "testAndroid";
    LinearLayout layout;
    Button btn;

    public void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);

        layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        btn = new Button(this);
        btn.setText("Button");
        btn.setOnClickListener(this);
        layout.addView(btn,150,50);

        setContentView(layout);
    }

    public void onClick(View v) {
            Log.v(TAG, "onClick");
    }
..
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2710624599176161803?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2710624599176161803/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2710624599176161803' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2710624599176161803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2710624599176161803'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/create-button-without-using-xml.html' title='create button without using xml'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6744770613479715751</id><published>2011-12-13T17:29:00.002+08:00</published><updated>2011-12-13T17:29:59.909+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>create android project from command line</title><content type='html'>就是 follow 這一篇： &lt;a href="http://developer.android.com/guide/developing/projects/projects-cmdline.html"&gt;http://developer.android.com/guide/developing/projects/projects-cmdline.html&lt;/a&gt;&lt;br&gt;
用 android sdk 提供的 tool : android，來 create project ，&lt;br&gt;
也就是說，幫你把 一堆 xml, java, folder 都create 好，然後填一些基本的東西。&lt;br&gt;
&lt;br&gt;
command example:
&lt;code&gt;android create project \
--target 1 \
--name MyAndroidApp \
--path ./MyAndroidAppProject \
--activity MyAndroidAppActivity \
--package com.example.myandroid
&lt;/code&gt;
target 的內容可以用 command:
&lt;code&gt;android list targets
----------
id: 1 or "android-3"
     Name: Android 1.5
     Type: Platform
     API level: 3
     Revision: 4
     Skins: HVGA-L, QVGA-L, HVGA-P, QVGA-P, HVGA (default)
     ABIs : armeabi
----------
id: 2 or "Google Inc.:Google APIs:3"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 3
     Description: Android + Google APIs
     Based on Android 1.5 (API level 3)
     Libraries:
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: QVGA-P, HVGA (default), HVGA-L, QVGA-L, HVGA-P
     ABIs : armeabi
----------
id: 3 or "android-4"
     Name: Android 1.6
     Type: Platform
     API level: 4
     Revision: 3
     Skins: WVGA800 (default), QVGA, HVGA, WVGA854
     ABIs : armeabi
&lt;/code&gt;
path 選項，如果 path 不存在，就會幫你create。&lt;br&gt;
這樣做完後，follow &lt;a href="http://r40eubuntu.blogspot.com/2011/11/google-android-build-build-apk-httpwww.html"&gt;上一篇&lt;/a&gt;，加上 Android.mk ，就可以 build 了。&lt;br&gt;
&lt;br&gt;
.. 會出現 error:
&lt;code&gt;Android make apk error:This attribute must be localized.&lt;/code&gt;
參考這一篇：&lt;a href="http://jjnnykimo.pixnet.net/blog/post/31996155-android-make-apk-error%3Athis-attribute-must-be-localized."&gt;http://jjnnykimo.pixnet.net/blog/post/31996155-android-make-apk-error%3Athis-attribute-must-be-localized.&lt;/a&gt;&lt;br&gt;
把原來寫死的 layout/main.xml 字串，改在 value/string.xml 中，就可以了。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6744770613479715751?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6744770613479715751/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6744770613479715751' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6744770613479715751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6744770613479715751'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/create-android-project-from-command.html' title='create android project from command line'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5638349268631947787</id><published>2011-12-08T09:50:00.001+08:00</published><updated>2011-12-08T09:57:54.771+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>some tools from SE released source</title><content type='html'>&lt;a href="http://developer.sonyericsson.com/wportal/devworld/search-downloads/opensource/android?cc=gb&amp;lc=en"&gt;Sony-Ericson release 的 source code&lt;/a&gt;有一些東西：
&lt;ol&gt;
&lt;li&gt;kexec-tools : running system 抽換 kernel 的 tool , (當然 kernel 要有 enable kexec 才行)&lt;/li&gt;
&lt;li&gt;inputattach : 把新的 serial input device 加到 kernel 的 input system 中 (例如搖桿)&lt;/li&gt;
&lt;/ol&gt;
可惜一般的 android kernel 不會 enable KEXEC。所以要用 1 的話，可能要重 build kernel。&lt;br&gt;
2 的話，可能可以用在bluetooth 搖桿上...&lt;br&gt;
bt 搖桿 --&gt; serial 裝置 --&gt; attach 到 kernel input interface&lt;br&gt;
&lt;br&gt;
這樣就可以直接 support 利用 kernel input interface 操縱的 ap/system  (android support ?)&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5638349268631947787?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5638349268631947787/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5638349268631947787' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5638349268631947787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5638349268631947787'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/some-tools-from-se-released-source.html' title='some tools from SE released source'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6663773894210010895</id><published>2011-12-07T16:45:00.001+08:00</published><updated>2011-12-07T17:24:18.072+08:00</updated><title type='text'></title><content type='html'>init/main.c 的 start_kernel : setup_arch(&amp;command_line)&lt;br&gt;
kernel/setup.c 的 __init setup_arch(char **cmdline_p)&lt;br&gt;
&lt;pre&gt;  有加 _init，會不會後來又再 run 一次? &lt;/pre&gt;
code:
&lt;code&gt;        struct tag *tags = (struct tag *)&amp;init_tags;
        struct machine_desc *mdesc;
        char *from = default_command_line;

        mdesc = setup_machine(machine_arch_type);
        machine_name = mdesc-&gt;name;

        if (mdesc-&gt;soft_reboot)
                reboot_setup("s");

        if (__atags_pointer)
                tags = phys_to_virt(__atags_pointer);
        else if (mdesc-&gt;boot_params)
                tags = phys_to_virt(mdesc-&gt;boot_params);
        else
                init_tags.mem.start = PHYS_OFFSET;
&lt;/code&gt;
__atags_pointer 是 uboot 傳遞參數的位址，boot_params 也是。&lt;br&gt;
&lt;br&gt;
這裡的 boot loader 好像都沒有用，所以是用 PHYS_OFFSET。&lt;br&gt;
這個 constant 每個 chip 定義不一樣。&lt;br&gt;
&lt;br&gt;
&lt;code&gt;/arch/arm/plat-mxc/include/mach/memory.h:17:#define MX1_PHYS_OFFSET  UL(0x08000000)
./arch/arm/plat-mxc/include/mach/memory.h:18:#define MX21_PHYS_OFFSET UL(0xc0000000)
./arch/arm/plat-mxc/include/mach/memory.h:19:#define MX25_PHYS_OFFSET UL(0x80000000)
./arch/arm/plat-mxc/include/mach/memory.h:20:#define MX27_PHYS_OFFSET UL(0xa0000000)
./arch/arm/plat-mxc/include/mach/memory.h:21:#define MX3x_PHYS_OFFSET UL(0x80000000)
./arch/arm/plat-mxc/include/mach/memory.h:22:#define MX37_PHYS_OFFSET UL(0x40000000)
./arch/arm/plat-mxc/include/mach/memory.h:23:#define MX50_PHYS_OFFSET UL(0x70000000)
./arch/arm/plat-mxc/include/mach/memory.h:24:#define MX51_PHYS_OFFSET UL(0x90000000)
./arch/arm/plat-mxc/include/mach/memory.h:25:#define MX53_PHYS_OFFSET UL(0x70000000)
./arch/arm/plat-mxc/include/mach/memory.h:26:#define MXC91231_PHYS_OFFSET UL(0x90000000)
&lt;/code&gt;
所以是 MX51 是 0x90000000 &lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6663773894210010895?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6663773894210010895/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6663773894210010895' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6663773894210010895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6663773894210010895'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/initmain.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5025368572968995142</id><published>2011-12-07T09:38:00.001+08:00</published><updated>2011-12-07T16:09:52.939+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>property_set/get in android</title><content type='html'>android 的 property 系統也是一種 IPC 的方法 (用在跟 system 溝通上).&lt;br&gt;
一般 c program 可以用 property_set, property_get 來設定/取得 property 值。&lt;br&gt;
&lt;br&gt;
property related function  實做在 system/core/libcutils/propertied.c&lt;br&gt;
基本上就是用 local socket 跟 PROP_SERVICE_NAME 溝通。&lt;br&gt;
&lt;br&gt;
property service 好像是在 init 就啟動了..
&lt;code&gt;void start_property_service(void)
{
    int fd;

    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();

    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
    if(fd &lt; 0) return;
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    fcntl(fd, F_SETFL, O_NONBLOCK);

    listen(fd, 8);
    property_set_fd = fd;
}
&lt;/code&gt;
core/init 這個 process 最後，好像就是在做 property_service.. main() 的最後：
&lt;code&gt;
  for(;;) {
    ...
    ...

        nr = poll(ufds, fd_count, timeout);
        if (nr &lt;= 0)
            continue;

        for (i = 0; i &lt; fd_count; i++) {
            if (ufds[i].revents == POLLIN) {
                if (ufds[i].fd == get_property_set_fd())
                    handle_property_set_fd();
                else if (ufds[i].fd == get_keychord_fd())
                    handle_keychord();
                else if (ufds[i].fd == get_signal_fd())
                    handle_signal();
            }
        }
  }
&lt;/code&gt;
ufds 就是剛剛 create_socket(PROP_SERVICE_NAME...) 的 fd&lt;br&gt;
&lt;br&gt;
這個 source file : core/init/property_service.c 有所有 property 的操作。&lt;br&gt;
&lt;br&gt;
像:&lt;br&gt;
persistant property value (以 persistant. 開頭的 property)存放方式，位置:
&lt;code&gt;#define PERSISTENT_PROPERTY_DIR  "/data/property"&lt;/code&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5025368572968995142?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5025368572968995142/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5025368572968995142' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5025368572968995142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5025368572968995142'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/android-property-ipc-system.html' title='property_set/get in android'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4316309418362193125</id><published>2011-12-05T11:27:00.001+08:00</published><updated>2011-12-05T11:35:54.376+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>"adb server is out of date. killing"</title><content type='html'>啟動 adb 時，會出現："adb server is out of date. killing"。&lt;br&gt;
因為 adb server 被重啟動，所以沒有辦法建立兩個連線。&lt;br&gt;
&lt;br&gt;
查這段 message "adb server is out of date. killing"，是在
&lt;code&gt;./system/core/adb/adb_client.c:251:            printf("adb server is out of date.  killing...\n");&lt;/code&gt;
是 compare version:
&lt;code&gt;int adb_connect(const char *service)
{
    // first query the adb server's version
    int fd = _adb_connect("host:version");
    ....

        char buf[100];
        int n;
        int version = ADB_SERVER_VERSION - 1;

        // if we have a file descriptor, then parse version result
            if(readx(fd, buf, 4)) goto error;

            buf[4] = 0;
            n = strtoul(buf, 0, 16);
            if(readx(fd, buf, n)) goto error;
            adb_close(fd);

            if (sscanf(buf, "%04x", &amp;version) != 1) goto error;
        } else {
        ........
        }
        ....
        if(version != ADB_SERVER_VERSION) {
            printf("adb server is out of date.  killing...\n");
&lt;/code&gt;
就是去詢問 host adb server 的版本，然後和自己比較。&lt;br&gt;
不一樣就 print msg &amp; restart&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
就在我加上　debug message (print out version)，重新 run 後，就 OK 了 &lt;br&gt;
===&gt; 所以說，我 pc 上的 adb 版本太舊了...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4316309418362193125?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4316309418362193125/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4316309418362193125' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4316309418362193125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4316309418362193125'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/12/adb-server-is-out-of-date-killing.html' title='&quot;adb server is out of date. killing&quot;'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2609901796943931280</id><published>2011-11-28T16:58:00.001+08:00</published><updated>2011-11-29T10:42:48.325+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>libusb-1.0.0.8 for android</title><content type='html'>就 這篇 &lt;a href="http://android.serverbox.ch/?p=151"&gt;http://android.serverbox.ch/?p=151&lt;/a&gt; 和 &lt;a href="http://my0613.blogspot.com/2010/11/porting-lsusb-libusb-on-android.html"&gt;http://my0613.blogspot.com/2010/11/porting-lsusb-libusb-on-android.html&lt;/a&gt; 分別是 libusb 和 lsusb。&lt;br&gt;
&lt;br&gt;
porting lib 還是和以前一樣，要先run ./configure. 產生 config.h，然後再自己改成 for android 的配置。&lt;br&gt;
&lt;br&gt;然後加入 Android.mk (兩個)&lt;br&gt;
&lt;br&gt;再修改一下 build error 的 file&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
我的 config.h:
&lt;code&gt;/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Default visibility */
#define API_EXPORTED __attribute__((visibility("default")))

/* Debug message logging */
/* #undef ENABLE_DEBUG_LOGGING */

/* Message logging */
#define ENABLE_LOGGING 1

/* Define to 1 if you have the &lt;dlfcn.h&gt; header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the &lt;inttypes.h&gt; header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `rt' library (-lrt). */
#define HAVE_LIBRT 1

/* Define to 1 if you have the &lt;memory.h&gt; header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the &lt;stdint.h&gt; header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the &lt;stdlib.h&gt; header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the &lt;strings.h&gt; header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the &lt;string.h&gt; header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the &lt;sys/stat.h&gt; header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the &lt;sys/types.h&gt; header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the &lt;unistd.h&gt; header file. */
#define HAVE_UNISTD_H 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"

/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */

/* Darwin backend */
/* #undef OS_DARWIN */

/* Linux backend */
#define OS_LINUX /**/

/* Name of package */
#define PACKAGE "libusb"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Define to the full name of this package. */
#define PACKAGE_NAME "libusb"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libusb 1.0.8"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libusb"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.8"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Backend handles timeout */
/* #undef USBI_OS_HANDLES_TIMEOUT */

/* timerfd headers available */
/* #undef USBI_TIMERFD_AVAILABLE */

/* Version number of package */

#define VERSION "1.0.8"

/* Use GNU extensions */
#define _GNU_SOURCE /**/

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
/* #undef inline */
#endif
                                                                                                                                                                              &lt;/code&gt;&lt;br&gt;
我的 external/libusb-1.0.0.8/Android.mk:
&lt;code&gt;LOCAL_PATH := $(call my-dir)
subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
                libusb \
                examples \
                ))
include $(subdirs)
&lt;/code&gt;&lt;br&gt;
我的 external/libusb-1.0.0.8/libusb/Android.mk
&lt;code&gt;LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS:= tests
LOCAL_PRELINK_MODULE:= false

LOCAL_SRC_FILES:= \
 core.c \
 descriptor.c \
 io.c \
 sync.c \
 os/linux_usbfs.c

LOCAL_C_INCLUDES += \
 external/libusb-1.0.8/ \
 external/libusb-1.0.8/libusb/ \
 external/libusb-1.0.8/libusb/os

LOCAL_MODULE:= libusb
include $(BUILD_SHARED_LIBRARY)
&lt;/code&gt;&lt;br&gt;
我的 external/libusb-1.0.0.8/example/Android.mk
&lt;code&gt;LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := lsusb.c
LOCAL_MODULE := lsusb
LOCAL_C_INCLUDES += external/libusb-1.0.8/
LOCAL_SHARED_LIBRARIES := libc libusb
include $(BUILD_EXECUTABLE)
&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;download libusb-1.0.0.8, unzip to external (result in a external/libusb-1.0.0.8)&lt;/li&gt;
&lt;li&gt;run ./configure -disable-timerfd&lt;/li&gt;
&lt;li&gt;modify libusb/io.c&lt;br&gt;加上&lt;code&gt;#define TIMESPEC_TO_TIMEVAL(tv, ts)                                     \
        do {                                                            \
                (tv)-&gt;tv_sec = (ts)-&gt;tv_sec;                            \
                (tv)-&gt;tv_usec = (ts)-&gt;tv_nsec / 1000;                   \
        } while (0)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;add 3 Android.mk files&lt;/li&gt;
&lt;/ol&gt;
OK to build, mm&lt;br&gt; sync to target, run
&lt;code&gt;bash-3.2# lsusb
1d6b:0002 (bus 1, device 1)
1d6b:0002 (bus 2, device 1)
0424:2517 (bus 2, device 2)
0a12:0001 (bus 2, device 3)
13fe:1d00 (bus 2, device 4)
&lt;/code&gt;
&lt;br&gt;不用 mount usbfs /proc/bus/usbfs 就可以動作(?)&lt;br&gt;
&lt;br&gt;
查 libusb/os/linux_usbfs.c :
&lt;code&gt;static const char *find_usbfs_path(void)
{
        const char *path = "/dev/bus/usb";
        const char *ret = NULL;

        if (check_usb_vfs(path)) {
                ret = path;
        } else {
                path = "/proc/bus/usb";
                if (check_usb_vfs(path))
                        ret = path;
        }

        usbi_dbg("found usbfs at %s", ret);
        return ret;
}
&lt;/code&gt;
用的是 /dev/bus/usb&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
2008  這篇 &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=483392"&gt;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=483392&lt;/a&gt;  有說不要再 mount /proc/bus/usbfs，請直接用 /dev/bus/usb..&lt;br&gt;
&lt;br&gt;
但是到現在好像還很多人在用...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2609901796943931280?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2609901796943931280/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2609901796943931280' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2609901796943931280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2609901796943931280'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/libusb-1008-for-android.html' title='libusb-1.0.0.8 for android'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7653105922052814772</id><published>2011-11-24T14:27:00.001+08:00</published><updated>2012-02-06T17:08:50.182+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Keyboard shortcut (Hotkey) in Android</title><content type='html'>Android 有 keyboard shortcut 功能，就是自己定義按著 Search 時，同時按下某個 key 就 啟動 XX app (可以自訂)。&lt;br&gt;
&lt;br&gt;
但是要在有 keyboard 的 機器 上那個設定畫面才會出現。&lt;br&gt;
&lt;br&gt;
這個功能一樣做在 PhoneWindowManager.java 的 interceptKeyBeforeDispatching&lt;br&gt;
在 HOME, MENU, CALL,, 等等 KEYCODE 的判斷後面...
&lt;br&gt;
&lt;code&gt;        // Shortcuts are invoked through Search+key, so intercept those here
        if (mSearchKeyPressed) {
            if (down &amp;&amp; repeatCount == 0 &amp;&amp; !keyguardOn) {
                Intent shortcutIntent = mShortcutManager.getIntent(keyCode, metaState);
                if (shortcutIntent != null) {
                    shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    mContext.startActivity(shortcutIntent);

                    /*
                     * We launched an app, so the up-event of the search key
                     * should be consumed
                     */
                    mConsumeSearchKeyUp = true;
                    return true;
                }
            }
        }
&lt;/code&gt;
一樣用 startActivity( ) 叫起 app (intent)，那個 對應哪個 key，都在ShorcutManager 的 database (bookmark) 中紀錄。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
Setting 部份的 source code 在
&lt;code&gt;src/com/android/settings/ApplicationSettings.java&lt;/code&gt;&lt;br&gt;
如果沒有 physical keyboard，就移除這個 Setting:
&lt;code&gt;        if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_NOKEYS) {
            // No hard keyboard, remove the setting for quick launch
            Preference quickLaunchSetting = findPreference(KEY_QUICK_LAUNCH);
            getPreferenceScreen().removePreference(quickLaunchSetting);
        }
&lt;/code&gt;
&lt;br&gt;
實際設定的 class 是 quicklaunch&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
如果要作假...&lt;br&gt;
以叫起 browser (S-B) 為例..,
&lt;ol&gt;
&lt;li&gt;送出一個 SEARCH KEY Down : 217, down&lt;/li&gt;
&lt;li&gt;送出一個 b Key down, up : 48, down,up&lt;/li&gt;
&lt;li&gt;這時候就可以看到 browser 已經被叫起來了&lt;/li&gt;
&lt;li&gt;送出一個 SEARCH KEY Up : 217 up&lt;/li&gt;
&lt;/ol&gt;
keycode 定義可以看 ./include/linux/input.h&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
自己紀錄一下，就是：
&lt;ol&gt;
&lt;li&gt; echo D217 &amp;gt; vmevent&lt;/li&gt;
&lt;li&gt; echo 48 &amp;gt; vmevent  -- 可以看到 browser 起來了&lt;/li&gt;
&lt;li&gt; echo U217 &amp;gt; vmevent&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7653105922052814772?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7653105922052814772/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7653105922052814772' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7653105922052814772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7653105922052814772'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/keyboard-shortcut-hotkey-in-android.html' title='Keyboard shortcut (Hotkey) in Android'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-337020851078332960</id><published>2011-11-24T13:07:00.001+08:00</published><updated>2011-11-24T14:00:49.570+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>HOTKEY to launch HOME launcher</title><content type='html'>收到 KEYCODE_HOME 後：
&lt;code&gt;
launchHomeFromHotKey();
&lt;/code&gt;
&lt;br&gt;
launchHomeFromHotKey 中 laucn Home 的 code:
&lt;code&gt;            try {
                ActivityManagerNative.getDefault().stopAppSwitches();
            } catch (RemoteException e) {
            }
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
            startDockOrHome();
&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;stopAppSwitches()&lt;/li&gt;
&lt;li&gt;sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY)&lt;/li&gt;
&lt;li&gt;startDockOrHome()&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
stopAppSwitches():&lt;br&gt;
&lt;br&gt;
好像是停止 app switch 5 sec.
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY):&lt;br&gt;
&lt;br&gt;
是 call :
&lt;code&gt;                ActivityManagerNative.getDefault().closeSystemDialogs(reason);
&lt;/code&gt;
就是把 windws map 叫出來，一個一個 send message:
&lt;code&gt;        Message msg = Message.obtain();
        msg.what = CLOSE_SYSTEM_DIALOGS;
        msg.obj = reason;
        sendMessage(msg);
&lt;/code&gt;
&lt;hr&gt;
&lt;br&gt;
startDockOrHome:&lt;br&gt;
&lt;code&gt;
        mHomeIntent =  new Intent(Intent.ACTION_MAIN, null);
        mHomeIntent.addCategory(Intent.CATEGORY_HOME);
        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        ........
        startActivity(mHomeIntent)
&lt;/code&gt;
&lt;br&gt;&lt;br&gt;... framework 自己也用 startActivity...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-337020851078332960?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/337020851078332960/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=337020851078332960' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/337020851078332960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/337020851078332960'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/keycodehome-launchhomefromhotkey.html' title='HOTKEY to launch HOME launcher'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1058399545533760663</id><published>2011-11-24T10:35:00.001+08:00</published><updated>2011-11-24T11:23:00.745+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Add app project in android build system</title><content type='html'>google 的說明文件有 如何用 android 的 build 系統 build apk:&lt;br&gt;
&lt;a href="http://www.kandroid.org/online-pdk/guide/build_cookbook.html"&gt;http://www.kandroid.org/online-pdk/guide/build_cookbook.html&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
copy 一些過來：&lt;br&gt;
&lt;br&gt;
Android system 用 Android.mk，簡單的 apk 可以用：
&lt;code&gt;  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # Build all java files in the java subdirectory
  LOCAL_SRC_FILES := $(call all-subdir-java-files)
   
  # Name of the APK to build
  LOCAL_PACKAGE_NAME := LocalPackage
   
  # Tell it to build an APK
  include $(BUILD_PACKAGE)
&lt;/code&gt;
把這個 Android.mk 放在 app 的 folder 中就可以。&lt;br&gt;
... LocalPackage 就是最後 apk 的 filename&lt;br&gt;
&lt;br&gt;&lt;br&gt;
這一篇是說明把 Eclipse create 的 project folder 搬到 Android root 中 build 的方法：&lt;br&gt;
&lt;a href="http://owenhuangtw.pixnet.net/blog/post/23935524-using-android-bluetoothdevice-class-to-control-blue-deivce"&gt;http://owenhuangtw.pixnet.net/blog/post/23935524-using-android-bluetoothdevice-class-to-control-blue-deivce&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
.. 好像就是把 Android.mk 放進去就可以了 (?)
&lt;br&gt;
&lt;hr&gt;
用 eclipse create 的 project 如果有 build 過，搬到 android root 後，要把 gen, bin 清掉，不然 build 會有 R.jar 的 error。&lt;br&gt;
&lt;br&gt;
其實 developement/sample 下每一個 project 都是 用這個方法。&lt;br&gt;
可以參考&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1058399545533760663?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1058399545533760663/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1058399545533760663' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1058399545533760663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1058399545533760663'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/google-android-build-build-apk-httpwww.html' title='Add app project in android build system'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-464692457968254916</id><published>2011-11-23T10:55:00.001+08:00</published><updated>2011-11-23T14:37:34.424+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>forceStopPackage</title><content type='html'>ActivityManager.java:
&lt;code&gt;    public void forceStopPackage(String packageName) {
        try {
            ActivityManagerNative.getDefault().forceStopPackage(packageName);
        } catch (RemoteException e) {
        }
    }
&lt;/code&gt;
&lt;br&gt;
call 的是ActivivityManagerProxy Implement IActivityManager：
&lt;code&gt;    public void forceStopPackage(String packageName) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeString(packageName);
        mRemote.transact(FORCE_STOP_PACKAGE_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }
&lt;/code&gt;
&lt;br&gt;
mRemote transact 經由 IBinder 傳送 FORCE_STO_PACKAGE_TRANSACTION 需求。&lt;br&gt;
收到並執行的是&lt;br&gt;
在 ActivityManagerNative 的 onTransact():

&lt;code&gt;        case FORCE_STOP_PACKAGE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String packageName = data.readString();
            forceStopPackage(packageName);
            reply.writeNoException();
            return true;
        }
&lt;/code&gt;
&lt;br&gt;
onTransact 的 case handler &lt;br&gt;
呼叫的是ActivityManagerService 的 forceStopPackage(?):
&lt;code&gt;            IPackageManager pm = AppGlobals.getPackageManager();
            int pkgUid = pm.getPackageUid(packageName);
            forceStopPackageLocked(packageName, pkgUid);
&lt;/code&gt;
&lt;br&gt;
就是從 package manager 找出 packageName 的 pid，然後 call forceStopPackageLocked( ) 結束他。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
其中的 forceStopPackageLocked 是：
&lt;code&gt;    private void forceStopPackageLocked(final String packageName, int uid) {
        forceStopPackageLocked(packageName, uid, false, false, true);
        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
                Uri.fromParts("package", packageName, null));
        if (!mProcessesReady) {
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        }
        intent.putExtra(Intent.EXTRA_UID, uid);
        broadcastIntentLocked(null, null, intent,
                null, null, 0, null, null, null,
                false, false, MY_PID, Process.SYSTEM_UID);
    }
&lt;/code&gt;

就是call forceStopPackageLocked( ) 結束他，然後再 broadcast ACTION_PACKAGE_RESTARTED.. (叫他再起來?)&lt;br&gt;
&lt;br&gt;
&lt;code&gt;            Iterator&amp;lt;SparseArray&amp;lt;Long&amp;gt;&amp;gt; badApps = mProcessCrashTimes.getMap().values().iterator();
            while (badApps.hasNext()) {
                SparseArray&lt;Long&gt; ba = badApps.next();
                if (ba.get(uid) != null) {
                    badApps.remove();
                }
            }
&lt;/code&gt;
把 mProcessCrashTime (上次system crash 時的 proces map) 中，同 uid 的 process data 從 record map 中移除。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;code&gt;        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
                callerWillRestart, doit);
&lt;/code&gt;
然後 killPackageProcessLocked( ).&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;code&gt;        for (i=mMainStack.mHistory.size()-1; i&gt;=0; i--) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
            if (r.packageName.equals(name)) {
                if (!doit) {
                    return true;
                }
                didSomething = true;
                Slog.i(TAG, "  Force finishing activity " + r);
                if (r.app != null) {
                    r.app.removed = true;
                }
                r.app = null;
                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
            }
        }
&lt;/code&gt;
然後再從 目前系統 activiry stack (所有執行過的 activity) 中，找出符合name 的package，作 RESULT_CANCELED 的 finishActivityLocked( )。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
後面看起來會把 activity stack 中 下一個 activity resume 回來 (到 top)。&lt;br&gt;
&lt;br&gt;
如果 stack 是空的，就 launch home launcher&lt;br&gt;
trace code 的其中一點，最後是用 kill 把 process 殺掉。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-464692457968254916?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/464692457968254916/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=464692457968254916' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/464692457968254916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/464692457968254916'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/forcestoppackage.html' title='forceStopPackage'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8971203202992917419</id><published>2011-11-17T17:16:00.001+08:00</published><updated>2011-11-18T14:09:00.983+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Keypad action in Android Framework</title><content type='html'>keyboard input (包含 home, power, menu, back..etc) 的動作是在 framework/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java&lt;br&gt;
&lt;br&gt;
&lt;code&gt;    public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
            int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags) {
&lt;/code&gt;
可以看到這個 function 根據狀況決定HOME key 要不要處理。&lt;br&gt;
同時還處理 SEARCH , MENU。&lt;br&gt;
&lt;br&gt;
所有的 keyevent，會先進到這裡，再到其他地方。&lt;br&gt;
&lt;br&gt;
經過這個篩選後，key 會到 framwork/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java &lt;br&gt;
&lt;ol&gt;
&lt;li&gt;  protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) &lt;/li&gt;
&lt;li&gt;  protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) &lt;/li&gt;
&lt;/ol&gt;
keydown 是主要作動作的地方，keyup 只是detect longpress 的 cancel。&lt;br&gt;
像 KEYCODE_CAMERA 就會執行下面的code:
&lt;code&gt;                    sendCloseSystemWindows();
                    // Broadcast an intent that the Camera button was longpressed
                    Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
                    intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
                    getContext().sendOrderedBroadcast(intent, null);
&lt;/code&gt;
.. close current window &amp; launch CAMERA app&lt;br&gt;
&lt;br&gt;
在這裡處理的還有：
&lt;ol&gt;
&lt;li&gt;KEYCODE_VOLUME_UP/DOWN&lt;/li&gt;
&lt;li&gt;KEYCODE_MEDIA_PLAY_PAUSE&lt;/li&gt;
&lt;li&gt;KEYCODE_MUTE:KEYCODE_HEADSETHOOK.KEYCODE_MEDIA_STOP:KEYCODE_MEDIA_NEXT:KEYCODE_MEDIA_PREVIOUS:KEYCODE_MEDIA_REWIND:KEYCODE_MEDIA_FAST_FORWARD:&lt;/li&gt;
&lt;li&gt;KEYCODE_MENU&lt;/li&gt;
&lt;li&gt;KEYCODE_BACK&lt;/li&gt;
&lt;li&gt;KEYCODE_CALL&lt;/li&gt;
&lt;li&gt;KEYCODE_SEARCH&lt;/li&gt;
&lt;/ol&gt;
所以有 自己新增的 button 要作到 HOT-KEY 功能的，都可以作到這裡。&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8971203202992917419?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8971203202992917419/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8971203202992917419' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8971203202992917419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8971203202992917419'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/keyboard-input-home-power-menu-back.html' title='Keypad action in Android Framework'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8857708251304521639</id><published>2011-11-14T11:07:00.001+08:00</published><updated>2011-11-14T11:15:43.715+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='Info'/><title type='text'>Matthew Garrett 解決 2.6.38 開始，耗電增加 30% 的問題：ASPM</title><content type='html'>&lt;a href="http://www.phoronix.com/scan.php?page=article&amp;amp;item=linux_aspm_solution"&gt;http://www.phoronix.com/scan.php?page=article&amp;amp;item=linux_aspm_solution&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
這篇說明 linux kernel 從 2.6.37 進到 2.6. 38 後，耗電增加 30% 的問題。&lt;br&gt;
因為 38 開始依照 bios 回報的內容，開啟/關閉對 PCIe 裝置的電源管理功能...&lt;br&gt;
...&lt;br&gt;
結果...&lt;br&gt;
.. 一堆裝置都回報他門沒有電源管理功能...&lt;br&gt;
.. 所以 kernel 就不管他門了...就放著耗電...&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
後來 Matthew Garrett 參考 Windows Vista，發現 windows 都還是有管耶。&lt;br&gt;
然後就 follow hardware 的 window driver inf 檔，決定要不要管。 (而不是依照 hardware 的回報)。&lt;br&gt;
&lt;br&gt;
就這樣...&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
... 就說...照 datasheet 寫code的是笨蛋.. (一定會被騙...)&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8857708251304521639?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8857708251304521639/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8857708251304521639' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8857708251304521639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8857708251304521639'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/matthew-garrett-2638-30-aspm.html' title='Matthew Garrett 解決 2.6.38 開始，耗電增加 30% 的問題：ASPM'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-3813366512347614457</id><published>2011-11-14T10:38:00.001+08:00</published><updated>2011-11-14T10:42:20.262+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iMX51'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>imx51 : SION bit in GPIO config</title><content type='html'>&lt;a href="http://imxcommunity.org/forum/topics/how-to-use-the-sion-bit"&gt;http://imxcommunity.org/forum/topics/how-to-use-the-sion-bit&lt;/a&gt;&lt;br /&gt;
說明. GPIO 的 SION bit 就是把 gpio 的 pad 接到 input 端 -- 不管是configure 成　output 還是 input。&lt;br&gt;
&lt;br&gt;
說明是以 SD_CMD 為範例。&lt;br&gt;
CMD 是雙向 ，output 完馬上就改 input， read ack。&lt;br&gt;
所以要把 CMD pin 的 SION bit 打開&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-3813366512347614457?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/3813366512347614457/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=3813366512347614457' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3813366512347614457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3813366512347614457'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/imx51-sion-bit-in-gpio-config.html' title='imx51 : SION bit in GPIO config'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1326146805863261313</id><published>2011-11-11T13:29:00.001+08:00</published><updated>2011-11-11T13:57:51.048+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>android, bionic , overview &amp; test program</title><content type='html'>android 的 bionic 沒有 support pthread_cancel。&lt;br /&gt;
&amp;nbsp;-- 其實還有很多不 support 的，說明在 libc/doc/overview.txt.&lt;br /&gt;
&lt;br /&gt;
另外 android 也提供 bionic libc test code，在&lt;br /&gt;
&lt;code&gt; /system/extras/tests/bionic/libc&lt;/code&gt;&lt;br /&gt;
一般是不會 build 進 system。&lt;br /&gt;
&lt;br /&gt;
可以用&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; cd system/extras/tests/bionic/libc&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mm BIONIC_TESTS=1&lt;/code&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;這一篇有很好的說明：&lt;a href="http://codingrelic.geekhold.com/2008/11/six-million-dollar-libc.html"&gt;http://codingrelic.geekhold.com/2008/11/six-million-dollar-libc.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;這一篇遇到pthread_cancel 不 support ，他workaround 又遇到Dalvik 共用..之後的解決方法： &lt;a href="http://blogs.mentor.com/hollisblanchard/blog/tag/android/%20"&gt;http://blogs.mentor.com/hollisblanchard/blog/tag/android/ &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1326146805863261313?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1326146805863261313/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1326146805863261313' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1326146805863261313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1326146805863261313'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/android-bionic-overview-test-program.html' title='android, bionic , overview &amp; test program'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2670503465236093983</id><published>2011-11-10T14:42:00.000+08:00</published><updated>2011-11-10T19:05:23.171+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>ADV7180 detect the video signal discontinue</title><content type='html'>ADV7180 的 STATUS 3 :
&lt;ul&gt;
&lt;li&gt; bit 4 FREE_RUN_ACT : 沒偵測到signal，所以 output blue screen 中&lt;/li&gt;
&lt;li&gt; bit 5 STD FLD LEN : 使用目前的 standard 解 video frame 得到的 Field Length 是正確的&lt;/li&gt;
&lt;li&gt; bit 6 Interlaced : 偵測到 interlaced frame&lt;/li&gt;
&lt;/ul&gt;
有些low-end, ill-designed, 亂寫code的 video output device，輸出不太正確的 video signal，會導致 application processor 的 camera input module 錯誤。&lt;br&gt;
可以利用這幾個 bit 來偵測。&lt;br&gt;
&lt;br&gt;
當 4 出現代表目前沒信號。&lt;br&gt;
當 5 沒出現，代表 scan line 有錯&lt;br&gt;
當 6 沒出現，代表 沒有偵測到 interlaced frame&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
但是要用這個 register 有一個限制，要在每一個 frame 都讀一次，否則會被新的 frame 狀態 update ，就抓不到 frame lost 的瞬間了...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2670503465236093983?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2670503465236093983/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2670503465236093983' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2670503465236093983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2670503465236093983'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/adv7180-status-3-bit-4-freerunact.html' title='ADV7180 detect the video signal discontinue'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7247109776755619499</id><published>2011-11-09T14:34:00.000+08:00</published><updated>2011-11-09T14:44:42.440+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='ker'/><title type='text'>dynamic_debug in kernel</title><content type='html'>kernel 裡面有很多 pr_debug，這是被合 dynamic_debug 這個功能的 printk function。&lt;br&gt;
在 Documentation/dynamic-debug-howto.txt 有說明。&lt;br&gt;
&lt;br&gt;
大概就是：
&lt;ol&gt;
&lt;li&gt; menuconfig 圈選 dynamic_debug&lt;code&gt;CONFIG_DYNAMIC_DEBUG=y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt; 系統啟動後，手動 mount debugfs  : &lt;code&gt;#mkdir /mnt/debugfs
#mount -t debugfs none /mnt/debugfs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;把 /mnt/debugfs/dynamic_debug/control 打開來看..&lt;/li&gt;
&lt;li&gt;control 會列出所有 pr_debug 所在的source file 和位置，用 echo ... 可以把該 pr_debug 打開或關閉&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;br&gt;
control 檔的內容大概是:
&lt;code&gt;...
drivers/i2c/busses/mxc_i2c_hs.c:154 [mxc_i2c_hs]mxci2c_hs_bus_busy - "%s: Bus Busy!\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:264 [mxc_v4l2_capture]mxc_free_frames - "In MVC:mxc_free_frames\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:413 [mxc_v4l2_capture]mxc_streamoff - "In MVC:mxc_streamoff\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2825 [mxc_v4l2_capture]camera_init - "In MVC:camera_init\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:574 [mxc_v4l2_capture]start_preview - "MVC: start_preview\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:592 [mxc_v4l2_capture]start_preview - "End of %s: v2f pix widthxheight %d x %d\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:595 [mxc_v4l2_capture]start_preview - "End of %s: crop_bounds widthxheight %d x %d\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:598 [mxc_v4l2_capture]start_preview - "End of %s: crop_defrect widthxheight %d x %d\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:601 [mxc_v4l2_capture]start_preview - "End of %s: crop_current widthxheight %d x %d\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:617 [mxc_v4l2_capture]stop_preview - "MVC: stop preview\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:335 [mxc_v4l2_capture]mxc_streamon - "In MVC:mxc_streamon\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2714 [mxc_v4l2_capture]mxc_v4l2_resume p "In MVC:mxc_v4l2_resume\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2681 [mxc_v4l2_capture]mxc_v4l2_suspend - "In MVC:mxc_v4l2_suspend\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2812 [mxc_v4l2_capture]mxc_v4l2_master_detach - "In MVC:mxc_v4l2_master_detach\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2756 [mxc_v4l2_capture]mxc_v4l2_master_attach - "In MVC: mxc_v4l2_master_attach\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2757 [mxc_v4l2_capture]mxc_v4l2_master_attach - "   slave.name = %s\012"
drivers/media/video/mxc/capture/mxc_v4l2_capture.c:2758 [mxc_v4l2_capture]mxc_v4l2_master_attach - "   master.name = %s\012"
..
&lt;/code&gt;
中間那個 "-" 就代表不印出來，&lt;br&gt;
若是 "p" 就代表要印出來。&lt;br&gt;
&lt;br&gt;
所以要是希望 mxc_v4l2_capture.c 裡所有的 pr_debug 都印出來，可以用：
&lt;code&gt; echo 'file mxc_v4l2_capture.c  +p' &gt; control &lt;/code&gt;
如果不要了，就用：
&lt;code&gt;echo 'file mxc_v4l2_capture.c  -p' &gt; control &lt;/code&gt;
如果只是要第 617 行的 stop preview 印出來，就用：
&lt;code&gt;echo 'file mxc_v4l2_capture.c  line 617 +p' &gt; control  &lt;/code&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt; 雖然是enable print，但是 print level 還是follow 當初source code 寫得，所以有些還是要用 dmesg 才會看得到。&lt;/li&gt;
&lt;li&gt; 可以對 control 使用grep command，不必每次都cat 出來&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7247109776755619499?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7247109776755619499/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7247109776755619499' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7247109776755619499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7247109776755619499'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/kernel-prdebug-dynamicdebug-printk.html' title='dynamic_debug in kernel'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4645098180336337279</id><published>2011-11-04T10:53:00.000+08:00</published><updated>2011-11-04T10:53:06.541+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application'/><category scheme='http://www.blogger.com/atom/ns#' term='Graphic'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='工作的備worklog'/><title type='text'>Lost Lock in a short period</title><content type='html'>在接外部影像信號的時候，常常會發生信號短時間中斷的情況。&lt;br&gt;
例如一些糟糕的 dvr 和 media player，在切換畫面 : 播放 --- 設定 時，會有很短一下的信號中斷現象。&lt;br&gt;
&lt;br&gt;
而一些爛爛的 application processor 的 bt656 input 端，會發生不同步。最後就導致畫面有 scrolling 的現象。&lt;br&gt;
&lt;br&gt;
video converter ADV7180 的 register : status 有一個 bit : LOST_LOCK&lt;br&gt;
可以用來偵測這個現象。&lt;br&gt;
&lt;br&gt;
他的定義是：
&lt;pre&gt;Lost lock (since last read of this register)&lt;/pre&gt;
&lt;br&gt;
有 "Since last read of this register" 很重要。&lt;br&gt;
這樣就不用設定很高的 polling freq，來抓　lost lock 的瞬間了。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
但是有些 dvr 因為畫面切換信號中斷的時間很短，所以 ADV7180 也抓不到。&lt;br&gt;
這個方法就失效了 ....&lt;br&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4645098180336337279?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4645098180336337279/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4645098180336337279' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4645098180336337279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4645098180336337279'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/11/lost-lock-in-short-period.html' title='Lost Lock in a short period'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-3551676842325179318</id><published>2011-10-28T14:04:00.002+08:00</published><updated>2011-10-28T14:04:55.013+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>NetlinkEvent - uevent</title><content type='html'>原來 NetlinkEvent 是在處理 netlink 的 message。&lt;br&gt;
parsing netlink messaag:
&lt;code&gt;bool NetlinkEvent::decode(char *buffer, int size) {
    char *s = buffer;
    char *end;
    int param_idx = 0;
    int i;
    int first = 1;

    end = s + size;
    while (s &lt; end) {
        if (first) {
            char *p;
            for (p = s; *p != '@'; p++);
            p++;
            mPath = strdup(p);
            first = 0;
        } else {
            if (!strncmp(s, "ACTION=", strlen("ACTION="))) {
                char *a = s + strlen("ACTION=");
                if (!strcmp(a, "add"))
                    mAction = NlActionAdd;
                else if (!strcmp(a, "remove"))
                    mAction = NlActionRemove;
                else if (!strcmp(a, "change"))
                    mAction = NlActionChange;
            } else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM=")))
                mSeq = atoi(s + strlen("SEQNUM="));
            else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM=")))
                mSubsystem = strdup(s + strlen("SUBSYSTEM="));
            else
                mParams[param_idx++] = strdup(s);
        }
        s+= strlen(s) + 1;
    }
    return true;
}
&lt;/code&gt;
可以順便知道kobject, uevent 的 message 內容。&lt;br&gt;
在 Documentation/device-mapper/dm-uevent.txt 有例子：
&lt;pre&gt;UEVENT[1192521009.711215] change@/block/dm-3
ACTION=change
DEVPATH=/block/dm-3
SUBSYSTEM=block
DM_TARGET=multipath
DM_ACTION=PATH_FAILED
DM_SEQNUM=1
DM_PATH=8:32
DM_NR_VALID_PATHS=0
DM_NAME=mpath2
DM_UUID=mpath-35333333000002328
MINOR=3
MAJOR=253
SEQNUM=1130
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-3551676842325179318?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/3551676842325179318/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=3551676842325179318' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3551676842325179318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3551676842325179318'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/netlinkevent-uevent.html' title='NetlinkEvent - uevent'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2971589077278563336</id><published>2011-10-27T17:30:00.003+08:00</published><updated>2011-10-27T17:30:58.298+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Run native executable in Android App</title><content type='html'>Gwanline 給的 link:&lt;br&gt;
&lt;a href="http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App"&gt;Run native executable in Android App&lt;/a&gt;&lt;br&gt;
github: &lt;br&gt;
&lt;a href="https://github.com/gimite/android-native-exe-demo"&gt;https://github.com/gimite/android-native-exe-demo&lt;/a&gt; &lt;br&gt;
&lt;br&gt;
基本上是用
&lt;code&gt;            Process process = Runtime.getRuntime().exec(command); &lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2971589077278563336?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2971589077278563336/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2971589077278563336' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2971589077278563336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2971589077278563336'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/run-native-executable-in-android-app.html' title='Run native executable in Android App'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5607501392851525661</id><published>2011-10-27T15:46:00.000+08:00</published><updated>2011-10-27T15:46:44.289+08:00</updated><title type='text'></title><content type='html'>不知道為什麼要用 getBroadcaster( ) ,&lt;br&gt;
現在 所有用到 getBroadcaster 的code，都是拿來 call sendBroadcast( )&lt;br&gt;
&lt;code&gt;
mVm-&gt;getBroadcaster()-&gt;sendBroadcast();
&lt;/code&gt;
那幹麼還做出 getBroadcast( ) 這個 function？&lt;br&gt;
直接 implement 一個 sendBroadcast( ) 像：
&lt;code&gt;
mVm-&gt;sendBroadcast( );
&lt;/code&gt;
不就好？ &lt;br&gt;
&lt;br&gt;
&lt;br&gt;
push_back 是 stl . list 的操作 function，就是 insert。&lt;br&gt;
是 android 的 stl :
&lt;code&gt;/framework/base/include/utils/&lt;/code&gt;
 -- 奇怪，bionic 也有 implement 一份 stl 呀...為什麼要再作一份？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5607501392851525661?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5607501392851525661/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5607501392851525661' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5607501392851525661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5607501392851525661'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/getbroadcaster-getbroadcaster-code-call.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5861174235447380426</id><published>2011-10-26T14:17:00.003+08:00</published><updated>2011-10-26T20:22:34.191+08:00</updated><title type='text'></title><content type='html'>&lt;code&gt;
SocketListener
   |
FrameworkListener
  |
CommandListener
&lt;/code&gt;
Vold, Netd 各自implement 自己的 CommandListener.&lt;br&gt;
filename 還都叫一樣的 CommandListener.cpp,h&lt;br&gt;
但是在不同的 project (bin) ，所以同名沒關係。
&lt;hr&gt;
像 interface 的東西..
&lt;code&gt;
FrameworkCommand
  |
VoldCommand
 |
DumpCmd, VolumeCmd, ShareCmd, AsecCmd, ObbCmd, StorageCmd, XwarpCmd
&lt;/code&gt;
&lt;br&gt;
一樣，從 netd 來看&lt;br&gt;
&lt;code&gt;
FrameworkCommand
  |
NetdCommand
 |
UsbCmd, SoftapCmd, InterfaceCmd, IpFwdCmd, TetherCmd, NatCmd, ListTtysCmd, PppdCmd, PanCmd
&lt;/code&gt;
很有趣的是...這裡，各自 implement VoldCommand, NetCommand，結果內容是完全一樣的....&lt;br&gt;
為甚摩不省略這一層，直接 繼承 FrameworkCommand 就好？&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
還有用到 Netlink
&lt;code&gt;
SocketListener
  |
NetlinkListener
  |
NetlinkHandler
&lt;/code&gt;
也是一樣，vold, netd 各自 implement 自己的 NetlinkHandler
&lt;hr&gt;
這要的flow 寫在 SocketListener.&lt;br&gt;
thread create, thread start，thread run.&lt;br&gt;
&lt;code&gt;
runListener
  while(1) {
  FD_SET
  select( )
  if( FD_IISSET( ) {
   c = accept( )
  }
  do {
    for( i = clients-&gt;begin ~ end) {
      if(FD_ISSET(client(fd)))
              onDataAvailable(i)
&lt;/code&gt;
就是標準的 FD_SET, select 動作，當有monitor 到 fd 變更，在一一check client 的 fd，把對應的 client 的 onDataAvailable( ) 執行一次&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5861174235447380426?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5861174235447380426/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5861174235447380426' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5861174235447380426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5861174235447380426'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/socketlistener-frameworklistener.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8327059865023929917</id><published>2011-10-26T09:31:00.002+08:00</published><updated>2011-10-26T09:31:51.778+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><title type='text'>Bookmark : why GNU grep is fast</title><content type='html'>這一篇超不錯：
為什麼 gun grep 這麼快 &lt;a href="http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html"&gt;http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html&lt;/a&gt;&lt;br&gt;
為了防止不見，我整篇 copy 下來...
&lt;pre&gt;why GNU grep is fast

Mike Haertel mike at ducky.net 
Sat Aug 21 03:00:30 UTC 2010
Previous message: Latest intr problems
Next message: why GNU grep is fast
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi Gabor,

I am the original author of GNU grep.  I am also a FreeBSD user,
although I live on -stable (and older) and rarely pay attention
to -current.

However, while searching the -current mailing list for an unrelated
reason, I stumbled across some flamage regarding BSD grep vs GNU grep
performance.  You may have noticed that discussion too...

Anyway, just FYI, here's a quick summary of where GNU grep gets
its speed.  Hopefully you can carry these ideas over to BSD grep.

#1 trick: GNU grep is fast because it AVOIDS LOOKING AT
EVERY INPUT BYTE.

#2 trick: GNU grep is fast because it EXECUTES VERY FEW
INSTRUCTIONS FOR EACH BYTE that it *does* look at.

GNU grep uses the well-known Boyer-Moore algorithm, which looks
first for the final letter of the target string, and uses a lookup
table to tell it how far ahead it can skip in the input whenever
it finds a non-matching character.

GNU grep also unrolls the inner loop of Boyer-Moore, and sets up
the Boyer-Moore delta table entries in such a way that it doesn't
need to do the loop exit test at every unrolled step.  The result
of this is that, in the limit, GNU grep averages fewer than 3 x86
instructions executed for each input byte it actually looks at
(and it skips many bytes entirely).

See "Fast String Searching", by Andrew Hume and Daniel Sunday,
in the November 1991 issue of Software Practice &amp; Experience, for
a good discussion of Boyer-Moore implementation tricks.  It's
available as a free PDF online.

Once you have fast search, you'll find you also need fast input.

GNU grep uses raw Unix input system calls and avoids copying data
after reading it.

Moreover, GNU grep AVOIDS BREAKING THE INPUT INTO LINES.  Looking
for newlines would slow grep down by a factor of several times,
because to find the newlines it would have to look at every byte!

So instead of using line-oriented input, GNU grep reads raw data into
a large buffer, searches the buffer using Boyer-Moore, and only when
it finds a match does it go and look for the bounding newlines.
(Certain command line options like -n disable this optimization.)

Finally, when I was last the maintainer of GNU grep (15+ years ago...),
GNU grep also tried very hard to set things up so that the *kernel*
could ALSO avoid handling every byte of the input, by using mmap()
instead of read() for file input.  At the time, using read() caused
most Unix versions to do extra copying.  Since GNU grep passed out
of my hands, it appears that use of mmap became non-default, but you
can still get it via --mmap.  And at least in cases where the data
is already file system buffer caches, mmap is still faster:

  $ time sh -c 'find . -type f -print | xargs grep -l 123456789abcdef'
  real 0m1.530s
  user 0m0.230s
  sys 0m1.357s
  $ time sh -c 'find . -type f -print | xargs grep --mmap -l 123456789abcdef'
  real 0m1.201s
  user 0m0.330s
  sys 0m0.929s

[workload was a 648 megabyte MH mail folder containing 41000 messages]
So even nowadays, using --mmap can be worth a &gt;20% speedup.

Summary:

- Use Boyer-Moore (and unroll its inner loop a few times).

- Roll your own unbuffered input using raw system calls.  Avoid copying
  the input bytes before searching them.  (Do, however, use buffered
  *output*.  The normal grep scenario is that the amount of output is
  small compared to the amount of input, so the overhead of output
  buffer copying is small, while savings due to avoiding many small
  unbuffered writes can be large.)

- Don't look for newlines in the input until after you've found a match.

- Try to set things up (page-aligned buffers, page-sized read chunks,
  optionally use mmap) so the kernel can ALSO avoid copying the bytes.

The key to making programs fast is to make them do practically nothing. ;-)

Regards,

 Mike
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8327059865023929917?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8327059865023929917/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8327059865023929917' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8327059865023929917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8327059865023929917'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/bookmark-why-gnu-grep-is-fast.html' title='Bookmark : why GNU grep is fast'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8737303398044648842</id><published>2011-10-25T15:27:00.000+08:00</published><updated>2011-10-25T15:27:21.737+08:00</updated><title type='text'></title><content type='html'>http://www.vogella.de/articles/Andrpid/article.html &lt;br&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;Android Dalvik VM 和 java vm 不樣，google 提供 "dx" 這個tool，把 java Class file 轉成 Dalvik file (dex).&lt;/li&gt;
&lt;li&gt;Android 系統的執行檔格式是 apk，google 提供 "aapt" 這個 tool，把application 包裝成 apk。&lt;/li&gt;
&lt;li&gt;ADT plugin for Eclipse 提供整個服務：把 java class 轉成 dex，再包裝成 apk&lt;/li&gt;
&lt;li&gt;支援 2D, 3D 的opengl function&lt;/li&gt;
&lt;li&gt;使用 Sqlite 作data storage&lt;/li&gt;
&lt;li&gt;每一個 android 程式在 deployment 的時候，都會被賦予一個 userid，藉此區隔每個 application 的空間和權限。&lt;/li&gt;
&lt;/ol&gt;
Important Android Component
&lt;ol&gt;
&lt;li&gt;Activity -- Applaction 的展現，將資料展現在螢幕上，並且負責與 user 的互動。&lt;br&gt;一個 application 可以有很多個 activity，然後在執行時切換。&lt;/li&gt;
&lt;li&gt;Views -- Activitity 用來畫圖的class。都是繼承字 android.view.View。view 的layout 事由 android.view.ViewGroupe負責。&lt;/li&gt;
&lt;li&gt;Servuce -- 負責背景動作，可以經由 android 的 notification framwork，提供 user 資訊。&lt;/li&gt;
&lt;li&gt;Content Provider -- 負責提供資料給 application，經由 Content Provider，application 可以互相share 資料。-- Android 包含一個 SQlite db，作為 data provider。&lt;/li&gt;
&lt;li&gt;Intents -- &lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8737303398044648842?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8737303398044648842/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8737303398044648842' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8737303398044648842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8737303398044648842'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/httpwww.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4681053114216339399</id><published>2011-10-21T11:46:00.000+08:00</published><updated>2011-10-21T11:46:27.619+08:00</updated><title type='text'></title><content type='html'>原來, honeycomb 的 GPL code 已經 release:&lt;br&gt;
&lt;a href="http://source.android.com/source/build-numbers.html"&gt;http://source.android.com/source/build-numbers.htm&lt;/a&gt;l &lt;br&gt;
&lt;br&gt;
... GPL code 只佔 Android Source 的一小部份...

ICS 的 GPL code 也release，但是是在google groupe 中說得，以 tar download 的方式。&lt;br&gt;
所以不知道有沒有在 git branch 中..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4681053114216339399?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4681053114216339399/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4681053114216339399' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4681053114216339399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4681053114216339399'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/honeycomb-gpl-code-release-httpsource.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-3841322802546142858</id><published>2011-10-19T18:37:00.000+08:00</published><updated>2011-10-19T18:37:02.421+08:00</updated><title type='text'>bookmark for quick boot</title><content type='html'>&lt;ol&gt;
&lt;li&gt;http://www.linuxjournal.com/magazine/reducing-boot-time-embedded-linux-systems?page=0,0&lt;/li&gt;
&lt;li&gt;http://free-electrons.com/services/boot-time/&lt;/li&gt;
&lt;li&gt;http://free-electrons.com/pub/conferences/2011/genivi/boot-time.pdf&lt;/li&gt;
&lt;li&gt;http://free-electrons.com/blog/lzo-kernel-compression/&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-3841322802546142858?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/3841322802546142858/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=3841322802546142858' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3841322802546142858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3841322802546142858'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/bookmark-for-quick-boot.html' title='bookmark for quick boot'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6063963720478913129</id><published>2011-10-19T13:20:00.001+08:00</published><updated>2011-11-23T09:52:01.118+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>bookmarks : browse android sources in eclipse</title><content type='html'>android 官方說明如何用 eclipse build android framework code:
&lt;a href="http://source.android.com/source/using-eclipse.html"&gt;http://source.android.com/source/using-eclipse.html&lt;/a&gt;
&lt;br&gt;
這邊是對應的中文：&lt;br&gt;
&lt;a href="http://cheng-min-i-taiwan.blogspot.com/2011/02/android-source-core-eclipse.html"&gt;http://cheng-min-i-taiwan.blogspot.com/2011/02/android-source-core-eclipse.html&lt;/a&gt; &lt;br&gt;
&lt;br&gt;
這有兩篇：
&lt;ol&gt;
&lt;li&gt;
&lt;a href="http://blog.csdn.net/wufenglong/article/category/687662"&gt;http://blog.csdn.net/wufenglong/article/category/687662&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.cnblogs.com/keis/archive/2011/05/13/2045690.html"&gt;http://www.cnblogs.com/keis/archive/2011/05/13/2045690.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://tw.myblog.yahoo.com/jw!0.HxipORGB7SANBka8A2GVI-/archive?l=f&amp;id=1"&gt;http://tw.myblog.yahoo.com/jw!0.HxipORGB7SANBka8A2GVI-/archive?l=f&amp;id=1&lt;/a&gt;3
&lt;/li&gt;
&lt;/ol&gt;
build 得時候會遇到的問題：&lt;br&gt;
&lt;a href="http://stackoverflow.com/questions/885009/r-cannot-be-resolved-android-error"&gt;http://stackoverflow.com/questions/885009/r-cannot-be-resolved-android-error&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
英文&lt;br&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/&lt;/li&gt;
&lt;li&gt;http://achorniy.wordpress.com/2010/05/26/how-to-view-android-sources-in-eclipse/&lt;/li&gt;
&lt;li&gt;http://stackoverflow.com/questions/5233640/best-way-to-attach-android-source-to-eclipse&lt;/li&gt;
&lt;li&gt;http://johnsenf.blogspot.com/2011/04/android-sources-in-eclipse.html&lt;/li&gt;
&lt;li&gt;http://www.devfrustrated.com/devBlog/browsing-android-source-code-in-eclipse/&lt;/li&gt;
&lt;li&gt;http://www.bigbluebrains.com/index.php/2010/08/08/browsing-android-2-2-froyo-source-code-in-eclipse/&lt;/li&gt;
&lt;li&gt;http://www.androidzz.com/2011/08/browsing-android-source-in-eclipse/&lt;/li&gt;
&lt;li&gt;http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html&lt;/li&gt;
&lt;li&gt;http://android.opensourceror.org/2010/01/18/android-source/&lt;/li&gt;
&lt;li&gt;http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6063963720478913129?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6063963720478913129/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6063963720478913129' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6063963720478913129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6063963720478913129'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/android-eclipse-build-android-framework.html' title='bookmarks : browse android sources in eclipse'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6224002801940536299</id><published>2011-10-19T09:37:00.001+08:00</published><updated>2011-10-20T09:46:38.014+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VersionControl'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>get android source -- when android.kernel.org is down</title><content type='html'>Update :&lt;br&gt;
google 換了 android source server&lt;br&gt;
&lt;a href="http://source.android.com/source/downloading.html"&gt;http://source.android.com/source/downloading.html&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
配合的新版 repo:
&lt;code&gt;curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo &gt; ~/bin/repo&lt;/code&gt;
server address:
&lt;code&gt;$ repo init -u https://android.googlesource.com/platform/manifest -b android-2.3.7_r1&lt;/code&gt;

所以應該不用下面的方法了...&lt;br&gt;&lt;br&gt;

&lt;hr&gt;
&lt;hr&gt;
kernel.org 死了好久， www.kernel.org 恢復了。&lt;br&gt;
但是 android.kernel.org 還沒。&lt;br&gt;
&lt;br&gt;
這篇 有說改從 codeaurora download 的方法：&lt;br&gt;
&lt;a href="http://php.webtutor.pl/en/2011/09/05/kernel-org-hacked-how-to-get-android-repo/"&gt;http://php.webtutor.pl/en/2011/09/05/kernel-org-hacked-how-to-get-android-repo/ &lt;/a&gt;&lt;br&gt;
&lt;br&gt;
我照著 copy 一下：&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
1. 先抓 repo:
&lt;code&gt;curl "http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo" &gt; ~/bin/repo
chmod a+x ~/bin/repo
PATH=~/bin:$PATH&lt;/code&gt;
&lt;br&gt;
2. download code from codeaurora
&lt;code&gt;mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
repo init -u git://codeaurora.org/platform/manifest.git -b gingerbread
repo sync&lt;/code&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
雖然 android mirror 很多，但是大多沒有改 manifest，不然就是沒辦法support 像 android.kernel.org 這樣多目錄下的project，&lt;br&gt;
codeaurora 比較接近。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
另外這一篇也是一樣，是中文的，所以就不 copy 了：&lt;br&gt;
&lt;a href="http://joybo.blogspot.com/2011/10/android-source-23.html"&gt;http://joybo.blogspot.com/2011/10/android-source-23.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6224002801940536299?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6224002801940536299/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6224002801940536299' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6224002801940536299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6224002801940536299'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/get-android-source-when.html' title='get android source -- when android.kernel.org is down'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4315220461769151535</id><published>2011-10-14T13:16:00.002+08:00</published><updated>2011-10-17T13:07:49.077+08:00</updated><title type='text'></title><content type='html'>從 adb reboot 開始
&lt;ol&gt;
&lt;li&gt; 未改 : 28 sec&lt;/li&gt;
&lt;li&gt; 改 kernel : 27.2 sec&lt;/li&gt;
&lt;li&gt; 改 framework - preload &amp; remove battery, vibrator serer : 25 sec&lt;/li&gt;
&lt;li&gt;拿掉 bootanimation/ 或改靜態圖 : 22.7 sec&lt;/li&gt;
&lt;/ol&gt;

&lt;br&gt;
開機有一些 sensor 可以拿掉：看 log..
&lt;hr&gt;
使用自己的 launchre 和一堆 ap 後..&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;未改： 30.6sec&lt;/li&gt;
&lt;li&gt;改 kernel : 29.6sec&lt;/li&gt;
&lt;li&gt;改 framework/base + static bootanimation : 24.8 sec&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4315220461769151535?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4315220461769151535/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4315220461769151535' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4315220461769151535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4315220461769151535'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/adb-reboot-28-sec-kernel-27.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-35231395101195607</id><published>2011-10-13T18:45:00.000+08:00</published><updated>2011-10-13T18:45:40.539+08:00</updated><title type='text'></title><content type='html'>在 framework/base/services/java/com/android/server/am/ActivityManagerService.java:
&lt;code&gt;    public static final Context main(int factoryTest) {
        ........
        ActivityManagerService m = thr.mService;
        mSelf = m;
        ........  
        m.startRunning(null, null, null, null);

        return context;
    }
&lt;/code&gt;
startRunning( ) 的最後是 call  systemReady():
&lt;code&gt;    public final void startRunning(String pkg, String cls, String action,
        ........ 
        systemReady(null);
    }
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-35231395101195607?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/35231395101195607/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=35231395101195607' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/35231395101195607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/35231395101195607'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/frameworkbaseservicesjavacomandroidserv.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7032317356578694380</id><published>2011-10-12T13:30:00.001+08:00</published><updated>2011-10-21T16:00:23.640+08:00</updated><title type='text'>bootchart png s on target</title><content type='html'>1. 沒修改：&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-VsoKhoOa6wU/TpUiZWUK0bI/AAAAAAAAD6Q/M22BFP0J0g4/s1600/bootchart.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="324" width="400" src="http://3.bp.blogspot.com/-VsoKhoOa6wU/TpUiZWUK0bI/AAAAAAAAD6Q/M22BFP0J0g4/s400/bootchart.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
measured time:
&lt;ol&gt;
&lt;li&gt;poweron - load kernel &amp; root : 4.5 sec&lt;/li&gt;
&lt;li&gt;boot kernel unitll shell prompt : 10.0 sec&lt;/li&gt;
&lt;li&gt;unitl 2nd splash show up :13.1 sec&lt;/li&gt;
&lt;li&gt;until launcher show up : 14.2 sec&lt;/li&gt;
&lt;/ol&gt;
total : 42sec&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
2. preloaded-classes = empty&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-1wIyj62Z9_w/TpUrXmElo8I/AAAAAAAAD6c/p7UcfRHhJFw/s1600/bootchart.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="326" width="400" src="http://3.bp.blogspot.com/-1wIyj62Z9_w/TpUrXmElo8I/AAAAAAAAD6c/p7UcfRHhJFw/s400/bootchart.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
從 bootchart 看，雖然 zygote 到 start system server 的時間縮短了，&lt;br&gt;
但是 launcher 啟動的時間一樣維持在 29 sec。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
3. 改 internal eMMC， preloaded-classes 只有 java, dalvik 部份 (大約是原來的一半)&lt;br&gt;
&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-rBI9h4CBID8/TpWHiG7vAVI/AAAAAAAAD6o/1fQCuW9e2Zw/s1600/bootchartemmchalfpreload.gif" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-rBI9h4CBID8/TpWHiG7vAVI/AAAAAAAAD6o/1fQCuW9e2Zw/s400/bootchartemmchalfpreload.gif" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
可以看到，啟動 launcher 的時間縮短很多，前面的 30 sec，由原來的 IO bound 變成 cpu bound...&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
4. 跟 3 一樣，但是 preloaded-classes 是空的&lt;br&gt;
&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-ouG2BCFR1Yk/TpWLsUWoHrI/AAAAAAAAD60/CQ28a2AJM6k/s1600/bootchart.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="344" width="400" src="http://1.bp.blogspot.com/-ouG2BCFR1Yk/TpWLsUWoHrI/AAAAAAAAD60/CQ28a2AJM6k/s400/bootchart.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
原來7 sec 的 preloading 時間變成 3 sec。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
亂改一通後....&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-MvtFwEoqwUE/TqEmgb50kuI/AAAAAAAAD9I/ahBiQPu9X8Y/s1600/bootchart.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="376" src="http://1.bp.blogspot.com/-MvtFwEoqwUE/TqEmgb50kuI/AAAAAAAAD9I/ahBiQPu9X8Y/s400/bootchart.png" /&gt;&lt;/a&gt;&lt;/div&gt;
雖然好像很快...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7032317356578694380?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7032317356578694380/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7032317356578694380' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7032317356578694380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7032317356578694380'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/bootchart-png-s-on-target.html' title='bootchart png s on target'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-VsoKhoOa6wU/TpUiZWUK0bI/AAAAAAAAD6Q/M22BFP0J0g4/s72-c/bootchart.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1001471740466243097</id><published>2011-10-11T17:28:00.000+08:00</published><updated>2011-10-11T18:20:01.781+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>bootchart &amp; preloaded-classes</title><content type='html'>&lt;ol&gt;
&lt;li&gt;preloaded-class&lt;/li&gt;
&lt;li&gt;package scan&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
修改 preloaded-classes 就是修改 /framework/base/preloaded-classed&lt;br&gt;
然後重 build。&lt;br&gt;
&lt;br&gt;
下面是 原來的 和 0 -preload 的 bootchart :&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-OBmcli5RFFU/TpQYBHW5v0I/AAAAAAAAD54/0qDPMqWfpIc/s1600/bootchart.png.orig" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="229" width="400" src="http://4.bp.blogspot.com/-OBmcli5RFFU/TpQYBHW5v0I/AAAAAAAAD54/0qDPMqWfpIc/s400/bootchart.png.orig" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-0MsvqHD7emc/TpQYG6BlNcI/AAAAAAAAD6E/OHfudzDYYpA/s1600/bootchart.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="228" width="400" src="http://3.bp.blogspot.com/-0MsvqHD7emc/TpQYG6BlNcI/AAAAAAAAD6E/OHfudzDYYpA/s400/bootchart.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1001471740466243097?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1001471740466243097/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1001471740466243097' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1001471740466243097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1001471740466243097'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/preloaded-class-package-scan.html' title='bootchart &amp; preloaded-classes'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-OBmcli5RFFU/TpQYBHW5v0I/AAAAAAAAD54/0qDPMqWfpIc/s72-c/bootchart.png.orig' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-9153862784986249564</id><published>2011-10-11T13:51:00.001+08:00</published><updated>2011-10-11T13:51:09.759+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>use bootchart on android</title><content type='html'>squeeze 竟然沒有 bootchart...&lt;br&gt;
到 bootcharg.org download source - 0.9.? 版&lt;br&gt;
follow 說明，用 ant 來 build&lt;br&gt;
所以要先 install ant:
&lt;code&gt;$aptitude install ant&lt;/code&gt;
解開 bootchart source，然後到目錄去 run ant...&lt;br&gt;
出現 error。&lt;br&gt;
說 javac 找不到，找 com.sun..... 然後 path 指的卻是 openjdk。&lt;br&gt;
所以 run 
&lt;code&gt;$update-alternatives --all&lt;/code&gt;
所有 java 的部份，都由 openjdk 改為 sun-java。&lt;br&gt;
再 run ant --&gt; OK.&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
android 的部份，follow README.BOOTCHART &lt;br&gt;
在 system/core/init&lt;br&gt;
&lt;br&gt;
先把 INIT_BOOTCHART 打開build 出一個有 bootchart 的 init..
&lt;code&gt;
到 system/core/init
$ mm INIT_BOOTCHART=true
&lt;/code&gt;
dd 到 板子上後，啟動。&lt;br&gt;
&lt;br&gt;
然後手動做出 /data/bootchart-start:
&lt;code&gt; $ echo 60 &gt; bootchart-start
$adb push bootchart-start /data/
$adb shell sync
&lt;/code&gt;
然後就可以reboot..&lt;br&gt;
這樣開機後，在 /data 下就會多一個 bootchart 的 folder。&lt;br&gt;
/data/bootchart-start 裡面寫得就是 bootchart 要紀錄的秒數。&lt;br&gt;
--- 現在是 60 sec。&lt;br&gt;
&lt;br&gt;
等 60 sec 後，就可以 run /system/core/init/grabe-bootchart.sh&lt;br&gt;
會透過 adb 把 /data/bootchart/ 的資料 copy 回 pc，壓成 bootchart.tgz。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
然後 pc 端 run 剛剛裝好的 bootchart。從 bootchart.tgz 產生 png:
&lt;code&gt;java -jar bootchart.jar bootchart.tgz&lt;/code&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-nKlCXL4191Q/TpPZLrisM4I/AAAAAAAAD5s/L5q0q06p4as/s1600/bootchart00.jpeg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="229" width="400" src="http://4.bp.blogspot.com/-nKlCXL4191Q/TpPZLrisM4I/AAAAAAAAD5s/L5q0q06p4as/s400/bootchart00.jpeg" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-9153862784986249564?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/9153862784986249564/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=9153862784986249564' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/9153862784986249564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/9153862784986249564'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/use-bootchart-on-android.html' title='use bootchart on android'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-nKlCXL4191Q/TpPZLrisM4I/AAAAAAAAD5s/L5q0q06p4as/s72-c/bootchart00.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2394201001974120987</id><published>2011-10-11T11:53:00.002+08:00</published><updated>2011-10-11T11:53:49.895+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Disable screen off timeout</title><content type='html'>一陣子沒動作，就會把lcd 關掉，同時進 suspend。&lt;br&gt;
在 framework/base/services/java/com/android/server/PowerManagerService.java:
&lt;code&gt;    private class SettingsObserver implements Observer {
        ........
        public void update(Observable o, Object arg) {
            synchronized (mLocks) {
               
                   ......
                // SCREEN_OFF_TIMEOUT, default to 15 seconds
                mScreenOffTimeoutSetting = -1;//getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
&lt;/code&gt;
mScreenOffTimeoutSetting = -1;&lt;br&gt;
就可以disable 掉這個 function。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2394201001974120987?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2394201001974120987/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2394201001974120987' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2394201001974120987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2394201001974120987'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/disable-screen-off-timeout.html' title='Disable screen off timeout'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1164544002790023427</id><published>2011-10-07T13:55:00.000+08:00</published><updated>2011-10-07T19:02:42.329+08:00</updated><title type='text'></title><content type='html'>以P公司藍色測試 2G SD 為基準:&lt;br&gt;
&lt;hr&gt;
uImage : 3267264&lt;br&gt;
uramdisk : 293568&lt;br&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt; uboot load kernel and root : 7.5 sec&lt;/li&gt;
&lt;li&gt; kernel boot : 7.0 sec&lt;/li&gt;
&lt;li&gt; init to show splash : 27.4 sec&lt;/li&gt;
&lt;li&gt; splash to show launcher : 45.6&lt;/li&gt;
&lt;/ol&gt;
第二次開機：
&lt;ol&gt;
&lt;li&gt; uboot load kernel and root : 7,5 sec&lt;/li&gt;
&lt;li&gt; kernel boot : 7.8 sec&lt;/li&gt;
&lt;li&gt; init to show splash : 12.7 sec&lt;/li&gt;
&lt;li&gt; splash to show launcher : 10.6&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
刪掉一堆&lt;br&gt;
uImage : 2502056&lt;br&gt;
kernel boot L 6.4 sec&lt;br&gt;
&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1164544002790023427?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1164544002790023427/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1164544002790023427' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1164544002790023427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1164544002790023427'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/p-2g-sd-uboot-load-kernel-and-root-7.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6026866409157116084</id><published>2011-10-06T14:05:00.002+08:00</published><updated>2011-10-06T16:34:37.028+08:00</updated><title type='text'></title><content type='html'>mxc_uart.c 的 mxcuart_console_init ( ) 屬於 console_init 階段執行的 function.
&lt;code&gt;struct console mxc_consol

register_console(&amp;mxc_console);&lt;/code&gt;
&lt;br&gt;
mxc_reg 跟 mxc_console 各自包含對方：
&lt;code&gt;struct uart_console mxc_reg = {
  .con = (&amp;mxc_sonsole);
};

struct console mxc_console = {
  .data = &amp;mxc_reg;
}
&lt;/code&gt;

&lt;hr&gt;
&lt;br&gt;
另外一個是 module_init 階段執行的 mxcuart_init 
&lt;code&gt;uart_register(&amp;mxc_reg);
platform_driver_register(&amp;mxcuart_driver);
&lt;/code&gt;
mxcuart_driver 是 platform_driver 結構，name 是 mxcintuart (internal uart ?)&lt;br&gt;
&lt;br&gt;
platform_driver 的 mxcuart_resume(struct platform_device *pdev) 只是..&lt;br&gt;
取出 platform_device 的 data : (uart_mxc_port)。參照裡面的 port.flag，決定要不要call uart_resume_port( ):
&lt;code&gt;        uart_mxc_port *umxc = platform_get_drvdata(pdev);
        if (umxc &amp;&amp; umxc-&gt;port.flags &amp; ASYNC_SUSPENDED) {
                umxc-&gt;port.state-&gt;port.tty-&gt;hw_stopped = 0;
                uart_resume_port(&amp;mxc_reg, &amp;umxc-&gt;port);
        }
&lt;/code&gt;
這裡的 uart_resume_port 在 serial_core.c 裡。&lt;br&gt;
&lt;br&gt;
uart_resume_port 也是取出 argument :uart_driver 裡的tty_port 結構資料 : port。&lt;br&gt;
依照 port-&gt; flags 的內容決定要不要對 hardware 動作。&lt;br&gt;
&lt;br&gt;

所以 mxcuart_resume --- uart_resume_port  裡面都有對 port 動作，但是兩個的 port 並不一樣。&lt;br&gt;
&lt;br&gt;
mxcuart_resume 是：
&lt;code&gt;platform_device --&gt; (uart_mxc_port) --&gt; port.flags&lt;/code&gt;
uart_resume_port 是：
&lt;code&gt;uart_driver --&gt; uart_state --&gt;tty_port --&gt; flags&lt;/code&gt;
好像不相關.&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
mxcuart_resume 的參數： platform_device 是宣告在另一個 source : arch:
&lt;code&gt;
static struct platform_device mxc_uart_device1 = {
        .name = "mxcintuart",
        .id = 0,
        .num_resources = ARRAY_SIZE(mxc_uart_resources1),
        .resource = mxc_uart_resources1,
        .dev = {
                .platform_data = &amp;mxc_ports[0],
                },
};&lt;/code&gt;
&lt;br&gt;
mxc_port 是：
&lt;code&gt;static uart_mxc_port mxc_ports[] = {
        [0] = {
               .port = {
                        .iotype = SERIAL_IO_MEM,
                        .fifosize = 32,
                        .flags = ASYNC_BOOT_AUTOCONF ,
                        .line = 0,
                        },
               .ints_muxed = 1,
               .mode = MODE_DCE,
               .ir_mode = NO_IRDA,
               .enabled = 1,
               .cts_threshold = UART1_UCR4_CTSTL,
               .dma_enabled = UART1_DMA_ENABLE,
               .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
               .rx_threshold = UART1_UFCR_RXTL,
               .tx_threshold = UART1_UFCR_TXTL,
               .dma_tx_id = MXC_DMA_UART1_TX,
               .dma_rx_id = MXC_DMA_UART1_RX,
               .rxd_mux = MXC_UART_RXDMUX,
               },
&lt;/code&gt;
看到那個 flags 欄位。&lt;br&gt;
這個欄位好像沒有改變。&lt;br&gt;
&lt;br&gt;
uart_resume_port( ) 的參數是mxc_uart_resume 呼叫時傳進去的。
&lt;code&gt;               uart_resume_port(&amp;mxc_reg, &amp;umxc-&gt;port);&lt;/code&gt;
所以就是 
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6026866409157116084?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6026866409157116084/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6026866409157116084' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6026866409157116084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6026866409157116084'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/mxcuart_06.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4877398849179249799</id><published>2011-10-06T11:21:00.000+08:00</published><updated>2011-10-06T11:21:26.379+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenCL'/><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='software_package'/><title type='text'>Bookmark : install AMD APP SDK on Debian - OpenCL</title><content type='html'>&lt;a href="http://wiki.cchtml.com/index.php/Debian"&gt;http://wiki.cchtml.com/index.php/Debian&lt;/a&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4877398849179249799?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4877398849179249799/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4877398849179249799' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4877398849179249799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4877398849179249799'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/bookmark-install-amd-app-sdk-on-debian.html' title='Bookmark : install AMD APP SDK on Debian - OpenCL'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4358599498674661008</id><published>2011-10-05T15:28:00.000+08:00</published><updated>2011-10-05T18:55:04.219+08:00</updated><title type='text'></title><content type='html'>mxc_uart.c 的 mxcuart_init( ) 被放在 module_init(mxcuart_init)，所以在 kernel 啟動時，會自動被呼叫。&lt;br&gt;
&lt;br&gt;
mxcuart_init 負責：
&lt;ol&gt;
&lt;li&gt;uart_register_driver&lt;/li&gt;
&lt;li&gt;platform_driver_register&lt;/li&gt;
&lt;/ol&gt;

mxc_uart 的 platform driver name 是 mxcintuart。&lt;br&gt;
對應的 platform device 在 arch/arm serial.c 李，一共宣告了 5 個 (因為有 5 個 serial port, -- 51 只有 3 個)&lt;br&gt;
 platform_device 的資料： platform_data 是 
&lt;code&gt;uart_mxc_port &lt;/code&gt; 
其中包含有 .port 這個 property。&lt;br&gt;
裡面有 flags 這個 field。&lt;br&gt;
&lt;br&gt;
這個flag 是給 driver 用的(?)，因為 serial_core.c 的 suspend/resume function 會依照 consoel_suspend_enabled 來動作，並且 update port-&gt;flag 的 ASYNC_SUSPEND 這個 flag。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
看來是 uart_open 沒有被 call 到，所以 resume 狀態和 suspend 狀態不一致。&lt;br&gt;
&lt;br&gt;
看一下 uart_open 對那些 hardware register 有動作：
&lt;code&gt;
uart_change_pm(state,0);
uart_startup(state,0);
uart_update_termios(state)
&lt;/code&gt;
&lt;br&gt;
mxcuart_startup ( ) 變更的 register 有：
&lt;ol&gt;
&lt;li&gt;MXC_UARTUSR1, MXC_UARTUSR2&lt;/li&gt;
&lt;li&gt;UARTUCR3&lt;/li&gt;
&lt;li&gt;MXC_UARTUCR2&lt;/li&gt;
&lt;li&gt;MXC_UARTUFCR&lt;/li&gt;
&lt;li&gt;MXC_UARTUCR1&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
還是認真看一下..&lt;br&gt;
&lt;br&gt;
整個就只有mxc_uart_early, mxc_uart, serial_core 三個。&lt;br&gt;
要是要用 uart 當作 console ，就要加上 mxc_uart_early，否則不僅 kernel msg show 不出來，shell 也沒有動作。&lt;br&gt;
&lt;br&gt;
mxc_uart_early 的 init 被藏在很不清楚的地方 (why not follow DEBUG_LL &amp; EARLY_CONSOL ?)&lt;br&gt;
在MACHINE_START( ) 的 timer .init : mx51_babbage_timer_init ( ) 中。&lt;br&gt;
clock_init 完後，就 call         early_console_setup(UART1_BASE_ADDR, uart_clk); &lt;br&gt;
&lt;br&gt;
實際上就是call         mxc_early_serial_console_init(base, clk);&lt;br&gt;
&lt;br&gt;
early_console_setup( ) 傳進去的 UART1_BASE_ADDR, uart_clk 會填在 static 變數 mxc_early_device 的 port.mapbase 和 clk 裡。&lt;br&gt;
雖然 mxc_early_device 的 structure mxc_early_uart_device 宣告了內含一個很大的 structure : uart_port，實際上只有用到裡面的 membase 這個 field 而已.........&lt;br&gt;
&lt;br&gt;
比較有用的變數是
&lt;code&gt;static struct console mxc_early_uart_console __initdata = {
        .name = "ttymxc",
        .write = early_mxcuart_console_write,
        .setup = mxc_early_uart_setup,
        .flags = CON_PRINTBUFFER | CON_BOOT,
        .index = -1,
};
&lt;/code&gt;
這被用來        register_console(&amp;mxc_early_uart_console);&lt;br&gt;
&lt;br&gt;
*** -- 這個 early_driver 只有實做 write，沒有 read 喔...&lt;br&gt;
*** 沒有看到設 baudrate..
&lt;br&gt;&lt;br&gt;
register_console 在 kernel/printk.c&lt;br&gt;
&lt;br&gt;
可以看到 呼叫 early_setup( )，還有把 cmdline option 傳進setup( ).. 執行的 code。&lt;br&gt;
&lt;br&gt;
還可以看到當真正的 console register 時，bootconsole 會自動 unregister..&lt;br&gt;
&lt;br&gt;
printk 用來紀錄所有register 的 console 是
&lt;code&gt;struct console {
        char    name[16];
        void    (*write)(struct console *, const char *, unsigned);
        int     (*read)(struct console *, char *, unsigned);
        struct tty_driver *(*device)(struct console *, int *);
        void    (*unblank)(void);
        int     (*setup)(struct console *, char *);
        int     (*early_setup)(void);
        short   flags;
        short   index;
        int     cflag;
        void    *data;
        struct   console *next;
};
&lt;/code&gt;
其中 next 是用來做出 linking list&lt;br&gt;
&lt;br&gt;&lt;br&gt;
整個 printk.c 包含register_console ，還有 prtintk，就是把message 從所有 console 的 write( ) 送出去。&lt;br&gt;
&lt;br&gt;
printk.c : 中的 release_console_sem( ) 就會把 buffer 內容從所有 registered console 送出去..&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;hr&gt;
---- 所以整個只有 write,,,,,&lt;br&gt;&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4358599498674661008?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4358599498674661008/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4358599498674661008' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4358599498674661008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4358599498674661008'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/mxcuart.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-533931121056446313</id><published>2011-10-04T15:00:00.000+08:00</published><updated>2011-10-04T16:46:02.862+08:00</updated><title type='text'></title><content type='html'>sysfs:
&lt;pre&gt;/sys/devices/system&lt;/pre&gt;
suspend/hibernate 時：
&lt;code&gt;Suspending System Devices
Suspending type 'vfp':
 vfp0
Suspending type 'clocksource':
 clocksource0
Suspending type 'timekeeping':
 timekeeping0
Suspending type 'timer':
 timer0
Suspending type 'mxc_gpio':
 mxc_gpio0
Suspending type 'cpu':
 cpu0
&lt;/code&gt;
跟 /sys/device/system 下的目錄一致。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
hibernate fail 時，是 cpu0 fail。&lt;br&gt;
所以把 function address 印出來，到 System.mp 就可以查到 function name。&lt;br&gt;
結果 vfp0, clocksource0,.. mxc_gpio0 都沒有 suspend function。&lt;br&gt;
只有 cpu0 有，是 cpufreq_suspend。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
driver/cpufreq/cpufreq.c 中的 printk 是用 cpufreq_debug_printk( ) 作動態控制。&lt;br&gt;
控制的參數有 debug, debug_ratelimit&lt;br&gt;
&lt;br&gt;
這兩個參數被宣告成 module_param，所以都會在 /sys/module/cpufreq 裡出現。&lt;br&gt;
&lt;br&gt;
還有要開啟這個功能，要define CONFIG_CPU_FREQ_DEBUG。&lt;br&gt;
這在 menuconfig 打開： 
&lt;pre&gt;CPU Power Management --&gt; Enable CPUfreq debugging&lt;/pre&gt;
&lt;br&gt;
另外，看 cpufreq_debug_printk( ) 的 code，是 KERN_INFO，所以不會直接 output 到 console。&lt;br&gt;
要直接輸出(不經 dmesg)，就把他刪掉。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
這樣 build 好kernel 啟動後，還要：
&lt;code&gt; echo 7 &gt; /sys/module/cpufreq/debug
echo 0 &gt; /sys/module/cpufreq/debug_ratelimit&lt;/code&gt;
改一下 cpufreq 的debug 參數，讓他output message。&lt;br&gt;
然後作 hibernate ，就可以看到 cpufreq-core 的 message 了。&lt;br&gt;
&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-533931121056446313?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/533931121056446313/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=533931121056446313' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/533931121056446313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/533931121056446313'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/sysfs-sysdevicessystem.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-770342869287872913</id><published>2011-10-04T11:51:00.002+08:00</published><updated>2011-10-04T13:12:42.804+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>bookmark: boot time optimize done by TI</title><content type='html'>Ti 也很好心的寫了 boot time optimize procedure:
&lt;ol&gt;
&lt;li&gt;http://processors.wiki.ti.com/index.php/Android_Boot_Time_Optimization &lt;/li&gt;
&lt;li&gt;http://processors.wiki.ti.com/index.php/Optimize_Linux_Boot_Time&lt;/li&gt;
&lt;/ol&gt;
屬於 "盡力" 的方式，沒有用 hibernate 功能。&lt;br&gt;
比較特殊的大概是 deffered module，讓某些不急著load 的 module 晚點再 load.
&lt;br&gt;&lt;br&gt;
順便 link 一下 TI 的 Gingerbread sdk user guide:&lt;br&gt;
&lt;a href="http://processors.wiki.ti.com/index.php/TI-Android-GingerBread-2.3.4-DevKit-2.1_UserGuide"&gt;http://processors.wiki.ti.com/index.php/TI-Android-GingerBread-2.3.4-DevKit-2.1_UserGuide&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
FAQ 有提到， bracn -qb 就是 quickboot 的 branch&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-770342869287872913?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/770342869287872913/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=770342869287872913' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/770342869287872913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/770342869287872913'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/bookmark-boot-time-optimize-done-by-ti.html' title='bookmark: boot time optimize done by TI'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1603679959596707602</id><published>2011-10-04T11:48:00.000+08:00</published><updated>2011-10-04T11:48:58.584+08:00</updated><title type='text'></title><content type='html'>&lt;ol&gt;
&lt;li&gt;kernel + root only : suspend , resume OK, but shell no response after reumse, and takes long time to resume&lt;/li&gt;
&lt;li&gt;remove unnecessary option in kernel :  failed : Class driver suspend failed for cpu0&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1603679959596707602?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1603679959596707602/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1603679959596707602' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1603679959596707602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1603679959596707602'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/kernel-root-only-suspend-resume-ok-but.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4610554114426096064</id><published>2011-10-03T10:26:00.000+08:00</published><updated>2011-10-04T16:36:01.854+08:00</updated><title type='text'>bookmark : proc &amp; sysfs</title><content type='html'>因為Z的 bsp 還有一堆 driver 用 proc 作 device/userspace 溝通的管道。&lt;br&gt;
所以想看一下 proc, sysfs 介面的差異。&lt;br&gt;
&lt;br&gt;
剛好這一篇有簡單的 proc , sysfs interface example:&lt;br&gt;
&lt;a href="http://www.coding.com.br/kernel/adding-procfs-and-sysfs-interface-in-your-lkml/"&gt;http://www.coding.com.br/kernel/adding-procfs-and-sysfs-interface-in-your-lkml/&lt;/a&gt;&lt;br&gt;
**sysfs只有 create node，沒有 interface。&lt;br&gt;
&lt;br&gt;
但是 sysfs 很有趣的是，可以用 module_param 把module 的參數開放出來。&lt;br&gt;
用 module_param 宣告的參數，都會列在 /sys/module/&lt;module_name&gt; 目錄中。&lt;br&gt;
可以read /write (如果你有給權限的話)&lt;br&gt;
&lt;br&gt;
到 /sys/module 去看，會列出所有的 module。&lt;br&gt;
&lt;bre&gt;
ref: &lt;a href="http://nano-chicken.blogspot.com/2011/01/linux-modules11module-parameters.html"&gt;http://nano-chicken.blogspot.com/2011/01/linux-modules11module-parameters.html&lt;/a&gt;&lt;br&gt;
&lt;br&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4610554114426096064?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4610554114426096064/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4610554114426096064' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4610554114426096064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4610554114426096064'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/10/z-bsp-driver-proc-deviceuserspace-proc.html' title='bookmark : proc &amp; sysfs'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2364699102133539875</id><published>2011-09-30T19:25:00.003+08:00</published><updated>2011-10-03T15:12:22.985+08:00</updated><title type='text'></title><content type='html'>看來好像掛掉。&lt;br&gt;
再 trace 一下 mailinglist:&lt;br&gt;
&lt;br&gt;
LKML 的一封：https://lkml.org/lkml/2011/5/21/69&lt;br&gt;
&lt;pre&gt;"Rafael J. Wysocki" &lt;&gt;
Subject	[PATCH 0/3] Hibernate cleanups
Date	Sat, 21 May 2011 14:08:28 +0200

Hi,

Following are three hibernate patches I didn't have the time to
work on before.

[1/3] - Update comments in kernel/power/hibernate.c
[2/3] - Remove arch_prepare_suspend()
[3/3] - Update kerneldoc comments in kernel/power/hibernate.c

Since they don't make any functional changes, I don't think it makes sense
to wait with them for the next merge window, so I'd like to push them
for 2.6.40 if no one objects.

Thanks,
Rafael&lt;/pre&gt;
慘的是..後來 Linus 宣佈沒有 2.6.40，而是 3.0 ...&lt;br&gt;
&lt;br&gt;
LKML 的 interface 很好心，會把相關的 repy-discuss 放在一個 tree (頁面的左邊)，每點一個 message，要是裡面包含 path，就會出現一個 "diff" 的link，讓你把 patch 拿下來。
&lt;hr&gt;
&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
這是samsung 基於那個 NOKIA initial work 所做的：&lt;br&gt;
http://permalink.gmane.org/gmane.linux.power-management.general/22773&lt;br&gt;
&lt;br&gt;
有提到那個 lds.S 修改。另外他還加上 A9 的 support。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
還有 ，當 使用 eMMC /SD 作 resume partition 時，要等待 driver ready，所以&lt;br&gt;
http://www.spinics.net/lists/arm-kernel/msg142548.html&lt;br&gt;
&lt;br&gt;
這個 patch 加上 resumewait 參數，等 dev open success..&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2364699102133539875?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2364699102133539875/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2364699102133539875' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2364699102133539875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2364699102133539875'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/trace-mailinglist-lkml-httpslkml.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1453425367998438409</id><published>2011-09-30T19:25:00.002+08:00</published><updated>2011-09-30T19:25:11.340+08:00</updated><title type='text'>bookmark : kernel pm mantainer  說明 suspend, hibernation</title><content type='html'>寫在 &lt;a href="https://lkml.org/lkml/2006/7/25/105"&gt;https://lkml.org/lkml/2006/7/25/105&lt;/a&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1453425367998438409?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1453425367998438409/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1453425367998438409' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1453425367998438409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1453425367998438409'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/bookmark-kernel-pm-mantainer-suspend.html' title='bookmark : kernel pm mantainer  說明 suspend, hibernation'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-4466169427171028073</id><published>2011-09-30T19:23:00.001+08:00</published><updated>2011-09-30T19:23:59.321+08:00</updated><title type='text'>bookmark : webcore 導致 browser 當機，VM 重開問題</title><content type='html'>這個中國人有解答：&lt;br&gt;
http://blog.csdn.net/a345017062/article/details/6394864&lt;br&gt;
&lt;br&gt;
問題有列在 google code issue tracker :&lt;br&gt;
http://code.google.com/p/android/issues/detail?id=12987&lt;br&gt;
&lt;br&gt;
大概是 java function return class not match 問題。&lt;br&gt;
&lt;br&gt;
不過他很大方的寫出 trace bug 的方法，可以學一下。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-4466169427171028073?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/4466169427171028073/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=4466169427171028073' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4466169427171028073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/4466169427171028073'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/bookmark-webcore-browser-vm.html' title='bookmark : webcore 導致 browser 當機，VM 重開問題'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6650247893716440595</id><published>2011-09-30T13:39:00.000+08:00</published><updated>2011-09-30T13:48:42.728+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><title type='text'></title><content type='html'>說要加上 Will Deacon 的 cpu_reset patch。&lt;br&gt;
查一下，在 arch/arm/mm &lt;br&gt;
&lt;br&gt;
誰用到？&lt;br&gt;
&lt;br&gt;
宣告的地方：./arch/arm/include/asm/cpu-single.h
&lt;code&gt;#ifdef __STDC__
#define __catify_fn(name,x)     name##x
#else
#define __catify_fn(name,x)     name/**/x
#endif
#define __cpu_fn(name,x)        __catify_fn(name,x)

/*
 * If we are supporting multiple CPUs, then we must use a table of
 * function pointers for this lot.  Otherwise, we can optimise the
 * table away.
 */
#define cpu_proc_init                   __cpu_fn(CPU_NAME,_proc_init)
#define cpu_proc_fin                    __cpu_fn(CPU_NAME,_proc_fin)
#define cpu_reset                       __cpu_fn(CPU_NAME,_reset)
#define cpu_do_idle                     __cpu_fn(CPU_NAME,_do_idle)
#define cpu_dcache_clean_area           __cpu_fn(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm                __cpu_fn(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext                 __cpu_fn(CPU_NAME,_set_pte_ext)

#include &lt;asm/page.h&gt;

struct mm_struct;

/* declare all the functions as extern */
extern void cpu_proc_init(void);
extern void cpu_proc_fin(void);
extern int cpu_do_idle(void);
extern void cpu_dcache_clean_area(void *, int);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
&lt;/code&gt;
所以 cpu_reset( ) 會變成 CPU_NAME_reset&lt;br&gt;
&lt;br&gt;
CPU_NAME 定義在 ./arch/arm/include/asm/proc-fns.h
&lt;code&gt;# ifdef CONFIG_CPU_V6
#  ifdef CPU_NAME
#   undef  MULTI_CPU
#   define MULTI_CPU
#  else
#   define CPU_NAME cpu_v6
#  endif
# endif
# ifdef CONFIG_CPU_V7
#  ifdef CPU_NAME
#   undef  MULTI_CPU
#   define MULTI_CPU
#  else
#   define CPU_NAME cpu_v7
#  endif
# endif
&lt;/code&gt;
所以 cortext A8 的 kernel config 是：
&lt;code&gt;CONFIG_CPU_V7=y&lt;/code&gt;
也就是會變成 cpu_v7_reset( )&lt;br&gt;
&lt;br&gt;
所以 assembly 的部份要看 cpu_v7_reset， c source 的部份要看 cpu_reset ().&lt;br&gt;
.. 有一堆 source call cpu_reset...&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
ref:
&lt;ol&gt;
&lt;li&gt;http://comments.gmane.org/gmane.linux.ports.arm.kernel/119552&lt;/li&gt;
&lt;li&gt;http://lists.infradead.org/pipermail/linux-arm-kernel/2011-July/057302.html&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6650247893716440595?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6650247893716440595/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6650247893716440595' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6650247893716440595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6650247893716440595'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/will-deacon-cpureset-patch-archarmmm.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8135725030634755487</id><published>2011-09-29T14:48:00.000+08:00</published><updated>2011-10-12T11:43:03.208+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>build TINY_ANDROID &amp;&amp; some worklog on hibernate</title><content type='html'>問題應該還是在 kernel，android framework 在 suspend/resume 好像沒有限制，只有在特殊的情況會用 wakelock 防止suspend (跟hardware 相關，或是 charging)。&lt;br&gt;
其他部份好像都無關 (pure software component ?)&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
BUILD_TINY_ANDROID&lt;br&gt;
用&lt;code&gt;make -j4 BUILD_TINY_ANDROID=true  TARGET_NO_RECOVERY=true showcommands &lt;/code&gt;
來 build TINY_ANDROID。&lt;br&gt;
&lt;pre&gt; TINY_ANDROID 不會rebuild recovery，但是 Makefile 卻還是去 make recoveryimage，所以要手動加上 TARGET_NO_RECOVERY=true&lt;/pre&gt;&lt;br&gt;
build 出來後，到 out 去看 installed-files，果然有一堆沒包 (vimdiff with original build result)&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
兩個問題：
&lt;ol&gt;
&lt;li&gt;pmic_adc 在 resume 的時候會 hang 住一陣子&lt;/li&gt;
&lt;li&gt;resume 後，shell , rx 沒動作 ，tx好像還 OK,-- 從 shell 的 output 來看&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
about pmic_adc:
&lt;ol&gt;
&lt;li&gt; 先回到 resume OK 版本 -- 至少 screen 恢復&lt;/li&gt;
&lt;li&gt;移除 pmic_backlight 和 pmic_XXX (?) -- 看看是否OK&lt;/li&gt;
&lt;li&gt;pmic_adc 的 suspend/resume 似乎是以 adc wq 不終止的情況 考慮....&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8135725030634755487?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8135725030634755487/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8135725030634755487' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8135725030634755487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8135725030634755487'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/kernelandroid-framework-suspendresume.html' title='build TINY_ANDROID &amp;&amp; some worklog on hibernate'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-87202558714966283</id><published>2011-09-28T10:36:00.000+08:00</published><updated>2011-09-28T11:17:43.512+08:00</updated><title type='text'></title><content type='html'>enable LL (Low Level Debugging 後):
&lt;code&gt;  /toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcc 
-Wp,-MD,arch/arm/kernel/.debug.o.d  
-nostdinc 
-isystem /toolchain/arm-eabi-4.4.3/bin/../lib/gcc/arm-eabi/4.4.3/include 
-I/kernel_imx/arch/arm/include 
-Iinclude  
-include include/generated/autoconf.h 
-D__KERNEL__ 
-mlittle-endian 
-Iarch/arm/mach-mx5/include 
-Iarch/arm/plat-mxc/include 
-D__ASSEMBLY__ 
-mabi=aapcs-linux -mno-thumb-interwork 
-funwind-tables  
-D__LINUX_ARM_ARCH__=7 
-march=armv7-a  
-include asm/unified.h 
-msoft-float       
-c -o arch/arm/kernel/debug.o arch/arm/kernel/debug.S

  /toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcc 
-Wp,-MD,arch/arm/mm/.iomap.o.d  
-nostdinc 
-isystem /toolchain/arm-eabi-4.4.3/bin/../lib/gcc/arm-eabi/4.4.3/include 
-I/kernel_imx/arch/arm/include 
-Iinclude  
-include include/generated/autoconf.h 
-D__KERNEL__ 
-mlittle-endian 
-Iarch/arm/mach-mx5/include 
-Iarch/arm/plat-mxc/include 
-Wall 
-Wundef 
-Wstrict-prototypes 
-Wno-trigraphs 
-fno-strict-aliasing 
-fno-common 
-Werror-implicit-function-declaration 
-Wno-format-security 
-fno-delete-null-pointer-checks 
-Os 
-marm 
-mabi=aapcs-linux 
-mno-thumb-interwork 
-funwind-tables 
-D__LINUX_ARM_ARCH__=7 
-march=armv7-a 
-msoft-float 
-Uarm 
-Wframe-larger-than=1024 -fno-stack-protector 
-fomit-frame-pointer 
-Wdeclaration-after-statement 
-Wno-pointer-sign 
-fno-strict-overflow 
-fconserve-stack   
-D"KBUILD_STR(s)=#s" 
-D"KBUILD_BASENAME=KBUILD_STR(iomap)"  
-D"KBUILD_MODNAME=KBUILD_STR(iomap)"  
-c -o arch/arm/mm/.tmp_iomap.o arch/arm/mm/iomap.c

arch/arm/kernel/debug.S: Assembler messages:
arch/arm/kernel/debug.S:167: Error: garbage following instruction -- `ldrne r3,=MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)'
arch/arm/kernel/debug.S:183: Error: garbage following instruction -- `ldrne r3,=MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)'
make[1]: *** [arch/arm/kernel/debug.o] Error 1
make: *** [arch/arm/kernel] Error 2
make: *** Waiting for unfinished jobs....
 &lt;/code&gt;
trace debug.S :167
&lt;code&gt;		addruart r3, r1
&lt;/code&gt;
addruart 定義在 debug-macro.S:
&lt;code&gt;		.macro	addruart, rx, tmp
		mrc	p15, 0, \rx, c1, c0
		tst	\rx, #1			@ MMU enabled?
		ldreq	\rx, =UART_PADDR	@ physical
		ldrne	\rx, =UART_VADDR	@ virtual
&lt;/code&gt;
所以是 UART_VADDR 的定義： (debug-macro.S):
&lt;code&gt;#include &lt;mach/mx51.h&gt;
#define UART_PADDR	MX51_UART1_BASE_ADDR
#define UART_VADDR	MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
&lt;/code&gt;
的 MX51_AIPS1_IO_ADDRESS( ) 沒有展開 (定義)。&lt;br&gt;
這個是定義在 mx51.h。&lt;br&gt;
用 git blame 找一下 debug-macro.S ，發現原來是 include mx51.h ，後來在新增 mx5x.h 後，才改為 include mx51.h..&lt;br&gt;
&lt;br&gt;
改回去就 build OK...&lt;br&gt;
... 但是..&lt;br&gt;
&lt;br&gt;
在 boot argument 加上 earlyprintk 後，bootmessage 在 &lt;code&gt;Uncompressing Linxu... done, booting the kernel.&lt;/code&gt;
後，就沒有 message 了...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-87202558714966283?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/87202558714966283/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=87202558714966283' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/87202558714966283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/87202558714966283'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/enable-ll-low-level-debugging.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8813158219964050950</id><published>2011-09-28T09:18:00.000+08:00</published><updated>2011-09-28T09:18:05.278+08:00</updated><title type='text'></title><content type='html'>&lt;ol&gt;
&lt;li&gt;先看一下 _LL 造成 Assembly MACRO 展開的 error  : 大概看一下就好&lt;/li&gt;
&lt;li&gt;加上 framework, build 一版，注意 partition 問題。 recovery partition不能用，不然就要重新 partition&lt;/li&gt;
&lt;li&gt;那個 DPLL 的 patch 有沒有上&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8813158219964050950?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8813158219964050950/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8813158219964050950' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8813158219964050950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8813158219964050950'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/ll-assembly-macro-error-framework-build.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-5928272980638238410</id><published>2011-09-27T18:42:00.000+08:00</published><updated>2012-02-02T16:50:39.467+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><title type='text'>early_printk, DEBUG_LL</title><content type='html'>承 &lt;a href="http://r40eubuntu.blogspot.com/2011/09/initcall.html"&gt;http://r40eubuntu.blogspot.com/2011/09/initcall.html&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
單看 console 的部份。&lt;br&gt;
&lt;br&gt;
在 start_kernel 的最後 reset_init 用 kernel_thread 執行 kernel_init &lt;br&gt;
&lt;br&gt;
console 好像是 kernel 中很重要的東西(?)，在 kerne/printk.c 中。&lt;br&gt;
說明 cosole 依照開機的階段，分為兩種，這說明寫在 regisgter_console( ) 的前面：
&lt;code&gt;/*
 * The console driver calls this routine during kernel initialization
 * to register the console printing procedure with printk() and to
 * print any messages that were printed by the kernel before the
 * console driver was initialized.
 *
 * This can happen pretty early during the boot process (because of
 * early_printk) - sometimes before setup_arch() completes - be careful
 * of what kernel features are used - they may not be initialised yet.
 *
 * There are two types of consoles - bootconsoles (early_printk) and
 * "real" consoles (everything which is not a bootconsole) which are
 * handled differently.
 *  - Any number of bootconsoles can be registered at any time.
 *  - As soon as a "real" console is registered, all bootconsoles
 *    will be unregistered automatically.
 *  - Once a "real" console is registered, any attempt to register a
 *    bootconsoles will be rejected
 */&lt;/code&gt;
大概翻譯一下：
&lt;pre&gt;為了要讓 printk, early_printk能正常送出 message，要儘早 call register_console( ) 把 console 掛起來。
console 分為兩種：
1. bootconsole : 為了應付kernel boot 前段，真正的 (real) console 還沒決定的時候，所使用的 console
2. real consol : 就真正的 console。
在real console 被 register 後，bootconsole 就會自動被 unregister，然後就再也不允許有人註冊 boot_console 了。
&lt;/pre&gt;
在 arch/arm/kernal/ 下有 early_prink.c，但是要
&lt;code&gt;obj-$(CONFIG_EARLY_PRINTK)      += early_printk.o
 &lt;/code&gt;才會 build 進去。
&lt;br&gt;&lt;br&gt;
在 arch/arm/Kconfig include 的 Kconfig.debug 有option:
&lt;pre&gt;config EARLY_PRINTK
 bool "Early printk"
 depends on DEBUG_LL
 help
   Say Y here if you want to have an early console using the
   kernel low-level debugging functions. Add earlyprintk to your
   kernel parameters to enable this console.
&lt;/pre&gt;
所以要 enable DEBUG_LL (Kernel low-level debugging functions)，才會顯示出來。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-5928272980638238410?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/5928272980638238410/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=5928272980638238410' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5928272980638238410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/5928272980638238410'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/httpr40eubuntu.html' title='early_printk, DEBUG_LL'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2339336471392347642</id><published>2011-09-26T17:22:00.000+08:00</published><updated>2011-09-26T17:22:14.055+08:00</updated><title type='text'></title><content type='html'>vt : virtual terminal (?), 就是 console (?).&lt;br&gt;
在 driver/char/vt.c 有:
&lt;code&gt;
struct vc vc_cons [MAX_NR_CONSOLES];
&lt;/code&gt;
MAX_NR_CONSOLES 定義在 include/linux/vt.h:
&lt;code&gt;
struct vc vc_cons [MAX_NR_CONSOLES];
&lt;/code&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2339336471392347642?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2339336471392347642/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2339336471392347642' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2339336471392347642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2339336471392347642'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/vt-virtual-terminal-console.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-7388255336205705487</id><published>2011-09-26T14:14:00.002+08:00</published><updated>2011-09-26T14:15:37.785+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='iMX51'/><title type='text'>Accessing Registers from User space</title><content type='html'>imxwiki有一篇，用 mmap 方式存取整個 imx51 register 的 user tool: &lt;br&gt;
&lt;a href="http://www.imxdev.org/wiki/index.php?title=All_Boards_AccessingRegisters"&gt;http://www.imxdev.org/wiki/index.php?title=All_Boards_AccessingRegisters&lt;/a&gt;&lt;br&gt;
跟以前寫的一篇一樣：&lt;a href="http://r40eubuntu.blogspot.com/2011/05/read-soc-register-from-devmem.html"&gt;http://r40eubuntu.blogspot.com/2011/05/read-soc-register-from-devmem.html&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
source code 是 GPLed，所以把他copy 到　github (免得不見 XD).&lt;br&gt;
&lt;a href="https://github.com/checko/imx_io_test"&gt;https://github.com/checko/imx_io_test&lt;/a&gt;&lt;br&gt;
Wiki 中有說明從　data sheet 對應到 register address 的方法(?).


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-7388255336205705487?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/7388255336205705487/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=7388255336205705487' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7388255336205705487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/7388255336205705487'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/accessing-registers-from-user-space.html' title='Accessing Registers from User space'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2585019118871978077</id><published>2011-09-23T17:05:00.000+08:00</published><updated>2011-09-30T13:48:42.696+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><title type='text'>hibernate . code trace</title><content type='html'>&lt;code&gt; echo disk &amp;gt; /sys/power/state&lt;/code&gt;
收到的是&lt;br&gt;
kernek/power/main.c : 
&lt;code&gt;static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
			   const char *buf, size_t n)
&lt;/code&gt;
suspend to disk 部份超快，就..
&lt;code&gt;	if (len == 4 &amp;amp;&amp;amp; !strncmp(buf, "disk", len)) {
		error = hibernate();
  goto Exit;
	}
&lt;/code&gt;直接 call kernel/power/hibernate.c 的 hibernate( )&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;br&gt;
snapshot_device_available 被用作 snaphot 的 mutex，初始是 1，使用時 -1。&lt;br /&gt;
也就是說： 1 可用，0 不行。&lt;br /&gt;
所以 kernel code 要操作 snapshot 時，都要先作:
&lt;code&gt; atomic_add_unless(&amp;amp;snapshot_device_available, -1 ,0)&lt;/code&gt;
用來確認 snaphot_device_available 是不是 1 (available)，&lt;br /&gt;
再繼續動作。&lt;br /&gt;
&lt;br /&gt;
實際上依靠 snaphost_device_avaiable 的 function 有：
&lt;br /&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;hibernate()&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;software_resume( )&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;snapshot_open( ) -- user interface of device "snapshot'&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

pm_notifier_call_chain : call blocking_notifier_call_chain( ).&lt;br&gt;
好像有以下幾個 chain:
&lt;ol&gt;
&lt;li&gt;PM_HIBERNATION_PREPARE&lt;/li&gt;
&lt;li&gt;PM_POST_HIBERNATION&lt;/li&gt;
&lt;li&gt;PM_RESTORE_PREPARE&lt;/li&gt;
&lt;li&gt;PM_POST_RESTORE&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
定義在：notifier.h
&lt;code&gt;/* Hibernation and suspend events */
#define PM_HIBERNATION_PREPARE	0x0001 /* Going to hibernate */
#define PM_POST_HIBERNATION	0x0002 /* Hibernation finished */
#define PM_SUSPEND_PREPARE	0x0003 /* Going to suspend the system */
#define PM_POST_SUSPEND		0x0004 /* Suspend finished */
#define PM_RESTORE_PREPARE	0x0005 /* Going to restore a saved image */
#define PM_POST_RESTORE		0x0006 /* Restore failed */
&lt;/code&gt;
&lt;br&gt;
RCU : &lt;a href="http://www.rdrop.com/users/paulmck/RCU/"&gt;Read-Copy-Update&lt;/a&gt; &lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
&lt;code&gt;static int orig_fgconsole, orig_kmsg;

int pm_prepare_console(void)
{
	orig_fgconsole = vt_move_to_console(SUSPEND_CONSOLE, 1);
	if (orig_fgconsole &lt; 0)
		return 1;

	orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE);
	return 0;
}

void pm_restore_console(void)
{
	if (orig_fgconsole &gt;= 0) {
		vt_move_to_console(orig_fgconsole, 0);
		vt_kmsg_redirect(orig_kmsg);
	}
}
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2585019118871978077?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2585019118871978077/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2585019118871978077' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2585019118871978077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2585019118871978077'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/echo-disk-syspowerstate-kernekpowermain.html' title='hibernate . code trace'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-6506481009221632602</id><published>2011-09-23T16:36:00.000+08:00</published><updated>2011-09-23T16:36:09.317+08:00</updated><title type='text'></title><content type='html'>driver/char/vt.c&lt;br&gt;
切換 console:&lt;br&gt;
使用 want_console 跟 console_callback( ) 來完成動作：
&lt;ol&gt;
&lt;li&gt; want_console = new_console;&lt;/li&gt;
&lt;li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-6506481009221632602?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/6506481009221632602/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=6506481009221632602' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6506481009221632602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/6506481009221632602'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/drivercharvt.html' title=''/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8235062201436808812</id><published>2011-09-23T14:09:00.000+08:00</published><updated>2011-09-23T16:36:55.066+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>atomic_add_unless</title><content type='html'>是說：&lt;a href="http://www.fsl.cs.sunysb.edu/kernel-api/re14.html"&gt;add unless valus is the given number&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
arm 版 在 arch/arm/include/asm : atomic.h:
&lt;code&gt;static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
	int c, old;

	c = atomic_read(v);
	while (c != u &amp;&amp; (old = atomic_cmpxchg((v), c, c + a)) != c)
		c = old;
	return c != u;
}
&lt;/code&gt;
然後 cmpxchg 是
&lt;code&gt;static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{
	unsigned long oldval, res;

	smp_mb();

	do {
		__asm__ __volatile__("@ atomic_cmpxchg\n"
		"ldrex	%1, [%3]\n"
		"mov	%0, #0\n"
		"teq	%1, %4\n"
		"strexeq %0, %5, [%3]\n"
		    : "=&amp;r" (res), "=&amp;r" (oldval), "+Qo" (ptr-&gt;counter)
		    : "r" (&amp;ptr-&gt;counter), "Ir" (old), "r" (new)
		    : "cc");
	} while (res);

	smp_mb();

	return oldval;
}&lt;/code&gt;
 就是 swp. armv6 版.&lt;br&gt;
&lt;br&gt;
所以重點在 &lt;code&gt;atomic_cmpxchg((v),c , c+a))&lt;/code&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
關於 atomic 的操作，可以看 Documentation/atomic_ops.txt &lt;br&gt;
&lt;br&gt;
&lt;pre&gt;		Semantics and Behavior of Atomic and
		         Bitmask Operations
&lt;/pre&gt;
這個 documsnt 的說明好像跟實做一饃一樣。&lt;br&gt;
&lt;br&gt;
atomic_t 宣告在 linux/types.h 
&lt;code&gt;
typedef struct {
	int counter;
} atomic_t;
&lt;/code&gt;
宣告後，要初始化： (atomic.h)
&lt;code&gt;
#define ATOMIC_INIT(i)	{ (i) }
&lt;/code&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
這一篇說得很清楚喔： &lt;a href="http://blog.roodo.com/use_the_force/archives/3420371.html"&gt;http://blog.roodo.com/use_the_force/archives/3420371.html&lt;/a&gt;
&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8235062201436808812?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8235062201436808812/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8235062201436808812' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8235062201436808812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8235062201436808812'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/atomicaddunless.html' title='atomic_add_unless'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-1925513360073043320</id><published>2011-09-23T10:21:00.001+08:00</published><updated>2011-09-23T10:21:36.949+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtualization'/><title type='text'>vmware - install vmware tool in ubuntu guest os</title><content type='html'>會要重 build module，所以要安裝 build-essential, linux-header-$(uname -r)。&lt;br&gt;
還有 path 的問題，所以要手動建 link，否則就會有 kernel-header 找不到的問題。&lt;br&gt;
不然就要改 install script。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-1925513360073043320?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/1925513360073043320/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=1925513360073043320' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1925513360073043320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/1925513360073043320'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/vmware-install-vmware-tool-in-ubuntu.html' title='vmware - install vmware tool in ubuntu guest os'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-3381709043192296471</id><published>2011-09-21T15:24:00.000+08:00</published><updated>2011-09-30T13:48:42.713+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><title type='text'>initcall, &amp; hibernate, resume, console.</title><content type='html'>在 include/linux/init.h 有定義：
&lt;code&gt;#define early_initcall(fn)		__define_initcall("early",fn,early)

/*
 * A "pure" initcall has no dependencies on anything else, and purely
 * initializes variables that couldn't be statically initialized.
 *
 * This only exists for built-in code, not for modules.
 */
#define pure_initcall(fn)		__define_initcall("0",fn,0)

#define core_initcall(fn)		__define_initcall("1",fn,1)
#define core_initcall_sync(fn)		__define_initcall("1s",fn,1s)
#define postcore_initcall(fn)		__define_initcall("2",fn,2)
#define postcore_initcall_sync(fn)	__define_initcall("2s",fn,2s)
#define arch_initcall(fn)		__define_initcall("3",fn,3)
#define arch_initcall_sync(fn)		__define_initcall("3s",fn,3s)
#define subsys_initcall(fn)		__define_initcall("4",fn,4)
#define subsys_initcall_sync(fn)	__define_initcall("4s",fn,4s)
#define fs_initcall(fn)			__define_initcall("5",fn,5)
#define fs_initcall_sync(fn)		__define_initcall("5s",fn,5s)
#define rootfs_initcall(fn)		__define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn)		__define_initcall("6",fn,6)
#define device_initcall_sync(fn)	__define_initcall("6s",fn,6s)
#define late_initcall(fn)		__define_initcall("7",fn,7)
#define late_initcall_sync(fn)		__define_initcall("7s",fn,7s)
&lt;/code&gt;
其中 __define_initcall 是：
&lt;code&gt;#define __define_initcall(level,fn,id) \
	static initcall_t __initcall_##fn##id __used \
	__attribute__((__section__(".initcall" level ".init"))) = fn
&lt;/code&gt;
會把 function 放在 .initcall + level 這個section..&lt;br /&gt;
&lt;br /&gt;
在 init/main.c : kernel_init 會
&lt;code&gt;do_basic_setup( )
 --&amp;gt; do_initcalls()
 
static void __init do_initcalls(void)
{
	initcall_t *fn;

	for (fn = __early_initcall_end; fn &amp;lt; __initcall_end; fn++)
		do_one_initcall(*fn);

	/* Make sure there is no pending stuff from the initcall sequence */
	flush_scheduled_work();
}&lt;/code&gt;
在 vmlinux.lds :
&lt;code&gt;. = ALIGN(16); __setup_start = .; *(.init.setup) __setup_end = .;
  __initcall_start = .;
 *(.initcallearly.init) __early_initcall_end = .;
 *(.initcall0.init) *(.initcall0s.init) 
 *(.initcall1.init) *(.initcall1s.init)
 *(.initcall2.init) *(.initcall2s.init)
 *(.initcall3.init) *(.initcall3s.init)
 *(.initcall4.init) *(.initcall4s.init)
 *(.initcall5.init) *(.initcall5s.init)
 *(.initcallrootfs.init)
 *(.initcall6.init) *(.initcall6s.init)
 *(.initcall7.init) *(.initcall7s.init)
 __initcall_end = .;
 &lt;/code&gt;
? 為什摩中間有一個 initcallrootfs ?&lt;br /&gt;
.. 也就是說各 kernel module 中宣告 xxx_initcall( ) 的 function ，都會以上面 define 的次序，在 start_kernel( ) 時，一一被呼叫..

&lt;br /&gt;
&lt;hr /&gt;
&lt;br /&gt;
hibernate.c :
&lt;code&gt;late_initcall(software_resume);
&lt;/code&gt;

因為在 開完後，手動 resume , sh console 是 OK 的，所以改一下 software_resume( ) 的位置...&lt;br /&gt;
從  late_initcall( ) 拿出來，在做完 
&lt;code&gt;/* Open the /dev/console on the rootfs, this should never fail */
	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) &amp;lt; 0)
		printk(KERN_WARNING "Warning: unable to open an initial console.\n");
&lt;/code&gt;
以後再 call，就 OK 了&lt;br /&gt;
----&amp;gt; why ?
&lt;br /&gt;
&lt;br /&gt;
&lt;hr&gt;
&lt;br&gt;
init/main.c :
&lt;code&gt;
start_kernel( )
----&gt; console_init()
----&gt; reset_init( )
--------&gt;kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
------------&gt;sys_open("/dev/console",..)
&lt;/code&gt;
console_init( ) 跟 上面的 initcall 一樣：
&lt;code&gt;void __init console_init(void)
{
	initcall_t *call;

	/* Setup the default TTY line discipline. */
	tty_ldisc_begin();

	/*
	 * set up the console device so that later boot sequences can
	 * inform about problems etc..
	 */
	call = __con_initcall_start;
	while (call &lt; __con_initcall_end) {
		(*call)();
		call++;
		printk("*");
	}
}
&lt;/code&gt;
可以打開 System.map 看 symbol:
&lt;pre&gt;800301c4 T __con_initcall_start
800301c4 t __initcall_con_init
800301c4 T __initcall_end
800301c8 t __initcall_mxcuart_console_init
800301cc T __con_initcall_end
&lt;/pre&gt;其中 __initcall_con_init 和 __initcall_end 是同一個位置，所以實際上只有兩個 function &lt;br&gt;
boot log 會有兩個 *.&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-3381709043192296471?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/3381709043192296471/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=3381709043192296471' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3381709043192296471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/3381709043192296471'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/initcall.html' title='initcall, &amp; hibernate, resume, console.'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8617847086351445208</id><published>2011-09-21T11:51:00.000+08:00</published><updated>2011-09-21T15:43:38.788+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='software_package'/><title type='text'>editor : sublimetext2</title><content type='html'>http://lucifr.com/139225/sublime-text-2-tricks-and-tips/
&lt;br /&gt;
&lt;br /&gt;
挺不錯的 (可惜要錢，還挺貴的 $60)。&lt;br /&gt;
但是開發中免費 (?)&lt;br /&gt;
&lt;br /&gt;
還可以用 vim 的 command 喔...&lt;br /&gt;
http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/
&lt;br /&gt;
&lt;br /&gt;
開啟 Preference -Global Setting - default
&lt;br /&gt;
&lt;hr /&gt;
跟 geany 比：&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;字型漂亮&lt;/li&gt;
&lt;li&gt;排版漂亮&lt;/li&gt;
&lt;li&gt;有支援 vi command&lt;/li&gt;
&lt;li&gt;command line 啟動，每次都會開一個新 session&lt;/li&gt;
&lt;li&gt;沒有 function list --- 要自己弄 ctags ?&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8617847086351445208?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8617847086351445208/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8617847086351445208' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8617847086351445208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8617847086351445208'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/httplucifr.html' title='editor : sublimetext2'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-8520715288784812543</id><published>2011-09-21T10:16:00.000+08:00</published><updated>2011-09-21T13:49:41.446+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iMX51'/><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><title type='text'>build linux dist for imx51</title><content type='html'>解開 _boundle.tar.gz，會有 doc 跟 source。&lt;br&gt;
解開 source，會要你指定 解開的 目錄，也是以後工作的目錄。&lt;br&gt;
解開後，會要確認 license，然後繼續，最後提醒你，到工作目錄去 run ltib&lt;br&gt;
&lt;br&gt;
bsp 用的是 ltib : Linux Target Image Bullder : &lt;a href="http://ltib.org/pages/LTIB_generic_v1.4_-_version_6.4.1.pdf"&gt;http://ltib.org/pages/LTIB_generic_v1.4_-_version_6.4.1.pdf&lt;/a&gt;
&lt;br&gt;
整個 build 動作用 rpm，所以會檢查：
&lt;code&gt;Package                Minimum ver   Installed info
-------                -----------   ---------------
rpm                    0             not installed
rpm-build              0             not installed
&lt;/code&gt;
這兩個command都在 rpm 這個 package，所以 aptitude install rpm 就可以了。&lt;br&gt;
&lt;br&gt;
會先 build 自己需要的 tool (即使 host 已經有一套)，會放在 /opt/freescale/ltib/&lt;br&gt;
出現 error。&lt;br&gt;
看一下 host_config.log..
&lt;code&gt;compr_lzo.c:29:23: error: lzo/lzo1x.h: No such file or directory
&lt;/code&gt;
因為沒有 liblzo2-dev。&lt;br&gt;
裝完後繼續 ./ltib，會有 error，所以手動把  /opt/freescale/ltib/usr/src/rpm/BUILD/mtd-utils 目錄刪除，再作 ./ltib&lt;br&gt;
&lt;br&gt;
又有 error:
&lt;code&gt;mkfs.ubifs.h:48:23: error: uuid/uuid.h: No such file or directory
&lt;/code&gt;
裝 uuid-dev ，手動刪掉 /opt/freescale/ltib/usr/src/rpm/BUILD/mtd-utils 後繼續..&lt;br&gt;
&lt;br&gt;
host tool 都　build 完後，開始 build target image，會出現一個 selection menu..&lt;br&gt;
選好繼續....&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
build gnome dist 的話，會要一堆 lib-dev，碰到 error 時再裝就可以。&lt;br&gt;
&lt;br&gt;
有一個 error:
&lt;code&gt;make[2]: Entering directory `/home/charles-chang/L2.6.35/ltib/rpm/BUILD/gtk+-2.14.3/demos'
no --raw --build-list		\
	        apple_red  ./apple-red.png	\
                gnome_foot ./gnome-foot.png	\
        &gt; test-inline-pixbufs.h				\
	|| (rm -f test-inline-pixbufs.h &amp;&amp; false)
/bin/bash: no: command not found
make[2]: *** [test-inline-pixbufs.h] Error 1
make[2]: Leaving directory `/home/charles-chang/L2.6.35/ltib/rpm/BUILD/gtk+-2.14.3/demos'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/charles-chang/L2.6.35/ltib/rpm/BUILD/gtk+-2.14.3'
make: *** [all] Error 2
error: Bad exit status from /home/charles-chang/L2.6.35/ltib/tmp/rpm-tmp.29984 (%build)
&lt;/code&gt;
在這一篇 (http://ubuntuforums.org/showthread.php?t=962233 ) 說是缺 mono-mcs。
&lt;br&gt;
sudo apt-get install libgdk-pixbuf2.0-dev&lt;br&gt;
&lt;br&gt;
這一篇 : http://forums.freescale.com/t5/i-MX-Microprocessors/iMX25-SDK-LTIB-error-with-Ubuntu/td-p/52117&lt;br&gt;
&lt;br&gt;
說，安裝後，要刪掉 BUILD/gtk+ .. 後再 build 一次。&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;哪個 no : command not found，去 gtk/demo/Makefile 看，是 某個 tool : csource 變數設定是 no。&lt;br&gt;
猜是這個是 autoconfig probe 出來的，system 沒有，就寫 no。所以 install necessary package 後，要刪掉 build folder，這樣才會重 run 一次 autoconfig，重新產生 Makefile..&lt;br&gt;
&lt;br&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-8520715288784812543?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/8520715288784812543/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=8520715288784812543' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8520715288784812543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/8520715288784812543'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/boundle.html' title='build linux dist for imx51'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-9144164187845345740</id><published>2011-09-20T12:08:00.002+08:00</published><updated>2011-10-03T15:14:28.577+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>github kerel source of various android tablet</title><content type='html'>這人很好新的蒐集了一些 android tablet 的 kernel source code:&lt;br&gt;
&lt;a href="https://github.com/richardtrip"&gt;https://github.com/richardtrip&lt;/a&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-9144164187845345740?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/9144164187845345740/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=9144164187845345740' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/9144164187845345740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/9144164187845345740'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/github-kerbel-source-of-various-android.html' title='github kerel source of various android tablet'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-59345686725815191.post-2626808965401407687</id><published>2011-09-19T11:29:00.001+08:00</published><updated>2011-10-03T15:16:11.198+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='工作的備worklog'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernation'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>swsusp for imx51 : worklog</title><content type='html'>software_resume ( ) 進行 image check, image restore 後，就做 hiberate_restore( )，然後就不會回來了 (?) ...&lt;br&gt;
&lt;code&gt;
/**
 *	hibernation_restore - quiesce devices and restore the hibernation
 *	snapshot image.  If successful, control returns in hibernation_snaphot()
 *	@platform_mode - if set, use the platform driver, if available, to
 *			 prepare the platform firmware for the transition.
 *
 *	Must be called with pm_mutex held
 */

int hibernation_restore(int platform_mode)
{
	int error;
	gfp_t saved_mask;

	pm_prepare_console();
	suspend_console();
	saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
	error = dpm_suspend_start(PMSG_QUIESCE);
	if (!error) {
		error = resume_target_kernel(platform_mode);
		dpm_resume_end(PMSG_RECOVER);
	}
	set_gfp_allowed_mask(saved_mask);
	resume_console();
	pm_restore_console();
	return error;
}
&lt;/code&gt;
根據 comment, run 完會回到 hibernate_snapshot( ) , 猜是 stack 變更，所以這個 function return 回去會到 hibnation_snapshot( ).&lt;br&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
卡在 kernel_imx/driver/base/power/main.c 的 dpm_resume( ) 的：
&lt;code&gt;	while (!list_empty(&amp;dpm_list)) {
		dev = to_device(dpm_list.next);
		get_device(dev);
		if (dev-&gt;power.status &gt;= DPM_OFF &amp;&amp; !is_async(dev)) {
			int error;

			mutex_unlock(&amp;dpm_list_mtx);

			error = device_resume(dev, state, false);

			mutex_lock(&amp;dpm_list_mtx);
			if (error)
				pm_dev_err(dev, state, "", error);
		} else if (dev-&gt;power.status == DPM_SUSPENDING) {
			/* Allow new children of the device to be registered */
			dev-&gt;power.status = DPM_RESUMING;
		}
		if (!list_empty(&amp;dev-&gt;power.entry))
			list_move_tail(&amp;dev-&gt;power.entry, &amp;list);
		put_device(dev);
	}
&lt;/code&gt;
中間有 mmc0: error -110 during reumse (card was remved?) 的 error.&lt;br&gt;
==&gt; 拿掉 mmc0 的 driver ，雖然 error 不再發生了，但是還是一樣卡住...約 48 sec 後才完成這個section。
&lt;br&gt;&lt;br&gt;
拿掉 使用 dma 的 uart 後，經過 48 sec 的 resume後，沒有　core dump 了， kernel msg 可以正常的輸出，但是 console input 還是沒回應。&lt;br&gt;
==&gt; 將所有uart 的   DMA 都關掉後，雖然還是要 48 sec，但是 resume 後已經沒有 core dump 了 .... console 依然不回應 ..&lt;br&gt;
&lt;br&gt;
在 get_device( )後印出 device 的 init_name，還有 dev-&gt;driver-&gt;name。發現好像是 pmic_adc 和 pmic_leds 卡住。
&lt;br&gt;&lt;br&gt;
拿掉 pmic_led,  pmic_backlight (從 menuconfig 拿掉).&lt;br&gt;
==&gt; 剩下 pmic_adc 需要 10 幾秒的 resume 時間，而且是卡在 pmic_adc_resume( ) 中..&lt;br&gt;
&lt;br&gt;
拿掉 pmic_adc_resume( ) 中 對 register 的 read/write code 後，就沒有卡住了。&lt;br&gt;
==&gt; 但是 console 還是沒反應..&lt;br&gt;
&lt;br&gt;
拿到 uboot 的 resume=? 參數，等開機進入 kernel 後，再用手動 echo 179:4 &gt; /sys/power/resume&lt;br&gt;
==&gt; console 有反應.....所以原因是？ .. root 是 ramdisk ?.. console not setup correctly ?&lt;br&gt;
&lt;br&gt;
因為 android dev 在 mmcblk 加入一層 block，和kernel 不一樣。&lt;br&gt;
所以，在kernel boot phase，要用以前的 /dev/mmcblk0p4，而不是開機完後的，/dev/block/mmcblk0p4&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/59345686725815191-2626808965401407687?l=r40eubuntu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://r40eubuntu.blogspot.com/feeds/2626808965401407687/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=59345686725815191&amp;postID=2626808965401407687' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2626808965401407687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/59345686725815191/posts/default/2626808965401407687'/><link rel='alternate' type='text/html' href='http://r40eubuntu.blogspot.com/2011/09/softwareresume-image-check-image.html' title='swsusp for imx51 : worklog'/><author><name>Checko</name><uri>http://www.blogger.com/profile/03239306354367907990</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://photos1.blogger.com/blogger/669/302/320/IMGP0803.jpg'/></author><thr:total>0</thr:total></entry></feed>
