搜索
开启辅助访问切换到宽版
查看: 616|回复: 0

Android x86 initrd解读

[复制链接]
发表于 2018-10-9 14:58:43 | 显示全部楼层 |阅读模式
Android x86 initrd.img 解读 Android x86 的 initrd.img 名义上是 img 文件,实质是用 gz 压缩的 cpio 包。
1、解包 initrd.img: 自己找地方建个文件夹,例如 initrd,解压进去就好 zcat initrd.img | cpio -id > /dev/null 2、打包: find . |cpio -o -H newc |gzip -c > ../initrd.img 3、文件结构 以 Android x86 7 为例: 文件结构如下: . ├── android 空目录,系统启动后来挂载安卓的根目录 ├── bin 放置可执行文件的目录 │ ├── busybox 可执行文件,是一个集成了一百多个最常用 linux 命令和工具的软件 │ ├── ld-linux.so.2 可执行文件,同时也是库文件 │ └── lndir 可执行文件,shell 脚本,给目录下所有的文件或者子文件目录建立链接 ├── hd 空目录,系统启动后?? ├── init 可执行文件,核心启动脚本,initrd.img 首先启动 init,再通过它调用其他程序和脚本来完成启动。
├── iso 空目录,系统启动后来挂载 iso 镜像 ├── lib │ ├── ld-linux.so.2 -> /bin/ld-linux.so.2 软链接到/bin/ld-linux.so.2 │ ├── libcrypt.so.1 库文件 │ ├── libc.so.6 库文件 │ ├── libdl.so.2 库文件 │ ├── libm.so.6 库文件 │ ├── libntfs-3g.so.31 库文件 │ ├── libpthread.so.0 库文件 │ └── librt.so.1 库文件 ├── mnt 空目录,系统启动后来挂载 system.sfs 等 ├── proc 空目录 ├── sbin 放置可执行文件的目录 │ └── mount.ntfs-3g 可执行文件,用来挂载 ntfs 磁盘的 ├── scripts 放置启动脚本的目录 │ ├── 00-ver 版本号,例如:VER=2016-10-03 │ ├── 0-auto-detect 启动脚本,包含 auto_detect()和 load_modules()两个函数,加载驱动用 │ ├── 1-install 启动脚本,安卓 x86 安装脚本,do_install()函数 │ ├── 2-mount 启动脚本,包含 mount_data()和 mount_sdcard()两个函数 │ ├── 3-tslib 启动脚本,setup_tslib()函数,启动参数 BOARD_USES_TSLIB,触摸屏相关 │ └── 4-dpi 启动脚本,setup_dpi()函数,使得启动参数设置 DPI=??,可以设置 dpi ├── sfs 空目录, ├── sys 空目录, └── tmp 空目录, 4、init 文件分析 (建立新目录,文件硬链接) 是指此脚本使用/bin/busybox sh 来解释执行, #!/bin/busybox sh # # By Chih-Wei Huang # and Thorsten Glaser # # Last updated 2015/10/23 # # License: GNU Public License #是 注释符,这些都是注释 #! 是 Shebang 符号
# We explicitely grant the right to use the scripts # with Android-x86 project. # 设置环境变量 PATH,告诉 shell 去那些文件夹找可执行文件 PATH=/sbin:/bin:/system/bin:/system/xbin; export PATH # configure debugging output #设置 debug 信息的输出模式# if [ -n "$DEBUG" ]; then 如果 存在 $DEBUG 参数,则 LOG=/tmp/log 变量 LOG,赋值为,/tmp/log,意味着以后的 log 文件就是/tmp/log 了 set -x 把 set -x 命令以后的命令打印到屏幕上 else 否则 LOG=/dev/null 变量 LOG,赋值为/dev/null,意味着不在记录 log 文件 test -e "$LOG" || busybox mknod $LOG c 1 3测试,$LOG 所定义的文件是不是存在,不存在的话,建立 字符设备主设备号 fi 为 1,次设备号为 3 exec 2>> $LOG 把 exec 2>> $LOG 以后的命令的错误信息输出到$LOG 所定义的文件中 # early boot 如果 HAS_CTTY 不等于 Yes,则 if test x"$HAS_CTTY" != x"Yes"; then #初始化/proc 和/sys # initialise /proc and /sys 挂载 proc 这个虚拟文件系统到/proc 目录 busybox mount -t proc proc /proc 挂载 sysfs 这个虚拟文件系统到/sys 目录 busybox mount -t sysfs sys /sys sysfs 是一个特殊文件系统,并没有一个实际存放文件的介质。
# let busybox install all applets as symlinks #创建所有命令的符号链接:busybox --install -s busybox --install -s #debug 和 installer 模式下启动 tty2 和 tty3 # spawn shells on tty 2 and 3 if debug or installer 如果 DEBUG 或 INSTALL 不为空,则 if test -n "$DEBUG" || test -n "$INSTALL"; then 建立字符设备/dev/tty 主设备号为 5,次设备号为 0 # ensure they can open a controlling tty 建立字符设备/dev/tty2 主设备号为 4,次设备号为 2 mknod /dev/tty c 5 0 建立字符设备/dev/tty3 主设备号为 4,次设备号为 3 # create device nodes then spawn on them mknod /dev/tty2 c 4 2 && openvt mknod /dev/tty3 c 4 3 && openvt fi 如果 DEBUG 存在或 INSTALL 不为空,则 if test -z "$DEBUG" || test -n "$INSTALL"; then 将 0 0 0 0 覆盖写入/proc/sys/kernel/printk,以将 echo 0 0 0 0 > /proc/sys/kernel/printk 打印输出的优先级提高到最高, fi # initialise /dev (first time) 建立文件夹/dev/block,-p 递归创建目录 mkdir -p /dev/block 将 /sbin/mdev 覆盖写入 /proc/sys/kernel/hotplug, echo /sbin/mdev > /proc/sys/kernel/hotplug 以设置系统的 hotplug 程序为 mdev mdev -s mdev –s,自动装配/dev 目录下的设备文件 # re-run this script with a controlling tty 设置 HAS_CTTY=Yes,重新启动本脚本 exec env HAS_CTTY=Yes setsid cttyhack /bin/sh "$0""$@" fi # now running under a controlling tty; debug output from stderr into log file #开始启动安卓 # boot up Android error() { echo $* return 1 } 下面是定义的几个函数。
#是 注释符,这些都是注释,意思是现在是在 tty 控制台下运行了,debug 信息输出到日志文件了 try_mount() { RW=$1; shift if [ "${ROOT#*:/}" != "$ROOT" ]; then # for NFS roots, use nolock to avoid dependency to portmapper RW="nolock,$RW" fi error()返回错误 try_mount(),挂载设备用,避免直接用 mount 不支持 ntfs check_root(),检查并挂载安卓系统文件 ramdisk,system 到目录(/android) 下 remount_rw() 将/mnt 重新挂载为可读写模式 debug_shell()启动一个新的 shell 作为 debug_shell,,2>&1 指将标准信息 输出路径指定为错误信息输出路径(也就是都输出在一起
# FIXME: any way to mount ntfs gracefully? mount -o $RW,noatime $@ || mount.ntfs-3g -o rw,force $@ } check_root() { if [ "`dirname $1`" = "/dev" ]; then [ -e $1 ] || return 1 blk=`basename $1` [ ! -e /dev/block/$blk ] && ln $1 /dev/block dev=/dev/block/$blk else dev=$1 fi try_mount ro $dev /mnt || return 1 if [ -n "$iso" -a -e /mnt/$iso ]; then mount --move /mnt /iso mkdir /mnt/iso mount -o loop /iso/$iso /mnt/iso SRC=iso elif [ ! -e /mnt/$SRC/ramdisk.img ]; then return 1 fi zcat /mnt/$SRC/ramdisk.img | cpio -id > /dev/null if [ -e /mnt/$SRC/system.sfs ]; then mount -o loop,noatime /mnt/$SRC/system.sfs /sfs mount -o loop,noatime /sfs/system.img system elif [ -e /mnt/$SRC/system.img ]; then remount_rw mount -o loop,noatime /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 mnt echo " found at $1" rm /sbin/mke2fs hash -r } remount_rw() { # "foo"as mount source is given to workaround a Busybox bug with NFS # - as it's ignored anyways it shouldn't harm for other filesystems. mount -o remount,rw foo /mnt } debug_shell() { if [ -x system/bin/sh ]; then echo Running MirBSD Korn Shell... USER="($1)" system/bin/sh -l 2>&1 else echo Running busybox ash... sh 2>&1
fi } echo -n Detecting Android-x86... [ -z "$SRC" -a -n "$BOOT_IMAGE" ] && SRC=`dirname $BOOT_IMAGE` for c in `cat /proc/cmdline`; do case $c in iso-scan/filename=*) eval `echo $c | cut -b1-3,18-` ;; *) ;; esac done 以 tmpfs 模式挂载/android 切换目录到 /android mount -t tmpfs tmpfs /android cd /android 在各个磁盘里尝试执行 check_root 函数,搜 while :; do 索 android x86 系统并挂载 for device in ${ROOT:-/dev/[hmsv][dmr][0-9a-z]*}; do check_root $device && break 2 mountpoint -q /mnt && umount /mnt done sleep 1 echo -n . 把 mnt/$SRC 链接为/src done ln -s mnt/$SRC /src 把 ../system/lib/firmware(内核的 firmware,就 ln -s android/system / 是在 system.sfs 里的) ../system/lib/modules (内 ln -s ../system/lib/firmware ../system/lib/modules /lib 核的驱动模块, 就是在 system.sfs 里的) 链接到/lib 把 android/system 链接到根目录 if [ -n "$INSTALL" ]; then 文件夹内 zcat /src/install.img | ( cd /; cpio -iud > /dev/null ) 如 果 启 动 参 数 里 有 INSTALL , 解 压 fi if [ -x system/bin/ln -a \( -n "$DEBUG" -o -n "$BUSYBOX" \) ]; then 进程了。
mv /bin /lib . sed -i 's|\( PATH.*\)|\1:/bin|' init.environ.rc rm /sbin/modprobe busybox mv /sbin/* sbin rmdir /sbin ln -s android/bin android/lib android/sbin / hash -r 如果启动参数中有 INSTALL 或 DEBUG,加载键盘驱动。
fi # ensure keyboard driver is loaded [ -n "$INSTALL" -o -n "$DEBUG" ] && busybox modprobe -a atkbd hid-apple /src/install.img 到根目录。
也就是准备启动安装 if [ 0$DEBUG -gt 0 ]; then 如果 DEBUG 为 0,进入 debug 模式。
此时没有脚本被加载 echo -e "\nType 'exit' to continue booting...\n" debug_shell debug-found fi # load scripts for s in `ls /scripts/* /src/scripts/*`; do 加载启动脚本( /scripts/ 和 /src/scripts 目录里面 test -e "$s"&& source $s 的) done
# # # [ A target should provide its detect_hardware function. On success, return 0 with the following values set. return 1 if it wants to use auto_detect "$AUTO" != "1" ] && detect_hardware && FOUND=1 如果启动参数中有 INSTALL,进入 INSTALL 模式 [ -n "$INSTALL" ] && do_install load_modules mount_data mount_sdcard setup_tslib setup_dpi post_detect 启动脚本中的函数以加载内核模块、挂载 data 、挂载 sdcard、设置触摸屏、设置 dpi 等 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 为 1,进入 debug 模式。
此时启动脚本被加载 debug_shell debug-late 了 fi [ -n "$DEBUG" ] && SWITCH=${SWITCH:-chroot} 如果 DEBUG 不为空,SWITCH=${SWITCH:-chroot}, # We must disable mdev before switching to Android 将 mdev 从/proc/sys/kernel/hotplug 去掉,防止切换 # since it conflicts with Android's init echo > /proc/sys/kernel/hotplug 到 android 与 init export ANDROID_ROOT=/system exec ${SWITCH:-switch_root} /android /init 设至 ANDROID_ROOT=/system, switch_root (切换根目录, 同时删除现在的根目录)到/android,并执行 init,启 动安卓系统喽 # avoid kernel panic while :; do echo echo ' Android-x86 console shell. Use only in emergencies.' echo debug_shell fatal-err 如果上边执行失败了,进入 shell 以备万一 done

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

安卓x86中文站|android x86|androidx86|android for x86

网站简介:安卓X86中文站为安卓桌面版爱好者提供下载、测评、资讯的平台。网站广告收入为维持服务费用,请理解!

自定义文字

关于我们

  • 工作时间:如果QQ没上线请发邮件或留言!谢谢!
  • 客服电话:请QQ资讯
  • 78260551#qq.com
  • 公司地址:四川省中江县南华镇金龙街6号

QQ|小黑屋|手机版|Archiver|安卓x86中文站|android x86|androidx86|android for x86 ( 蜀ICP备12015179号-1 )

Powered by Discuz! X3.4 © 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表