这几天可能要接个Android的项目,基于x86平台。因此先了解一下android的安装过程。在其官方网站上下载了Android的img,先面就解压出来看看吧,须要说明的是如下的操做都是在root用户下进行的。linux
mkdir android mount android-x86-4.3-20130725.iso android
经过以上的命令能够把咱们下载的android镜像挂载到android目录下,下面咱们能够看一下他的目录结构:android
├── initrd.img ├── install.img ├── isolinux │ ├── android-x86.png │ ├── boot.cat │ ├── isolinux.bin │ ├── isolinux.cfg │ ├── TRANS.TBL │ └── vesamenu.c32 ├── kernel ├── ramdisk.img ├── system.sfs └── TRANS.TBL
对以上文件详细的了解能够参考csdn的这篇博文shell
http://blog.csdn.net/liujixin8/article/details/4029887
接下来看一下install.img这个文件,咱们用file命令看一下这个文件属性app
android# file install.img install.img: gzip compressed data, from Unix, last modified: Fri Jul 26 02:05:58 2013, max compression
能够看到这个文件是一个gzip的文件,因此咱们能够解压出来看看,命令以下:ide
mkdir install cp /tmp/android/install.img /tmp/install mv install.img install.img.gz gunzip install.img.gz cpio -i -F install.img
这个时候咱们看下install这个目录的结构:函数
install# ls bin grub install.img lib sbin scripts
能够看出经过这个文件的解压多出了如下目录:oop
bin grub lib sbin scripts
不过经过以上的目录能够看出,基于x86结构的android是用grub引导的。接下来看一下他的启动流程,在看启动流程以前咱们先看一下isolinux.cfg这个文件,这个文件的具体做用在上面的内容中已经说过,在此不在赘述,文件内容以下:post
default vesamenu.c32 timeout 600 menu background android-x86.png menu title Android-x86 Live & Installation CD 4.3-test menu color border 0 #ffffffff #00000000 menu color sel 7 #ffffff00 #ff000000 menu color title 0 #ffffffff #00000000 menu color tabmsg 0 #ffffffff #00000000 menu color unsel 0 #ffffffff #00000000 menu color hotsel 0 #ffffff00 #ff000000 menu color hotkey 7 #ffffff00 #00000000 label livem menu label Live CD - ^Run Android-x86 without installation kernel /kernel append initrd=/initrd.img root=/dev/ram0 androidboot.hardware=android_x86 video=-16 quiet SRC= DATA= label vesa menu label Live CD - ^VESA mode kernel /kernel append initrd=/initrd.img root=/dev/ram0 androidboot.hardware=android_x86 video=-16 quiet nomodeset vga=788 SRC= DATA= label debug menu label Live CD - ^Debug mode kernel /kernel append initrd=/initrd.img root=/dev/ram0 androidboot.hardware=android_x86 video=-16 vga=788 DEBUG=2 SRC= DATA= label install menu label Installation - ^Install Android-x86 to harddisk kernel /kernel append initrd=/initrd.img root=/dev/ram0 androidboot.hardware=android_x86 video=-16 INSTALL=1 DEBUG=
咱们主要看下面的label这几个选项。一共有四个label选项,前面的两个不太熟悉,不过在这里不影响咱们。第三个为debug模式,第四个为install模式,也就是android的安装,从加在这里的内核参数能够看出,系统启动的是initrd.img里的内容,那接下来咱们就分析一下initrd.img 这个文件。咱们用file命令看一下这个文件的属性就能够知道他和上文说的install.img的文件属性是同样的,咱们用一样的方法把他解压出来,内容以下:学习
initrd# ls
android bin hd init lib mnt proc sbin scripts sfs sys tmp
以上就是把initrd.img文件解压出来的内容,系统的启动就是从这个地方开始,熟悉linux的朋友看到这个就知道是从那个文件开始执行了。接下来咱们看一下init这个文件,这个文件是一个文本文件,能够看一下它的文件属性网站
initrd# file init init: a /bin/busybox sh script, ASCII text executable
下面能够看一下这个脚本的内容:
echo -n Detecting Android-x86... mount -t tmpfs tmpfs /android cd /android while :; do for device in ${ROOT:-/dev/sr* /dev/[hs]d[a-z]*}; do check_root $device && break 2 mountpoint -q /mnt && umount /mnt done sleep 1 echo -n . done
这个是脚本的初始函数,至关于c语言的mian函数,首先看到的地一个mount命令挂载了tmpfs文件系统,对这个不是很熟悉,等有时间了学习了一下这个在把这个补上。看看接下来while循环,在这一段内容里重点看一下 check_root,这个是定义的一个函数,这个函数定义以下:
try_mount() { RW=$1; shift if [ "${ROOT#*:/}" != "$ROOT" ]; then # for NFS roots, use nolock to avoid dependency to portmapper RW="nolock,$RW" fi # FIXME: any way to mount ntfs gracefully? mount -o $RW $@ || mount.ntfs-3g -o rw,force $@ } check_root() { try_mount ro $1 /mnt && [ -e /mnt/$SRC/ramdisk.img ] [ $? -ne 0 ] && return 1 zcat /mnt/$SRC/ramdisk.img | cpio -id > /dev/null if [ -e /mnt/$SRC/system.sfs ]; then mount -o loop /mnt/$SRC/system.sfs /sfs mount -o loop /sfs/system.img system elif [ -e /mnt/$SRC/system.img ]; then mount -o loop /mnt/$SRC/system.img system elif [ -d /mnt/$SRC/system ]; then remount_rw mount --bind /mnt/$SRC/system system else rm -rf * return 1 fi mkdir cache mnt mnt/sdcard mount -t tmpfs tmpfs cache echo " found at $1" }
这个函数的做用主要是挂载ramdisk.img和system.sfs,这两个文件能够看看咱们最初始解压的文件。这里须要说明的是system.sfs这个文件解压出来是system.img。system.img里包含的就是具体的系统文件了。这个到后面会讲到。
ln -s mnt/$SRC /src
ln -s android/system /
ln -s ../system/lib/modules /lib
ln -s ../system/lib/firmware /lib
if [ -n "$INSTALL" ]; then
cd /
zcat /src/install.img | cpio -iud > /dev/null
fi
if [ -x system/bin/ln -a \( -n "$DEBUG" -o -n "$BUSYBOX" \) ]; then
mv /bin /lib .
system/bin/ln -s android/lib /lib
system/bin/ln -s android/bin /bin
sed -i 's|\(PATH *\)\(/sbin\)|\1/bin:\2|' init.rc
mv /sbin/* sbin
rmdir /sbin
ln -s android/sbin /
fi
# ensure keyboard driver is loaded
[ -n "$INSTALL" -o -n "$DEBUG" ] && modprobe atkbd
if [ 0$DEBUG -gt 0 ]; then
echo -e "\nType 'exit' to continue booting...\n"
debug_shell debug-found
fi
# load scripts
for s in `ls /scripts/* /src/scripts/*`; do
test -e "$s" && source $s
done
以上作的就是一些初始化的工做,而且根据不一样启动参数,所作的操做也略有不一样。能够看看上面标出的红色部分,此处的主要做用是若是判断出系统启动时所带的参数为install,则进入安装模式。接着往下看
[ "$AUTO" != "1" ] && detect_hardware && FOUND=1 [ -n "$INSTALL" ] && do_install load_modules mount_data mount_sdcard setup_tslib setup_dpi post_detect find_network_dev_name if [ 0$DEBUG -gt 1 ]; then echo -e "\nUse Alt-F1/F2/F3 to switch between virtual consoles" echo -e "Type 'exit' to enter Android...\n" debug_shell debug-late fi [ -n "$DEBUG" ] && SWITCH=${SWITCH:-chroot} # We must disable mdev before switching to Android # since it conflicts with Android's init echo > /proc/sys/kernel/hotplug exec ${SWITCH:-switch_root} /android /init # avoid kernel panic while :; do echo echo ' Android-x86 console shell. Use only in emergencies.' echo debug_shell fatal-err done
能够看出上面的代码用红色标注了两处,其中第一处是用来判断是不是install模式,在这个地方须要注意下,若是是正常的启动此处是不会执行到的,若是是安装模式则会调用安装脚本,这个安装脚本是放在install.img 这个文件里。这个文件的目录在上文我已经列过了。具体的看看do_install这个函数,这个函数是定义在install.img 解压出文件的scripts/1-install这个文件当中,在这个脚本中为何能调用这个函数呢,注意这一句:
# load scripts
for s in `ls /scripts/* /src/scripts/*`; do
test -e "$s" && source $s
done
这一段代码遍历了/scripts/和 /src/scripts/这两个目录下的脚本文件。注意后面的source $s,正是有了这一句,咱们才能够在在init脚本里调用1-install这个脚本的函数。这个install.sh就是实现了咱们的安装功能。咱们将在下一篇中分析do_install 这个函数