Android 的 HAL(硬體抽像層)是 Google 因應廠商「希望不公開源碼」的要求下,所推出的新觀念,其架構如下圖。雖然 HAL 現在的「抽象程度」還不足,現階段實作還不是全面符合 HAL 的架構規劃,不過也確實給了我們很好的思考空間。
圖1:Android HAL 架構規劃
這是 Patrick Brady (Google) 在2008 Google I/O 所發表的演講「Anatomy & Physiology of an Android」
中,所提出的 Android HAL 架構圖。從這張架構圖我們知道,HAL 的目的是為了把 Android framework 與 Linux
kernel 完整「隔開」。讓 Android 不至過度依賴 Linux kernel,有點像是「kernel
independent」的意思,讓 Android framework 的開發能在不考量驅動程式的前提下進行發展。
在 Android 原始碼裡,HAL 主要的實作儲存於以下目錄:
1. libhardware_legacy/ – 過去的實作、採取程式庫模組的觀念進行
2. libhardware/ – 新版的實作、調整為 HAL stub 的觀念
3. ril/ – Radio Interface Layer
在 HAL 的架構實作成熟前(即圖1的規劃),我們先就目前 HAL 現況做一個簡單的分析。另外,目前 Android 的 HAL 實作,仍舊散佈在不同的地方,例如 Camera、WiFi 等,因此上述的目錄並不包含所有的 HAL 程式碼。
HAL 的過去
圖2:Android HAL / libhardware_legacy
過去的 libhardware_legacy 作法,比較是傳統的「module」方式,也就是將 *.so 檔案當做「shared
library」來使用,在 runtime(JNI 部份)以 direct function call 使用 HAL
module。透過直接函數呼叫的方式,來操作驅動程式。
在
討論了不少基本概念後,在這裡小結一下 HAL stub 的實作步驟。HAL stub 的起頭是「繼承 HAL 的 struct
hw_module_t」,這是 HAL stub
的設計理念,除了讓架構的條理分明外,也容易做後續擴充與維護。以下改用實用上的習慣用語,小結一下 HAL stub 實作步驟,並提供一段例。
Make sure your kernel is compiled with OProfile support (CONFIG_OPROFILE=y, CONFIG_HAVE_OPROFILE=y)
If you want to profile the kernel, have the vmlinux binary ready
If you want to profile a native application, compile it with debug symbols (-g)
After system has loaded, execute once: “opcontrol –setup –event=CPU_CYCLES:50000″
If you also want to profile the kernel, add the params “–vmlinux=full-path-to-your-vmlinux-file-on-target
–kernel-range=start-of-kernel-text-section,end-of-kernel-text-section”
(use your toolchain’s objdump to find the relevant addresses)
Before beginning the profiling, execute on the target: “opcontrol –reset”
To begin profiling, execute: “opcontrol –start”
During profiling, you might want to make sure that samples are being collected: “opcontrol –status”
Stop profiling by executing: “opcontrol –stop”
On your host: cd mydroid/external/oprofile
On your host, execute: “./opimport_pull result_folder” (imports the
samples collected from the target, saves them in a newly created folder
and prints a basic report)
On your host, execute: “cd mydroid/prebuilt/linux-x86/oprofile/bin”
To get an annotated report, execute: “./opannotate -p
<path-to-folder-with-your-native-app-w-symbols-and-any-other-binary-you-want-detailed-report-of-like-libc-so-for-example>
If
you’re having trouble estimating the time and complexity of porting
Google’s Android mobile platform to your embedded device, our
experience porting Android to a Nokia N810 Internet Tablet may provide
you with useful information.
Android overview
Android is a mobile phone
software platform created by Google. It is based on the Linux kernel, a
number of software libraries written in ‘C,’ a Java-like virtual
machine for running application code, and a full suite of mobile phone
applications.
Android costs nothing and the source code is
freely available. Its license terms (see the Apache license link at the
end) are commercial-friendly, saying, in essence, "Do what you like
with it, just don’t sue us if something goes wrong." The one exception
to this rule is the Linux kernel, which is licensed under the GNU
Public License. Because of this, manufacturers must release their
device’s Linux kernel source code after product shipment.
Taiwan’s
HTC shipped the first Android phone, the G1, in October 2008. Other
mobile manufacturers, including Motorola, LG, and Samsung are all
reportedly creating Android-based phones. Additionally, from NthCode’s
home base in China, we see many startups and smaller manufacturers
leveraging Android in an attempt to gain a foothold in the global
smartphone market.
T-Mobile G1, the first Android phone
The
Android platform provides all the services one would expect in a mobile
phone, including phone calling, networking, messaging, and multimedia.
Our analysis of the source code so far is that these services are
complete and built on top of an excellent architecture, but do not
implement every last feature found in modern mobile phones. This is the
1.0 release, after all.
For application developers, Android
builds on top of the popular open-source Eclipse integrated development
environment. Developers can use Eclipse to write Java applications,
which are then compiled to Java bytecode before being translated for
running on Android’s Dalvik Virtual Machine (VM).
Google
claims their Dalvik VM runs more efficiently in terms of speed and
memory tradeoffs than Java — slyly suggesting that Google wrote their
own VM for performance reasons. However, while we haven’t seen
supporting data, we suppose Google really created Dalvik to escape from
needing to cede control or pay a license fee to Sun, the creator and
steward of the Java platform.
By translating from Java to Dalvik
bytecode, Google is able to leverage the mature tools and large
existing community of Java developers. The downside is that developers
will need to take the additional step of running the Google translation
tool on their compiled Java code before their application will run on
an Android phone (Google automates this step in their Android Eclipse
plug-in, however).
Android emulator screenshot
Google
also provides an Android emulator. The emulator is a virtualized ARM
microprocessor that runs the same system code — and almost exactly the
same Linux kernel — that runs on a device. Google provides an Eclipse
add-on so that Android programs can be compiled and debugged in Eclipse
while running in their emulator. The Android emulator is as complete an
emulator as we have ever seen — just make sure your developers have
enough RAM in their PCs to be able to run Eclipse and the emulator
together.
So what’s in it for Google?
Google has
given mobile phone manufacturers everything they want — a free, open,
mobile operating system — and, in return, only asked that the devices
they create can run Android applications. We can only speculate that
Google expects to eventually earn more from consumers using Google
services on Android devices than it costs Google to develop and
maintain Android.
Overview of the Nokia N810
We
work with embedded Linux systems at NthCode, so we thought it would be
a fun challenge (and would help with a project we’re working on) if we
could port Android to an existing Linux device.
Luckily, we
already had two Nokia N810 Internet Tablets in the office. The N810 is
a handheld mobile device that comes with a high-resolution 4.1-inch
touch screen and a slide-out QWERTY keyboard. The N810 has a 400 MHz
Texas Instruments OMAP 2420 CPU, 128MB RAM, and WiFi networking. The
one thing the N810 can’t do is make phone calls — this is why Nokia
markets it as an Internet Tablet that can surf the web, rather than a
phone. At the time of this writing, the N810 costs about USD $425.
An
active community of enthusiasts enjoys hacking the N810’s Linux-based
software. While some of those enthusiasts had already ported a
pre-release version of the Android SDK to the N810, we discovered that
no one had yet ported the Android 1.0 release to it. So we decided to
see how long it would take us, and what we could learn in the process.
Development steps
As
mentioned earlier, the Android system software runs on top of a Linux
kernel. This Linux kernel provides services to applications — such as
file access, process scheduling, and inter-process communication.
Google
made a number of modifications to the standard Linux kernel for
Android. Likewise, Nokia modified the standard Linux kernel to support
their hardware, such as the keypad, touch screen, and file system.
We
quickly discovered that Nokia’s N810 changes are made against an
earlier 2.6.21 Linux kernel. And, unlike earlier Android prereleases,
the Android 1.0 modifications are made against a later 2.6.25 Linux
kernel. We investigated and discovered that between these two versions,
a year had elapsed and the Linux community had made thousands of
changes to kernel source code.
So, to make both Nokia’s and
Google’s modifications work together on the N810 we either needed to
port the N810 changes to work on the newer 2.6.25 Linux kernel, or port
the Android changes to the N810’s earlier 2.6.21 Linux kernel.
What did Google change in the kernel?
We
checked the differences between the Android kernel and the standard
Linux kernel and found that Google had changed 75 files and added an
additional 88. We have prepared an annotated list of changed files at
the end of this document, and a brief summary here.
Goldfish — 44 Files
— The Android emulator runs a virtual CPU that Google calls Goldfish.
Goldfish executes ARM926T instructions and has hooks for input and
output — such as reading key presses from or displaying video output
in the emulator.
These interfaces are implemented in files
specific to the Goldfish emulator and will not be compiled into a
kernel that runs on real devices. So we safely ignored these files in
our work.
YAFFS2 — 35 Files — Unlike PCs,
which store files on disks, mobile phones store files in sold-state
flash memory chips. The HTC G1 uses NAND flash, a type of flash memory
that is becoming more popular due to its combination of high density
and low cost.
YAFFS2 is an acronym for "Yet Another Flash File
System, 2nd edition." It provides a high-performance interface between
the Linux kernel and NAND flash devices. YAFFS2 was already freely
available for Linux. However, it is not part of the standard 2.6.25
Linux kernel, and so Google added it to Android.
Bluetooth — 10 files
— Google made changes to 10 files in the Bluetooth communications
stack. These changes fix apparent bugs related to Bluetooth headsets,
and add Bluetooth debugging and access control functions.
Scheduler — 5 files
— The Android kernel also contains slight changes to the CPU process
scheduler and time-keeping algorithms. We don’t know the history of
these changes, and the impact was not evident based on a cursory
examination.
New Android Functionality — 28 files
— In addition to bug fixes and other small changes, Android contains a
number of new subsystems that are worth mentioning here, including the
following:
IPC Binder — The IPC Binder is an
Inter-Process Communication (IPC) mechanism. It allows processes to
provide services to other processes via a set of higher-level APIs than
are available in standard Linux. An Internet search indicated that the
Binder concept originated at Be, Inc., and then made its way into
Palm’s software, before Google wrote a new Binder for Android.
Low Memory Killer
— Android adds a low-memory killer that, each time it’s called, scans
the list of running Linux processes, and kills one. It was not clear in
our cursory examination why Android adds a low-memory killer on top of
the already existing one in the standard Linux kernel.
Ashmem
— Ashmem is an Anonymous SHared MEMory system that adds interfaces so
processes can share named blocks of memory. As an example, the system
could use Ashmem to store icons, which multiple processes could then
access when drawing their UI. The advantage of Ashmem over traditional
Linux shared memory is that it provides a means for the kernel to
reclaim these shared memory blocks if they are not currently in use. If
a process then tries to access a shared memory block the kernel has
freed, it will receive an error, and will then need to reallocate the
block and reload the data.
RAM Console and Log Device
— To aid in debugging, Android adds the ability to store kernel log
messages to a RAM buffer. Additionally, Android adds a separate logging
module so that user processes can read and write user log messages.
Android Debug Bridge
— Debugging embedded devices can best be described as challenging. To
make debugging easier, Google created the Android Debug Bridge (ADB),
which is a protocol that runs over a USB link between a hardware device
running Android and a developer writing applications on a desktop PC.
Android
also adds a new real-time clock, switch support, and timed GPIO
support. We list the impacted files for these new modules at the end of
this document.
Power Management — 5 files
— Power management is one of the most difficult pieces to get right in
mobile devices, so we split it out into a group separate from the other
pieces. It’s interesting to note that Google added a new power
management system to Linux, rather than reuse what already existed. We
list the impacted files at the end of this document.
Miscellaneous Changes — 36 files
— In addition to the above, we found a number of changes that could
best be described as, ‘Miscellaneous.’ Among other things, these
changes include additional debugging support, keypad light controls,
and management of TCP networking.
NetFilter — 0 files
— Finally, our change list showed Netfilter as having 22 changed
files. However, examination showed the only difference was the
capitalization of the filenames (xt_DSCP.c vs. xc_dscp.c). The contents
of the files were all identical. So we ignored these files in our port.
Port the N810 changes forward or the Android changes backward?
As
you can see from the above, Android makes significant changes to the
standard Linux kernel. Additionally, Google’s system software checks to
make certain the kernel version is 2.6.25 or newer. This led us to
wonder if Android requires features in the standard 2.6.25 Linux kernel
that are not in earlier releases.
On the other hand, the N810
kernel changes were only to add hardware support. Nokia did not change
core operating system services or add new interfaces.
We decided that we would have a higher chance of success by porting the N810 changes forward to the 2.6.25 Linux kernel.
So, without further ado…
Step 1: Port the N810 kernel changes to the 2.6.25 Linux kernel
This work took one developer seven days to complete, and included the following steps:
Downloaded the latest Linux-OMAP-2.6 kernel from Montavista
Selected the 2.6.25 version from the kernel download (used ‘git reset –hard v2.6.25-omap1’))
Patched the 2.6.25 kernel with the following patches from the N810’s 2.6.21 kernel:
N810 Multi Media Card (MMC) driver
N810 I2C serial bus controller chip driver
N810 touch screen driver
N810 keyboard mapping
N810 audio and video DSP driver
N810 DMA driver
N810 board revision patch
After
a number of software build/flash/test/debug cycles, our new kernel was
able to boot the N810’s default software and function well.
One
issue we did have is that the kernel driver for the CX3110 WiFi chip is
provided as a binary-only kernel module, not source code that we could
recompile on the new kernel. This meant that we were not able to make
our new kernel support WiFi on the N810.
This is an important
note for those trying to do similar ports: if you have binary-only
drivers, make sure they’ve been compiled against the kernel baseline
that you plan to use.
Step 2: Add the Android kernel patches to the 2.6.25 N810 Linux kernel
With
our new N810 Linux kernel up and running, we could now apply the
Android patches. This was mostly straightforward and took one developer
two and a half days of applying patches, flashing the kernel, and
verifying the patches worked.
If you are using a kernel baseline
different from the one in the Android SDK, you should plan to spend
more time and resources to make it work correctly.
Luckily,
the Android and N810 patches do not touch any of the same kernel parts.
This made merging these two change sets much easier.
Step 3: Bring-up Android on our new kernel
After
two weeks of patching and testing, we were finally ready to try to boot
the full Android system. Software development would not be any fun if
everything worked the first time, so, luckily, there were issues (that
is a joke).
Here is the list of what we worked through:
The N810’s jffs2 file system lacked a feature Android needs in the mmap system call
So we switched to using the ext2 file system, but it reported data corruption
So we switched to using the ext3 file system, and the corruption went away
The system hung while booting, and while we were trying to debug, it would reboot
We discovered the watchdog timer was rebooting the system, so we disabled it
After that, the system sometimes successfully booted, but the screen was blank
We could see graphics after we applied a double-buffered video patch to the N810
After this, we could sometimes boot to the home screen, but the system often crashed
We recopied some system libraries to the N810, and the crashes went away
We enabled the touch screen by changing a power setting in the system software
We enabled the keypad by fixing a keymap file in the system software
And,
finally, afer 19 days, it worked. The Android robot would show while
powering up, and then we could see the main menu and use the
applications.
Android 1.0 booting on the N810 (Click to play)
Step 4: Play Around
This,
of course was the pay off. If you get this far, we recommend that you
take a photo and email it to your nerdiest friends and colleagues to
show off your accomplishment.
Android 1.0 running on Nokia’s N810 Internet tablet (Click to enlarge)
Next steps
We
want to be able to create our own Android applications and run them on
the N810. To do that, we will need to add support for the Android Debug
Bridge, fix an intermittent system crash, and see if we can enable
battery charging when the power supply is plugged in. Additionally, our
application needs Internet access, so we either need to make the WiFi
chip work, or enable USB Ethernet to send network data through the USB
cable to a host PC, which can then route the N810’s data to the
Internet.
Finishing up
Before we’re done, we will
release the changes we made back to the Android and N810 communities so
that they can take advantage of the work we have done and have a bit of
fun.
Things to consider in your project
If you’re porting Android to a new device, we recommend you consider the following points:
First,
this is a just a milestone along the way to any kind of shipping
product. We still have work to do before the N810 will be good enough
for us to develop custom applications. Likewise, the N810 isn’t a
phone, so we didn’t have to spend time debugging the call stack. And
then there are the pieces that don’t work — power management, WiFi,
etc. — that could all take more time to make work than we spent on
this initial port. So the hard work is ahead, not behind.
Second,
the N810 is a shipped commercial product that has gone through Nokia’s
strenuous quality control processes and is well loved by lots of
hackers. We have worked on other projects with flakey hardware and no
vendor support (yeah, that was a huge mistake — and it was made even
worse by doing it fixed-bid). If you are porting Android to your own
hardware, be sure to factor time and resources into dealing with
hardware risks. We highly recommend that you make sure there are
software people assigned to making the hardware drivers work.
Third,
figure out which baseline kernel version you will use at the start.
This way, you can verify or add tasks for making sure your hardware has
the kernel drivers developed for that version of the Linux kernel. And
since an outside vendor often provides binary drivers, make certain
that you will have those drivers compiled against your Linux kernel
when you need them.
Fourth, use the right tools and processes —
preferably the same ones that the Linux and Android developers use.
We’ve worked with big companies who import open-source software into
closed-source development models. While this makes it easier to get
started, these teams later pay a price when they are not able to easily
merge new versions of open-source software into their code base.
Additionally, if your developers want to use Windows at all, we
recommend you push them out of their cocoon and into the Linux world. A
highly effective team would be one running Linux on their desktop, git
for source control, and vim or emacs to edit ‘C’ code.
Finally,
assemble the right team. While we’re new to Android, we’ve been hacking
embedded Linux systems for a long time. So check your teams’ experience
and plan accordingly.
Saying thanks
First, I’d
like to thank Tang Yongjun, the NthCode developer who actually ported
Android to the N810. I don’t know that I would have been as patient as
he was.
He and I would both like to also thank PenguinBait,
B-man, and QWERTY-12 (yes, awesome names), who made the original port
of the pre-release Android SDK to the N810. We were able to follow many
of their steps to make our port of the Android 1.0 release easier.
Finally,
this is a living document. If you spotted a mistake, or think others
would benefit some piece of piece of information we don’t have here,
please email me so I can consider the change.
Download
We
have placed our kernel patch, a complied kernel image, a compiled
userspace image, and a few notes at the following SourceForge.Net page: Android-N810 Downloads.
This paper was originally published by NthCode, here. It is reproduced with permission.
About the author
— Beijing resident and American expatriate Peter McDermott founded
NthCode in 2005 to tap into the talent he saw in his Chinese co-workers
while creating some of the world’s first Linux-powered mobile phones.
Peter enjoys running NthCode to this day and maintains a personal
weblog, Beijing Analog to Digital where he discusses technology, business, and life in Beijing. Click the photo at left for an NthCode staff photo.
Google explains that Android is a software stack for mobile
devices that includes an operating system, middleware and key
applications. This document explains the Android architecture by Google
and porting procedure on the real hardware. The explanation is based on
the m3 sdk version of the Android emulator.
If you have enough knowledge about patching the kernel, resolving
rejections from a patch, making an ramdisk image, and the Linux kernel
itself, reading this article will be easier.
This document is copyright (c) Kwangwoo Lee (kwangwoo.lee at gmail
dot com). Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License.
The most different things are the Android kernel uses ARM EABI(Embedded Application Binary Interface) and OpenBinder
IPC(Inter Process Communication). If you want to compile the kernel
supporting ARM EABI, you should rebuild toolchains to support ARM EABI.
The Android sdk emulates goldfish architecture using qemu. The
alsa may be used for audio on Android. See the audio.c file in the
goldfish architecture directory and the driver uses /dev/eac for audio
on the Android system. RTC(Real Time Clock) device is also used through
/dev/rtc0.
Example with long ftruncate64(unsigned int fd, loff_t length):
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 the
CONFIG_AEABI and CONFIG_OABI_COMPAT. You can see the differences of the
executable binary as follows :
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 ARM
and its partners (including CodeSourcery) that explains how compilers,
assemblers, linkers, and other similar tools should generate object
files and executable files. Tools that correctly implement the ABI for
the ARM Architecture can interoperate; i.e., objects files built with
one toolchain can be combined with object files built with another
toolchain if both compilers use the ABI for the ARM Architecture. The
"ARM EABI" is an informal name for the ABI for the ARM Architecture.
The OpenBinder
provides a object-oriented operating system environment. It is designed
to be hosted by traditional kernels. This project is started at Be.
Inc. as the part of the next generation BeOS, and finished implementing at PalmSource as a core part at the Cobalt system.
It is a system oriented component architecture rather than
application oriented, and It provides IPC between processes,
threadpool, memory management and clean up feature at the end of
reference of an binder object.
The vanilla kernel do not have OpenBinder IPC mechanism you should patch the kernel. The OpenBinder
offers thread management for the system through /dev/binder. It is the
reason that Android system do not offer thread libraries.
Dianne Hackborn worked for the BeOS explains briefly at osnews.com.
The basic frame buffer driver should be implemented already. After
that you need to implement the differences between your architecture
driver and the goldfish driver.
The frame buffer driver of the goldfish architecture supports the
fb_pan_display function of the struct fb_ops. It means you should
allocate memory twice rather than the actual frame size.
Android uses event device for user input. There are three devices
such as keypad, qwerty2 keyboard and mouse. The qwerty2 keyboard and
mouse are normal devices. So I just explain the keypad and touchscreen
which 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.
Qemu emulates goldfish-events-keyboard. It is a keypad using event
device(/dev/input/event0). So you should know which key event and
values come from the event device to activate Android applications. To
do that, read event0 device with cat and redirect the output to a file.
If you push and release the key button on emulator, the output values
will be saved.
The output format is struct input_event. So the output on each
event is 16 bytes like 8 bytes for time, 2 bytes for type, 2 bytes for
code, 4 bytes for value. Read input.txt and input-programming.txt about
input event devices in the Documentation/input directory of the Linux
kernel 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. The
following shows the key layout on evaluation board, scancode table, and
Android keycodes:
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 scancode
with the keycode of the Android on the above table and send event to
user space application.
The high resolution timer – hrtimer is used for reduce keypad debounce.
Touchscreen
If you have a touchscreen driver supporting the event interface
for a pointing device, it’ll work well. If you do not have it, you may
implement it or use other pointing devices. Fortunately the evaluation
board has already implemented touchscreen driver –
drivers/input/touchscreen/tsc2007.c – which is made just before
beginning to porting Android. Refer the drivers on
drivers/input/touchscreen/ to implement your own driver and the text
files on Documentation/input/.
Here is the output of the /proc/bus/input/{devices,handlers} on evaluation board.
The Linux Kernel has an OOM(Out of Memory) killer for the
situation that no memory is left to allocate for a request of a
process. It examines all processes and keeps score with some
restrictions. The process with highest score will be killed except
init.
The Low Memory Killer of the Android behaves a bit different
against OOM killer. It classifies processes according to the importance
with groups and kills the process in the lowest group. It will make the
system to be stable at the view of the end users. For example, the UI
Process – foreground process – is the most important process for the
end users. So to keep the process live looks more stable than keeping
other background processes live.
Enable CONFIG_LOW_MEMORY_KILLER after patching the kernel.
If you enable this feature, you can see some useful information
about Android through /dev/log/main. There are three device files on
/dev/log such as main, events, radio. The /dev/log/radio file seems to
be related with a modem device and ril daemon – rild – on Android
system.
When this logger is enabled, the system performance is a bit
slower on the system. To use this feature, enable
CONFIG_ANDROID_LOGGER.
The Android power is for the battery management on devices and
some subsystem related with power management like inotify feature on
file system. It is not necessary to start up Android through the init(ShellScript)
of the Android system. But the runtime binary looks up some files
regarding Android power – /sys/android_power/acruire_partial_wake_lock
– on starting up Android manually and failed to start up. Enable
CONFIG_ANDROID_POWER to use.
Android emulator has 3 basic images on tools/lib/images directory.
ramdisk.img
system.img
userdata.img
ramdisk.img is gziped cpio archive. ramdisk image is very small
and contains configuration files, and some executable files such as
init and recovery. The init file is not a regular system V init. It is
made just for the Android and do special things to start up the Android
system.
system.img and userdata.img are VMS Alpha executable. system.img
and userdata.img have the contents of /system and /data directory on
root file system. They are mapped on NAND devices with yaffs2 file
system. /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 ApiDemos.apk package.
The main services are zygote(/system/bin/app_process),
runtime(/system/bin/runtime), and dbus(/system/bin/dbus-daemon). You
can see the /etc/init.rc file on the Android ramdisk image.
tools/lib/images/NOTICE contains package lists and licenses for
each libraries. The table of the licenses is cited from the
presentation by Lim,GeunSik at 2008 Korea Android Summit.
The toolchain represents the tools to be used for the system
development. It contains C/C++ compiler, linker, libraries, binutils,
and etc. The Android kernel and system requires EABI support. So legacy
toolchain is not compatible to make the Android system.
To port the Android on a real hardware is started by Benno (http://benno.id.au),
you can see some useful information on his blog. On his blog some
pre-compiled static binaries are linked. It is very helpful for
debugging Android system. You can also build static build busybox and
strace binaries, but it’s better to get them and use.
You can get patch file including the differences between the
Android kernel and the vanilla kernel with 2.6.23 version. It has all
differences between them. So you need to extract parts of them, and
make your own patch for your system architecture.
For example, the Android kernel has it’s own yaffs file system
patch. If you have your own yaffs or some other file systems like jffs2
on your architecture, then you need to remove the yaffs parts of the
patch. The goldfish architecture which the Android kernel emulate an
ARM architecture on qemu is not necessary part for your architecture.
It can be removed.
The Android kernel emulates ARMv5 instructions. So ARM926EJ-S (ARMv5TEJ) will be good to work.
Benno played with a NEO1973 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 making
patch including binder, android power, android logger, low memory
killer except goldfish and qemu specific parts, get vanilla 2.6.23
version 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_ANDROID_GADGET is not set # CONFIG_ANDROID_RAM_CONSOLE is not set # CONFIG_ANDROID_POWER is not set # CONFIG_ANDROID_LOGGER is not set ...
The root file system is composed of three parts such as a primary
ramdisk 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 and
each of them has 64 MiB capacity on the Android emulator.
The extracted system and data directories are copied to the real
existing NAND device and they are mounted with –bind option to work on
a real hardware.
6.3Integrate 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 except
system and data directory. And make just mount point for system and
data 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 start
the system and It read a configuration file on /etc/init.rc.
Make run.sh script. /dev/block/mtdblock5 is a mtd partition on a
real NAND device, and it is mounted on /mnt. data and system
directories are already copied on mtdblock5. So the script below just
shows bind mounting each directory on /. Fix your script according to
your 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
The contents of the system and data directories are copied to
mtdblock5 already. You should copy your own method. To use it, I chose
bind mounting on root directory. Bind mounting is a technique to mount
an existing directory with a new mount point.
Now the kernel, ramdisk, and data directories – data and system –
are ready. It’s time to see the red cylon eye. After boot up your
integrated 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 #
Do not make eac device file on /dev. It is for the audio
on qemu. If it exists, the start up sequence will wait forever to
finish writing some data to the sound device.
Use the Android init binary instead of manual startup. The manual
start up will require the android power patch. In that case the start
up sequence will access /sys/android_power/acquire_partial_wake_lock
and wait.
The Android applications use Java syntax and xml layouts, but it
is not a Java. Because they use their own virtual machine – dalvik –
and compiler for dex file format. And use package named apk such as
Home.apk, Phone.apk, ApiDemos.apk and etc.
The apk file is a Zip archive and it has four parts.
AndroidManifest.xml
classes.dex
resources.arsc
res directory
The Dex file format is explained on http://www.retrodev.com/android/dexformat.html.
And the contents of the files and directories are explained some day by
Google. It is not explained currently. We can just guess about it.
The Android system seems to be a new kind of a Linux based distribution for a mobile environment like Debian, RedHat, SuSE,
and etc. They just use the Linux kernel and a lot of different
libraries in the open source world. They offer a software based OpenGL-ES
library on a 3D acceleration currently, but they are developing on a
hardware accelerated baseband processor for it. The hardware
acceleration is necessary for fast UI rendering effects later.
The Android system on the sdk is not a completed one to port on a
real hardware, because some device – for example, camera – related
libraries and classes are not implemented yet and not opened for users.
It seems to be under the development stage. So we would better to wait
the Google announces the whole porting kit.
Until then, we should look for the business model with the Android
system. It requires a bit high cpu performance, so the carrier vendors
will require a cheap baseband processor (RF part) and a multimedia
co-processor, because the baseband processor including multimedia
features will be very expensive.
从新加坡的Tanah Merah Ferry Terminal出发。早上9点多的船。五人不到一小时便来到这个度假小岛。小岛北岸东西约20多分钟的车程,西边相对比较热闹,有三四家度假村,有著名的海上餐厅Kelong,还有一条当地风情的小步行街Pasah Oleh Oleh;而东边只有Bintan Lagoon Resort这一个度假村而已。我们在促销期间定下了Bintan Lagoon的两间房,起初还觉得可能出行不太方便,到了之后才发现,选择这里真是太明智了。
中午在房间里略作休息后,我们跟随旅游车来到红树林。这里曾经获得03年亚太地区生态旅游的金奖。
按照事先的安排,红树林后本应该是在Pasah Oleh Oleh逛逛,但由于第二天回新加坡的渡口也在这边,我们便临时决定第二天临走再来逛逛,买些东西。
第二天早上,虽然定了闹钟,但还是晚起来了一个小时。吃过自助早餐(其实我们是当午餐吃的),我们来到传说中世界Top 100的Bintan Lagoon的高尔夫球场。一会发球,一会推洞,差不多一上午的时间都花在了打高尔夫球上,到现在手和胳膊还疼呢。玩到尽兴,还回了球杆和球,我们略有些不知所措。毕竟这里是度假村,太多的景点是没有的,大部分前来度假的都是奔着海滩和高尔夫球来的。我们在大厅里商量了一下行程,初步敲定再去海滩玩一会,然后就到Pasah Oleh Oleh去逛逛,晚上在那边吃饭,回家。
休息了片刻,时候差不多了,我们准备向西边进发。本来宾馆只提供到渡口的免费巴士,我们因为要先去Pasah Oleh Oleh逛逛,只好自己打出租车了。后来想想,因为渡口与Pasah Oleh Oleh距离不远,我们可以先乘坐大巴去渡口,然后在那边打车可能会便宜一些。
拉古洼水库 The Lagoi Reservoir:拉古洼公园&水库是民丹岛上最大规模的水库,占地14.7平方千米,存水量达到六百万立方米。水库存水按照WHO标准收集和管理,为周围度假村提供水源水源。 建议在下午4点钟游览公园,享受公园的宁静,绿荫和清新的空气。公园有各种活动,例如单人、双人皮艇,钓鱼,烧烤,野炊等。门票:成人3新元,儿童2新元。交 通:乘坐Pasar Oleh Oleh班车。
民丹岛最佳旅游时间:民丹岛地处亚热带,四季气温变化不大。三月底到十一月初的气候干燥舒爽,阳光明媚,海面平静,是休闲旅游的最佳季节;十一月底到转年三月初经常有风,适合风力传送的运动,例如冲浪。每年1月份这里都会举行Mana Mana Amslam 亚洲杯国际风浪板巡回赛。11月至3月有东北季风,这段时间水上运动设施可能会短缺。
Tanah MerahFerry Terminal
取完行李,出了海关后在大厅里等接我们的人,拿了船票价值 33 SGD。机场外天还是刚蒙蒙亮。一路来到了Tanah Merah Ferry Terminal 。就是和候机楼一样,只不过是等船的,也要check in ,要托运行李,过边防,过海关。新加坡什么都贵,毕竟人家是发达国家。我们就托运了两箱大依云,准备到哪去泡茶喝。也要换boarding pass,背面标有登船的信息。然后就是出境新加坡,去boarding gate 。流程,布局和机场是完全一样的,只不过你上的不是飞机,而是船。走过一条很长的走廊,到了登船的码头。船还不错,就是大型的游艇,白色的,很漂亮。收boarding pass,然后上船,船上的座位和飞机也差不多,随便坐。托运的行李也是由搬动式搬上船,全放在船舱的最前面,然后用布盖上。船是分上下两层,都可以座人,船内设施还不错,有大电视可看,座位布局和飞机也差不多,就是空间大了些,座椅全都朝前。有出售的饮料和食物。
一路到了NIRWANA 酒店,路不宽,只有两车道,旁边全是树,很自然的感觉。酒店的门口有两个池塘,里面有盆栽的荷花,水里有大条的锦鲤。还有身穿传统服装的人在演奏当地乐器,表示对客人的欢迎。到大堂去check in ,柜台上面的墙上有国徽和国王的相片,看得出来这是一个很尊重领导人的国家。大堂很大,不过是个开放式的建筑,没有空调,比较热。这间酒店的大体色调为棕色,用了很多木质建材,很贴近自然,在大堂周围有很多开放的空间,让人能更好地融入自然。先出来转转,熟悉一下环境,花园弄得很精致,各种花草很漂亮,还有很多高大的椰子树。园中有一个草棚子,里面展示有两艘当地的木船。游泳池边有一个卖饮料的亭子。超过泳池就到了海边,白色的细沙滩,高高的椰子树,碧海,蓝天。旁边有中文提示,主要是说小心风浪,小心jelly fish 海蜇,小心TAR 石油。如果被海蜇蜇了,要赶快去医院。附近的海域有时会有轮船经过,漏出的石油就会漂到海边,如果粘在身上是擦不掉的,要用汽油,找酒店工作人员就行,他们有准备。也别担心,不像环境污染的片子里拍得那么可怕,你用肉眼是看不到石油的,只是不知不觉的时候粘上了一点点,根本不影响海景。从海滩回来,冲脚用的柱子上是一个青蛙雕塑很可爱。
Nirwana ResortHotel
一路到了NIRWANA 酒店,路不宽,只有两车道,旁边全是树,很自然的感觉。酒店的门口有两个池塘,里面有盆栽的荷花,水里有大条的锦鲤。还有身穿传统服装的人在演奏当地乐器,表示对客人的欢迎。到大堂去check in ,柜台上面的墙上有国徽和国王的相片,看得出来这是一个很尊重领导人的国家。大堂很大,不过是个开放式的建筑,没有空调,比较热。这间酒店的大体色调为棕色,用了很多木质建材,很贴近自然,在大堂周围有很多开放的空间,让人能更好地融入自然。先出来转转,熟悉一下环境,花园弄得很精致,各种花草很漂亮,还有很多高大的椰子树。园中有一个草棚子,里面展示有两艘当地的木船。游泳池边有一个卖饮料的亭子。超过泳池就到了海边,白色的细沙滩,高高的椰子树,碧海,蓝天。旁边有中文提示,主要是说小心风浪,小心jelly fish 海蜇,小心TAR 石油。如果被海蜇蜇了,要赶快去医院。附近的海域有时会有轮船经过,漏出的石油就会漂到海边,如果粘在身上是擦不掉的,要用汽油,找酒店工作人员就行,他们有准备。也别担心,不像环境污染的片子里拍得那么可怕,你用肉眼是看不到石油的,只是不知不觉的时候粘上了一点点,根本不影响海景。从海滩回来,冲脚用的柱子上是一个青蛙雕塑很可爱。