分类:
2009-03-06 10:59:03
Contents 6.1 Get ramdisk image from emulator6.3 Integrate the Android system with a existing ramdisk image. [] Introduction Google explains that Android is a software stack for mobiledevices that includes an operating system, middleware and keyapplications. This document explains the Android architecture by Googleand porting procedure on the real hardware. The explanation is based onthe m3 sdk version of the Android emulator. If you have enough knowledge about patching the kernel, resolvingrejections from a patch, making an ramdisk image, and the Linux kernelitself, reading this article will be easier. [] Copyright and Acknowledgements This document is copyright (c) Kwangwoo Lee<>. Permission is granted tocopy, distribute and/or modify this document under the terms of the GNUFree Documentation License. - Korean translation by dasomoli (). [] The brief analysis of the Android architecture [] Android Kernel The most different things are the Android kernel uses ARM EABI(Embedded Application Binary Interface) and penBinderIPC(Inter Process Communication). If you want to compile the kernelsupporting ARM EABI, you should rebuild toolchains to support ARM EABI. The Android sdk emulates goldfish architecture using qemu. Thealsa may be used for audio on Android. See the audio.c file in thegoldfish architecture directory and the driver uses /dev/eac for audioon the Android system. RTC(Real Time Clock) device is also used through/dev/rtc0. The following parts explain the main differences: [] ARM EABI EABI is the new "Embedded" ABI by ARM Ltd. The changes are listed on Debian wiki. ()
legacy ABI: - put fd into r0 - put length into r1-r2 - use "swi #(0x900000 + 194)" to call the kernel new ARM EABI: - put fd into r0 - put length into r2-r3 (skipping over r1) - put 194 into r7 - use "swi 0" to call the kernel The Android uses EABI kernel feature. Enable kernel options of theCONFIG_AEABI and CONFIG_OABI_COMPAT. You can see the differences of theexecutable binary as follows :
private flags = 202: [APCS-32] [FPA float format] [software FP] [has entry point] $ file t7-demo t7-demo: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3, dynamically linked (uses shared libs), for GNU/Linux 2.4.3, stripped
private flags = 4000002: [Version4 EABI] [has entry point] $ file t7-demo t7-demo: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, dynamically linked (uses shared libs), for GNU/Linux 2.6.14, stripped : What is the ABI for the ARM Architecture? Is it the same as the ARM EABI? The ABI for the ARM Architecture is a standard developed by ARMand its partners (including CodeSourcery) that explains how compilers,assemblers, linkers, and other similar tools should generate objectfiles and executable files. Tools that correctly implement the ABI forthe ARM Architecture can interoperate; i.e., objects files built withone toolchain can be combined with object files built with anothertoolchain if both compilers use the ABI for the ARM Architecture. The"ARM EABI" is an informal name for the ABI for the ARM Architecture. [] penBinder The penBinderprovides a object-oriented operating system environment. It is designedto be hosted by traditional kernels. This project is started at Be.Inc. as the part of the next generation eOS, and finished implementing at almSource as a core part at the Cobalt system. It is a system oriented component architecture rather thanapplication oriented, and It provides IPC between processes,threadpool, memory management and clean up feature at the end ofreference of an binder object. The vanilla kernel do not have penBinder IPC mechanism you should patch the kernel. The penBinderoffers thread management for the system through /dev/binder. It is thereason that Android system do not offer thread libraries.
[] Frame Buffer The basic frame buffer driver should be implemented already. Afterthat you need to implement the differences between your architecturedriver and the goldfish driver. The frame buffer driver of the goldfish architecture supports thefb_pan_display function of the struct fb_ops. It means you shouldallocate memory twice rather than the actual frame size.
... fbinfo->fix.ypanstep = 1; fbinfo->var.yres_virtual = gm->lcd.yres * 2; fbinfo->fix.smem_len = (gm->lcd.xres * gm->lcd.yres * gm->lcd.bpp / 8) * 2;
... fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE); fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, &fbi->map_dma, GFP_KERNEL);
{ ... } static struct fb_ops mvfb_ops = { .owner = THIS_MODULE, .fb_check_var = mvfb_check_var, .fb_set_par = mvfb_set_par, .fb_setcolreg = mvfb_setcolreg, .fb_blank = mvfb_blank, .fb_pan_display = mvfb_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_mmap = mvfb_mmap, }; The device file is located at /dev/graphics/fb0. [] Input Devices Android uses event device for user input. There are three devicessuch as keypad, qwerty2 keyboard and mouse. The qwerty2 keyboard andmouse are normal devices. So I just explain the keypad and touchscreenwhich mouse device is replaced with. On the Android shell, Cat the /proc/bus/input/{devices,handlers} and then you will see the devices used for the Android.$ adb shell # cat /proc/bus/input/devices I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="goldfish-events-keyboard" P: Phys= S: Sysfs=/class/inut/input0 U: Uniq= H: Handlers=kbd mouse0 event0 ... # # cat /proc/bus/input/handlers N: Number=0 Name=kbd N: Number=1 Name=mousedev Minor=32 N: Number=2 Name=evdev Minor=64 #
The output format is struct input_event. So the output on eachevent is 16 bytes like 8 bytes for time, 2 bytes for type, 2 bytes forcode, 4 bytes for value. Read input.txt and input-programming.txt aboutinput event devices in the Documentation/input directory of the Linuxkernel source code. struct input_event { struct timeval time; unsigned short type; unsigned short code; unsigned int value; }; The Tiger7 evaluation board has it's own scancode table. Thefollowing shows the key layout on evaluation board, scancode table, andAndroid keycodes:/* * Key Layout Scancode Table * * 1 2 3 0x1 0x10 0x100 * 4 5 6 0x2 0x20 0x200 * 7 8 9 0x4 0x40 0x400 * * 0 # 0x8 0x80 0x800 */ static unsigned short android_keycode[] = { /* * 0x66 0x67 0x9e Home Up Back * 0x69 0xe8 0x6a Left Ok Right * 0xe7 0x6c 0x6b Send Down Hangup * 0xe5 Menu just_distinction_for_private */ KEY_HOME, KEY_UP, KEY_BACK, KEY_LEFT, KEY_REPLY, KEY_RIGHT, KEY_SEND, KEY_DOWN, KEY_END, KEY_KBDILLUMDOWN, KEY_RESERVED, KEY_PLAY }; There is a power button on emulator, but I skipped it to get output value. If an interrupt of the keypad is caught, translate the scancodewith the keycode of the Android on the above table and send event touser space application.... keycode = translate_keycode(scancode); ... input_event(keydev->input, EV_KEY, keycode, KEY_PRESSED); or input_event(keydev->input, EV_KEY, keycode, KEY_RELEASED); ... The high resolution timer - hrtimer is used for reduce keypad debounce.
Here is the output of the /proc/bus/input/{devices,handlers} on evaluation board.# cat /proc/bus/input/devices I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="MVT7 KEYPAD" P: Phys= S: Sysfs=/class/input/input0 U: Uniq= H: Handlers=kbd event0 evbug B: EV=f ... I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="TSC2007 Touchscreen" P: Phys=0-0090/input0 S: Sysfs=/class/input/input1 U: Uniq= H: Handlers=event1 evbug B: EV=b B: KEY=400 0 0 0 0 0 0 0 0 0 0 B: ABS=1000003 # cat /proc/bus/input/handlers N: Number=0 Name=kbd N: Number=1 Name=evdev Minor=64 N: Number=2 Name=evbug As a result, the keypad uses /dev/input/event0 and the touchscreen interface uses /dev/input/event1 on application layer. [] Low Memory Killer The Linux Kernel has an OOM(Out of Memory) killer for thesituation that no memory is left to allocate for a request of aprocess. It examines all processes and keeps score with somerestrictions. The process with highest score will be killed exceptinit. The Low Memory Killer of the Android behaves a bit differentagainst OOM killer. It classifies processes according to the importancewith groups and kills the process in the lowest group. It will make thesystem to be stable at the view of the end users. For example, the UIProcess - foreground process - is the most important process for theend users. So to keep the process live looks more stable than keepingother background processes live. Enable CONFIG_LOW_MEMORY_KILLER after patching the kernel. [] Android Logger If you enable this feature, you can see some useful informationabout Android through /dev/log/main. There are three device files on/dev/log such as main, events, radio. The /dev/log/radio file seems tobe related with a modem device and ril daemon - rild - on Androidsystem. When this logger is enabled, the system performance is a bitslower on the system. To use this feature, enableCONFIG_ANDROID_LOGGER. [] Android Power The Android power is for the battery management on devices andsome subsystem related with power management like inotify feature onfile system. It is not necessary to start up Android through the init(hellScript)of the Android system. But the runtime binary looks up some filesregarding Android power - /sys/android_power/acruire_partial_wake_lock- on starting up Android manually and failed to start up. EnableCONFIG_ANDROID_POWER to use.- 예전 버전의 문서에서 init은 바이너리로 되어있었는데 쉘스크립트로 바뀌어 있네요.이전 문서에서 말한 init은 안드로이드 램디스크의 루트 디렉토리 밑에 있는 init 바이너리를 말씀하신 것 같은데, 그 것이아니고 다른 init인건가요? 아니면 그 init이 쉘 스크립트인 것인가요? -- dasomoli - 문서를 작성한 m3 버전에서는 binary 였습니다. 다른 분이 shell script로 바꾼 것 같네요. 번역해 주셔서 감사합니다. -- - m5 버전에서도 바이너리인 것 같아서요. 그리고 별 말씀을요.^^; -- dasomoli [] Panic Timeout It is not necessary to start up Android on evaluation board. Set CONFIG_PANIC_TIMEOUT with a desired value. [] Android Root File system Android emulator has 3 basic images on tools/lib/images directory.
system.img and userdata.img are VMS Alpha executable. system.imgand userdata.img have the contents of /system and /data directory onroot file system. They are mapped on NAND devices with yaffs2 filesystem. /dev/block/mtdblock0 for /system and /dev/block/mtdblock1 for/data. /system directory has libraries and default system packages (*.apk). /data directory has timezone, cache, and piDemos.apk package. The main services are zygote(/system/bin/app_process),runtime(/system/bin/runtime), and dbus(/system/bin/dbus-daemon). Youcan see the /etc/init.rc file on the Android ramdisk image. ... zygote { exec /system/bin/app_process args { 0 -Xzygote 1 /system/bin 2 --zygote } autostart 1 } runtime { exec /system/bin/runtime autostart 1 } ... dbus { exec /system/bin/dbus-daemon args.0 --system args.1 --nofork autostart 1 } ... [] Licenses of the Android Packages tools/lib/images/NOTICE contains package lists and licenses foreach libraries. The table of the licenses is cited from thepresentation by Lim,eunSik at 2008 Korea Android Summit.
[] Toolchain supporting ARM EABI The toolchain represents the tools to be used for the systemdevelopment. It contains C/C++ compiler, linker, libraries, binutils,and etc. The Android kernel and system requires EABI support. So legacytoolchain is not compatible to make the Android system. [] Building toolchain To make life easier, I used the crosstool-0.43 script () by Dan Kegel. Unfortunately it is not support to build eabi toolchain, so I applied a glibc 2.5+ nptl build for arm softfloat eabi patch () by Khem Raj. $./arm-softfloat-eabi.sh If the network is connected, the script will download and build toolchain using gcc 4.1.1 and glibc 2.5. [] Other toolchain I did not use the codesourcery toolchain, but they said it will work for the building Android system. * [] Kernel To port the Android on a real hardware is started by Benno (),you can see some useful information on his blog. On his blog somepre-compiled static binaries are linked. It is very helpful fordebugging Android system. You can also build static build busybox andstrace binaries, but it's better to get them and use. You can get patch file including the differences between theAndroid kernel and the vanilla kernel with 2.6.23 version. It has alldifferences between them. So you need to extract parts of them, andmake your own patch for your system architecture. For example, the Android kernel has it's own yaffs file systempatch. If you have your own yaffs or some other file systems like jffs2on your architecture, then you need to remove the yaffs parts of thepatch. The goldfish architecture which the Android kernel emulate anARM architecture on qemu is not necessary part for your architecture.It can be removed. The Android kernel emulates RMv5 instructions. So RM926EJ-S (RMv5TEJ) will be good to work. [] Patch kernel Benno played with a EO1973 device by openmoko. So he made patch files for it. Get the original patch file from http://benno.id.au/blog/2007/11/21/android-neo1973, I used android.diff. It has whole things about goldfish, qemu, yaffs, and Android specific parts. You can edit and remove the patch file directly. After makingpatch including binder, android power, android logger, low memorykiller except goldfish and qemu specific parts, get vanilla 2.6.23version Linux kernel and patch it. If you use a 2.6.24.1 version Linux kernel, some part regarding android power should be fixed accordingly or disabled to work. [] .config
CONFIG_PANIC_TIMEOUT=0 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y CONFIG_BINDER=y CONFIG_LOW_MEMORY_KILLER=y ...
# CONFIG_ANDROID_GADGET is not set # CONFIG_ANDROID_RAM_CONSOLE is not set # CONFIG_ANDROID_POWER is not set # CONFIG_ANDROID_LOGGER is not set ... [] Root file system The root file system is composed of three parts such as a primaryramdisk image on ram, a system image on nand dev0(/dev/block/mtdblock0), and a data image on nand dev1(/dev/block/mtdblock1). The mtd devices has a yaffs2 file system andeach of them has 64 iB capacity on the Android emulator. The extracted system and data directories are copied to the realexisting NAND device and they are mounted with --bind option to work ona real hardware. [] Get ramdisk image from emulator 1. unpack ramdisk image from tools/lib/images/ramdisk.img$ gzip -cd ramdisk.img > ramdisk $ cpio -iv -F ramdisk cpio will extract files and directories on current working directory. 2. the contents list of the ramdiskdata dev etc etc/default.prop etc/firmware etc/firmware/brf6150.bin etc/firmware/brf6300.bin etc/hcid.conf etc/hosts etc/init.gprs-pppd etc/init.rc etc/init.ril etc/init.testmenu etc/ppp etc/ppp/chap-secrets etc/ppp/ip-down etc/ppp/ip-up etc/qemu-init.sh etc/system.conf etc/system.d etc/system.d/bluez-hcid.conf etc/usbd.conf init proc sbin sbin/recovery sys system tmp var var/run [] Get data and system directory from emulator To get data and system directory you need a static compiled busybox binary. The compiled binary can be obtained from http://benno.id.au/blog/2007/11/14/android-busybox , or make your own binary. 1. launch the Android emulator 2. push static compiled busybox into emulator# adb push busybox . 3. launch the Android shell# adb shell 4. make tarball with busybox# chmod +x /busybox # busybox tar -c /data.tar /data # busybox tar -c /system.tar /system # exit 5. extract tarball from the emulator# adb pull /data.tar . # adb pull /system.tar . Extract command often failed. So you may repeat it again until it has done successfully. [] Integrate the Android system with a existing ramdisk image. The ramdisk for your architecture can make your work a bit easier.Copy the contents of the Android ramdisk to your own ramdisk exceptsystem and data directory. And make just mount point for system anddata directory. The mount points will be used later with a bind option.The init binary of the Android ramdisk image is the key binary to startthe system and It read a configuration file on /etc/init.rc. Edit /etc/init.rc and comment out qemu part. ... startup { ... # qemu-init { # exec /etc/qemu-init.sh # } } ... Make run.sh script. /dev/block/mtdblock5 is a mtd partition on areal NAND device, and it is mounted on /mnt. data and systemdirectories are already copied on mtdblock5. So the script below justshows bind mounting each directory on /. Fix your script according toyour board configuration. #!/bin/sh mount -t yaffs /dev/block/mtdblock5 /mnt mount --bind /mnt/data /data mount --bind /mnt/system /system # data folder is owned by system user on emulator. Fix 777 to other. chmod 777 /data #chmod 777 /system export PATH=/system/sbin:/system/bin:/sbin/usr/local/bin export LD_LIBRARY_PATH=/system/lib export ANDROID_BOOTLOGO=1 export ANDROID_ROOT=/system export ANDROID_ASSETS=/system/app export EXTERNAL_STORAGE=/sdcard export ANDROID_DATA=/data export DRM_CONTENT=/data/drm/content /init An optional configuration for touchscreen - SLib. ... export TSLIB_CONSOLEDEVICE=none export TSLIB_FBDEVICE=/dev/fb0 export TSLIB_TSDEVICE=/dev/input/event1 export TSLIB_CALIBFILE=/etc/pointercal export TSLIB_CONFFILE=/etc/ts.conf export TSLIB_PLUGINDIR=/lib/ts export LD_PRELOAD=/lib/libts.so:/lib/ts/pthres.so ... [] System and Data directories The contents of the system and data directories are copied tomtdblock5 already. You should copy your own method. To use it, I chosebind mounting on root directory. Bind mounting is a technique to mountan existing directory with a new mount point. [] Run and Debug Now the kernel, ramdisk, and data directories - data and system -are ready. It's time to see the red cylon eye. After boot up yourintegrated system, run the run.sh on root directory. # cd / # . /android/run.sh yaffs: dev is 32505861 name is "mtdblock5" yaffs: passed flags "" yaffs: Attempting MTD mount on 31.5, "mtdblock5" yaffs: auto selecting yaffs2 # init: HOW ARE YOU GENTLEMEN init: reading config file init: device init init: mtd partition -1, init: mtd partition 0, "l1boot" init: mtd partition 1, "u-boot" init: mtd partition 2, "params" init: mtd partition 3, "kernel" init: mtd partition 4, "ramdisk" init: mtd partition 5, "rootfs" sh: can't access tty; job control turned off # binder_open(c394bcc8 c3c731a0) (pid 1577) got c3e48000 binder_open(c394bcc8 c3cd8dc0) (pid 1616) got c319f000 binder_open(c394bcc8 c3cd8ac0) (pid 1673) got c3d10000 binder_open(c394bcc8 c3cd8940) (pid 1680) got c0e19000 binder_open(c394bcc8 c3cd88c0) (pid 1691) got c2fa0000 binder_open(c394bcc8 c3d174a0) (pid 1592) got c25b8000 binder_release(c394bcc8 c3cd88c0) (pid 1691) pd c2fa0000 #
#!/bin/sh # set environment variables above example ... /system/bin/app_process -Xzygote /system/bin --zygote /system/bin/dbus-daemon --system /system/bin/runtime The above example shows manual startup sequence, use strace on run /system/bin/runtime binary. ./strace -ff -F -tt -s 200 -o /tmp/strace runtime [] Screenshots
[] Application Development The Android applications use Java syntax and xml layouts, but itis not a Java. Because they use their own virtual machine - dalvik -and compiler for dex file format. And use package named apk such asHome.apk, Phone.apk, ApiDemos.apk and etc. The apk file is a Zip archive and it has four parts.
The Android SDK will create an *.apk file. [] Install Eclipse IDE Install procedure from 1. Eclipse IDE for Java developer (JDT and WST plugins are included) from 2. JDK (Java SE) from 3. ADT (Android Development Tools) with a eclipse plugin including Apache Ant [] Build and Run Sample Applications 1. Open sample projects and build 2. Run sample applications on emulator [] Screenshots
[] Epilogue The Android system seems to be a new kind of a Linux based distribution for a mobile environment like Debian, , ,and etc. They just use the Linux kernel and a lot of differentlibraries in the open source world. They offer a software based penGL-ESlibrary on a 3D acceleration currently, but they are developing on ahardware accelerated baseband processor for it. The hardwareacceleration is necessary for fast UI rendering effects later. The Android system on the sdk is not a completed one to port on areal hardware, because some device - for example, camera - relatedlibraries and classes are not implemented yet and not opened for users.It seems to be under the development stage. So we would better to waitthe Google announces the whole porting kit. Until then, we should look for the business model with the Androidsystem. It requires a bit high cpu performance, so the carrier vendorswill require a cheap baseband processor (RF part) and a multimediaco-processor, because the baseband processor including multimediafeatures will be very expensive. [] Links and References
|