ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年12月29日 星期四

microcom : busybox version minicom

Busybox 提供一個 serial port 通訊程式,類似 minicom。

microcom -d 1200 -s 115200 /dev/ttyUSB3 : 設定 character timeout 是 1200ms,baudrate 是 115200,對 /dev/ttyUSB3 動作。


package 有問題,ref: http://r40eubuntu.blogspot.tw/2013/10/uart-terminal-with-log-microcom.html

android root fs file,dir attribute

android root 的directory, file attribute 是在製作 root image 時就設定的。
permission 的設定是在 system/core/include/private/android_filesystem_config.h 實際reference ,使用的是: system/core/cpio/mkbootfs.c

2011年12月28日 星期三

CHT E180 (Huawei) 3G dongle in Debian

中華電信的 E180 3G dongle ,實際插入後看 VID, PID 不是 E180。
idVendor=12d1, idProduct=140c 但是和網路上 140C 的 Huawei dongle 不一樣的是,這個(fake) E180 是同時有 3G modem, CD ROM + card reader 三種 device profile 同時啟動。
所以不必用 usb modeswitch 來切換到 usb serial mode。

插入後會看到 6 個裝置:
  1. ttyUSB0-3
  2. CD-ROM
  3. Direct Access ,SD Storage
插入後,用 debian 內建的 network manager 就可以,
依照 SIM card 選 Taiwan, CHT (emome) 就會設定好 APN, dial number..

然後就可以上網了。

Network manager 一旦關閉掉這個 mobile 連線 後,要再重新插拔一次dongle 才會出現..(很慢,大約要 15 sec)。



寄一下這個 sim card 的 default gw 是:10.64.64.64 route : 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


ttyUSB3 好像是 control port,但是一上電,會自動,定期送: ^BOOT:32614906,0,0,0,20 ^SRVST:1 ^MODE:5,4 ^STIN:0,0,0 ^RSSI:13 ^RSSI:13 .. 依照 這一篇(http://forum.huawei.com/jive4/thread.jspa?threadID=328818) 的說法,下 AT^CURC=0 就可以停止這些 unsolicied response.

2011年12月26日 星期一

usb ethernet -- android & linux

開啟 USB Tethering 後...可以參考http://support.google.com/mobile/bin/answer.py?hl=en&answer=182134
文章是說明 XP 的,沒有Linux 的原因是,linux native support ..(?)

實際插入後,dmesg 看.. [ 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 所以host 要 support,要 enable cdc_ether ,還有 rndis_host。

在 driver/net/usb/Makefile 有: obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
有關 USB_NET_CDCETHER : config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)" depends on USB_USBNET default y
所以要 enable USB_USBNET: config USB_USBNET tristate "Multi-purpose USB Networking Framework" select MII 還有,這些是屬於... menu "USB Network Adapters" depends on USB && NET

2011年12月23日 星期五

Use wlan & in-office nic

大概就是
  1. 公司內部的server ,用 eth0
  2. 外部,用 wireless
因為wireless 用 3G-Ap,沒有鎖 port, site。

方法:

就是改 route table,把公司的 ip 導到 eth0,其他都是 wlan0

wireless, ethernet 都接上後, route : $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 公司內部又分很多 sub network,我的ethernet 好像是在 192.168.144.0 網段,
所以仙家一下: $sudo route add -net 192.168.144.netmask 255.255.255. dev eth0 然後加上要 access 的 server: $sudo route add -host 191.168.147.233 gw 192.168.144.254 dev eth0 因為公司有分很多 sub net, 144 網段的 gateway 是 254。

這樣就可以了,
-- check 一下 default gw,要是 wireless 的 192.168.43.1。
如果有新增加eth 的 gw,要刪除掉。


還有接上外部網站變慢是 dns 的關係,注意要把 dns 加到 route path 中: sudo route add -host 192.168.147.15 gw 192.168.144.254 dev eth0



一個一個加很白痴,就設 192.168.147.0 的 gw 是 192.168.144.254 就好..
sudo route add -net 192.168.147.0 netmask 255.255.255.0 gw 192.168.144.254 dev eth0

enable dell inspiron N4010 wireless module

先 lspci 看一下 wireless module 是.. 04:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g/n Wireless LAN Controller (rev 01) 或是用 lshw --class network 看 *-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 知道是 BCM4313

然後 google 到這一篇:http://wiki.debian.org/brcm80211
照著作,安裝 firmware-brcm80211,然後 modprobe..
-- 奇怪我第一次 modprobe 沒效, -r 後再 一次才 iwconfig OK.

裝進去後,就可以在 GUI networkmanager applet看到...
... 就可以操作了..

2011年12月20日 星期二

3G 開通紀錄

紀錄一下,3G 開通。

2011年12月15日 星期四

Activity Stack 只留一個 app (act)

其實就是 setAlwaysFinish 就可以。
-- 如果可以把 system setting 的 default 就設 enable 應該比較漂亮。

不然就在 Code 中: import android.app.ActivityManagerNative; import android.util.Log; try { ActivityManagerNative.getDefault().setAlwaysFinish(true); } catch (RemoteException ex) { Log.d(TAG,"setAlwaysFinish failed!!"); } 結果可以用 adk 的 hierarchyviewer 來看。

2011年12月14日 星期三

use sqilt3 command to show the system settings

android 的 system settings 存放在 sqilt3 database 裡。
所以可以用 sqilt3 command 來檢視/變更。

先開啟 database: #sqilt3 /data/data/com.android.providers.settings/database/settings.db 顯示 所有內容: sqilte>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> default 沒有 show 欄位名稱,可以用: sqlite>.header on 打開,然後再顯示一次.. sqlite> 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 ...

limit max process & immediately destroy activity

限制 max activity 的code 是在./services/java/com/android/server/am/ActivityManagerService.java
其中的trimApplication()

call trimApplication 的有:
  1. activityStopped
  2. unregisterReceiver
  3. finishReceiver
另外,還有./services/java/com/android/server/am/ActivityStack.java 的
  1. activityIdleInternal
是在handleMessage( ) 中呼叫。
呼叫的時機:
  1. IDLE_TIMEOUT_MSG
  2. IDLE_NOW_MSG
還有 ./services/java/com/android/server/am/ActivityManagerService.java 的
activityIdle


除了以上的code,在 trimApplication( ) 中可以看到,mProcessLimit 也可以用來限制 activity 的數量。

mProcessLimit 的存取 方法是:
  1. setProcessLimit
  2. getProcessLimit
這個 SET_PROCESS_LIMIT 好像也是 app 的 permission。

在 developement Setting 的 writeProcessLimitOptions( ) 使用到

這個就是 Immediately Destroy Activity 的上一個選項 max process limit (?)

但是實際測試, max process limit=1,和 immediately destroy activity 好像效果不一樣。
以 播放影片的 Gallery 為例:
程式進入,是 GalleryPicker, 選好 folder 後,再開啟 ImageGallery。

當 enable immediately destroy activity 時,可以正常動作。
但是 set max process limit=1 卻不行,要開啟 ImageGallery 時,就 fail 回到GalleryPicker。

activity hierarchy

android 的 activity 是像 stack 一樣堆疊起來。
android sdk 提供一個 tool,讓你看activity stack 的狀態: hierarchyviewer 是 GUI 介面,會自動 update。
用這個 tool,可以看到 stack 的狀態。

實際測試,可以知道 在 app 中按下 HOME key,只是把 launcher 叫出來,原app 被 push 到 stack。

要在該 app 按 BACK,才會從 activity stack 中剔除。

另外,配合上一篇的內容。

當 enable "Immediately destroy activies" 的話。
activity stack 只會留最上面的 app,一旦被推到後面的 app,會從 stack 中移除。
-- 就像按下 BACK 一樣。

但是這只限於 activity。
app 中的 service 並不受影響。




hierarchyviewer 有兩個,一個是 eclipse 的 perspective view,另一個在 out/host/linux-x86/bin 下。
這邊用的是 eclipse 的

update flashplayer 11 for debian squeeze

最近 squeeze 的 chrom 一直 complain flash player plugin 太舊,所以不執行。

所以到 adobe 網站去download,但是沒有 debian 的版本。
只好 download tar.gz 版,自己解開。

google 一下手動安裝。
好像就是把 libflashplayer.so copy 到某個目錄就可以。
其他 /usr /,... 的,大概是因為原來就有 install none-free 版的 rev 10,所以不必用。

這樣,就只要把解開的 libflashplayer.so 覆蓋掉 /usr/lib/flashplugin-nonfree/libflash.so
然後重開 chrome 就可以..

至少沒有 complain,然後 youtube 播放 OK。

test android app state

看看 app 內部的變數,會因為 HOME, BACK 後重啟動而有不同嗎?
test app 就是用 一個 button,按一下 increase 一次 counter,然後看每次啟動 counter 是否被 reset。

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)); } 結果..

啟動 app,按button 3 次後, button 顯示 3,然後:
  1. 按下 HOME 後再重新啟動:一樣是 3
  2. 按下 BACK 後再重新啟動:顯示 0 (被 reset)
所以 HOME key 並不會destroy app... back 才會。

實際上, HOME 沒有 destroy app 的說法不一定成立。
.. 到 development setting,設定 "immediately destroy activity"
這樣按 HOME key 每次都會 destroy app..

看 logcat message... enable "immediately destroy activity" 時,
按下 HOME key 的行為就像按下 BACK 一樣 (對單一 activity 的 app 而言)。

android app, input

android 的每個 app 好像都是一個包含完整的 framework 程式。
舉例來說:
framework 的 keyinput 機制,包含在每個 app 中。
所以當按下 HOME 鍵,會因為 app 中的 input framework 會收到 KEYCODE_HOME。

因為 framework 的 input framwework 有處理 HOME key,並且寫好了對 KEYCODE_HOME 的動作: sent intent to HOME。
所以會叫起 Launcher。
....
也就是說,按HOME 鍵,其實是 app 處理 (並沒有一個 處理 home key 的 server process)。 app 裡的 input framework code ,叫起 HOME launcher。

create button without using xml

完全寫在 code 裡的方法, layout 和 button 都不用 xml 定義。
from : http://toimy.blogspot.com/2010/07/android.html
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"); } ..

2011年12月13日 星期二

create android project from command line

就是 follow 這一篇: http://developer.android.com/guide/developing/projects/projects-cmdline.html
用 android sdk 提供的 tool : android,來 create project ,
也就是說,幫你把 一堆 xml, java, folder 都create 好,然後填一些基本的東西。

command example: android create project \ --target 1 \ --name MyAndroidApp \ --path ./MyAndroidAppProject \ --activity MyAndroidAppActivity \ --package com.example.myandroid target 的內容可以用 command: 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 path 選項,如果 path 不存在,就會幫你create。
這樣做完後,follow 上一篇,加上 Android.mk ,就可以 build 了。

.. 會出現 error: Android make apk error:This attribute must be localized. 參考這一篇:http://jjnnykimo.pixnet.net/blog/post/31996155-android-make-apk-error%3Athis-attribute-must-be-localized.
把原來寫死的 layout/main.xml 字串,改在 value/string.xml 中,就可以了。

另外這一篇 http://www.kandroid.org/online-pdk/guide/build_cookbook.html 有提供一些 template 寫 Android.mk

2011年12月8日 星期四

some tools from SE released source

Sony-Ericson release 的 source code有一些東西:
  1. kexec-tools : running system 抽換 kernel 的 tool , (當然 kernel 要有 enable kexec 才行)
  2. inputattach : 把新的 serial input device 加到 kernel 的 input system 中 (例如搖桿)
可惜一般的 android kernel 不會 enable KEXEC。所以要用 1 的話,可能要重 build kernel。
2 的話,可能可以用在bluetooth 搖桿上...
bt 搖桿 --> serial 裝置 --> attach 到 kernel input interface

這樣就可以直接 support 利用 kernel input interface 操縱的 ap/system (android support ?)

2011年12月7日 星期三

init/main.c 的 start_kernel : setup_arch(&command_line)
kernel/setup.c 的 __init setup_arch(char **cmdline_p)
  有加 _init,會不會後來又再 run 一次? 
code: struct tag *tags = (struct tag *)&init_tags; struct machine_desc *mdesc; char *from = default_command_line; mdesc = setup_machine(machine_arch_type); machine_name = mdesc->name; if (mdesc->soft_reboot) reboot_setup("s"); if (__atags_pointer) tags = phys_to_virt(__atags_pointer); else if (mdesc->boot_params) tags = phys_to_virt(mdesc->boot_params); else init_tags.mem.start = PHYS_OFFSET; __atags_pointer 是 uboot 傳遞參數的位址,boot_params 也是。

這裡的 boot loader 好像都沒有用,所以是用 PHYS_OFFSET。
這個 constant 每個 chip 定義不一樣。

/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) 所以是 MX51 是 0x90000000

property_set/get in android

android 的 property 系統也是一種 IPC 的方法 (用在跟 system 溝通上).
一般 c program 可以用 property_set, property_get 來設定/取得 property 值。

property related function 實做在 system/core/libcutils/propertied.c
基本上就是用 local socket 跟 PROP_SERVICE_NAME 溝通。

property service 好像是在 init 就啟動了.. 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 < 0) return; fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFL, O_NONBLOCK); listen(fd, 8); property_set_fd = fd; } core/init 這個 process 最後,好像就是在做 property_service.. main() 的最後: for(;;) { ... ... nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < 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(); } } } ufds 就是剛剛 create_socket(PROP_SERVICE_NAME...) 的 fd

這個 source file : core/init/property_service.c 有所有 property 的操作。

像:
persistant property value (以 persistant. 開頭的 property)存放方式,位置: #define PERSISTENT_PROPERTY_DIR "/data/property"

2011年12月5日 星期一

"adb server is out of date. killing"

啟動 adb 時,會出現:"adb server is out of date. killing"。
因為 adb server 被重啟動,所以沒有辦法建立兩個連線。

查這段 message "adb server is out of date. killing",是在 ./system/core/adb/adb_client.c:251: printf("adb server is out of date. killing...\n"); 是 compare version: 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", &version) != 1) goto error; } else { ........ } .... if(version != ADB_SERVER_VERSION) { printf("adb server is out of date. killing...\n"); 就是去詢問 host adb server 的版本,然後和自己比較。
不一樣就 print msg & restart



就在我加上 debug message (print out version),重新 run 後,就 OK 了
===> 所以說,我 pc 上的 adb 版本太舊了...

2011年11月28日 星期一

libusb-1.0.0.8 for android

就 這篇 http://android.serverbox.ch/?p=151http://my0613.blogspot.com/2010/11/porting-lsusb-libusb-on-android.html 分別是 libusb 和 lsusb。

porting lib 還是和以前一樣,要先run ./configure. 產生 config.h,然後再自己改成 for android 的配置。

然後加入 Android.mk (兩個)

再修改一下 build error 的 file



我的 config.h: /* 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 header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the 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 header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the 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
我的 external/libusb-1.0.0.8/Android.mk: LOCAL_PATH := $(call my-dir) subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ libusb \ examples \ )) include $(subdirs)
我的 external/libusb-1.0.0.8/libusb/Android.mk 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)
我的 external/libusb-1.0.0.8/example/Android.mk 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)



  1. download libusb-1.0.0.8, unzip to external (result in a external/libusb-1.0.0.8)
  2. run ./configure -disable-timerfd
  3. modify libusb/io.c
    加上#define TIMESPEC_TO_TIMEVAL(tv, ts) \ do { \ (tv)->tv_sec = (ts)->tv_sec; \ (tv)->tv_usec = (ts)->tv_nsec / 1000; \ } while (0)
  4. add 3 Android.mk files
OK to build, mm
sync to target, run 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)
不用 mount usbfs /proc/bus/usbfs 就可以動作(?)

查 libusb/os/linux_usbfs.c : 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; } 用的是 /dev/bus/usb



2008 這篇 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=483392 有說不要再 mount /proc/bus/usbfs,請直接用 /dev/bus/usb..

但是到現在好像還很多人在用...

2011年11月24日 星期四

Keyboard shortcut (Hotkey) in Android

Android 有 keyboard shortcut 功能,就是自己定義按著 Search 時,同時按下某個 key 就 啟動 XX app (可以自訂)。

但是要在有 keyboard 的 機器 上那個設定畫面才會出現。

這個功能一樣做在 PhoneWindowManager.java 的 interceptKeyBeforeDispatching
在 HOME, MENU, CALL,, 等等 KEYCODE 的判斷後面...
// Shortcuts are invoked through Search+key, so intercept those here if (mSearchKeyPressed) { if (down && repeatCount == 0 && !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; } } } 一樣用 startActivity( ) 叫起 app (intent),那個 對應哪個 key,都在ShorcutManager 的 database (bookmark) 中紀錄。



Setting 部份的 source code 在 src/com/android/settings/ApplicationSettings.java
如果沒有 physical keyboard,就移除這個 Setting: 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); }
實際設定的 class 是 quicklaunch


如果要作假...
以叫起 browser (S-B) 為例..,
  1. 送出一個 SEARCH KEY Down : 217, down
  2. 送出一個 b Key down, up : 48, down,up
  3. 這時候就可以看到 browser 已經被叫起來了
  4. 送出一個 SEARCH KEY Up : 217 up
keycode 定義可以看 ./include/linux/input.h
-- 新版 (3.0.X) 在 /include/uapi/linux/input.h



自己紀錄一下,就是:
  1. cd /sys/devices/platform/virkeyboard/
  2. echo D217 > vmevent
  3. echo 48 > vmevent -- 可以看到 browser 起來了
  4. echo U217 > vmevent

HOTKEY to launch HOME launcher

收到 KEYCODE_HOME 後: launchHomeFromHotKey();
launchHomeFromHotKey 中 laucn Home 的 code: try { ActivityManagerNative.getDefault().stopAppSwitches(); } catch (RemoteException e) { } sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); startDockOrHome();
  1. stopAppSwitches()
  2. sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY)
  3. startDockOrHome()



stopAppSwitches():

好像是停止 app switch 5 sec.


sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY):

是 call : ActivityManagerNative.getDefault().closeSystemDialogs(reason); 就是把 windws map 叫出來,一個一個 send message: Message msg = Message.obtain(); msg.what = CLOSE_SYSTEM_DIALOGS; msg.obj = reason; sendMessage(msg);

startDockOrHome:
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)

... framework 自己也用 startActivity...

Add app project in android build system

google 的說明文件有 如何用 android 的 build 系統 build apk:
http://www.kandroid.org/online-pdk/guide/build_cookbook.html

copy 一些過來:

Android system 用 Android.mk,簡單的 apk 可以用: 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) 把這個 Android.mk 放在 app 的 folder 中就可以。
... LocalPackage 就是最後 apk 的 filename


這一篇是說明把 Eclipse create 的 project folder 搬到 Android root 中 build 的方法:
http://owenhuangtw.pixnet.net/blog/post/23935524-using-android-bluetoothdevice-class-to-control-blue-deivce

.. 好像就是把 Android.mk 放進去就可以了 (?)

用 eclipse create 的 project 如果有 build 過,搬到 android root 後,要把 gen, bin 清掉,不然 build 會有 R.jar 的 error。

其實 developement/sample 下每一個 project 都是 用這個方法。
可以參考


很奇怪,給 file path 就不行,可以的是用 MediaScanner scan 過後,再傳 uri 過去。
所以可能要自己 scan,
example 在 development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java:

scan 單檔的 方法:
            File path = Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES);
            File file = new File(path, "DemoPicture.jpg");
            .....
            .....
            // Tell the media scanner about the new file so that it is
            // immediately available to the user.
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                    Log.i("ExternalStorage", "Scanned " + path + ":");
                    Log.i("ExternalStorage", "-> uri=" + uri);
                }
            });

2011年11月23日 星期三

forceStopPackage

ActivityManager.java: public void forceStopPackage(String packageName) { try { ActivityManagerNative.getDefault().forceStopPackage(packageName); } catch (RemoteException e) { } }
call 的是ActivivityManagerProxy Implement IActivityManager: 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(); }
mRemote transact 經由 IBinder 傳送 FORCE_STO_PACKAGE_TRANSACTION 需求。
收到並執行的是
在 ActivityManagerNative 的 onTransact(): case FORCE_STOP_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); forceStopPackage(packageName); reply.writeNoException(); return true; }
onTransact 的 case handler
呼叫的是ActivityManagerService 的 forceStopPackage(?): IPackageManager pm = AppGlobals.getPackageManager(); int pkgUid = pm.getPackageUid(packageName); forceStopPackageLocked(packageName, pkgUid);
就是從 package manager 找出 packageName 的 pid,然後 call forceStopPackageLocked( ) 結束他。


其中的 forceStopPackageLocked 是: 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); } 就是call forceStopPackageLocked( ) 結束他,然後再 broadcast ACTION_PACKAGE_RESTARTED.. (叫他再起來?)

Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); while (badApps.hasNext()) { SparseArray ba = badApps.next(); if (ba.get(uid) != null) { badApps.remove(); } } 把 mProcessCrashTime (上次system crash 時的 proces map) 中,同 uid 的 process data 從 record map 中移除。


boolean didSomething = killPackageProcessesLocked(name, uid, -100, callerWillRestart, doit); 然後 killPackageProcessLocked( ).


for (i=mMainStack.mHistory.size()-1; i>=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"); } } 然後再從 目前系統 activiry stack (所有執行過的 activity) 中,找出符合name 的package,作 RESULT_CANCELED 的 finishActivityLocked( )。



後面看起來會把 activity stack 中 下一個 activity resume 回來 (到 top)。

如果 stack 是空的,就 launch home launcher
trace code 的其中一點,最後是用 kill 把 process 殺掉。

2011年11月17日 星期四

Keypad action in Android Framework

keyboard input (包含 home, power, menu, back..etc) 的動作是在 framework/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags, int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags) { 可以看到這個 function 根據狀況決定HOME key 要不要處理。
同時還處理 SEARCH , MENU。

所有的 keyevent,會先進到這裡,再到其他地方。

經過這個篩選後,key 會到 framwork/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
  1. protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event)
  2. protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event)
keydown 是主要作動作的地方,keyup 只是detect longpress 的 cancel。
像 KEYCODE_CAMERA 就會執行下面的code: 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); .. close current window & launch CAMERA app

在這裡處理的還有:
  1. KEYCODE_VOLUME_UP/DOWN
  2. KEYCODE_MEDIA_PLAY_PAUSE
  3. KEYCODE_MUTE:KEYCODE_HEADSETHOOK.KEYCODE_MEDIA_STOP:KEYCODE_MEDIA_NEXT:KEYCODE_MEDIA_PREVIOUS:KEYCODE_MEDIA_REWIND:KEYCODE_MEDIA_FAST_FORWARD:
  4. KEYCODE_MENU
  5. KEYCODE_BACK
  6. KEYCODE_CALL
  7. KEYCODE_SEARCH
所以有 自己新增的 button 要作到 HOT-KEY 功能的,都可以作到這裡。

2011年11月14日 星期一

Matthew Garrett 解決 2.6.38 開始,耗電增加 30% 的問題:ASPM

http://www.phoronix.com/scan.php?page=article&item=linux_aspm_solution

這篇說明 linux kernel 從 2.6.37 進到 2.6. 38 後,耗電增加 30% 的問題。
因為 38 開始依照 bios 回報的內容,開啟/關閉對 PCIe 裝置的電源管理功能...
...
結果...
.. 一堆裝置都回報他門沒有電源管理功能...
.. 所以 kernel 就不管他門了...就放著耗電...


後來 Matthew Garrett 參考 Windows Vista,發現 windows 都還是有管耶。
然後就 follow hardware 的 window driver inf 檔,決定要不要管。 (而不是依照 hardware 的回報)。

就這樣...



... 就說...照 datasheet 寫code的是笨蛋.. (一定會被騙...)

imx51 : SION bit in GPIO config

http://imxcommunity.org/forum/topics/how-to-use-the-sion-bit
說明. GPIO 的 SION bit 就是把 gpio 的 pad 接到 input 端 -- 不管是configure 成 output 還是 input。

說明是以 SD_CMD 為範例。
CMD 是雙向 ,output 完馬上就改 input, read ack。
所以要把 CMD pin 的 SION bit 打開

2011年11月11日 星期五

android, bionic , overview & test program

android 的 bionic 沒有 support pthread_cancel。
 -- 其實還有很多不 support 的,說明在 libc/doc/overview.txt.

另外 android 也提供 bionic libc test code,在
/system/extras/tests/bionic/libc
一般是不會 build 進 system。

可以用
    cd system/extras/tests/bionic/libc
    mm BIONIC_TESTS=1



  1. 這一篇有很好的說明:http://codingrelic.geekhold.com/2008/11/six-million-dollar-libc.html
  2. 這一篇遇到pthread_cancel 不 support ,他workaround 又遇到Dalvik 共用..之後的解決方法: http://blogs.mentor.com/hollisblanchard/blog/tag/android/

2011年11月10日 星期四

ADV7180 detect the video signal discontinue

ADV7180 的 STATUS 3 :
  • bit 4 FREE_RUN_ACT : 沒偵測到signal,所以 output blue screen 中
  • bit 5 STD FLD LEN : 使用目前的 standard 解 video frame 得到的 Field Length 是正確的
  • bit 6 Interlaced : 偵測到 interlaced frame
有些low-end, ill-designed, 亂寫code的 video output device,輸出不太正確的 video signal,會導致 application processor 的 camera input module 錯誤。
可以利用這幾個 bit 來偵測。

當 4 出現代表目前沒信號。
當 5 沒出現,代表 scan line 有錯
當 6 沒出現,代表 沒有偵測到 interlaced frame


但是要用這個 register 有一個限制,要在每一個 frame 都讀一次,否則會被新的 frame 狀態 update ,就抓不到 frame lost 的瞬間了...

2011年11月9日 星期三

dynamic_debug in kernel

kernel 裡面有很多 pr_debug,這是被合 dynamic_debug 這個功能的 printk function。
在 Documentation/dynamic-debug-howto.txt 有說明。

大概就是:
  1. menuconfig 圈選 dynamic_debugCONFIG_DYNAMIC_DEBUG=y
  2. 系統啟動後,手動 mount debugfs : #mkdir /mnt/debugfs #mount -t debugfs none /mnt/debugfs
  3. 把 /mnt/debugfs/dynamic_debug/control 打開來看..
  4. control 會列出所有 pr_debug 所在的source file 和位置,用 echo ... 可以把該 pr_debug 打開或關閉


control 檔的內容大概是: ... 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" .. 中間那個 "-" 就代表不印出來,
若是 "p" 就代表要印出來。

所以要是希望 mxc_v4l2_capture.c 裡所有的 pr_debug 都印出來,可以用: echo 'file mxc_v4l2_capture.c +p' > control 如果不要了,就用: echo 'file mxc_v4l2_capture.c -p' > control 如果只是要第 617 行的 stop preview 印出來,就用: echo 'file mxc_v4l2_capture.c line 617 +p' > control
  1. 雖然是enable print,但是 print level 還是follow 當初source code 寫得,所以有些還是要用 dmesg 才會看得到。
  2. 可以對 control 使用grep command,不必每次都cat 出來

2011年11月4日 星期五

Lost Lock in a short period

在接外部影像信號的時候,常常會發生信號短時間中斷的情況。
例如一些糟糕的 dvr 和 media player,在切換畫面 : 播放 --- 設定 時,會有很短一下的信號中斷現象。

而一些爛爛的 application processor 的 bt656 input 端,會發生不同步。最後就導致畫面有 scrolling 的現象。

video converter ADV7180 的 register : status 有一個 bit : LOST_LOCK
可以用來偵測這個現象。

他的定義是:
Lost lock (since last read of this register)

有 "Since last read of this register" 很重要。
這樣就不用設定很高的 polling freq,來抓 lost lock 的瞬間了。



但是有些 dvr 因為畫面切換信號中斷的時間很短,所以 ADV7180 也抓不到。
這個方法就失效了 ....

2011年10月28日 星期五

NetlinkEvent - uevent

原來 NetlinkEvent 是在處理 netlink 的 message。
parsing netlink messaag: 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 < 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; } 可以順便知道kobject, uevent 的 message 內容。
在 Documentation/device-mapper/dm-uevent.txt 有例子:
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

2011年10月27日 星期四

Run native executable in Android App

Gwanline 給的 link:
Run native executable in Android App
github:
https://github.com/gimite/android-native-exe-demo

基本上是用 Process process = Runtime.getRuntime().exec(command);
不知道為什麼要用 getBroadcaster( ) ,
現在 所有用到 getBroadcaster 的code,都是拿來 call sendBroadcast( )
mVm->getBroadcaster()->sendBroadcast(); 那幹麼還做出 getBroadcast( ) 這個 function?
直接 implement 一個 sendBroadcast( ) 像: mVm->sendBroadcast( ); 不就好?


push_back 是 stl . list 的操作 function,就是 insert。
是 android 的 stl : /framework/base/include/utils/ -- 奇怪,bionic 也有 implement 一份 stl 呀...為什麼要再作一份?

2011年10月26日 星期三

SocketListener, FrameworkListener & CommandListener

SocketListener | FrameworkListener | CommandListener Vold, Netd 各自implement 自己的 CommandListener.
filename 還都叫一樣的 CommandListener.cpp,h
但是在不同的 project (bin) ,所以同名沒關係。
像 interface 的東西.. FrameworkCommand | VoldCommand | DumpCmd, VolumeCmd, ShareCmd, AsecCmd, ObbCmd, StorageCmd, XwarpCmd
一樣,從 netd 來看
FrameworkCommand | NetdCommand | UsbCmd, SoftapCmd, InterfaceCmd, IpFwdCmd, TetherCmd, NatCmd, ListTtysCmd, PppdCmd, PanCmd 很有趣的是...這裡,各自 implement VoldCommand, NetCommand,結果內容是完全一樣的....
為甚摩不省略這一層,直接 繼承 FrameworkCommand 就好?


還有用到 Netlink SocketListener | NetlinkListener | NetlinkHandler 也是一樣,vold, netd 各自 implement 自己的 NetlinkHandler
這要的flow 寫在 SocketListener.
thread create, thread start,thread run.
runListener while(1) { FD_SET select( ) if( FD_IISSET( ) { c = accept( ) } do { for( i = clients->begin ~ end) { if(FD_ISSET(client(fd))) onDataAvailable(i) 就是標準的 FD_SET, select 動作,當有monitor 到 fd 變更,在一一check client 的 fd,把對應的 client 的 onDataAvailable( ) 執行一次

Bookmark : why GNU grep is fast

這一篇超不錯: 為什麼 gun grep 這麼快 http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html
為了防止不見,我整篇 copy 下來...
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 & 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 >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

2011年10月25日 星期二

http://www.vogella.de/articles/Andrpid/article.html

  1. Android Dalvik VM 和 java vm 不樣,google 提供 "dx" 這個tool,把 java Class file 轉成 Dalvik file (dex).
  2. Android 系統的執行檔格式是 apk,google 提供 "aapt" 這個 tool,把application 包裝成 apk。
  3. ADT plugin for Eclipse 提供整個服務:把 java class 轉成 dex,再包裝成 apk
  4. 支援 2D, 3D 的opengl function
  5. 使用 Sqlite 作data storage
  6. 每一個 android 程式在 deployment 的時候,都會被賦予一個 userid,藉此區隔每個 application 的空間和權限。
Important Android Component
  1. Activity -- Applaction 的展現,將資料展現在螢幕上,並且負責與 user 的互動。
    一個 application 可以有很多個 activity,然後在執行時切換。
  2. Views -- Activitity 用來畫圖的class。都是繼承字 android.view.View。view 的layout 事由 android.view.ViewGroupe負責。
  3. Servuce -- 負責背景動作,可以經由 android 的 notification framwork,提供 user 資訊。
  4. Content Provider -- 負責提供資料給 application,經由 Content Provider,application 可以互相share 資料。-- Android 包含一個 SQlite db,作為 data provider。
  5. Intents --

2011年10月21日 星期五

原來, honeycomb 的 GPL code 已經 release:
http://source.android.com/source/build-numbers.html

... GPL code 只佔 Android Source 的一小部份... ICS 的 GPL code 也release,但是是在google groupe 中說得,以 tar download 的方式。
所以不知道有沒有在 git branch 中..

2011年10月19日 星期三

bookmark for quick boot

  1. http://www.linuxjournal.com/magazine/reducing-boot-time-embedded-linux-systems?page=0,0
  2. http://free-electrons.com/services/boot-time/
  3. http://free-electrons.com/pub/conferences/2011/genivi/boot-time.pdf
  4. http://free-electrons.com/blog/lzo-kernel-compression/

bookmarks : browse android sources in eclipse

android 官方說明如何用 eclipse build android framework code: http://source.android.com/source/using-eclipse.html
這邊是對應的中文:
http://cheng-min-i-taiwan.blogspot.com/2011/02/android-source-core-eclipse.html

這有兩篇:
  1. http://blog.csdn.net/wufenglong/article/category/687662
  2. http://www.cnblogs.com/keis/archive/2011/05/13/2045690.html
  3. http://tw.myblog.yahoo.com/jw!0.HxipORGB7SANBka8A2GVI-/archive?l=f&id=13
build 得時候會遇到的問題:
http://stackoverflow.com/questions/885009/r-cannot-be-resolved-android-error


英文

  1. http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/
  2. http://achorniy.wordpress.com/2010/05/26/how-to-view-android-sources-in-eclipse/
  3. http://stackoverflow.com/questions/5233640/best-way-to-attach-android-source-to-eclipse
  4. http://johnsenf.blogspot.com/2011/04/android-sources-in-eclipse.html
  5. http://www.devfrustrated.com/devBlog/browsing-android-source-code-in-eclipse/
  6. http://www.bigbluebrains.com/index.php/2010/08/08/browsing-android-2-2-froyo-source-code-in-eclipse/
  7. http://www.androidzz.com/2011/08/browsing-android-source-in-eclipse/
  8. http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html
  9. http://android.opensourceror.org/2010/01/18/android-source/
  10. http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/

get android source -- when android.kernel.org is down

Update :
google 換了 android source server
http://source.android.com/source/downloading.html

配合的新版 repo: curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo server address: $ repo init -u https://android.googlesource.com/platform/manifest -b android-2.3.7_r1 所以應該不用下面的方法了...



kernel.org 死了好久, www.kernel.org 恢復了。
但是 android.kernel.org 還沒。

這篇 有說改從 codeaurora download 的方法:
http://php.webtutor.pl/en/2011/09/05/kernel-org-hacked-how-to-get-android-repo/

我照著 copy 一下:


1. 先抓 repo: curl "http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo" > ~/bin/repo chmod a+x ~/bin/repo PATH=~/bin:$PATH
2. download code from codeaurora mkdir WORKING_DIRECTORY cd WORKING_DIRECTORY repo init -u git://codeaurora.org/platform/manifest.git -b gingerbread repo sync


雖然 android mirror 很多,但是大多沒有改 manifest,不然就是沒辦法support 像 android.kernel.org 這樣多目錄下的project,
codeaurora 比較接近。


另外這一篇也是一樣,是中文的,所以就不 copy 了:
http://joybo.blogspot.com/2011/10/android-source-23.html

2011年10月14日 星期五

從 adb reboot 開始
  1. 未改 : 28 sec
  2. 改 kernel : 27.2 sec
  3. 改 framework - preload & remove battery, vibrator serer : 25 sec
  4. 拿掉 bootanimation/ 或改靜態圖 : 22.7 sec

開機有一些 sensor 可以拿掉:看 log..
使用自己的 launchre 和一堆 ap 後..
  1. 未改: 30.6sec
  2. 改 kernel : 29.6sec
  3. 改 framework/base + static bootanimation : 24.8 sec

2011年10月13日 星期四

在 framework/base/services/java/com/android/server/am/ActivityManagerService.java: public static final Context main(int factoryTest) { ........ ActivityManagerService m = thr.mService; mSelf = m; ........ m.startRunning(null, null, null, null); return context; } startRunning( ) 的最後是 call systemReady(): public final void startRunning(String pkg, String cls, String action, ........ systemReady(null); }

2011年10月12日 星期三

bootchart png s on target

1. 沒修改:


measured time:
  1. poweron - load kernel & root : 4.5 sec
  2. boot kernel unitll shell prompt : 10.0 sec
  3. unitl 2nd splash show up :13.1 sec
  4. until launcher show up : 14.2 sec
total : 42sec



2. preloaded-classes = empty

從 bootchart 看,雖然 zygote 到 start system server 的時間縮短了,
但是 launcher 啟動的時間一樣維持在 29 sec。



3. 改 internal eMMC, preloaded-classes 只有 java, dalvik 部份 (大約是原來的一半)


可以看到,啟動 launcher 的時間縮短很多,前面的 30 sec,由原來的 IO bound 變成 cpu bound...



4. 跟 3 一樣,但是 preloaded-classes 是空的


原來7 sec 的 preloading 時間變成 3 sec。


亂改一通後....
雖然好像很快...

2011年10月11日 星期二

bootchart & preloaded-classes

  1. preloaded-class
  2. package scan

修改 preloaded-classes 就是修改 /framework/base/preloaded-classed
然後重 build。

下面是 原來的 和 0 -preload 的 bootchart :

use bootchart on android

squeeze 竟然沒有 bootchart...
到 bootcharg.org download source - 0.9.? 版
follow 說明,用 ant 來 build
所以要先 install ant: $aptitude install ant 解開 bootchart source,然後到目錄去 run ant...
出現 error。
說 javac 找不到,找 com.sun..... 然後 path 指的卻是 openjdk。
所以 run $update-alternatives --all 所有 java 的部份,都由 openjdk 改為 sun-java。
再 run ant --> OK.



android 的部份,follow README.BOOTCHART
在 system/core/init

先把 INIT_BOOTCHART 打開build 出一個有 bootchart 的 init.. 到 system/core/init $ mm INIT_BOOTCHART=true dd 到 板子上後,啟動。

然後手動做出 /data/bootchart-start: $ echo 60 > bootchart-start $adb push bootchart-start /data/ $adb shell sync 然後就可以reboot..
這樣開機後,在 /data 下就會多一個 bootchart 的 folder。
/data/bootchart-start 裡面寫得就是 bootchart 要紀錄的秒數。
--- 現在是 60 sec。

等 60 sec 後,就可以 run /system/core/init/grabe-bootchart.sh
會透過 adb 把 /data/bootchart/ 的資料 copy 回 pc,壓成 bootchart.tgz。



然後 pc 端 run 剛剛裝好的 bootchart。從 bootchart.tgz 產生 png: java -jar bootchart.jar bootchart.tgz

Disable screen off timeout

一陣子沒動作,就會把lcd 關掉,同時進 suspend。
在 framework/base/services/java/com/android/server/PowerManagerService.java: 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); mScreenOffTimeoutSetting = -1;
就可以disable 掉這個 function。

2011年10月7日 星期五

以P公司藍色測試 2G SD 為基準:

uImage : 3267264
uramdisk : 293568

  1. uboot load kernel and root : 7.5 sec
  2. kernel boot : 7.0 sec
  3. init to show splash : 27.4 sec
  4. splash to show launcher : 45.6
第二次開機:
  1. uboot load kernel and root : 7,5 sec
  2. kernel boot : 7.8 sec
  3. init to show splash : 12.7 sec
  4. splash to show launcher : 10.6

刪掉一堆
uImage : 2502056
kernel boot L 6.4 sec

2011年10月6日 星期四

mxc_uart.c 的 mxcuart_console_init ( ) 屬於 console_init 階段執行的 function. struct console mxc_consol register_console(&mxc_console);
mxc_reg 跟 mxc_console 各自包含對方: struct uart_console mxc_reg = { .con = (&mxc_sonsole); }; struct console mxc_console = { .data = &mxc_reg; }

另外一個是 module_init 階段執行的 mxcuart_init uart_register(&mxc_reg); platform_driver_register(&mxcuart_driver); mxcuart_driver 是 platform_driver 結構,name 是 mxcintuart (internal uart ?)

platform_driver 的 mxcuart_resume(struct platform_device *pdev) 只是..
取出 platform_device 的 data : (uart_mxc_port)。參照裡面的 port.flag,決定要不要call uart_resume_port( ): uart_mxc_port *umxc = platform_get_drvdata(pdev); if (umxc && umxc->port.flags & ASYNC_SUSPENDED) { umxc->port.state->port.tty->hw_stopped = 0; uart_resume_port(&mxc_reg, &umxc->port); } 這裡的 uart_resume_port 在 serial_core.c 裡。

uart_resume_port 也是取出 argument :uart_driver 裡的tty_port 結構資料 : port。
依照 port-> flags 的內容決定要不要對 hardware 動作。

所以 mxcuart_resume --- uart_resume_port 裡面都有對 port 動作,但是兩個的 port 並不一樣。

mxcuart_resume 是: platform_device --> (uart_mxc_port) --> port.flags uart_resume_port 是: uart_driver --> uart_state -->tty_port --> flags 好像不相關.


mxcuart_resume 的參數: platform_device 是宣告在另一個 source : arch: 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 = &mxc_ports[0], }, };
mxc_port 是: 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, }, 看到那個 flags 欄位。
這個欄位好像沒有改變。

uart_resume_port( ) 的參數是mxc_uart_resume 呼叫時傳進去的。 uart_resume_port(&mxc_reg, &umxc->port); 所以就是

Bookmark : install AMD APP SDK on Debian - OpenCL

http://wiki.cchtml.com/index.php/Debian

2011年10月5日 星期三

mxc_uart.c 的 mxcuart_init( ) 被放在 module_init(mxcuart_init),所以在 kernel 啟動時,會自動被呼叫。

mxcuart_init 負責:
  1. uart_register_driver
  2. platform_driver_register
mxc_uart 的 platform driver name 是 mxcintuart。
對應的 platform device 在 arch/arm serial.c 李,一共宣告了 5 個 (因為有 5 個 serial port, -- 51 只有 3 個)
platform_device 的資料: platform_data 是 uart_mxc_port 其中包含有 .port 這個 property。
裡面有 flags 這個 field。

這個flag 是給 driver 用的(?),因為 serial_core.c 的 suspend/resume function 會依照 consoel_suspend_enabled 來動作,並且 update port->flag 的 ASYNC_SUSPEND 這個 flag。



看來是 uart_open 沒有被 call 到,所以 resume 狀態和 suspend 狀態不一致。

看一下 uart_open 對那些 hardware register 有動作: uart_change_pm(state,0); uart_startup(state,0); uart_update_termios(state)
mxcuart_startup ( ) 變更的 register 有:
  1. MXC_UARTUSR1, MXC_UARTUSR2
  2. UARTUCR3
  3. MXC_UARTUCR2
  4. MXC_UARTUFCR
  5. MXC_UARTUCR1



還是認真看一下..

整個就只有mxc_uart_early, mxc_uart, serial_core 三個。
要是要用 uart 當作 console ,就要加上 mxc_uart_early,否則不僅 kernel msg show 不出來,shell 也沒有動作。

mxc_uart_early 的 init 被藏在很不清楚的地方 (why not follow DEBUG_LL & EARLY_CONSOL ?)
在MACHINE_START( ) 的 timer .init : mx51_babbage_timer_init ( ) 中。
clock_init 完後,就 call early_console_setup(UART1_BASE_ADDR, uart_clk);

實際上就是call mxc_early_serial_console_init(base, clk);

early_console_setup( ) 傳進去的 UART1_BASE_ADDR, uart_clk 會填在 static 變數 mxc_early_device 的 port.mapbase 和 clk 裡。
雖然 mxc_early_device 的 structure mxc_early_uart_device 宣告了內含一個很大的 structure : uart_port,實際上只有用到裡面的 membase 這個 field 而已.........

比較有用的變數是 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, }; 這被用來 register_console(&mxc_early_uart_console);

*** -- 這個 early_driver 只有實做 write,沒有 read 喔...
*** 沒有看到設 baudrate..

register_console 在 kernel/printk.c

可以看到 呼叫 early_setup( ),還有把 cmdline option 傳進setup( ).. 執行的 code。

還可以看到當真正的 console register 時,bootconsole 會自動 unregister..

printk 用來紀錄所有register 的 console 是 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; }; 其中 next 是用來做出 linking list


整個 printk.c 包含register_console ,還有 prtintk,就是把message 從所有 console 的 write( ) 送出去。

printk.c : 中的 release_console_sem( ) 就會把 buffer 內容從所有 registered console 送出去..



---- 所以整個只有 write,,,,,

2011年10月4日 星期二

sysfs:
/sys/devices/system
suspend/hibernate 時: 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 跟 /sys/device/system 下的目錄一致。


hibernate fail 時,是 cpu0 fail。
所以把 function address 印出來,到 System.mp 就可以查到 function name。
結果 vfp0, clocksource0,.. mxc_gpio0 都沒有 suspend function。
只有 cpu0 有,是 cpufreq_suspend。


driver/cpufreq/cpufreq.c 中的 printk 是用 cpufreq_debug_printk( ) 作動態控制。
控制的參數有 debug, debug_ratelimit

這兩個參數被宣告成 module_param,所以都會在 /sys/module/cpufreq 裡出現。

還有要開啟這個功能,要define CONFIG_CPU_FREQ_DEBUG。
這在 menuconfig 打開:
CPU Power Management --> Enable CPUfreq debugging

另外,看 cpufreq_debug_printk( ) 的 code,是 KERN_INFO,所以不會直接 output 到 console。
要直接輸出(不經 dmesg),就把他刪掉。


這樣 build 好kernel 啟動後,還要: echo 7 > /sys/module/cpufreq/debug echo 0 > /sys/module/cpufreq/debug_ratelimit 改一下 cpufreq 的debug 參數,讓他output message。
然後作 hibernate ,就可以看到 cpufreq-core 的 message 了。

bookmark: boot time optimize done by TI

Ti 也很好心的寫了 boot time optimize procedure:
  1. http://processors.wiki.ti.com/index.php/Android_Boot_Time_Optimization
  2. http://processors.wiki.ti.com/index.php/Optimize_Linux_Boot_Time
屬於 "盡力" 的方式,沒有用 hibernate 功能。
比較特殊的大概是 deffered module,讓某些不急著load 的 module 晚點再 load.

順便 link 一下 TI 的 Gingerbread sdk user guide:
http://processors.wiki.ti.com/index.php/TI-Android-GingerBread-2.3.4-DevKit-2.1_UserGuide

FAQ 有提到, bracn -qb 就是 quickboot 的 branch


  1. kernel + root only : suspend , resume OK, but shell no response after reumse, and takes long time to resume
  2. remove unnecessary option in kernel : failed : Class driver suspend failed for cpu0

2011年10月3日 星期一

bookmark : proc & sysfs

因為Z的 bsp 還有一堆 driver 用 proc 作 device/userspace 溝通的管道。
所以想看一下 proc, sysfs 介面的差異。

剛好這一篇有簡單的 proc , sysfs interface example:
http://www.coding.com.br/kernel/adding-procfs-and-sysfs-interface-in-your-lkml/
**sysfs只有 create node,沒有 interface。

但是 sysfs 很有趣的是,可以用 module_param 把module 的參數開放出來。
用 module_param 宣告的參數,都會列在 /sys/module/ 目錄中。
可以read /write (如果你有給權限的話)

到 /sys/module 去看,會列出所有的 module。
ref: http://nano-chicken.blogspot.com/2011/01/linux-modules11module-parameters.html

2011年9月30日 星期五

看來好像掛掉。
再 trace 一下 mailinglist:

LKML 的一封:https://lkml.org/lkml/2011/5/21/69
"Rafael J. Wysocki" <>
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
慘的是..後來 Linus 宣佈沒有 2.6.40,而是 3.0 ...

LKML 的 interface 很好心,會把相關的 repy-discuss 放在一個 tree (頁面的左邊),每點一個 message,要是裡面包含 path,就會出現一個 "diff" 的link,讓你把 patch 拿下來。




這是samsung 基於那個 NOKIA initial work 所做的:
http://permalink.gmane.org/gmane.linux.power-management.general/22773

有提到那個 lds.S 修改。另外他還加上 A9 的 support。


還有 ,當 使用 eMMC /SD 作 resume partition 時,要等待 driver ready,所以
http://www.spinics.net/lists/arm-kernel/msg142548.html

這個 patch 加上 resumewait 參數,等 dev open success..

bookmark : kernel pm mantainer 說明 suspend, hibernation

寫在 https://lkml.org/lkml/2006/7/25/105

bookmark : webcore 導致 browser 當機,VM 重開問題

這個中國人有解答:
http://blog.csdn.net/a345017062/article/details/6394864

問題有列在 google code issue tracker :
http://code.google.com/p/android/issues/detail?id=12987

大概是 java function return class not match 問題。

不過他很大方的寫出 trace bug 的方法,可以學一下。
說要加上 Will Deacon 的 cpu_reset patch。
查一下,在 arch/arm/mm

誰用到?

宣告的地方:./arch/arm/include/asm/cpu-single.h #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 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)); 所以 cpu_reset( ) 會變成 CPU_NAME_reset

CPU_NAME 定義在 ./arch/arm/include/asm/proc-fns.h # 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 所以 cortext A8 的 kernel config 是: CONFIG_CPU_V7=y 也就是會變成 cpu_v7_reset( )

所以 assembly 的部份要看 cpu_v7_reset, c source 的部份要看 cpu_reset ().
.. 有一堆 source call cpu_reset...



ref:
  1. http://comments.gmane.org/gmane.linux.ports.arm.kernel/119552
  2. http://lists.infradead.org/pipermail/linux-arm-kernel/2011-July/057302.html

2011年9月29日 星期四

build TINY_ANDROID && some worklog on hibernate

問題應該還是在 kernel,android framework 在 suspend/resume 好像沒有限制,只有在特殊的情況會用 wakelock 防止suspend (跟hardware 相關,或是 charging)。
其他部份好像都無關 (pure software component ?)



BUILD_TINY_ANDROID
make -j4 BUILD_TINY_ANDROID=true TARGET_NO_RECOVERY=true showcommands 來 build TINY_ANDROID。
 TINY_ANDROID 不會rebuild recovery,但是 Makefile 卻還是去 make recoveryimage,所以要手動加上 TARGET_NO_RECOVERY=true

build 出來後,到 out 去看 installed-files,果然有一堆沒包 (vimdiff with original build result)


兩個問題:
  1. pmic_adc 在 resume 的時候會 hang 住一陣子
  2. resume 後,shell , rx 沒動作 ,tx好像還 OK,-- 從 shell 的 output 來看

about pmic_adc:
  1. 先回到 resume OK 版本 -- 至少 screen 恢復
  2. 移除 pmic_backlight 和 pmic_XXX (?) -- 看看是否OK
  3. pmic_adc 的 suspend/resume 似乎是以 adc wq 不終止的情況 考慮....

2011年9月28日 星期三

enable LL (Low Level Debugging 後): /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.... trace debug.S :167 addruart r3, r1 addruart 定義在 debug-macro.S: .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 所以是 UART_VADDR 的定義: (debug-macro.S): #include #define UART_PADDR MX51_UART1_BASE_ADDR #define UART_VADDR MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR) 的 MX51_AIPS1_IO_ADDRESS( ) 沒有展開 (定義)。
這個是定義在 mx51.h。
用 git blame 找一下 debug-macro.S ,發現原來是 include mx51.h ,後來在新增 mx5x.h 後,才改為 include mx51.h..

改回去就 build OK...
... 但是..

在 boot argument 加上 earlyprintk 後,bootmessage 在 Uncompressing Linxu... done, booting the kernel. 後,就沒有 message 了...
  1. 先看一下 _LL 造成 Assembly MACRO 展開的 error : 大概看一下就好
  2. 加上 framework, build 一版,注意 partition 問題。 recovery partition不能用,不然就要重新 partition
  3. 那個 DPLL 的 patch 有沒有上

2011年9月27日 星期二

early_printk, DEBUG_LL

http://r40eubuntu.blogspot.com/2011/09/initcall.html

單看 console 的部份。

在 start_kernel 的最後 reset_init 用 kernel_thread 執行 kernel_init

console 好像是 kernel 中很重要的東西(?),在 kerne/printk.c 中。
說明 cosole 依照開機的階段,分為兩種,這說明寫在 regisgter_console( ) 的前面: /* * 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 */ 大概翻譯一下:
為了要讓 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 了。
在 arch/arm/kernal/ 下有 early_prink.c,但是要 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 才會 build 進去。

在 arch/arm/Kconfig include 的 Kconfig.debug 有option:
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.
所以要 enable DEBUG_LL (Kernel low-level debugging functions),才會顯示出來。

2011年9月26日 星期一

vt : virtual terminal (?), 就是 console (?).
在 driver/char/vt.c 有: struct vc vc_cons [MAX_NR_CONSOLES]; MAX_NR_CONSOLES 定義在 include/linux/vt.h: struct vc vc_cons [MAX_NR_CONSOLES];

Accessing Registers from User space

imxwiki有一篇,用 mmap 方式存取整個 imx51 register 的 user tool:
http://www.imxdev.org/wiki/index.php?title=All_Boards_AccessingRegisters
跟以前寫的一篇一樣:http://r40eubuntu.blogspot.com/2011/05/read-soc-register-from-devmem.html

source code 是 GPLed,所以把他copy 到 github (免得不見 XD).
https://github.com/checko/imx_io_test
Wiki 中有說明從 data sheet 對應到 register address 的方法(?).

2011年9月23日 星期五

hibernate . code trace

echo disk > /sys/power/state 收到的是
kernek/power/main.c : static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) suspend to disk 部份超快,就.. if (len == 4 && !strncmp(buf, "disk", len)) { error = hibernate(); goto Exit; } 直接 call kernel/power/hibernate.c 的 hibernate( )



snapshot_device_available 被用作 snaphot 的 mutex,初始是 1,使用時 -1。
也就是說: 1 可用,0 不行。
所以 kernel code 要操作 snapshot 時,都要先作: atomic_add_unless(&snapshot_device_available, -1 ,0) 用來確認 snaphot_device_available 是不是 1 (available),
再繼續動作。

實際上依靠 snaphost_device_avaiable 的 function 有:
  1. hibernate()
  2. software_resume( )
  3. snapshot_open( ) -- user interface of device "snapshot'
pm_notifier_call_chain : call blocking_notifier_call_chain( ).
好像有以下幾個 chain:
  1. PM_HIBERNATION_PREPARE
  2. PM_POST_HIBERNATION
  3. PM_RESTORE_PREPARE
  4. PM_POST_RESTORE

定義在:notifier.h /* 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 */
RCU : Read-Copy-Update



static int orig_fgconsole, orig_kmsg; int pm_prepare_console(void) { orig_fgconsole = vt_move_to_console(SUSPEND_CONSOLE, 1); if (orig_fgconsole < 0) return 1; orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE); return 0; } void pm_restore_console(void) { if (orig_fgconsole >= 0) { vt_move_to_console(orig_fgconsole, 0); vt_kmsg_redirect(orig_kmsg); } }
driver/char/vt.c
切換 console:
使用 want_console 跟 console_callback( ) 來完成動作:
  1. want_console = new_console;

atomic_add_unless

是說:add unless valus is the given number

arm 版 在 arch/arm/include/asm : atomic.h: static inline int atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) c = old; return c != u; } 然後 cmpxchg 是 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" : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter) : "r" (&ptr->counter), "Ir" (old), "r" (new) : "cc"); } while (res); smp_mb(); return oldval; } 就是 swp. armv6 版.

所以重點在 atomic_cmpxchg((v),c , c+a))


關於 atomic 的操作,可以看 Documentation/atomic_ops.txt

		Semantics and Behavior of Atomic and
		         Bitmask Operations
這個 documsnt 的說明好像跟實做一饃一樣。

atomic_t 宣告在 linux/types.h typedef struct { int counter; } atomic_t; 宣告後,要初始化: (atomic.h) #define ATOMIC_INIT(i) { (i) }


這一篇說得很清楚喔: http://blog.roodo.com/use_the_force/archives/3420371.html

vmware - install vmware tool in ubuntu guest os

會要重 build module,所以要安裝 build-essential, linux-header-$(uname -r)。
還有 path 的問題,所以要手動建 link,否則就會有 kernel-header 找不到的問題。
不然就要改 install script。

2011年9月21日 星期三

initcall, & hibernate, resume, console.

在 include/linux/init.h 有定義: #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) 其中 __define_initcall 是: #define __define_initcall(level,fn,id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn 會把 function 放在 .initcall + level 這個section..

在 init/main.c : kernel_init 會 do_basic_setup( ) --> do_initcalls() static void __init do_initcalls(void) { initcall_t *fn; for (fn = __early_initcall_end; fn < __initcall_end; fn++) do_one_initcall(*fn); /* Make sure there is no pending stuff from the initcall sequence */ flush_scheduled_work(); } 在 vmlinux.lds : . = 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 = .; ? 為什摩中間有一個 initcallrootfs ?
.. 也就是說各 kernel module 中宣告 xxx_initcall( ) 的 function ,都會以上面 define 的次序,在 start_kernel( ) 時,一一被呼叫..


hibernate.c : late_initcall(software_resume); 因為在 開完後,手動 resume , sh console 是 OK 的,所以改一下 software_resume( ) 的位置...
從 late_initcall( ) 拿出來,在做完 /* Open the /dev/console on the rootfs, this should never fail */ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk(KERN_WARNING "Warning: unable to open an initial console.\n"); 以後再 call,就 OK 了
----> why ?



init/main.c : start_kernel( ) ----> console_init() ----> reset_init( ) -------->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); ------------>sys_open("/dev/console",..) console_init( ) 跟 上面的 initcall 一樣: 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 < __con_initcall_end) { (*call)(); call++; printk("*"); } } 可以打開 System.map 看 symbol:
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
其中 __initcall_con_init 和 __initcall_end 是同一個位置,所以實際上只有兩個 function
boot log 會有兩個 *.

editor : sublimetext2

http://lucifr.com/139225/sublime-text-2-tricks-and-tips/

挺不錯的 (可惜要錢,還挺貴的 $60)。
但是開發中免費 (?)

還可以用 vim 的 command 喔...
http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/

開啟 Preference -Global Setting - default

跟 geany 比:

  1. 字型漂亮
  2. 排版漂亮
  3. 有支援 vi command
  4. command line 啟動,每次都會開一個新 session
  5. 沒有 function list --- 要自己弄 ctags ?

build linux dist for imx51

解開 _boundle.tar.gz,會有 doc 跟 source。
解開 source,會要你指定 解開的 目錄,也是以後工作的目錄。
解開後,會要確認 license,然後繼續,最後提醒你,到工作目錄去 run ltib

bsp 用的是 ltib : Linux Target Image Bullder : http://ltib.org/pages/LTIB_generic_v1.4_-_version_6.4.1.pdf
整個 build 動作用 rpm,所以會檢查: Package Minimum ver Installed info ------- ----------- --------------- rpm 0 not installed rpm-build 0 not installed 這兩個command都在 rpm 這個 package,所以 aptitude install rpm 就可以了。

會先 build 自己需要的 tool (即使 host 已經有一套),會放在 /opt/freescale/ltib/
出現 error。
看一下 host_config.log.. compr_lzo.c:29:23: error: lzo/lzo1x.h: No such file or directory 因為沒有 liblzo2-dev。
裝完後繼續 ./ltib,會有 error,所以手動把 /opt/freescale/ltib/usr/src/rpm/BUILD/mtd-utils 目錄刪除,再作 ./ltib

又有 error: mkfs.ubifs.h:48:23: error: uuid/uuid.h: No such file or directory 裝 uuid-dev ,手動刪掉 /opt/freescale/ltib/usr/src/rpm/BUILD/mtd-utils 後繼續..

host tool 都 build 完後,開始 build target image,會出現一個 selection menu..
選好繼續....



build gnome dist 的話,會要一堆 lib-dev,碰到 error 時再裝就可以。

有一個 error: 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 \ > test-inline-pixbufs.h \ || (rm -f test-inline-pixbufs.h && 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) 在這一篇 (http://ubuntuforums.org/showthread.php?t=962233 ) 說是缺 mono-mcs。
sudo apt-get install libgdk-pixbuf2.0-dev

這一篇 : http://forums.freescale.com/t5/i-MX-Microprocessors/iMX25-SDK-LTIB-error-with-Ubuntu/td-p/52117

說,安裝後,要刪掉 BUILD/gtk+ .. 後再 build 一次。



哪個 no : command not found,去 gtk/demo/Makefile 看,是 某個 tool : csource 變數設定是 no。
猜是這個是 autoconfig probe 出來的,system 沒有,就寫 no。所以 install necessary package 後,要刪掉 build folder,這樣才會重 run 一次 autoconfig,重新產生 Makefile..

2011年9月20日 星期二

github kerel source of various android tablet

這人很好新的蒐集了一些 android tablet 的 kernel source code:
https://github.com/richardtrip

2011年9月19日 星期一

swsusp for imx51 : worklog

software_resume ( ) 進行 image check, image restore 後,就做 hiberate_restore( ),然後就不會回來了 (?) ...
/** * 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; } 根據 comment, run 完會回到 hibernate_snapshot( ) , 猜是 stack 變更,所以這個 function return 回去會到 hibnation_snapshot( ).



卡在 kernel_imx/driver/base/power/main.c 的 dpm_resume( ) 的: while (!list_empty(&dpm_list)) { dev = to_device(dpm_list.next); get_device(dev); if (dev->power.status >= DPM_OFF && !is_async(dev)) { int error; mutex_unlock(&dpm_list_mtx); error = device_resume(dev, state, false); mutex_lock(&dpm_list_mtx); if (error) pm_dev_err(dev, state, "", error); } else if (dev->power.status == DPM_SUSPENDING) { /* Allow new children of the device to be registered */ dev->power.status = DPM_RESUMING; } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &list); put_device(dev); } 中間有 mmc0: error -110 during reumse (card was remved?) 的 error.
==> 拿掉 mmc0 的 driver ,雖然 error 不再發生了,但是還是一樣卡住...約 48 sec 後才完成這個section。

拿掉 使用 dma 的 uart 後,經過 48 sec 的 resume後,沒有 core dump 了, kernel msg 可以正常的輸出,但是 console input 還是沒回應。
==> 將所有uart 的 DMA 都關掉後,雖然還是要 48 sec,但是 resume 後已經沒有 core dump 了 .... console 依然不回應 ..

在 get_device( )後印出 device 的 init_name,還有 dev->driver->name。發現好像是 pmic_adc 和 pmic_leds 卡住。

拿掉 pmic_led, pmic_backlight (從 menuconfig 拿掉).
==> 剩下 pmic_adc 需要 10 幾秒的 resume 時間,而且是卡在 pmic_adc_resume( ) 中..

拿掉 pmic_adc_resume( ) 中 對 register 的 read/write code 後,就沒有卡住了。
==> 但是 console 還是沒反應..

拿到 uboot 的 resume=? 參數,等開機進入 kernel 後,再用手動 echo 179:4 > /sys/power/resume
==> console 有反應.....所以原因是? .. root 是 ramdisk ?.. console not setup correctly ?

因為 android dev 在 mmcblk 加入一層 block,和kernel 不一樣。
所以,在kernel boot phase,要用以前的 /dev/mmcblk0p4,而不是開機完後的,/dev/block/mmcblk0p4

2011年9月16日 星期五

root only , enable shell

想要建立一個最小 root , 但是要有 shell 跟 busybox。
所以...
但是 android 的 system/core/sh 不是 static executable,有用到 share library。
所以要改一下 Android.mk。
加上: LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_STATIC_LIBRARIES := liblinenoise libc 這樣build 出來的 sh 會變大 (很多)

另外我們自己寫的小程式 oxstub,如果也要放進 root,也要改寫一下 Android.mk. LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_STATIC_LIBRARIES := libcutils libc
附上 使用的 init.rc: on early-init start ueventd on init sysclktz 0 loglevel 7 # setup the global environment export PATH /sbin:/bin on boot class_start default start console start mcustub ## Daemon processes to be run by init. ## service ueventd /sbin/ueventd service mcustub /sbin/xostub service console /sbin/sh console


root : lrwxrwxrwx 1 charles-chang charles-chang 4 Sep 16 15:45 bin -> sbin drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:45 data -rw-r--r-- 1 charles-chang charles-chang 118 Sep 16 15:45 default.prop drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:45 dev -rwxr-xr-x 1 charles-chang charles-chang 90132 Sep 16 15:45 init -rwxr-xr-x 1 charles-chang charles-chang 5 Sep 16 15:45 init.freescale.rc -rwxr-xr-x 1 charles-chang charles-chang 363 Sep 16 15:45 init.rc drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:45 proc drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:47 sbin drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:45 sys drwxr-xr-x 2 charles-chang charles-chang 4096 Sep 16 15:45 system -rw-r--r-- 1 charles-chang charles-chang 2089 Sep 16 15:45 ueventd.freescale.rc -rw-r--r-- 1 charles-chang charles-chang 0 Sep 16 15:45 ueventd.goldfish.rc -rw-r--r-- 1 charles-chang charles-chang 3764 Sep 16 15:45 ueventd.rc root tree: myroot2/ |-- bin -> sbin |-- data |-- default.prop |-- dev |-- init |-- init.freescale.rc |-- init.rc |-- proc |-- sbin | |-- adbd | |-- busybox | |-- mcustub | |-- sh | `-- ueventd -> ../init |-- sys |-- system |-- ueventd.freescale.rc |-- ueventd.goldfish.rc `-- ueventd.rc
附上 手動 make root image 的 command: mkbootfs myroot2 | minigzip > myramdisk.img 然後 imx51 的 uboot 需要在做: mkimage -A arm -O linux -T ramdisk -C none -a 0x90308000 -n "Android Root Filesystem" -d myramdisk2.img myuramdisk2.img 填入 64 bytes 的 uboot info



如果要加自己寫的 script,在 boot 的時候 run,要注意,rootfs 的 make system 會修改 file attrib,所以要:
ref :
  1. http://r40eubuntu.blogspot.com/2012/01/root-fs-copy-to-file-attribute.html



製作 static build 的 e2fs tool:

e2fs 相關的 tool 在 /external/e2fsprogs 目錄。
其中... misc.. e2fsck.. 兩個 folder 包涵 tool program。

static build 的方法,就跟上面的一樣,修改 Android.mk:
  1. 增加 LOCAL_FORCE_STATIC_EXECUTABLE := true
  2. 把 LOCAL_SYSTEM_SHARED_LIBRARIES 改為 LOCAL_STATIC_LIBRARIES,並且加入 libc
但是這個 project 還用了很多自己的 library,這些library 都要改成 static: e2fsck/Android.mk | 6 ++++-- lib/blkid/Android.mk | 2 +- lib/e2p/Android.mk | 2 +- lib/et/Android.mk | 2 +- lib/ext2fs/Android.mk | 2 +- lib/uuid/Android.mk | 2 +- misc/Android.mk | 13 ++++++++++--- 其中 lib 的部份都是 build library:
  1. 把 BUILD_SHARED_LIBRARY 改成 BUILD_STATIC_LIBRARY

標籤

網誌存檔