最新 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文件系统的一种获得方法

Mar 10, 2010 by zhaoruij...@gmail.com

  • 系统环境: ubuntu9.10
  • Date: 03/09/2010
/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

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定制,做到后面再看了