Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161522
  • 博文数量: 43
  • 博客积分: 2650
  • 博客等级: 少校
  • 技术积分: 465
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-31 10:00
文章分类

全部博文(43)

文章存档

2012年(1)

2011年(11)

2010年(17)

2009年(14)

我的朋友

分类: LINUX

2009-01-13 11:17:24

     最新 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 取出来:

     * 从 下载 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_write64((NE1_HW_LAYER_1 << 32) | (NE1_HW_LAYER_0 + offset), par->regs + MF_SADR_01);
+
+    return 0;
+}

2. Android 文件系统
===================

      要在目标板上启动 Android, 需要 Android 的文件系统。这些可以从 Android 的模拟器里得到。  参考这边文章:  extract-google-android-file-system

      以下是具体的步骤:

  * 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 above link 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 40064db0 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     1364  500   c003f6e4 40064db0 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   70640 18848 c009dbf0 afe0c464 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。


阅读(6799) | 评论(7) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-07-10 23:39:20

Uncompressing Linux............................................................................. done, booting the kernel. <5>Linux version 2.6.27 (jk@jk-laptop) (gcc version 4.2.4) #4 PREEMPT Fri Jul 10 23:34:52 CST 2009 CPU: XScale-PXA250 [69052904] revision 4 (ARMv5TE), cr=0000397f Machine: HP iPAQ H3900 Memory policy: ECC disabled, Data cache writeback <7>On node 0 totalpages: 16384 <7>free_area_init_node: node 0, pgdat c0255784, node_mem_map c02e7000 <7> DMA zone: 16256

chinaunix网友2009-02-23 01:54:26

VFS: Mounted root (yaffs filesystem). Freeing init memory: 136K init: cannot open '/initlogo.rle' init: Unable to open persistent property directory /data/property errno: 2 出现这种情况是什么问题?