现在的位置: 首页 > 综合 > 正文

Android内核移植,以及从普通文件系统启动后手动挂载android文件系统

2013年05月31日 ⁄ 综合 ⁄ 共 10313字 ⁄ 字号 评论关闭

http://handao.blog.techweb.com.cn/archives/55.html

 

最新 clone 下来的 Android Linux 内核是 2.6.27版本。与最开始发布(m5-rc14)的 Android 2.6.25 内核相比,2.6.27的内核删除了 goldfish 目标板的板机支持包。
1.  内核移植
===========
      前几天把NaviEngine一直到了 2.6.28 内核上,所以,现在只需要把 Android 的内核 patch 从 2.6.27
移植到 2.6.28 上。
     首先需要将 Android 内核  Patch 取出来:
     * 从 www.kernel.org
下载 2.6.27 的内核: linux-2.6.27.tar.gz, 并解压缩:
       # tar zxf linux-2.6.27.tar.gz
  
     * Android 的内核在 git repository 的 kernel 目录。 执行一下命令:
       # cd  android
       # diff -Nuar -x .git ../linux-2.6.27 kernel > android-2.6.27.patch
     
      然后把 android-2.6.27.patch 通过patch命令 apply 到 2.6.28 的内核之上。 patch 的时候会有冲突,
这时候需要手动修改一下源代码。 Android 的内核包含了很多设备驱动,但是如果目标板没有该设备的
话,这类驱动可以不用patch到自己的内核上,比如 bluetooth, i2c等等。 另外,它还包含了 yaffs2 文件系统,
如果不想使用该文件系统的话,这些源码也可以不要。
应用到 2.6.28 上的 patch: android-2.6.28.patch
另外,我对binder 和 framebuffer 的驱动做了一些修改,否则 Android 启动会不成功:
   * binder
Index: linux-2.6.28/drivers/misc/binder.c
===================================================================
— linux-2.6.28.orig/drivers/misc/binder.c
+++ linux-2.6.28/drivers/misc/binder.c
@@ -15,6 +15,7 @@
+#include
#include
#include
#include
@@ -55,7 +56,8 @@ static int binder_read_proc_proc(
#endif

#ifndef __i386__
-#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE | VM_EXEC)
+/* #define FORBIDDEN_MMAP_FLAGS                (VM_WRITE | VM_EXEC) */
+#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
#else
#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
#endif
  * framebuffer
      Android 使用了 double buffer/page flipping。 所以 framebuffer 的驱动必须支持 double buffer.
NaviEngine 原有的驱动并不支持该功能。我增加了这个patch: ne1-fb-double-buffer.patch
主要是增加了 ne1_fb_pan_display 函数。 这个函数是切换buffer时候被调用的。
      Double buffer 设计成 上下两个buffer的模式, 因此, xres_virtual = xres, yres_virtual = yres * 2,
struct fb_info  结构体的 ypanstep 要设成 1。 另外,内核分配framebuffer内存的时候也需要分配两倍的内存。
     这样,切换buffer 的时候会调用 ne1_fb_pan_display(), 该函数将新的内存地址写到LCD控制器。
+/*
+ * Set new x,y offsets in the virtual display for the visible area and switch
+ * to the new mode.
+ */
+static int ne1_fb_pan_display(struct fb_var_screeninfo *var,
+                   struct fb_info *info)
+{
+    struct ne1_fb_par *par = info->par;
+    unsigned int bytes_pixel = var->bits_per_pixel / 8;
+    unsigned long offset;
+
+    info->var.xoffset = var->xoffset;
+    info->var.yoffset = var->yoffset;
+
+    offset = var->xoffset * bytes_pixel +
+         var->yoffset * info->fix.line_length;
+
+    // Set buffer start address
+    ne1_fb_write****((NE1_HW_LAYER_1 regs + MF_SADR_01);
+
+    return 0;
+}
2. Android 文件系统
===================
      要在目标板上启动 Android, 需要 Android 的文件系统。这些可以从 Android 的模拟器里得到。  参考这边文章:  
[url=http://discuz-android.blogspot.com/2008/01/extract-google-android-file-system.html]extract-google-android-file-system[/url]
      以下是具体的步骤:
  * Start emulator in debug mode and with sdcard:
   
    # emulator -sdcard card.img -debug-kernel
  * card.img is created by mksdcard command:
    # mksdcard -l card 256M card.img
  * Download busybox from
[url=http://discuz-android.blogspot.com/2008/01/extract-google-android-file-system.html]above link[/url]
or busybox for android.
  * After emulator started, do this in host:
    # adb push busybox /system/bin/busybox
    # adb shell         (commands below runs on emulator shell)
    # chmod 755 /system/bin/busybox
    # cd /sdcard
    # busybox tar cf system.tar /system
    # cd /
    # umount /sdcard
    * Follow the guide above, it says the /data direcotry is also needed.
      But from the init.rc, the init scripts create this directory. So
      it is not necessary to dump data directory.
  * shutdown the emulator, and copy system.tar out
   
    # mount -o loop card.img /mnt/sdcard
    # ls /mnt/sdcard/ -l
    -r-xr-xr-x 1 root root 45923328 2009-01-09 13:46 system.tar
    # cp /mnt/sdcard/system.img  .
    # umount /mnt/sdcard
  * Make android filesystem
    Now we have all the files for android filesystem:
      * system.tar dumped from emulator
      * ramdisk.img in emulator directory:  tools/lib/images/

    # mkdir android_rootfs
    # cd android_rootfs
    * unpack system.tar
      # tar xf ~/android/system.tar
    * unpack ramdisk.img
      
      Android ram disk image is a gziped cpio archive.
      # cp ramdisk.img ramdisk.gz
      # gunzip ramdisk.gz
      # cd android_rootfs
      # cpio -iv < ../ramdisk
    * Now the android rootfs contained the files we need.
      另外,还有几个文件需要修改一下: init.rc init.goldfish.rc 和 /system/etc/init.goldfish.sh. 这几个文件都是针对 goldfish 目标板的。 init 程序会读这些文件并执行相应的命令。
     init 程序读取配置文件的时候,目标板的名字是通过以下接口获得的:
     # cat /proc/cpuinfo
     Processor       : ARMv6-compatible processor rev 4 (v6l)
     ……
     Hardware        : NE1
     Revision        : 0000
     上面 Hardware 就是 init 使用的目标板的名字。因此:
      # cp init.goldfish.rc init.ne1.rc
      # cp /system/etc/init.goldfish.sh /system/etc/init.ne1.sh
     然后再修改 init.rc init.ne1.rc 和/system/etc/init.ne1.sh
3. 启动  Android
================
    可以直接从 Android rootfs 里启动,也可以先从原有的根文件系统启动,然后通过 chroot 命令切换到 Android 文件系统并启动 Android. 这里选择后者。
    NaviEngine 使用 NFS, 因此,首先从 NFS 启动系统,然后在切换到 Android 文件系统。 这里将 Android 文件系统放在 USB HardDisk 上。
    NaviEngine 启动完之后,通过一下脚本  start_android.sh  切换到  Android 文件系统:
———————————-
#!/bin/sh -x
echo “Starting Android …”
mount /dev/sda1 /mnt/usb
rm -f /mnt/usb/tmp/*
umount /sys
umount /dev/pts
umount /proc
umask 000
chroot /mnt/usb /system/bin/sh
———————————-
   运行该脚本之后,进入了 Android 的 shell(注意上面 chroot 命令后面的参数: /system/bin/sh 表示切换之后运行该命令,启动shell)。
  最后,执行该命令:
  # ./init
  init: cannot open ‘/initlogo.rle’
  sh: can’t access tty; job control turned off
  # warning: `rild’ uses 32-bit capabilities (legacy support in use)
  LCD 上出现了 Android 文字和 Android 的 LOGO。  Enjoy it.
  # ps
USER     PID   PPID  VSIZE RSS   WCHAN    PC         NAME
root     1     0     1376  500   c003f6e4 400****db0 S /bin/busybox
root     2     0     0     0     c0051208 00000000 S kthreadd
root     3     2     0     0     c0041e50 00000000 S ksoftirqd/0
root     4     2     0     0     c0061790 00000000 S watchdog/0
root     5     2     0     0     c004e124 00000000 S events/0
root     6     2     0     0     c004e124 00000000 S khelper
root     101   2     0     0     c004e124 00000000 S kblockd/0
root     112   2     0     0     c026323c 00000000 S khubd
root     115   2     0     0     c02829a4 00000000 S kseriod
root     135   2     0     0     c0070800 00000000 S pdflush
root     136   2     0     0     c0070800 00000000 S pdflush
root     137   2     0     0     c007531c 00000000 S kswapd0
root     139   2     0     0     c004e124 00000000 S aio/0
root     140   2     0     0     c004e124 00000000 S nfsiod
root     142   2     0     0     c004e124 00000000 S xfs_mru_cache
root     143   2     0     0     c004e124 00000000 S xfslogd/0
root     144   2     0     0     c004e124 00000000 S xfsdatad/0
root     357   2     0     0     c004e124 00000000 S kpsmoused
root     359   2     0     0     c004e124 00000000 S kstriped
root     362   2     0     0     c004e124 00000000 S hid_compat
root     386   2     0     0     c004e124 00000000 S rpciod/0
root     443   1     2192  232   c009dbf0 4012fb34 S /devel/usr/sbin/telnetd
root     452   1     13****  500   c003f6e4 400****db0 S /bin/ash
root     456   2     0     0     c0252278 00000000 S scsi_eh_1
root     457   2     0     0     c027ba3c 00000000 S usb-storage
root     472   452   2840  1292  c003f6e4 40125778 S /bin/sh
root     478   472   708   320   c003f6e4 afe0d0dc S /system/bin/sh
root     479   478   288   196   c009d69c 0000c58c S ./init
root     733   479   740   332   c003f6e4 afe0d0dc S /system/bin/sh
system   734   479   812   268   c0240428 afe0c33c S /system/bin/servicemanager
root     735   479   1848  356   ffffffff afe0c09c S /system/bin/mountd
root     736   479   668   268   c02b0220 afe0cccc S /system/bin/debuggerd
radio    737   479   3276  616   ffffffff afe0c9ac S /system/bin/rild
root     738   479   70****0 18848 c009dbf0 afe0c4**** S zygote
media    739   479   17828 3476  ffffffff afe0c33c S /system/bin/mediaserver
bluetooth 740   479   1168  572   c009d69c afe0d2ac S /system/bin/dbus-daemon
root     741   479   804   312   c0309e6c afe0c09c S /system/bin/installd
system   755   738   174828 27052 ffffffff afe0c33c S system_server
radio    793   738   101896 17776 ffffffff afe0d434 S com.android.phone
app_3    797   738   115224 23304 ffffffff afe0d434 S android.process.acore
app_21   808   738   92532 14636 ffffffff afe0d434 S com.example.android.softkeyboard
app_7    824   738   96228 15628 ffffffff afe0d434 S com.android.mms
app_0    837   738   92768 14784 ffffffff afe0d434 S com.android.alarmclock
app_25   846   738   95016 14920 ffffffff afe0d434 S android.process.im
app_22   853   738   95016 16244 ffffffff afe0d434 S com.android.calendar
app_2    867   738   94960 15668 ffffffff afe0d434 S android.process.media
root     882   733   888   348   00000000 afe0c09c R ps
  也可以通过 logcat 命令查看 系统log。

 

 

 

/////////////////////////////////////

 

http://code.google.com/p/androidteam/wiki/AndroidFileSystemAnalysis1

 

AndroidFileSystemAnalysis1
 

Android文件系统的一种获得方法

Updated
Mar 10, 2010

by zhaoruij...@gmail.com


Android 文件系统分析

  • 系统环境: ubuntu9.10
  • Date: 03/09/2010

将Android源码编译后会在/home/zhaoruijia/zhaoAndroid/out/target/product/generic

录下发现编译后生成的3个镜像文件:system.img,ramdisk.img,userdata.img,其中system.img包括了主要的
包、库等文件,userdata.img包括了一些用户数据,模拟器加载这3个映像文件后,会把
system和data分别加载到ramdisk文件系统中的system和data目录下ramdisk.img是模拟器的文件系统,我们可以通过输
入:

zhaoruijia@zhaoruijia
-
ubunut
:~
$ androidemu 
zhaoruijia@zhaoruijia
- ubunut :~ $ adb shell
# ls

sqlite_stmt_journals
config
cache
sdcard
d
etc
system
sys
sbin
proc
init
. rc
init
. goldfish . rc
init
default . prop
data
root
dev


察到在模拟器的shell里根文件系统结构,如果要进行内核移植,根文件系统是必不可少的,目前有两种方法获得一个根文件系统,一种方法是将模拟器中的文
件系统通过打包的方式拖出来,然后以此为基础通过busybox重新定制一个根文件系统,还有一种方法就是我们可以把ramdisk.img里的所有文件
复制出来,system.img和userdata.img分别解压到ramdisk文件系统中的system和data目录下,这里由于Android
源码编译后除了生成system.img,userdata.img之外还生成system和
data文件夹,因此不需要解压它们。只需将他们拷贝出来即可,然后使用网络文件系统方式挂载Android文件系统,具体步骤如下:

1、将ramdisk.img复制到/home/zhaoruijia/workspace1目录下并将其名称改为ramdisk.img.gz

 zhaoruijia@zhaoruijia
-
ubunut
:~/
workspace1$ mv ramdisk
.
img ramdisk
.
img
.
gz

并使用命令

zhaoruijia@zhaoruijia
-
ubunut
:~/
workspace1$ gunzip ramdisk
.
img
.
gz 
zhaoruijia@zhaoruijia
- ubunut :~/ workspace1$ ls
ramdisk  ramdisk
. img

2、新建一个ramdisk文件夹然后输入如下:

zhaoruijia@zhaoruijia
-
ubunut
:~/
workspace1$ mkdir ramdisk
zhaoruijia@zhaoruijia
- ubunut :~/ workspace1$ cd ramdisk
zhaoruijia@zhaoruijia
- ubunut :~/ workspace1 / ramdisk$ cpio - i - F / home / zhaoruijia / workspace1 / ramdisk . img
494

3、然后把Android源码编译后生成的system和data里的文件复制到 ramdisk/system和 ramdisk/data下。这样就得到一个文件系统了。

zhaoruijia@zhaoruijia
-
ubunut
:~/
workspace1
/
ramdisk$ ls 
-
l
总用量 152
drwxrwx
-- x   2 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 42 data
- rw - r -- r --   1 zhaoruijia zhaoruijia     118 2010 - 03 - 10 17 : 42 default . prop
drwxr
- xr - x   2 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 42 dev
- rwxr - x ---   1 zhaoruijia zhaoruijia 103184 2010 - 03 - 10 17 : 42 init
- rwxr - x ---   1 zhaoruijia zhaoruijia   1677 2010 - 03 - 10 17 : 42 init . goldfish . rc
- rwxr - x ---   1 zhaoruijia zhaoruijia   12215 2010 - 03 - 10 17 : 42 init . rc
drwxr
- xr - x   2 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 42 proc
drwxr
- x ---   2 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 42 sbin
drwxr
- xr - x   2 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 42 sys
drwxr
- xr - x 10 zhaoruijia zhaoruijia   4096 2010 - 03 - 10 17 : 52 system

4、我们要使用网络文件系统方式挂载Android文件系统因此,我们需要建立/nfsroot目录,再建立/nfsroot/Androidfs目录,把刚才的Android文件系统改名为Androidfs,并链接到/nfsroot/Androidfs

5、
Android内核挂载/nfsroot/Androidfs之后,根据init.rc,init.goldfish.rc来初始化并装载系统库、程序等
直到开机完成。init.rc脚本包括了文件系统初始化、装载的许多过程。至于具体启动过程我会在下一篇文章中结合init.c源码来分析。

遗留问题:
由于内核移植没有成功能否通过网络文件系统方式挂载还是未知数,本文只是一个参考,个人更看好从模拟器中获得根文件系统后通过busybox定制,做到后面再看了


抱歉!评论已关闭.