小伙伴们的智能之旅

Brillo: 将系统移植到Raspberry Pi 2B(树莓派)上

Raspberry Pi 2B(树莓派)具有4个Cortex-A7 CPU, 1G的内存空间,使用TF卡作为存储介质,一个百兆有线网卡,40Pin的GPIO, 4个USB接口。Brillo系统跑在上面一点问题都没有。

NOTE:  

编译出来的系统只能在Raspberry Pi 2B上运行,其他的硬件版本是不支持的:CPU的指令集不同(需要armv7-a指令集)。

 

相关的文档可以参考:http://source.android.com/source/initializing.html

编译用的主机要求是x64平台,运行ubuntu 14.04系统, 2G以上的内存, 60G以上的剩余空间

安装java 7(可选, 如果想编译Android项目的话,还是安装一下好):

$ sudo apt-get update
$ sudo apt-get install openjdk-7-jdk

安装其他需要用到的文件:

$ sudo apt-get install git-core gnupg flex bison gperf build-essential \
  zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
  lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache \
  libgl1-mesa-dev libxml2-utils xsltproc unzip

配置USB访问权限:

$ wget -S -O - http://source.android.com/source/51-android.rules | \
    sed "s/<username>/$USER/" | \
    sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; \
    sudo udevadm control --reload-rules

相关的文档可以参考:http://source.android.com/source/downloading.html

安装repo:

$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

brillo原生系统代码及Raspberry Pi 2B linux kernel 代码下载:

$ mkdir -pv /local/brillo-m8-release && cd /local/brillo-m8-release
$ ~/bin/repo init -u https://android.googlesource.com/brillo/manifest -b brillo-m8-release

删除.repo/manifest.xml并将这个文件brillo-m8-release-for-rpi2b.xml.zip 解压并考贝到.repo/manifest.xml (替换),brillo原生系统使用的是brillo-m8-release这个分支,而Raspberry Pi 2B kernel使用的是rpi-4.1.y分支:

$ rm .repo/manifest.xml
$ wget https://www.brobwind.com/wp-content/uploads/2015/12/brillo-m8-release-for-rpi2b.xml_.zip && unzip brillo-m8-release-for-rpi2b.xml_.zip
$ cp brillo-m8-release-for-rpi2b.xml .repo/manifest.xml
$ ~/bin/repo sync -j 4

下载的代码约有13G, 漫长的等待。。。

Raspbrery Pi 2B设备相关的文件请从这里下载:brillo-m8-device-hzak-rpi2b.tar.gz

$ curl https://www.brobwind.com/wp-content/uploads/2015/12/brillo-m8-device-hzak-rpi2b.tar.gz | tar -zxvf -

由于Raspberry Pi 2B默认的kernel配置,编译出来的kernel虽然能够正常开机,但是系统的一些服务会出现非正常退出的情况,所以还需要更新一下kernel的配置文件bcm2709_defconfig:

cp device/hzak/rpi/bsp/kernel-config hardware/bsp/kernel/hzak/rpi-4.1.y/arch/arm/configs/bcm2709_defconfig

$ . build/envsetup.sh
$ lunch rpi-eng
$ make -j 4

又是漫长的等待。。。

先对SD卡进行分区,并进行格式化。需要3个分区, 第一个分区存放bootcode.bin, config.txt, start.elf, fixup.dat, cmdline.txt, kernel7.img, ramdisk7.img;第二个区公为系统分区:会写入system.img;第三个分区为data分区,用于存放运行时的配置文件等。

可以参考这个(一定要知道SD卡是属于哪个设备文件, 可以用dmesg | tail 查看):

$ sudo fdisk /dev/sd?

Command (m for help): o
Building a new DOS disklabel with disk identifier 0x29767d95.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 1): 
Using default value 1
First sector (2048-15523839, default 2048): 8192
Last sector, +sectors or +size{K,M,G} (8192-15523839, default 15523839): +400M 

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 2): 
Using default value 2
First sector (2048-15523839, default 2048): 827392
Last sector, +sectors or +size{K,M,G} (827392-15523839, default 15523839): +112M

Command (m for help): n
Partition type:
   p   primary (2 primary, 0 extended, 2 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 3): 
Using default value 3
First sector (2048-15523839, default 2048): 1056768
Last sector, +sectors or +size{K,M,G} (1056768-15523839, default 15523839): +512M

Command (m for help): p

Disk /dev/sd?: 7948 MB, 7948206080 bytes
245 heads, 62 sectors/track, 1021 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x29767d95

   Device Boot      Start         End      Blocks   Id  System
/dev/sd?1            8192      827391      409600   83  Linux
/dev/sd?2          827392     1056767      114688   83  Linux
/dev/sd?3         1056768     2105343      524288   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

可以看到/dev/sd?1为linux分区(id为83),一定要将其改成b (FAT32)分区,不然系统无法识别,开不了机。

下面是格式化分区:

$ sudo mkfs.vfat /dev/sd?1
$ sudo mkfs.ext4 /dev/sd?3

挂载/dev/sd?1分区,将out/target/product/rpi/boot中的文件copy过去,再将kernel, ramdisk.img也copy过去:

$ sudo mount /dev/sd?1 /mnt/
$ sudo cp out/target/product/rpi/boot/* /mnt/
$ sudo cp out/target/product/rpi/kernel /mnt/kernel7.img
$ sudo cp out/target/product/rpi/ramdisk.img /mnt/ramdisk7.img
$ sudo umount /mnt
$ sync

接着将system.img写到/dev/sd?2分区中(一定要按照下面的方法进行操作,如果进行mount, cp, umount的操作,开机的时候会出现意想不到的问题,因为system.img中的文件是有SELinux context的,使用cp命令无法进行完整的将SELinux context copy过去; SELinux context可以通过ls -Z or ps -Z查看):

$ sudo dd if=out/target/product/rpi/system.img of=/dev/sd?2
$ sync

做完这些,你就可以将TF卡插入Raspberry Pi 2B上开机运行了。

将Raspberry Pi 2B通过网线连入局域网,它会自动去获取IP地址。由于设备上有avahi-daemon, 所以可以PC可以通过avahi-browser来查找 它所分配的IP地址:

$ avahi-browse -a -r
+   eth0 IPv4 FD396216-7C5D-4D61-96E2-EFEB4B2113A9          _privet._tcp         local
=   eth0 IPv4 FD396216-7C5D-4D61-96E2-EFEB4B2113A9          _privet._tcp         local
   hostname = [linux.local]
   address = [10.0.0.13]
   port = [80]
   txt = ["note=brillo @ rpi" "flags=CA" "mmid=AAAAA" "id=764EEAA2-3183-48DF-8849-185E2EB30F0D" "services=vendor" "ty=rpi" "txtvers=3"]

我们可以看到设备的IP地址为10.0.0.13, 接着就可以查看到设备的信息:

$ curl -H "Authorization: Privet anonymous" http://10.0.0.13/privet/info
$ curl -H "Authorization: Privet anonymous" -k https://10.0.0.13/privet/info
$ cd hardware/bsp/kernel/hzak/rpi-4.1.y/
$ ARCH=arm CROSS_COMPILE=arm-linux-androideabi- make bcm2709_defconfig
$ ARCH=arm CROSS_COMPILE=arm-linux-androideabi- make menuconfig

# 保存当前的配置

$ cp .config arch/arm/config/bcm2709_defconfig

# 最后一定要执行make mrproper, 以删除当前的配置文件和产生的中间文件,
# 不然编译的时候会报错

$ ARCH=arm CROSS_COMPILE=arm-linux-androideabi- make mrproper

官方编译Raspberry Pi 2B的方法,相关文档:

https://github.com/raspberrypi/documentation/blob/master/linux/kernel/building.md

Raspberry Pi 2 Default Build Configuration

cd linux
KERNEL=kernel7
make bcm2709_defconfig

Build and install the kernel, modules and Device Tree blobs; this step takes a long time…

make zImage modules dtbs
sudo make modules_install
sudo cp arch/arm/boot/dts/*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
sudo scripts/mkknlimg arch/arm/boot/zImage /boot/$KERNEL.img

Note: On a Raspberry Pi 2, adding -j4 (make -j4 zImage modules dtbs) splits the work between all four cores, speeding up compilation significantly.