Monday, July 23, 2012

What Happens During Android Application Installation Process?

You can install an app on Android in 4 ways.

1. system apps, installed when system is initialized.
2. Install apps from Google Play Store.
3. Install apps using adb, "adb install xxx.apk".
4. Copy xxxapp.apk to sdcard, browse the .apk file from your phone, double click, the app would be                  installed.

What is inside an app package, i.e. the .apk file?

  • META-INFO/jar, contains signature info
  • res/, necessary resources
  • AndroidManifest.xml, app configuration and permission requirements
  • classes.dex, dalvik byte-code
  • resources.arsc, binary resource file after compiling

Which files are needed for an app to be run?

-- appname.apk, underlying libraries.

What happened during installation?

  • AndroidManifest.xml is parsed, information is extracted and stored into /data/system/packages.xml and /data/system/packages.list
  • .apk file is copied to a specific directory and a directory for data storage is created for this app

File copy and directory creation

1. For system apps
  • .apk file is copied to /system/app/
  • two directories for this app are created, respectively, /data/data/com.app.appname/ and /data/data/com.app.appname/lib
  • .dex file, which is extracted from the .apk file, is copied to /data/dalvik-cache/, named as, e.g. system@app@appname.apk.dex
2. Apps installed by adb
  • .apk file is copied to /data/app
  • two directories for this app are created, respectively, /data/data/com.app.appname/ and /data/data/com.app.appname/lib
  • .dex file, which is extracted from the .apk file, is copied to /data/dalvik-cache/, named as, e.g. system@app@appname.apk.dex
3. Apps installed from Google Play Store
  • the same as apps installed by adb
4. Apps installed from sdcard

  • the same as apps installed by adb

How is installation implemented?

  • xml parsing, resource analysis and .apk file copy are done by PackageManageService.java
  • directory creation is done by installd.c
  • PackageManageService.java communicates with installd.c via a local socket, located at /dev/socket/installd



Sunday, July 22, 2012

[Copied]android 中使用socket使native和framework通信

一般的native和framework的通信是通过jni,但是这一般只是framework调用native,native如果有消息要怎样通知上层呢?android中GSP模块提供一种解决思路,但是实现有些复杂,这里介绍一种使用socket通信的方法可以使native和framework自由通信,具体实现如下:
android中使用jni对linux中的socket进行了封装。使用起来十分的方便。
由于android是基于linux的,所以linux的代码会在java之前先执行,所以一般native端是服务器。framework端是客户端。
java层主要代码:
LocalSocket s =null;
LocalSocketAddress l;
s = new LocalSocket();
l = new LocalSocketAddress(SOCKET_NAME,LocalSocketAddress.Namespace.RESERVED);
s.connect(l);

到此时如果socket连接没有问题,就可以像正常的读写了。
native层主要代码:
s_fdListen = android_get_control_socket(SOCKET_NAME);
ret = listen(s_fdListen, n);
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);

如果连接没有问题就可以使用linux中的write/read来对socket进行读和写了;
这里有必要解释一下SOCKET_NAME,它的值是一个字符串,它在init.rc中定义的一个字符串。也就是说,我们可以通过修改init.rc中来申请我们需要的socket资源。
这里以ril为例来说明:
service ril-daemon /system/bin/rild
socket rild stream 660 root radio
socket rild-debug stream 660 radio system
user root
group radio cache inet misc audio

以上是摘自android 2.2 源码中的system\core\rootdir\init.rc中的片段。至于其具体含义可以参见init.c和system/core/init/readme.txt文件。他的作用是由init.c来解析init.rc,并为我们启动一个名为rild的守护进程,它是一个可执行程序,我们通过adb shell在system/bin中可以找到对应的rild文件。socket表示为这个守护进程分配一个socket资源,这个socket资源可以在/dev/socket/下找到rild。也就是本文要这里最关键的地方,socket能不能通就看守护进程能不能很好的起来。上面SOCKET_NAME也就是这里定义的字符串(在ril.java和ril.cpp中就有一个字符串常量SOCKET_NAME_RIL,他的值就是rild,和上面的对应)。
如果我们要自定义一个socket来进行通信,我们可以在init.rc的最后面加上
service myserver-daemon /system/bin/server
socket server stream 666 
oneshot

system/bin/server就是我们编译生成的服务器程序,在里面我们调用
s_fdListen = android_get_control_socket(“server”);
ret = listen(s_fdListen, n);
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);

就可以建立一个服务器端程序。
java只需要使用最上面的代码就可以和native通信了,注意SOCKET_NAME值必须上下统一和init.rc中的相等,此处为“rild”。这里的oneshot必须有,没有的话,你的server很可能起不来。
剩下的只剩下编译了。
关于编译可以参考ril中的中的Android.mk和rild.c和ril.cpp,自己把头文件挑出即可。
先用mm编译自己加的模块,编译好后,将添加的模块考出,在源码的根目录下make snod。将编译输出文件加到system.img中。最后将system.img和randisk.img拷到sdk对应的平台中。即可。主要这两个img文件都要拷,system.img中有你的可执行程序,而randisk.img中有你的init.rc。userdata.img不确定。
此时只需要用java写一个客户端程序即可。


Source Link: http://hi.baidu.com/leoispace/blog/item/8aa5f41cc8609d04304e15bf.html

Thursday, July 19, 2012

Wednesday, July 18, 2012

[Solved]goldfish kernel can't boot on emulator

Problem: Failed to boot the emulator when using goldfish kernel.
Reason: .config file out dated.
Solution: using goldfish_armv7_defconfig
Commands:
                 
  • git clone git://android.git.kernel.org/kernel/common.git
  • git checkout -t origin/android-goldfish-2.6.29 -b goldfish
  • make ARCH=arm goldfish_armv7_defconfig
  • make ARCH=arm CROSS_COMPILE=mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
  • emulator -kernel mydroid/kernel/common/arch/arm/boot/zImage
Enjoy!

Monday, July 16, 2012

Randomized Sort: Creating Loadable Kernel Modules for Android

Randomized Sort: Creating Loadable Kernel Modules for Android: The Loadable Kernel Module architecture in Linux allows a developer to extend the functionality of a pre-built Linux operating system.  We ...

Friday, July 13, 2012

[Copied]Hello World in C on Android


If you've been following the Android world, you'd know that Android's SDK requires you to write apps in Java. Ever since I got my phone I've been dying to run a Hello World C program, but I've been unable to get the right cross compiler for it.


Today I finally managed to do it using CodeSourcery's cross compiler on linux. A cross compiler is something which allows you to compile on one architecture (the host) and run the executable binary on another (the target). In this case, the host is the linux machine where we'll install the toolchain (linux intel x86) and android phone is the host (arm).
  1. Download CodeSourcery's toolchain installer for GNU/Linux target for IA32 host
  2. Install it: sh arm-2008q3-72-arm-none-linux-gnueabi.bin
  3. The toolchain provides the cross compiler arm-none-linux-gnueabi-gcc. You need to put it's directory in your $PATH. Once you have the toolchain, you can easily compile your hello world program: arm-none-linux-gnueabi-gcc -o hello -static hello.c
  4. Copy the binary to your phone and run it from an adb shell prompt: ./hello
Voila!

Points to note:
  • The above binary is static, that is it does not use the phone's libc libraries. Android ships with its own trimmed down version of libc, called bionic. Next I'll be trying to compile and run using bionic libc, so that I don't have to compile statically
  • The above steps do not use the toolchain in the android source code. I'll try later to cross compile using that.

Thursday, July 12, 2012

[Copied]Mixing Assembly and C


8.2 Mixing Assembly and C

Often it is a good idea to link assembly language programs or routines with high-level programs which may contain resources unavailable to you through direct assembly programming--such as using C's built in graphics library functions or string-processing functions. Conversely, it is often necessary to include short assembly routines in a compiled high-level program to take advantage of the speed of machine language.
All high-level languages have specific calling conventions which allow one language to communicate to the other; i.e., to send variables, values, etc. The assembly-language program that is written in conjunction with the high-level language must also reflect these conventions if the two are to be successfully integrated. Usually high-level languages pass parameters to subroutines by utilizing the stack. This is also the case for C.

8.2.1 Using Assembly Procedures in C Functions

8.2.1.1 Procedure Setup

In order to ensure that the assembly language procedure and the C program will combine and be compatible, the following steps should be followed:
  • Declare the procedure label global by using the GLOBAL directive. In addition, also declare global any data that will be used.
  • Use the EXTERN directive to declare global data and procedures as external. It is best to place the EXTERN statement outside the segment definitions and to place near data inside the data segment.
  • Follow the C naming conventions--i.e., precede all names (both procedures and data) with underscores.

8.2.1.2 Stack Setup

Whenever entering a procedure, it is necessary to set up a stack frame on which to pass parameters. Of course, if the procedure doesn't use the stack, then it is not necessary. To accomplish the stack setup, include the following code in the procedure:
        push    ebp
        mov     ebp, esp
EBP allows us to use this pointer as an index into the stack, and should not be altered throughout the procedure unless caution is taken. Each parameter passed to the procedure can now be accessed as an offset from EBP. This is commonly known as a "standard stack frame."

8.2.1.3 Preserving Registers

It is necessary that the procedure preserve the contents of the registers ESI, EDI, EBP, and all segment registers. If these registers are corrupted, it is possible that the computer will produce errors when returning to the calling C program.

8.2.1.4 Passing Parameters in C to the Procedure

C passes arguments to procedures on the stack. For example, consider the following statements from a C main program:
           |
extern int Sum();
           |
int a1, a2, x;
           |
x = Sum(a1, a2);
When C executes the function call to Sum, it pushes the input arguments onto the stack in reverse order, then executes a call to Sum. Upon entering Sum, the stack would contain the following:
Since a1 and a2 are declared as int variables, each takes up one word on the stack. The above method of passing input arguments is called passing by value. The code for Sum, which outputs the sum of the input arguments via register EAX, might look like the following:
_Sum
        push    ebp             ; create stack frame
        mov     ebp, esp
        mov     eax, [ebp+8]    ; grab the first argument
        mov     ecx, [ebp+12]   ; grab the second argument
        add     eax, ecx        ; sum the arguments
        pop     ebp             ; restore the base pointer
        ret
It is interesting to note several things. First, the assembly code returns the value of the result to the C program through EAX implicitly. Second, a simple RET statement is all that is necessary when returning from the procedure. This is due to the fact that C takes care of removing the passed parameters from the stack.
Unfortunately, passing by value has the drawback that we can only return one output value. What if Sum must output several values, or if Sum must modify one of the input variables? To accomplish this, we must pass arguments by reference. In this method of argument transmission, the addresses of the arguments are passed, not their values. The address may be just an offset, or both an offset and a segment. For example, suppose Sum wishes to modify a2 directly--perhaps storing the result in a2 such that a2 = a1 + a2. The following function call from C could be used:
Sum(a1, &a2);
The first argument is still passed by value (i.e., only its value is placed on the stack), but the second argument is passed by reference (its address is placed on the stack). The "&" prefix means "address of." We say that &a2 is a "pointer" to the variable a2. Using the above statement, the stack would contain the following upon entering Sum:
Note that the address of a2 is pushed on the stack, not its value. With this information, Sum can access the variable a2 directly. (Hint: use an index register to hold the offset, then use a memory access to access the variable).

8.2.1.5 Returning a Value from the Procedure

Assembly can return values to the C calling program using only the EAX register. If the returned value is only four bytes or less, the result is returned in register EAX. If the item is larger than four bytes, a pointer is returned in EAX which points to the item. Here is a short table of the C variable types and how they are returned by the assembly code:
Data TypeRegister
charAL
shortAX
int, long, pointer (*)EAX

8.2.1.6 Allocating Local Data Space on the Stack

Temporary storage space for local variables or data can be created by decreasing the contents of ESP just after setting up a stack frame at the beginning of the procedure. It is important to restore the stack space at the end of the procedure. The following code fragment illustrates the basic idea:
        push    ebp             ; Save caller's stack frame
        mov     ebp, esp        ; Establish new stack frame
        sub     esp, 4          ; Allocate local data space of
                                ;  4 bytes
        push    esi             ; Save critical registers
        push    edi
        ...
        pop     edi             ; Restore critical registers
        pop     esi
        mov     esp, ebp        ; Restore the stack
        pop     ebp             ; Restore the frame
        ret                     ; Return to caller

8.2.2 Using C Functions in Assembly Procedures

In most cases, calling C library routines or functions from an assembly program is more complex than calling assembly programs from C. An example of how to call the printf library function from within an assembly program is shown next, followed by comments on how it actually works.
global  _main

extern  _printf

section .data

text    db      "291 is the best!", 10, 0
strformat db    "%s", 0

section .code

_main
        push    dword text
        push    dword strformat
        call    _printf
        add     esp, 8
        ret
Notice that the procedure is declared global, and its name must be _main, which is the starting point of all C code.
Since C pushes its arguments onto the stack in reverse order, the offset of the string is pushed first, followed by the offset of the format string. The C function can then be called, but care must be taken to restore the stack once it has completed.
When linking the assembly code, include the standard C library (or the library containing the functions you use) in the link. For a more detailed (and perhaps more accurate) description of the procedures involved in calling C functions, refer to another text on the subject.

Source link: http://courses.engr.illinois.edu/ece390/books/labmanual/c-prog-mixing.html