Step I :Compile Android Kernel
-
Download source code;Kernel's subproject has kernel source code corresponding to the devices here:
https://android.googlesource.com
You can find kernel source code path corresponding to your device here
http://source.android.com/source/building-kernels.html
Download of this git project is slow,you can use bitbucket or deveo to transfer
-
checkout branch;Change to the source directory,use
$ git branch -a
View all branches,then use
$ git checkout <branch_name>
Check codes,here branch_name may have remotes/origin prefix,and there is no need to add -b option,else it will create a new branch
-
Configuration compiling environment;Clone this repo(you may need transfer):
https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6
set PATH environment variable,add bin directory beneath repo
-
Compile source code
$ export ARCH=arm $ export SUBARCH=arm $ export CROSS_COMPILE=arm-eabi- $ make xx_defconfig # (Here you can find) config:http://source.android.com/source/building-kernels.html) $ make
Compiled kernel is
arch/arm/boot/zImage
(Nexus 5 iszImage-dtb
) - Flush a new ROM
-
Method One:set TARGET_PREBUILT_KERNEL environment variable as compiled kernel,then m make boot.img,using
$ fastboot flash boot boot.img
Flush
- Method Two:copy compiled kernel to out/x/x/x/ directory,named after kernel,then m make boot.img,flush with fastboot
-
Step II :Compile Android Source Code
-
Download source code;Here you can find Android versions which devices support:
https://developers.google.com/android/nexus/drivers
-
Download driver;Here has driver corresponding to devices:
https://developers.google.com/android/nexus/drivers
Get a script after download and extract,put it in Android directory to execute
-
Configuration compiling environment
System:Ubuntu x86_64 EN Package: build-essential/gcc&g++/lib32stdc++6 jdk6 python 2.6.x/2.7.x gperf libzip/zlib1g&zlib1g-dev/libzzip-dev lib32z1 bison flex libxml2-utils git bc zip squashfs-tools libncurses5-dev
-
Enter Android source code directory;Execute following command to compile source code:
$ source build/envsetup.sh $ lunch # (choose target corresponding to device) $ m
-
Connecting devices;Execute following command to flush a new ROM(you need run as root):
$ adb reboot bootloader $ fastboot devices $ fastboot flashall -w
Step III :Kernel Modification
Conbinder Driver
- Enter
drivers/staging/android/
directory - Create
conbinder.h
andconbinder.c
- Move the header file of
binder.c
toconbinder.h
,theninclude "conbinder.h"
- Remove
static
frombinder_fops
struct's function,then add its declaration inconbinder.h
- Add
CONBINDER_GET_CURRENT_CONTAINER
macro definition inconbinder.h
(ioctl
operation gets container's ID in which current process is) - Add virtual driver code in
conbinder.c
- Modify
binder_ioctl
function inbinder.c
,add treatment codes ofCONBINDER_GET_CURRENT_CONTAINER
command - Modify
Kconfig
,addANDROID_CONBINDER_IPC
option - Modify
Makefile
,addconbinder.o
compilation configuration
Conalarm Driver
- Enter
drivers/rtc/
directory - Modify
alarm-dev.c
,addconalarm_fops
andconalarm_device
data struct,initialize code and customizeconalarm_open
function - Using macro definition-
ANDROID_CONALARM
to control relevantconalarm
code if compiled - Modify
Kconfig
,addANDROID_CONALARM_DEV
option - Modify
Makefile
,add compilation configuration(ccflags
) of macro definitionANDROID_CONALARM
Container Driver
- Enter
drivers/staging/android/
directory - Create
container.h
andcontainer.c
- Add macro definition of
ioctl
command incontainer.h
- Add driver function,data struct and initialization code of container device in
container.c
- Modify
Kconfig
,addANDROID_CONTAINER
option - Modify
Makefile
,addcontainer.o
compilation configuration
Compile Configuration
-
Modify
.config
,add following compilation configuration optionsANDROID_CONBINDER_IPC ANDROID_CONALARM_DEV ANDROID_CONTAINER IKCONFIG IKCONFIG_PROC
- According to
lxc-checkconfig
,add compilation configuration options -
According toStep II
,compile
Step IV :ramdisk modification
init.rc
-
Remove
mount rootfs rootfs / ro remount
-
Add
mount tmpfs tmpfs /run symlink /system/bin /bin
-
Add it after PATH environment variable
:/system/busybox/bin:/system/busybox/sbin:/system/local/bin
-
Add it after LD_LIBRARY_PATH:
:/system/local/lib
-
Add
export ANDROID_CT /system/local/var/lib/lxc/android4.x.x
uevent.rc
-
Add
/dev/conbinder1 0666 root root ... /dev/conbinder9 0666 root root
-
Add
/dev/conalarm 0664 system radio
-
Add
/dev/container 0666 root root
Step V :LXC Modification and Compilation
Code modification
- Use chroot to replace pivot_root system call
Cross compilinglxc
- Download Android NDK
-
Extract NDK,then execute in it
$ build/tools/make-standalone-toolchain.sh
Find tool chain in /tmp directory
-
Add tool chain directory after PATH environment variable
-
Download
lxc-1.0.0.alpha*
source code -
Execute in lxc source code
$ autogen.sh
-
Execute
$ ./configure --host=arm-linux-androideabi --prefix=/system/local CC=arm-linux-androideabi-gcc --disable-capabilities
- Execute 'make',ignore relevant lua wrong
-
Execute
$ sudo make prefix=/system/local install
You can find compiled procedure in
/system/local
Step VI :Modify system partitions
Busybox
Put compiled busybox in system directory
LXC
Pack the folders in lxc's installation directory,then extractit in /system/local directory
Cgroups
-
Create cgroup directory beneath /system/,and Create following directory beneath cgroup
cpuset memory blkio freezer device
-
Create script file
mount-cgroups.sh
beneath /system/local/bin,to mount cgroups and ashmem;command is following:for t in `ls /system/cgroup` do mount -t cgroup -o $t cgroup /system/cgroup/$t done mkdir /dev/shm mount -t tmpfs -o nodev,noexec tmpfs /dev/shm
ServiceManager
- Modify filter rule of service name,allow registering modified service
Container configure and root filesystem
- Create folder
androidx.x.x
beneath/system/local/var/lib/lxc
to save container system - Create file config and directory rootfs within the folder
config
lxc.utsname = android4.1.2
lxc.tty = 0
lxc.rootfs = /system/local/var/lib/lxc/android4.1.2/rootfs
lxc.cgroup.devices.allow = a
rootfs
- Copy all files beneath original system root directory to rootfs directory
- Create symbolic Links corresponding to original system root directory
-
Create directories beneath system root directory,following the principles:(copy means copying directories of host;empty means creating a empty directory;the same below)
/firmware copy /persist copy /storage empty /config copy /cache empty /acct empty /mnt empty /sys empty /sbin empty /run empty /res copy /proc empty /data empty /root empty /dev empty /system empty
- Create device nodes in rootfs/dev,according to filename,device number,permission and owner of all device files
-
Create folder and directory beneath system directory,as following rules:
app empty bin copy build.prop copy busybox copy etc copy fonts copy framework empty lib empty media empty priv-app empty tts copy usr copy vendor copy xbin copy
Other Script
-
Create script file
mount-bind.sh
inandroid4.x.x
directory,Enter the following command:mount -o bind /system/app rootfs/system/app mount -o bind /system/framework rootfs/system/framework mount -o bind /system/lib rootfs/system/lib mount -o bind /system/media rootfs/system/media mount -o bind /system/priv-app rootfs/system/priv-app mount -o bind /dev/conbinder1 rootfs/dev/binder mount -o bind /dev/conalarm rootfs/dev/alarm
-
Create script file
share.sh
inandroid4.x.x
directory,Enter the following command:echo "SurfaceFlinger" >>/proc/conbinder/sharedservices
init
- Forbid creating /dev directory
- Forbid mounting tmpfs on /dev directory
init.rc
- Forbidden ueventd
- Forbidden servicemanager
Step VII :Start Container
- Start host
-
Enter shell using following command as root:
# adb root # adb shell
-
Execute following command to mount various folders:
# mount-rw.sh # mount-cgroups.sh
-
Enter directory in which container is,and execute following command:
# ./mount-bind.sh # ./share.sh
-
Execute following command to clear log:
# dmesg -c # logcat -c
-
Execute following command to start container:
lxc-start -n <container name>