Вы находитесь на странице: 1из 12

RK29 modding tutorial by wackym

v1.0

This tutorial is written to demystify the art of modding and help you (the reader) to help yourself and inspire you to share your knowledge and help others All credit for the tools used in this tutorial goes to their respective authors. I only wrote *.sh scripts to use those tools.

1. Basic requirements
To start developing you need the following: - Ubuntu/Lubuntu/Xubuntu etc. or similar Linux environment (I recommend Lubuntu, since its very lightweight and works fast even in virtual machines) tools.tar.bz2 pack installed at ~ /bin
mkdir ~/bin cd ~/bin tar xvf ~/Downloads/tools.tar.bz2

make sure the following tools are installed on your Linux distro: awk, grep, gzip, du, find, wc, rsync, head, cpio or you will get errors running the scripts rkusb drivers and RKBatchTool (you get these with the update image)

Familiarize yourself with (at least) basic Linux commands like: chmod, chown, mc, cp, mkdir, rm, rsync, grep, mount, umountand with Linux permissions, especially set user and set group permissions. Which are important for proper rooting. And finally, why Linux at all? Because file permissions and ownerships are crucial to modding and they get lost on Windows. You could, however, use Cygwin

2. RK image structure
RK image structure: Outer layer (rk_xyz.img) consists of: - Inner layer (update.img) consists of o Bootloader.bin (this is the initial program which configures hardware to be able to properly load kernel and RAM file system; WARNING, NEVER change this file in any way! If this stops working then you will end up with a VERY EXPENSIVE paper weight.) o package-file (contains information about partition to file mappings, if kernel is included in boot.img then it is commented out in this file) o parameter (contains information about device and most importantly command line (CMDLINE) passed to kernel) o recover-script (script executed on firmware recovery) o update-script (script executed on firmware update) o Image/boot.img (this image can be packed with kernel or RAM file system by itself) o Image/kernel.img (this image contains kernel the core program which is the advocate between hardware and applications; it also contains an embedded image the first one displayed upon device startup) o Image/recovery.img (this is a safe backup which gets executed if boot.img fails and first time after new firmware update) o Image/misc.img (this contains a special script which usually formats /data and /sdcard partitions upon flashing of device) o Image/system.img (contains applications, framework etc. most of the time youll only need to edit this image) bootloader location MD5 checksum

3. Unpacking <rk_xyz.img> packed with RockChip tools


Lets assume you acquired an rk_xyz.img file and copied it into you project directory ~/project1 (by now you should know that ~ represents your home directory on linux fi. /home/userXY). Step 1: Check if the tools are working by running ver.sh. You should get a similar output:
user@ubu1004:~/project1$ ver.sh Usage: /home/user/bin/ver.sh <apk dir> user@ubu1004:~/ project1$

If you get command not found or similar try to open a new shell or do this export PATH=~ /bin:$PATH and go to step 1. Step2: Use rkimg.sh to unpack the image:
user@ubu1004:~/project1$ rkimg.sh -u rk_xyz.img ****** Cleaning dev folders ****** Unpacking rk_xyz.img to unpack_update/ rom version: 0.2.3 build time: 2012-02-08 17:26:33 chip: 50 checking md5sum....OK Check file...OK ------- UNPACK ------package-file 0x00000800 0x0000021C RK29xxLoader(L)_V2.06.bin 0x00001000 0x00021FDA parameter 0x00023000 0x00000265 Image/misc.img 0x00023800 0x0000C000 Image/boot.img 0x0002F800 0x007C4000 Image/recovery.img 0x007F3800 0x00960000 Image/system.img 0x01153800 0x14000000 SELF 0x00000000 0x15154804 Skip SELF file. update-script 0x15153800 0x000003A5 recover-script 0x15154000 0x0000010A UnPack OK! ****** Done. user@ubu1004:~/project1$

If you do ls -la you will see source_img and unpack_update directories got created. source_img contains all the img files and unpack_update contains all special files.

4. Editing system.img
4.1. Mounting system.img
First you need to mount the image. You can do it manually or use sysmount.sh script. Using sysmount.sh:
user@ubu1004:~/project1$ sysmount.sh m # this mounts the system.img in source_img dir

Using manual approach:


user@ubu1004:~/project1$ mkdir system # this creates a folder in which well mount our image user@ubu1004:~/project1$ sudo mount -o loop source_img/system.img system/ [sudo] password for user: user@ubu1004:~/project1$

By mounting as a loop device we let linux to figure out the type of file system it is mounting. In the case of RK the file system type is usually ext3 (for other SDKs it could be ext2, yaffs2, cramfs, ext4 etc.). This is also the file system that gets created with rkimg.sh script. After mounting you can use mc (Midnight Commander) to easily navigate around system folder. Remember: before packing/moving/copying/<or doing whatever with> system.img you MUST unmount it first or you will risk using a corrupted system.img. When you unmount the image Linux writes back to the image any cached changes that youve made while it was mounted.

4.2. Unmounting
Automatic approach:
user@ubu1004:~/project1$ sysmount.sh u # this unmounts the system.img and also performs some fixes of the usual faults (described in tweaks and fixes section below)

Manual approach:
user@ubu1004:~/project1$ sudo umount system/ system/ directory in current folder # this unmounts (whichever) img thats mounted at

4.3. Folder structure


user@ubu1004:~/project1$ cd system/ user@ubu1004:~/project1/system$ ls -la total 33 drwxr-xr-x 14 root root 1024 2012-02-29 11:31 ./ drwxr-xr-x 5 user user 4096 2012-03-03 13:27 ../ drwxr-xr-x 2 root root 4096 2012-02-29 09:06 app/ # all .apk files that are shipped with firmware drwxr-xr-x 2 root 2000 5120 2012-02-28 16:22 bin/ # system executables busybox, chmod, chown etc. drwxr-xr-x 11 root root 1024 2012-02-29 09:06 etc/ # configuration files (mounting, permissions) drwxr-xr-x 3 root root 1024 2012-02-28 16:11 fonts/ drwxr-xr-x 2 root root 1024 2012-02-29 09:06 framework/ # basic apks and jars providing API to other apks drwxr-xr-x 8 root root 7168 2012-02-29 09:06 lib/ # basic libraries + libs from apks in app folder (remark: if you do not copy libs from apks you add to app folder then those apps will crash on startup) drwx------ 2 root root 1024 2012-02-29 11:31 lost+found/ drwxr-xr-x 3 root root 1024 2012-02-29 09:06 media/ # bootanimation.zip (animation after boot image), audio (sounds) drwxr-xr-x 3 root root 1024 2012-02-28 15:55 tts/ # text-to-speech files drwxr-xr-x 8 root root 1024 2012-02-28 16:07 usr/ # some more configuration files important: keylayout (contains mapping from external buttons to functions) drwxr-xr-x 4 root 2000 1024 2012-02-28 15:55 vendor/ # contains vendor specific stuff and facelock files drwxr-xr-x 2 root 2000 1024 2012-02-28 16:21 xbin/ # additional system executables + su (superuser); su can also be in bin folder (but there may be only one) -rw-r--r-- 1 root root 2246 2012-02-29 11:10 build.prop # build, version, settings, properties etc.

Note the root:root (the same as 0:0) or root:2000 (the same as 0:2000) permissions. These permissions are crucial. If you accidently change them your device will most likely not boot (stay in boot animation endlessly).

4.4. Permissions and ownerships


I assume you have (at least) basic knowledge of Linux permissions and ownershipsif not then you can learn more about it here: http://www.tuxfiles.org/linuxhelp/filepermissions.html http://code.google.com/edu/tools101/linux/ownership_permissions.html All files in system.img must be owned by root (id 0) but the groups can be different to allow access to those files to special system services. Thats why some folders (bin/, xbin/, vendor/) have group set to id 2000 instead of root. When youre adding a file you should be doing this in superuser mode. As default, every file you add will get root:root ownership. For files in bin/ xbin/ and vendor/ you will probably need to change that to root:2000. If unsure, do ls -la in the folder and see what ownerships other files have. To change ownerships use sudo chown root:2000 <file> or sudo chown -R root:2000 <folder> (this changes ownerships for every file and subfolder in that folder). Permissions for files in executables folders (bin/, xbin/) should always be at least readable and executable for all, and writable for owner and group. Some files require also SETUID and SETGUID permissions (fi. su). Adding setuid can be done like so: sudo chmod u+s <file>. Adding setgid is similar: sudo chmod g+s <file>.

4.5. Editing system.img


A rule of thumb is to always make sure you have enough space for what you want to do To check this you have to mount system.img and use command df. It will show you exactly how much space is used inside the image.
user@ubu1004:~/project1$ df # this command shows information about all mounted devices Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 24688764 19455028 3979592 84% / none 250152 212 249940 1% /dev none 254384 164 254220 1% /dev/shm none 254384 88 254296 1% /var/run none 254384 0 254384 0% /var/lock none 254384 0 254384 0% /lib/init/rw .host:/ 732568572 725397128 7171444 100% /mnt/hgfs /dev/loop0 349991 349887 104 100% /home/user/project1/system user@ubu1004:~/project1$

Here we see that I have mounted an image (system.img) as loop device to system/ folder and that is has only 104 KB (why KB? Note the 1K-blocks label in the output) space left. Lets presume you want to add a new apk and you have too little free space. You can either remove the apks you dont want/need and then add new apks or extract (read: copy) the contents from system.img.

4.6. Extracting system.img


Make sure youve mounted system.img (see Mounting system.img). If youre unsure check with mount command. By now you should have system.img mounted to system/ folder in your current project folder. So, to make a perfect copy of system well use rsync -a command.
user@ubu1004:~/project1$ sudo rsync -a system/ system_new [sudo] password for user: user@ubu1004:~/project1$ ls la # after rsync you should see a similar output total 21 drwxr-xr-x 6 user user 4096 2012-03-04 13:30 ./ drwxr-xr-x 16 user user 4096 2012-03-03 10:40 ../ drwxr-xr-x 2 user user 4096 2012-03-03 10:44 source_img/ drwxr-xr-x 14 root root 1024 2012-02-29 11:31 system/ drwxr-xr-x 14 root root 4096 2012-02-29 11:31 system_new/ drwxr-xr-x 2 user user 4096 2012-03-03 10:44 unpack_update/ user@ubu1004:~/project1$

Now unmount system.img (see Unmounting) as we dont need it and well replace it later.

4.7. Adding apk(s) to system


The easiest way (at least for me) is to use Midnight Commander (no mouse required ). Make sure you run it as superuser: sudo mc. This will allow you to edit system/ or system_new/ and at the same time it will keep ownerships of any files you add as root:root. To add new apk(s) you need to copy them into app/ folder. Then you need to copy all *.so files from lib/ folder inside apk (if the folder is present) to <system>/lib/ folder. Some apk(s) contain libs for multiple architectures only copy those for ARM architecture (there will be a word arm in the subfolder). If it has multiple arm subfolders then use *.so files from armv7. Quick tip: to navigate inside apk(s) just use Midnight Commander. After you add files to app/ make sure they have proper permissions (they should be -rw-r--r-- or 755 in octal).
user@ubu1004:~/project1/system_new/app$ ls l New.apk -rw-r--r-- 1 root root 11928009 2012-02-29 09:06 New.apk

4.8. Comparing, replacing, removing apk(s)


To compare apks you need their versions. For this I wrote ver.sh script. It creates a list (named appver.txt) of all apks and their versions for the specified directory.
user@ubu1004:~/project1$ ver.sh Usage: ver.sh <apk dir> user@ubu1004:~/project1$ ver.sh system_new/app/ Created /home/user/project1/appver.txt

You will get a similar output:


user@ubu1004:~/project1$ cat appver.txt # print appver.txt to console Apk versions: ApplicationsProvider.apk package: name='com.android.providers.applications' versionCode='15' versionName='4.0.3eng.wbx.20120229.121900' BackupRestoreConfirmation.apk package: name='com.android.backupconfirm' versionCode='15' versionName='4.0.3eng.wbx.20120229.121900' BooksProvider.apk package: name='com.android.rk.books' versionCode='400' versionName='4.00'

With this output you can decide which apk to use Quick tip: to compare two appver.txt files you can use meld. Deciding which apk to keep can be puzzling, so heres a link to Cynogens wiki which has description of most of the default apks: http://wiki.cyanogenmod.com/wiki/Barebones Latest (tested) google apps can be found here: http://wiki.rootzwiki.com/Google_Apps When replacing apps take extra care with apks that use special devices like Camera, Bluetooth, etc. These apks are often vendor specific and non-portable to other devices.

4.9. Compressing/creating ext3 system.img


This is needed only if you extracted system.img. To create new system.img use sysimg.sh script.
user@ubu1004:~/project1$ sysimg.sh Usage: sysimg.sh <system dir> user@ubu1004:~/project1$ sysimg.sh system_new/ ****** Finding required inode count and required size... [sudo] password for user: ****** >> Estimated required size of system.img is 351 MB ****** Creating ext3 system.img... 351+0 records in 351+0 records out 368050176 bytes (368 MB) copied, 8.23738 s, 44.7 MB/s mke2fs 1.41.12 (17-May-2010) target_img/system.img is not a block special device. Proceed anyway? (y,n) Filesystem label=system OS type: Linux Block size=1024 (log=0)

Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 2112 inodes, 359424 blocks 17971 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67633152 44 block groups 8192 blocks per group, 8192 fragments per group 48 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185 Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 30 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. ****** Disabling auto-checking of system.img tune2fs 1.41.12 (17-May-2010) Setting maximal mount count to -1 Setting interval between checks to 0 seconds ****** ****** ****** ****** Copying data... Setting owner... Setting permissions... Unmounting image...

****** Checking and optimizing system.img e2fsck 1.41.12 (17-May-2010) Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 3A: Optimizing directories Pass 4: Checking reference counts Pass 5: Checking group summary information system: ***** FILE SYSTEM WAS MODIFIED ***** system: 1278/2112 files (4.1% non-contiguous), 352324/359424 blocks user@ubu1004:~/project1$

This script also fixes permissions and ownerships for app/ directory. Newly created system.img will be put into target_img/ directory. To use this system.img with sysmount.sh or rkimg.sh script you need to move it to source_img/ folder. Remember to always check that system.img is not mounted before you move or copy over it (see Extracting system.img).

5. Editing boot.img and recovery.img


WARNING, do not change recovery.img at all! Theres no need to.

5.1. Unpacking
There are two types of boot.img. Some contain kernel and others dont. This issue is handled automatically by unpack.sh script.
user@ubu1004:~/project1$ unpack.sh boot ****** Cleaning dev folders ****** Unpacking boot.img >> this image contains ramdisk and kernel writing boot image config in bootimg.cfg extracting kernel in zImage extracting ramdisk in initrd.img ****** Extracting ramdisk... 2782 blocks # deletes boot/ and unpack_boot/ folders # kernel can also be in a separate kernel.img

# extracts initrd.img to boot/

Doing ls -la boot/ will show you a similar output. Files of interest are marked orange.
user@ubu1004:~/project1$ ls -la boot/ total 656 drwxr-xr-x 9 user user 4096 2012-03-05 drwxr-xr-x 9 user user 4096 2012-03-05 drwxrwx--x 2 user user 4096 2012-03-05 drwxr-xr-x 2 user user 4096 2012-03-05 drwxr-xr-x 2 user user 4096 2012-03-05 drwxr-xr-x 3 user user 4096 2012-03-05 drwxr-x--- 2 user user 4096 2012-03-05 drwxr-xr-x 2 user user 4096 2012-03-05 drwxr-xr-x 2 user user 4096 2012-03-05 -rwxr-x--- 1 user user 240612 2012-03-05 -rw-r--r-- 1 user user 116 2012-03-05 -rwxr-x--- 1 user user 102816 2012-03-05 -rwxr-x--- 1 user user 2344 2012-03-05 developers -rwxr-x--- 1 user user 17072 2012-03-05 -rwxr-x--- 1 user user 4091 2012-03-05 stuff -rwxr-x--- 1 user user 5692 2012-03-05 usb modes -rw-r--r-- 1 user user 114479 2012-03-05 -rw-r--r-- 1 user user 115596 2012-03-05 -rw-r--r-- 1 user user 272 2012-03-05 -rw-r--r-- 1 user user 3825 2012-03-05 -rw-r--r-- 1 user user 1785 2012-03-05 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 13:04 ./ ../ data/ dev/ proc/ res/ sbin/ sys/ system/ charger* default.prop init* init.goldfish.rc*

# this is used by # init stuff # vendor specific init # PIDs & VIDs for different

13:04 init.rc* 13:04 init.rk29board.rc* 13:04 init.rk29board.usb.rc* 13:04 13:04 13:04 13:04 13:04

rk29xxnand_ko.ko.2.6.32.27 rk29xxnand_ko.ko.3.0.8+ # kernel module for NAND ueventd.goldfish.rc ueventd.rc ueventd.rk29board.rc

Theres really no need to edit these files (unless you want to disable boot logo or smth.). But if you decide to edit these files then you already know what youre doing

5.2. Packing
Packing is as easy as unpacking.
user@ubu1004:~/project1$ pack.sh boot ****** Packing boot/ to boot.img-raw ****** Creating boot.img >> Kernel is included in boot.img reading config file unpack_boot/bootimg.cfg reading kernel from unpack_boot/zImage reading ramdisk from unpack_boot/initrd.img-new Writing Boot Image target_img/boot.img

This scripts detects boot.img type by reading original boot.img in source_img folder then uses that information to pack files, kernel, bootcmd to target_img/boot.img. To use this image in final firmware image you have to copy it to source_img folder.
user@ubu1004:~/project1$ cp f target_img/boot.img source_img/boot.img

6. Editing firmware parameter file


Parameter file contains information about machine, kernel location in RAM (KERNEL_IMG), kernel command line location in RAM (ATAG) and most important actual command line (CMDLINE) that is passed to kernel upon boot. This is what a sample parameter file looks like. CMDLINE looks like its multiline but in fact its a straight line without any newlines.
user@ubu1004:~/project1$ cat unpack_update/parameter FIRMWARE_VER:0.2.3 MACHINE_MODEL:Full AOSP on Rk29sdk MACHINE_ID:007 MANUFACTURER:RK29SDK MAGIC: 0x5041524B ATAG: 0x60000800 MACHINE: 2929 CHECK_MASK: 0x80 KERNEL_IMG: 0x60408000 CMDLINE: quiet console=ttyS1,115200n8n androidboot.console=ttyS1 init=/init initrd=0x62000000,0x800000 mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00004000@0x00004000(kernel),0x00008000@0x00008000 (boot),0x00008000@0x00010000(recovery),0x00100000@0x00018000(backup),0x0003a000@0x00118000(cache),0 x00200000@0x00152000(userdata),0x00002000@0x00352000(kpanic),0x00100000@0x00354000(system),@0x00454000(user)

Why is CMDLINE so important? It contains information about flash partitioning (mtdparts=) aka. how much space is reserved and where is it located.

6.1. Editing mdtparts


mtdparts expanded looks like this:
<number of sectors>@<location in sector units>(<name of partition>) 0: 0x00002000@0x00002000(misc), 8.192K 1: 0x00004000@0x00004000(kernel), 16.384K 2: 0x00008000@0x00008000(boot), 32.768K 3: 0x00008000@0x00010000(recovery), 32.768K 4: 0x00100000@0x00018000(backup), 524.288K 5: 0x0003a000@0x00118000(cache), 118.784K 6: 0x00200000@0x00152000(userdata), 1.048.576K 7: 0x00002000@0x00352000(kpanic), 8.192K 8: 0x00100000@0x00354000(system), 524.288K 9: -@0x00454000(user) 14.508.032K

Bear in mind that each sector is 512 bytes long Ive added sizes in kilobytes for easier reading. Since 1GB (1.048.576K) of userdata space is (for most) too little space for user apps you might want to increase it. In following example Ill double the space.
0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 0x00002000@0x00002000(misc), 0x00004000@0x00004000(kernel), 0x00008000@0x00008000(boot), 0x00008000@0x00010000(recovery), 0x00100000@0x00018000(backup), 0x0003a000@0x00118000(cache), 0x00400000@0x00152000(userdata), 0x00002000@0x00552000(kpanic), 0x00100000@0x00554000(system), -@0x00654000(user) 8.192K 16.384K 32.768K 32.768K 524.288K 118.784K 2.097.152K 8.192K 524.288K 13.459.456K

Userdata space is now increased by 0x00200000 sectors (or 1GB) and subsequently also all locations of partitions after userdata are moved for same amount of sectors. This increase in userdata space is then finally deducted from user partition (minus sign before @ means that user partition will use all the space left). user partition is also the partition that gets mounted as internal SD card and is unfortunately deleted and recreated with every firmware update.

7. Creating final firmware image for flashing with RK29BatchTool


Before packing firmware make sure that you: Unmounted system.img Copied all imgs (that youve created and wish to use) from target_img to source_img Didnt delete unpack_update folder or any files in it I also recommend comparing your modded (unpacked) firmware to original (unpacked) firmware. A good tool for this is meld. By comparing you can easily spot missing, added, changed files and decide whether this is what you intended or a mistake. To create (pack) final image (firmware) use rkimg.sh.
user@ubu1004:~/project1$ rkimg.sh -p xyz_mod.img ****** Packing to xyz_mod.img ------ PACKAGE -----Add file: unpack_update/package-file Add file: unpack_update/RK29xxLoader(L)_V2.06.bin Add file: unpack_update/parameter Add file: unpack_update/Image/misc.img Add file: unpack_update/Image/boot.img Add file: unpack_update/Image/recovery.img Add file: unpack_update/Image/system.img Add file: unpack_update/update-script Add file: unpack_update/recover-script Add CRC... ------ OK -----Pack OK! generate image... append md5sum... success! ****** Done. user@ubu1004:~/project1$

This script temporarily moves and renames source_img to unpack_update/Image/ then uses afptool to create intermediate update.img. img_maker then adds some device info, md5 sum and outputs final firmware to be used with rkbatchtools.

10

8. FAQ
Q: Ive flashed a new firmware and device shows me a broken robot. What to do? A: This is most likely due to bad boot.img. Press and hold power button until device turns off then repeat the flashing with better firmware. Q: After flashing device is showing only black screen. What to do? A: See previous answer. You will see the difference in screen lighting when device is off. Q: After flashing device is looping endlesly in boot animation. What to do? A: See previous answers. Theres something wrong in system.img. Q: How can I increase application space? A: See Editing mdtparts. Q: I cannot write to external sdcard and/or usb. What to do? A: Theres a permission file (platform.xml) in system.img in folder /etc/permissions/. Sometimes it helps by adding <group gid=media_rw /> to EXTERNAL_STORAGE and <group gid=sdcard_rw /> to MEDIA_STORAGE. This issue could (possibly) be also solved by editing init*.rc scripts Q: External SD doesnt mount at all. What to do? A: Check logs with CatLog or similar app and see if theres an error while mounting. Perhaps the SD is corrupted. If theres no error then check file /etc/vold.fstab (in system.img) entries usb entry might be wrong.

11

9. Useful links/further reading


Linux: http://linuxreviews.org/beginner/ http://fosswire.com/post/2007/08/unixlinux-command-cheat-sheet/ http://www.tuxfiles.org/linuxhelp/filepermissions.html http://code.google.com/edu/tools101/linux/ownership_permissions.html

Firmware tweaks, google apps, etc.: http://forum.xda-developers.com/showthread.php?t=1331351 http://wiki.cyanogenmod.com/wiki/Barebones http://wiki.rootzwiki.com/Google_Apps http://androtab.info/cyanogenmod/rockchip/ For learning about my scripts/building your own: http://www.slatedroid.com/topic/26030-cube-u9gt2-flashing-and-customizing-linux-tools/ https://github.com/jhonxie/rk2918_tools http://www.arctablet.com/wiki/index.php/Rksp_relink https://github.com/naobsd/rkutils http://www.slatedroid.com/topic/19808-rk29xx-imagetools-v21/page__st__40 Further development: http://forum.xda-developers.com/showthread.php?t=1389375 https://github.com/eyecatchup/net.bexton.android.UsbMassStorageToggle http://codewalkerster.blogspot.com/2012_02_01_archive.html http://apkmultitool.com/node/7 http://forums.androidcentral.com/hacking/144804-how-compile-ics-aosp-4-0-3-xoom-gnex-nexus-s.html http://wendal.net/350.html

To relax your mind after reading this tutorial : Music from this page: http://ask.metafilter.com/178886/EpicEmotional-Soundtrack-Music#2573739

For everything else:

http://www.google.com/

12

Вам также может понравиться