Since the kernel.org servers were hacked a browsable repository can be found here.
Pages
-
Meta
-
RSS Feeds
Since the kernel.org servers were hacked a browsable repository can be found here.
Compile Android’s kernel tree
This generates a file named arch/arm/boot/zImage
Compile Android’s emulator kernel
This generates a file named arch/arm/boot/zImage
Both the standard and emulator kernels are provided precompiled in the SDK at ${SDK_ROOT}/prebuilt/android-arm/kernel.
You can now run the emulator as:
Note that as a convenience, if the name of the kernel image ends with -armv7, then the cortex-a8 emulation will be turned on automatically. Otherwise you would have to pass the flags manually (-qemu -cpu cortex-a8).
Reportedly the qemu emulator included in the Android SDK doesn’t support ARMv7 emulation properly.
Ramdisk
A ramdisk.img (initrd) is a small partition image that is mounted read-only by the kernel at boot time. It only contains /init and a few config files. It is used to start init which will mount the rest of the system images properly and run the init procedure. A Ramdisk is a standard Linux feature.
ramdisk.img is included ($SDK_ROOT/tools/lib/images/ramdisk.img) or compiled ($SDK_ROOT/out/target/product/$PRODUT_NAME/ramdisk.img) by the google android sdk. It’s in a gzipped cpio file.
Modifying Android’s ramdisk image
To modify it, first copy it to your Linux machine and extract it as follows:
Make any changes you want to the extracted ramdisk.cpio, and remove the unneeded files. Recreate the ramdisk.cpio with command:
System and data images
The system.img is a partition image that will be mounted as / and thus contains all system binaries.
The userdata.img is a partition image that can be mounted as /data and thus contains all application-specific and user-specific data.
On the real device they have to be mounted by the init.rc script which runs from the ramdisk. They can be of different formats, usually YAFFS2, EXT4 or UBI-FS.
They are generated by the build system and can be used to flash to a real device. The emulator uses them differently (see below)
Android emulator images
The emulator will not modify system.img and userdata.img since they were generated as device images.
Extracting Android’s YAFFS2 images
A YAFFS2 file is identied as a “VMS Alpha executable” by Linux.
Download unyaffs from the unyaffs Google Project Hosting.
If the executable does not work on your system you can download the source and recompile it.
Copy the YAFF2 img files to the same folder and extract them:
Extracting JFFS2 images
Just for completion, here is how to extract a JFFS2 image.
RS232 focusses on the connection of DTE, data terminal equipment (computers, printers, etc.) with DCE, data communication equipment (modems).RS232 cables can use DB25 or DB9 connectors. DB25 connectors have provision for two RS232 connections, but the single connection DB9 is most commonly used.
| 1 | DCD | Data carrier detect |
| 2 | RD | Receive data |
| 3 | TD | Transmit data |
| 4 | DTR | Data terminal ready |
| 5 | SG | Signal ground |
| 6 | DSR | Data set ready |
| 7 | RTS | Request to send |
| 8 | CTS | Clear to send |
| 9 | RI | Ring indicator |
The purpose of a null-modem cable is to permit two RS-232 DTE devices to communicate with each other without modems or other communication devices (i.e., DCEs ) between them.
A null modem cable is an RS232 serial cable where the transmit and receive lines are crosslinked. In some cables there are also handshake lines crosslinked. In many situations a straight through serial cable is used, together with a null modem adapter. The adapter contains the necessary crosslinks between the signals.
Null modem without handshaking
| Connector 1 | Connector 2> | Function |
| 2 | 3 | Rx -> Tx> |
| 3 | 2 | >Tx> -> Rx |
| 5 | 5 | Signal ground |
Null modem with loop back handshaking
| Connector 1 | Connector 2 | Function |
| 2 | 3 | Rx -> Tx |
| 3 | 2 | Tx -> Rx |
| 5 | 5 | Signal ground |
| 1 + 4 + 6 | - | DTR -> >CD + DSR |
| - | 1 + 4 + 6 | DTR -> CD + DSR |
| 7 + 8 | - | RTS -> CTS |
| - | 7 + 8 | >RTS -> CTS |
Null modem with partial handshaking
| Connector 1 | Connector 2 | Function |
| 1 | 7 + 8 | RTS2 -> CTS2 + CD1 |
| 2 | 3 | Rx -> Tx |
| 3 | 2 | Tx -> Rx |
| 4 | 6 | DTR -> DSR |
| 5 | 5 | Signal ground |
| 6 | 4 | >DSR -> DTR |
| 7 + 8 | 1 | RTS1 -> CTS1 + CD2 |
Null modem with full handshaking
| Connector 1 | Connector 2 | Function |
| 2 | 3 | Rx -> Tx |
| 3 | 2 | Tx -> Rx |
| 4 | 6 | DTR -> DSR |
| 5 | 5 | Signal ground |
| 6 | 4 | DSR -> DTR |
| 7 | 8 | RTS -> CTS |
| 8 | 7 | CTS -> RTS |
When one end of a data link is unable to accept any more data (or approaching that point), it sends XOFF to the other end. The other end receives the XOFF code, and suspends transmission.
Once the first end is ready to accept data again, it sends XON, and the other end resumes transmission.
Requires less wiring and is slower, as sending XOFF requires at least one character time to transmit, it may be queued, has to be done in software and has the overhead of escaping the control codes so that they are not confused with data.
XOFF/XON representations in ASCII
| Code | Meaning | ASCII | Dec | Hex | Keyboard |
| XOFF | Pause transmission | DC3 | 19 | 0×13 | CTRL+S |
| XON | Resume transmission | DC1 | 17 | 0×11 | CTRL+Q |
In common RS232 there are pairs of control lines:
Hardware flow control is typically handled by the DTE or “master end”, as it is first raising or asserting its line to command the other side.
In case of RTS control flow, DTE sets its RTS, which signals the opposite end (the slave end such as a DCE) to begin monitoring its data input line. When ready for data, the slave end will raise its complementary line,
CTS in this example, which signals the master to start sending data, and for the master to begin monitoring the slave’s data output line. If either end needs to stop the data, it lowers its respective “data readyness” line.
For PC-to-modem and similar links, the case of DTR flow control, DTR/DSR are raised for the entire modem session (say a dialup internet call), and RTS/CTS are raised for each block of data.
Print configuration
Set to 38400, no flow control, one stop bit, odd parity, 8 bit, disable special characters
On target,
On host,
To turn on the hardware flow control, do:
The Android Gingerbread battery service has a JNI interface which supports a power supply class battery driver with hardcoded attributes. However, different platforms drivers may provide different attributes, so to allow for this configurability you can add platform specific system properties like:
devices/<manuf>/<platform>/system.prop
ro.power_supply.ac.online = online ro.power_supply.usb.online is not supported ro.power_supply.bat.status = status ro.power_supply.bat.health is not supported ro.power_supply.bat.present = present ro.power_supply.bat.capacity = capacity ro.power_supply.bat.voltage_now = voltage_avg ro.power_supply.bat.temperature is not supported ro.power_supply.bat.technology = technology
And then you retrive and use each of the properties, for example.
property_get("ro.power_supply.ac.online", value, ""); snprintf(path, sizeof(path), "%s/%s/%s", POWER_SUPPLY_PATH, name,value);
For the battery status to be updated by the Battery Service, it needs to receive a uevent from the Linux kernel driver. Verify that your battery driver does something like:
if( bat_status_old != bat_status.status ) power_supply_changed(&chg_device->psy); bat_status_old = bat_status.status
At least on the status and capacity update functions.
The battery data is dumped into /data/system/batterystats.bin, a binary file that can be dumped using dumpsys.
Your app would need android.permission.DUMP to execute dumpsys.
GPIOs are very common in embedded hardware, representing pins connected to ball grid array (BGA)
packages.They are commonly used to provide flexibility in System On Chip (SOC), and
it is common for pins to be multiplexed and shared for different functionality. As such,
GPIOs are specific to each platform and we can only speak in generic terms.
Usually they can be used as writable output and readable inputs which can also be used
as IRQs.
Linux platforms that support GPIO conventions declare GENERIC_GPIO, and drivers use the
interface in linux/gpio.h. GPIOs are identified by platform specific integer
numbers, with negative numbers being invalid.
int gpio_is_valid(int number);
Check whether a given number is a valid GPIO.
int gpio_request(unsigned gpio, const char *label);
Request a GPIO returning 0 on success or a negative error value.
void gpio_free(unsigned gpio);
Frees a previously requested GPIO.
int gpio_direction_input(unsigned gpio); int gpio_direction_output(unsigned gpio, int value);
Set the direction of the GPIO returning 0 on success or a negative error value.
int gpio_get_value(unsigned gpio); void gpio_set_value(unsigned gpio, int value);
The getter return 0 or 1 (high or low), and the setter sets 0 or 1 (high or low).
Most GPIO controllers are accessed withouth the need for sleep and can be safely
accessed through IRQ handlers. Some use message buses like I2C or SPI which may sleep,
and this should be accessed by the following accessors:
int gpio_get_value_cansleep(unsigned gpio); void gpio_set_value_cansleep(unsigned gpio, int value);
Platform code will have defined the mapping between the GPIOs and IRQs number
namespaces, so we can use the following functions to swap between them.
int gpio_to_irq(unsigned gpio); int irq_to_gpio(unsigned irq);
Not al GPIOs can be configured as IRQs and in that case they will return a negative
errno.
An optional framework to support diferrent GPIO controllers (packaged as a “struct
gpio_chip”) with the same API. With debugfs available, /sys/kernel/debug/gpio lists all
registered controllers and the state of used GPIOs. The platform will define
ARCH_REQUIRE_GPIOLIB to compile the framework in, ARCH_WANT_OPTIONAL_GPIOLIB to let the
user built it into the kernel optionally, or none if GPIOLIB is not supported.
When using GPIOLIB, a sysfs interface can be enabled to control GPIO directon and value
from userspace. The control interface lives in /sys/class/gpio.
echo 19 > /sys/class/gpio/export
Will create a gpio19 node and request the GPIO number 19.
echo 19 > /sys/class/gpio/unexport
Will free the GPIO 19.
echo "in" > /sys/class/gpio/gpio19/direction echo "out" > /sys/class/gpio/gpio19/direction
Will configure it as input or output.
cat /sys/class/gpio/gpio19/value
Will read from an input GPIO.
echo 0 > /sys/class/gpio/gpio19/value echo 1 > /sys/class/gpio/gpio19/value
Will write to an output GPIO.
echo rising > /sys/class/gpio/gpio19/edge echo falling > /sys/class/gpio/gpio19/edge echo both > /sys/class/gpio/gpio19/edge echo none > /sys/class/gpio/gpio19/edge
If the GPIO can be configured as IRQ,the above configure the signal edges.
Drivers can also make GPIOs available through sysfs using:
int gpio_export(unsigned gpio, bool direction_may_change); void gpio_unexport();
And the following can be used to symlink to a different sysfs location to provide the
interface under a different device.
int gpio_export_link(struct device *dev, const char *name,unsigned gpio)
The Linux kernel will launch the init process which is the parent of all othe processes in the system.
Init will execute the init.rc script launching the system service processes.
The first process to launch is Zygote, which will execute and initialize the Dalvik VM.
The first Java component to start is the system server. This in turn will launch all the rest of the Android services, which will run in the System Server context.
frameworks/base/services/java/com/android/server/SystemServer.java
The server loads a native android_servers library that provides interfaces to native funcitonality.
Then init1(args), the native init method that starts up native services is called. This is implemented in system_init in frameworks/base/cmds/system_server/library/system_init.cpp
Once it finishes starting native services there is a callback to init2:
runtime->callStatic("com/android/server/SystemServer", "init2");
Which then creates the server thread. Each service started by the system server runs as a separate Dalvik thread in the SystemServer process. These can be analyzed using the DDMS tool.
After the system boot has completed there is a standard broadcast android.intent.action.BOOT_COMPLETED. This can be used to start a service or perform some action by an application if it includes a broadcast receiver that registers for this intent.
A property is a key/value pair, both of which are of string type. Many android applications and libraries directly or indirectly relies on this feature to determine their runtime behavior.
Properties are stored in a shared memory block which can only be written to by the property service process. This service, started by init, reads properties from persisten storage and writes them into memory.
To read properties a consumer process (via libcutil) loads the shared memory into its own virtual memory, using an enviromental variable called ANDROID_PROPERTY_WORKSPACE which keeps the fd for the shared memory area and its size.
To write properties a setter process will also load the shared memory into its virtual space, but will rely on a unix domain socket (/dev/socket/property_service) to tell the property service to change a property both in shared memory and in persistent storage.
The shared memory region is structured as follows:
count serial magic version reserved[4] toc[1] ... starts at 1024 bytes offset. prop_info[PA_COUNT_MAX]
Where PA_COUNT_MAX is defined in system\core\init\property_service.c, and it’s 247 by default.
After setting up the shared memory area,the init process will load properties from following files:
/default.prop /system/build.prop /system/default.prop /data/local.prop
Then init starts the property service and waits polling on its socket.
To get or set properties:
Native code (linking against libcutils)
#include <cutils/properties.h>
property_get/property_set
Java code
System.getProperty/System.setProperty functions in the java.lang library. These are Java properties, stored on a hashtable.
android.os.SystemProperties can be used to access native properties through JNI. Anyone can read them, but only the system server UID can write to them. The class is defined in https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/SystemProperties.java
Currently, properties can’t be removed.
When you duplicate a disk you do something like:
dd if=/dev/sda of=/tmp/mydisk.dd
When you receive an image file, you can check it with file:
mydisk.dd: x86 boot sector; partition 1: ID=0x83, starthead 0, startsector 15128,7722844 sectors, extended partition table (last)\011, code offset 0x0
And with fdisk:
fdisk -l -u mydisk.dd
You must set cylinders.
You can do this from the extra functions menu.
Disk mydisk.dd: 0 MB, 0 bytes
122 heads, 62 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x674d869c
Device Boot Start End Blocks Id System
mydisk.ddp1 15128 7737971 3861422 83 Linux
To mount it, you need to specify the offset of the partition you want to mount, not in sectors but in bytes. So to mount sector 15128 the offset is 15128*512:
sudo mount -o loop,offset=7745536 -t auto /my/path/mydisk.dd /mnt