最新 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 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 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。
阅读(1897) | 评论(0) | 转发(1) |