RPi 2B: 编译运行Android系统 – n-preview-2

看起来在RPi 2B(树莓派)上运行Android系统地不是一件很难的事情。到目前为止,我已经能够使n-preview-2版本的Android系统在Rpi 2B上跑起来了。

为了能够方便地更新系统,我们使用Brillo系统作为recovery系统,通过fastboot命令更新system image。

具体的使用方法请看:http://www.brobwind.com/archives/975

  • 方法及步骤

当前所使用的项目模板为:device/generic/mini-emulator-armv7-a-neon

1. 修改BroadConfig.mk下的WITH_DEXPREOPT变量,将其注掉或者是设为false, 不进行dexpreopt的操作

2. 修改fstab, 使init进程能够挂载正确的分区:

# Android fstab file.
#<src>                                                  <mnt_point>         <type>    <mnt_flags and options>                              <fs_mgr_flags>
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
/dev/block/mmcblk0p5                                    /boot               vfat      defaults                                             defaults
/dev/block/mmcblk0p6                                    /system             ext4      ro,barrier=1                                         wait
/dev/block/mmcblk0p7                                    /data               ext4      noatime,nosuid,nodev,barrier=1,nomblk_io_submit      wait,check
/dev/block/mmcblk0p8                                    /cache              ext4      noatime,nosuid,nodev  wait,check

3. 修改device/generic/goldfish/init.goldfish.sh文件,重新设置eth0的IP地址,以便能够通过adb命令进行交互:

#!/system/bin/sh

# Setup networking when boot starts
ifconfig eth0 192.168.5.127 netmask 255.255.255.0 up
route add default gw 192.168.5.1 dev eth0

# ro.kernel.android.qemud is normally set when we
# want the RIL (radio interface layer) to talk to
# the emulated modem through qemud.
#!/system/bin/sh

# Setup networking when boot starts
ifconfig eth0 192.168.5.127 netmask 255.255.255.0 up
route add default gw 192.168.5.1 dev eth0

# ro.kernel.android.qemud is normally set when we
# want the RIL (radio interface layer) to talk to
# the emulated modem through qemud.
...

4. 设置LIBART_IMG_TARGET_BASE_ADDRESS(build/core/dex_preopt_libart.mk)的值为0x30000000, 以便不出现如下fatal  error:

01-01 00:00:13.789   113   113 W art     : Failed to open oat file '/data/dalvik-cache/arm/system@framework@boot.oat' referenced from image /data/dalvik-cache/arm/system@framework@boot.art: Failed to allocate ElfFile reservation for /data/dalvik-cache/arm/system@framework@boot.oat: Failed to mmap at expected address, mapped at 0x6c716000 instead of 0x71684000 : Requested region 0x71684000-0x75bc0000 overlaps with existing map 0x740b6000-0x744f3000 (/system/lib/libart.so)
01-01 00:00:13.789   113   113 W art     : 0x740b6000-0x744f3000 r-x /system/lib/libart.so
01-01 00:00:13.789   113   113 W art     : 0x744f3000-0x744f4000 ---
01-01 00:00:13.789   113   113 W art     : 0x744f4000-0x744fc000 r-- /system/lib/libart.so
01-01 00:00:13.789   113   113 W art     : 0x744fc000-0x744fe000 rw- /system/lib/libart.so
--------- beginning of crash
01-01 00:00:35.026   118   118 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x9c in tid 118 (zygote)
01-01 00:00:35.050   396   396 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-01 00:00:35.051   396   396 F DEBUG   : Build fingerprint: 'Android/m_e_arm/mini-emulator-armv7-a-neon:6.0.1/MASTER/hzak05050809:eng/test-keys'
01-01 00:00:35.051   396   396 F DEBUG   : Revision: '0'
01-01 00:00:35.051   396   396 F DEBUG   : ABI: 'arm'
01-01 00:00:35.051   396   396 F DEBUG   : pid: 118, tid: 118, name: zygote  >>> zygote <<<
01-01 00:00:35.051   396   396 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x9c
01-01 00:00:35.078   396   396 F DEBUG   : Abort message: 'art/runtime/gc/heap.cc:391] Check failed: non_moving_space_mem_map != nullptr Failed to mmap at expected address, mapped at 0x6ca41000 instead of 0x72d7b000 : Requested region 0x72d7b000-0x76d7b000 overlaps with existing map 0x740b6000-0x744f3000 (/system/lib/libart.so)'
01-01 00:00:35.082   396   396 F DEBUG   :     r0 00000000  r1 00000010  r2 00000000  r3 00000000
01-01 00:00:35.082   396   396 F DEBUG   :     r4 7eb0aff4  r5 00000000  r6 00000000  r7 7eb0aff8
01-01 00:00:35.082   396   396 F DEBUG   :     r8 00000000  r9 7eb0b02c  sl 7eb0b240  fp 00000000
01-01 00:00:35.082   396   396 F DEBUG   :     ip 00000000  sp 7eb0afc8  lr 00000000  pc 743d77b0  cpsr 40000030
01-01 00:00:35.118   396   396 F DEBUG   :
01-01 00:00:35.118   396   396 F DEBUG   : backtrace:
01-01 00:00:35.118   396   396 F DEBUG   :     #00 pc 0032c7b0  /system/lib/libart.so (art::DumpCheckpoint::Run(art::Thread*)+195)
01-01 00:00:35.118   396   396 F DEBUG   :     #01 pc 00326b3d  /system/lib/libart.so (art::ThreadList::RunCheckpoint(art::Closure*)+324)
01-01 00:00:35.118   396   396 F DEBUG   :     #02 pc 003267a9  /system/lib/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+180)
01-01 00:00:35.118   396   396 F DEBUG   :     #03 pc 0030e119  /system/lib/libart.so (art::AbortState::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+372)
01-01 00:00:35.119   396   396 F DEBUG   :     #04 pc 00305353  /system/lib/libart.so (art::Runtime::Abort()+90)
01-01 00:00:35.119   396   396 F DEBUG   :     #05 pc 000b1fd9  /system/lib/libart.so (art::LogMessage::~LogMessage()+864)
01-01 00:00:35.119   396   396 F DEBUG   :     #06 pc 0017a96b  /system/lib/libart.so (art::gc::Heap::Heap(unsigned int, unsigned int, unsigned int, unsigned int, double, double, unsigned int, unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, art::InstructionSet, art::gc::CollectorType, art::gc::CollectorType, art::gc::space::LargeObjectSpaceType, unsigned int, unsigned int, unsigned int, bool, unsigned int, unsigned int, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, unsigned l
01-01 00:00:35.119   396   396 F DEBUG   :     #07 pc 00307337  /system/lib/libart.so (art::Runtime::Init(art::RuntimeArgumentMap&&)+6542)
01-01 00:00:35.119   396   396 F DEBUG   :     #08 pc 003092b3  /system/lib/libart.so (art::Runtime::Create(std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void const*>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void const*> > > const&, bool)+66)
01-01 00:00:35.119   396   396 F DEBUG   :     #09 pc 002313b3  /system/lib/libart.so (JNI_CreateJavaVM+382)

不知道为什么在RPi 2B上,libart.so map的地址为~0x740b600, 而在emulator上, map的地址却在~0xa7f36000:

a5af5000-a7af6000 rw-p 00000000 00:04 2841       /dev/ashmem/dalvik-card table (deleted)
a7af6000-a7bb6000 rw-p 00000000 00:04 2838       /dev/ashmem/dalvik-allocspace main rosalloc space 1 mark-bitmap 2 (deleted)
a7bb6000-a7c76000 rw-p 00000000 00:04 2837       /dev/ashmem/dalvik-allocspace main rosalloc space 1 live-bitmap 2 (deleted)
a7d36000-a7e36000 rw-p 00000000 00:04 2830       /dev/ashmem/dalvik-allocspace zygote / non moving space mark-bitmap 0 (deleted)
a7e36000-a7f36000 rw-p 00000000 00:04 2829       /dev/ashmem/dalvik-allocspace zygote / non moving space live-bitmap 0 (deleted)
a7f36000-a8373000 r-xp 00000000 1f:00 1014       /system/lib/libart.so
a8373000-a8374000 ---p 00000000 00:00 0
a8374000-a837c000 r--p 0043d000 1f:00 1014       /system/lib/libart.so
a837c000-a837e000 rw-p 00445000 1f:00 1014       /system/lib/libart.so
a837e000-a8380000 rw-p 00000000 00:00 0          [anon:.bss]
a8380000-a8500000 rw-p 00000000 00:00 0          [anon:libc_malloc]
a8502000-a8521000 r--p 00000000 1f:00 741        /system/fonts/NotoSansDevanagariUI-Regular.ttf
a8521000-a852e000 r-xp 00000000 1f:00 1024       /system/lib/libbacktrace.so
a852e000-a852f000 r--p 0000c000 1f:00 1024       /system/lib/libbacktrace.so
a852f000-a8530000 rw-p 0000d000 1f:00 1024       /system/lib/libbacktrace.so
a8530000-a8535000 r-xp 00000000 1f:00 1175       /system/lib/libspeexresampler.so
a8535000-a8536000 r--p 00004000 1f:00 1175       /system/lib/libspeexresampler.so
a

5. 设置system property:

- ro.sf.lcd_density为240

- ro.kernel.qemu为1, 使用software OpenGL

  • 分区表信息

与Brillo系统相比,Android系统需要多出一下cache分区,所以还需要对SD卡进行重新分区:

TF card (8GiB) – MBR partition table
Primary
mmcblk0p1
Extended
mmcblk0p5 mmcblk0p6 mmcblk0p7 mmcblk0p8
RECOVERY(384MiB) boot(64MiB) system(550MiB) data(5GiB) cache(550MiB) OTHER

NOTE:

- system分区的大小需要大于550MiB,system分区大小是在device/generic/armv7-a-neon/BoardConfig.mk文件中指定的:

...
TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 576716800
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_FLASH_BLOCK_SIZE := 512
TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
...

-使用fdisk分区结束后需要使用mkfs.ext4命令格式化/dev/block/mmcblk0p7与/dev/block/mmcblk0p8。fastboot只是用来更新system分区。

  • 更新方法
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ fastboot -s tcp:192.168.5.127 getvar product
error: Failed to connect to 192.168.5.127:5554
< waiting for tcp:192.168.5.127 >
product: rpi3b
finished. total time: 0.002s
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ fastboot -s tcp:192.168.5.127 flash system system.img 
target reported max download size of 67108864 bytes
Invalid sparse file format at header magi
erasing 'system'...
(bootloader) erase /dev/block/mmcblk0p6:  10/100
(bootloader) erase /dev/block/mmcblk0p6:  20/100
(bootloader) erase /dev/block/mmcblk0p6:  30/100
(bootloader) erase /dev/block/mmcblk0p6:  40/100
(bootloader) erase /dev/block/mmcblk0p6:  50/100
(bootloader) erase /dev/block/mmcblk0p6:  60/100
(bootloader) erase /dev/block/mmcblk0p6:  70/100
(bootloader) erase /dev/block/mmcblk0p6:  80/100
(bootloader) erase /dev/block/mmcblk0p6:  90/100
(bootloader) erase /dev/block/mmcblk0p6: 100/100
OKAY [  4.512s]
sending sparse 'system' 1/4 (65532 KB)...
OKAY [  6.188s]
writing 'system' 1/4...
OKAY [ 29.167s]
sending sparse 'system' 2/4 (63565 KB)...
OKAY [  5.999s]
writing 'system' 2/4...
OKAY [ 14.270s]
sending sparse 'system' 3/4 (58332 KB)...
OKAY [  5.845s]
writing 'system' 3/4...
OKAY [ 90.887s]
sending sparse 'system' 4/4 (8932 KB)...
OKAY [  0.923s]
writing 'system' 4/4...
OKAY [  1.887s]
finished. total time: 159.678s
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ adb connect 192.168.5.127
connected to 192.168.5.127:5555
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ adb shell mount /dev/block/mmcblk0p5 /boot/
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ adb push ramdisk.img /boot/ramdisk7.img
[100%] /boot/ramdisk7.img
hzak@B85RPI:/data/n-preview-2/out/target/product/mini-emulator-armv7-a-neon$ adb shell sync
  • 存在的问题

1. 第一次开机花了十几分钟才进入桌面,CPU还是很有温度的,难怪需要添加一个风扇

2. 显示存在问题,可能需要修改kernel framebuffer driver才能解决

评论

3 Comments on "RPi 2B: 编译运行Android系统 – n-preview-2"

提醒我
avatar

欧建深
游客
欧建深
2 年 3 月 之前

你研究得好前沿,N-PREVIEW-2 和brillo-m10标签没打上几天,就玩上了。
能否回个邮件给我邮箱,交个朋友。

wpDiscuz