使用HiKey进行开发

Android官方目前支持的有一款开发板,名为HiKey,我们可以通过研究它对AOSP有更深的理解。

官方购买链接是一个国外网站,购买起来不方便。其实这块板子是中国的一个公司生产(我和这家公司并无利益关系,所以这里也不贴具体信息了)的,我买了一块用来进行AOSP的研究。

HiKey开发板


HiKey是符合Linaro LCG组织的96Boards设计标准的开发板。而96Boards是基于ARM架构芯片的开放平台规范,同时也是第一个定义Cortex-A开发板的开放规范。好处在于基于96Boards标准开发的组件可以在任意兼容96Boards的平台上使用。

Google支持这款开发板,并且将其作为一个Android参考的开发板。AOSP为HiKey提供kernel源码和主板支持,使得开发者可以迅速地创建和调试新的和现有的外围设备的驱动,进行kernel开发和进行其它任务。

借用一张Google上的图片
使用HiKey进行开发_第1张图片

在HiKey上运行Android

  • 下载Android源码:
$ repo init -u https://android.googlesource.com/platform/manifest -b master

$ repo sync -j24

上面是Google上的命令,其实就是从master分支同步最新的AOSP源码。这里将安装开发工具包、JDK、配置源码环境等都省略掉了,具体可以参考我前边的文章 Android源代码编译笔记(支持5.x及以上版本)

  • 下载并且解压HDMI驱动到Android源代码:
$ wget https://dl.google.com/dl/android/aosp/linaro-hikey-20160226-67c37b1a.tgz

$ tar xzf linaro-hikey-20160226-67c37b1a.tgz

$ ./extract-linaro-hikey.sh

好消息:https://dl.google.com下的东西无需可以直接下载了。

  • 安装mcopy工具:
$ sudo apt-get install mtools
  • 编译:
$ source build/envsetup.sh

$ lunch hikey-userdebug

$ make -j32

对于4GB内存版本的板子,将$ make -j32替换为$ make -j32 TARGET_USERDATAIMAGE_4GB=true

对于make -j的值根据你CPU的核心数的1-2倍来进行设置。

刷机前的一些小准备

编译完成之后,我们先不着急刷机,了解我们接下来要做的究竟是什么。

如果你稍微接触过Android设备刷机,就会听说过fastboot
那么它究竟是什么?

fastboot

如果你搜索fastboot,90%以上都是如何进入fastboot模式,怎样使用fastboot(第三方包装的刷机工具或者Android SDK附带的原版fastboot)等等。

但是,fastboot究竟是什么呢?它有3层意思

  • Android设备(手机、平板、盒子、现在大热的汽车和开发板)硬件与电脑(Windows, Linux, Mac平台都已实现)的通信协议
  • 进入fastboot模式时,设备端运行的软件
  • 进入fastboot模式时,电脑端运行的与手机通信的软件 - 即fastboot命令

fastboot电脑端与设备端的通信其实是一个C/S架构,电脑端作为客户端,将指令与文件内容发送到服务器端(设备端),服务器端执行对应的指令(清除分区,写分区等等)。

平常见到的C/S架构还有很多,比如HTTP通信(浏览器客户端/Web服务器),SSH通信(ssh客户端/sshd服务器程序)等。

阅读刷机脚本flash-all.sh

这一块内容较多,可以参考我的另一篇文章 通过阅读刷机脚本flash-all.sh来学习shell脚本

实际刷机

可以参考的地方有2个地方,一个是Google,另一个是开发板生产商。

但是它们教程都多多少少有些问题,其中有些坑,如果没人指导,能把你绕好久。

该板子支持Debian系统,这里我们不做讨论,只关注Android系统。

刷机分为2个阶段

  • bootloader阶段,在这个阶段你要把真正的bootloader - l-loader.bin刷进去。

生产商将其称之为flashing environment,我觉得不恰当。

  • fastboot阶段,在这个阶段你会使用fastboot flash [partition name] [image file]依次刷入7个文件,即7个分区,分别是
partition name image file comment
ptable ptable-aosp-8g.img 分区表
fastboot fip.bin
nvme mvme.img
boot boot.img kernel
cache cache.img 文件系统
system system.img 文件系统
userdata userdata.img 文件系统

如果我们设置了正确的跳线,见下文
那么使用device/linaro/hikey/installer/flash-all.sh脚本就可以完成全部刷机工作。

而Selecting Devices里边的Flashing images已经没有必要再重复刷,因为boot和system分区已经在上面的脚本里边刷过了。

注意Building the kernel部分是可选的,flash-all.sh中刷的是out目录下面的boot.img,这个文件应该是已经预编译的,因为我们可以从开机之后的截图判断出来。

使用HiKey进行开发_第2张图片

如果要自己编译kernel并刷入HiKey,请参考我的文章编译HiKey内核。

遇到的问题与解决

python缺少serial模块

准备刷入bootloader的时候,碰到错误ImportError: No module named serial

这是因为python的serial模块没有安装,网上有几种安装的方法。我最终通过下面的方法安装成功:

sudo apt-get install pip
sudo pip install pyserial

刷入bootloader后,一直提示

这时我们需要更换跳线至fastboot模式,Google和生产商在这一点上说得都不清楚。
正确的设置是

  • j15 3-4闭合,会进入bootloader模式,这时候我们只会刷入一个bootloader文件
  • j15 5-6闭合,会进入fastboot模式,使用fastboot命令的都需要在这个模式下进行

bootloader模式,没有任何指示灯。
可以使用指令查看设备是否已连接:
$ ls /dev/ttyUSB*

fastboot模式,会有一个绿色的指示灯。
可以使用指令查看设备是否已连接:
$ fastboot devices

直接执行fastboot找不到设备,必须要sudo fastboot才能找到

这是因为按照生产商的教程配置/etc/udev/rules.d/51-android.rules文件时并没有加上当前用户的权限,所以只能以root权限才可以访问到设备。

原来的配置是

# fastboot protocol on HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d00d", MODE="0660", GROUP="dialout"
# adb protocol on HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1057", MODE="0660", GROUP="dialout"
# rndis for HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1050", MODE="0660", GROUP="dialout"

这里因为我不清楚GROUP="dialout"是否有被用到,所以按照编译Android系统的官方教程修改该配置文件,加上OWNER,改为下面的样子

# fastboot protocol on HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d00d", MODE="0660", GROUP="dialout", OWNER="$USER_NAME"
# adb protocol on HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1057", MODE="0660", GROUP="dialout", OWNER="$USER_NAME"
# rndis for HiKey
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1050", MODE="0660", GROUP="dialout", OWNER="$USER_NAME"

注意,将$USER_NAME改为你自己的用户名。

USB外设(鼠标/键盘)与OTG-USB的冲突

实际当中发现,通过OTG-USB连接调试之后,USB外设都无法使用,不知道这是不是一个bug。

无奈,只好使用蓝牙模式连接上鼠标和键盘,这样才算解决了OTG-USB的冲突问题。

横竖屏切换

默认启动起来是横屏显示,但是打开竖屏应用或者连接ADB调试后会变成竖屏。

因为没有重力传感器,所以我们可以使用命令来更改设备的屏幕方向。

按照教程上的说法,首先要关闭自动旋转(但其实HiKey这块板子并没有自动旋转的能力),然后写入新的user_orientation的值。

具体是:

关闭自动旋转

adb shell content insert --uri content://settings/system --bind name:s:accelerometer_rotation --bind value:i:0

设置新的屏幕方向

adb shell content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:${new_orientation}

请将${new_orientation}用下面其中一个值来替换

对于手机

  • 0, 竖屏
  • 1,顺时针旋转90°,横屏
  • 2,顺时针旋转180°,竖屏(与0方向相反)
  • 3,顺时针旋转270°,横屏(与1方向相反)

对于HiKey

  • 0, 横屏
  • 1,顺时针旋转90°,竖屏
  • 2,顺时针旋转180°,横屏(与0方向相反)
  • 3,顺时针旋转270°,竖屏(与1方向相反)

从上面可以发现一个规律:
0是设备屏幕默认的方向,或者我们可以叫做基准方向;
1/2/3分别是以0为基准,顺时针旋转90°/180°/270°。

在使用一台红米Note 3全网通测试时发现一件有趣的事情,当你使用>3的值来测试的时候,屏幕完全是以竖屏模式旋转。比如,值为5,屏幕变成了完全将竖屏旋转90度,这时为了等比例缩放,显示区域会变小很多。

对比几台其它厂商的手机可以发现,红米的“特殊现象”是它自己的实现。
而标准的Android实现只接受0-3的取值,如果使用其它值(如4),会抛异常:
java.lang.IllegalArgumentException: Invalid value: 4 for setting: user_rotation

参考


  1. Selecting Devices
  2. Android源代码编译笔记(支持5.x及以上版本)
  3. What is fastboot
  4. 通过阅读刷机脚本flash-all.sh来学习shell脚本
  5. Changing Android Device orientation with ADB
  6. 编译HiKey内核

你可能感兴趣的:(Android->AOSP研究)