关键词:平头哥玄铁、RISC-V架构,RISC-V操作系统,安卓,虚拟机,玄铁C910,嵌入式操作系统,AOSP,调试
引言
本文主要介绍了如何基于开源的aosp risc-v仓库构建玄铁910开发板安卓镜像,和在玄铁910开发板上烧写安卓镜像与自引导启动。此外还对构建的过程、可能遇到的问题、常用的工具命令进行了相关的说明。
代码仓库
aosp-riscv仓库存放于Github托管平台:
https://github.com/T-head-Semi/aosp-riscv
可以通过以下git命令进行基本仓库的拉取:
git clone https://github.com/T-head-Semi/aosp-riscv.git
主要包含了AOSP on RISC-V的架构支持、构建脚本以及一些简要的操作说明:
├─ patches RISC-V架构支持相关patch存放目录
│ ├── art JAVA运行时的RISC-V支持
│ ├── bionic C语言标准库的RISC-V支持
│ ├── build
│ │ ├── make RISC-V架构及板级配置
│ │ └── soong 构建工具的RISC-V支持
│ ├── cts 兼容性测试集的编译支持
│ ├── dalvik libdex的RISC-V支持
│ ├── development 开发工具的RISC-V支持
│ ├── device
│ │ ├── generic
│ │ └── thead
│ │ └── thead_ice910
│ │ ├── Android.mk
│ │ ├── AndroidProducts.mk 产品包含定义
│ │ ├── audio Audio hal对接
│ │ ├── BoardConfigCommon.mk 板级通用配置
│ │ ├── device-common.mk 板级通用包引用配置
│ │ ├── ice910 镜像生成配置及rc脚本
│ │ ├── ice910.mk 产品配置文件
│ │ ├── kernel 预编译内核镜像和dtb
│ │ ├── manifest.xml 图形hal对接配置
│ │ └── prebuilts 预编译的内核模块
│ ├── external
│ ├── frameworks RISC-V编译支持和模拟器延时修改
│ ├── hardware
│ ├── libcore JAVA核心库的RISC-V支持
│ ├── libnativehelper
│ ├── manifest repo manifest覆盖文件
│ ├── prebuilts
│ │ ├── android-emulator 预编译的模拟器
│ │ ├── clang 预编译的Clang/LLVM工具链
│ │ ├── clang-tools 预编译的Clang小工具
│ │ ├── gcc 预编译的Clang工具链
│ │ ├── misc 预编译的gdbserver
│ │ ├── ndk 预编译的ndk
│ │ ├── qemu-kernel 预编译的模拟器内核
│ │ └── vndk 预编译的vndk
│ ├── system 原生系统核心程序的RISC-V支持
│ └── test 测试集的RISC-V支持
├── QUICKSTART.md 构建快速上手
├── README.md 仓库简介
├── reproduce.sh AOSP on RISC-V整体构建脚本
├── resources 其他资源存储路径
└── script
├── download_prebuilts.sh 预编译工程下载脚本
└── patch.sh AOSP添加RISC-V支持脚本
工程构建
当aosp-riscv下载完成后可以通过reproduce.sh脚本进行系统的构建,默认情况下构建的是基于模拟器的AOSP工程:
cd aosp-riscv
./reproduce.sh
可以通过添加参数ice选择编译基于玄铁910开发板平台的AOSP工程:
./reproduce.sh ice
建议使用ubuntu系统的多核服务器进行构建,并拥有200G以上的可用空间。若无法搭建合适的构建环境,则可参考烧写安卓镜像的第二步:下载镜像使用预编译的镜像进行烧写。
构建脚本和常见问题说明
reproduce.sh主要包含环境检查、下载预编译工程、下载AOSP源码、添加RISC-V支持、编译AOSP几个部分组成。
环境检查
脚本首先会检查当前执行环境,确保当前环境安装了repo、git、curl、unzip等一些常用工具。若发现工具缺失则可按照以下链接安装各个依赖程序:
https://source.android.com/setup/build/initializing
预编译下载
之后脚本会从OSS服务器下载预编译的工具和镜像。此处可能由于服务器地域限制导致各类下载问题,如DNS无法解析
--2021-01-01 00:00:00-- https://rosp-riscv.oss-cn-hangzhou.aliyuncs.com/prebuilts/android-emulator/linux-x86_64.zip
Resolving rosp-riscv.oss-cn-hangzhou.aliyuncs.com (rosp-riscv.oss-cn-hangzhou.aliyuncs.com)... failed: Name or service not known.
wget: unable to resolve host address ‘rosp-riscv.oss-cn-hangzhou.aliyuncs.com’
可以尝试以下操作: a) 重新手动执行script/download_prebuilts.sh脚本 b) 更换DNS服务器设置,如223.5.5.5、8.8.8.8等等 c) 使用中国区域VPN服务
AOSP代码同步
在完成预编译工程下载后,脚本会从AOSP的清华源同步代码。此处会下载大约100G左右的代码。下载过程中可能由于服务器压力,网络状态等原因出现以下错误:
error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was received.
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
可以尝试以下操作: a) 修改git配置放宽下载限制
vi ~/.gitconfig
添加以下内容
[http]
postBuffer = 524288000
lowSpeedLimit = 0
lowSpeedTime = 999999
sslVerify = false
使用repo sync -j 1进行下载
b) 使用初始化包进行下载
wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar
tar xf aosp-latest.tar
c) 使用google源进行下载
修改初始化使用的代码源
diff --git a/reproduce.sh b/reproduce.sh
index 560c844..306a38a 100755
--- a/reproduce.sh
+++ b/reproduce.sh
@@ -46,7 +57,7 @@ fi
if [ ! -f ${AOSP_RISCV_TOP}/stages/.stamp_repo_sync ]; then
mkdir -p ${AOSP_RISCV_BUILD_TOP}
cd ${AOSP_RISCV_BUILD_TOP}
- repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android10-release;
+ repo init -u https://android.googlesource.com/platform/manifest -b android10-release;
cp ${AOSP_RISCV_PATCH_TOP}/manifest/default.xml ${AOSP_RISCV_BUILD_TOP}/.repo/manifests/default.xml
repo sync
cd ${AOSP_RISCV_TOP}
添加RISC-V支持
之后reproduce.sh会调用script/patch.sh,向AOSP中的各个工程应用patches目录下的RISC-V相关patch和修改。若需要还原整个AOSP工程目录,则可使用以下命令:
cd aosp
repo forall -c "git clean -df"
repo forall -c "git checkout ."
repo sync
系统编译
上述过程完成之后,即会调用AOSP相关配置和构建命令,编译生成相关的镜像。开发过程中通常会单独使用以下命令进行编译配置等等操作:
初始化AOSP的编译环境:
source ./build/envsetup.sh
选择RISC-V的模拟器配置:
lunch aosp_riscv64-eng
选择RISC-V的玄铁910开发板板级配置:
lunch ice910-userdebug
工程整体编译:
m
模块单独编译:
cd [module_path]/[ module_name]
mm
执行emulator:
emulator -selinux permissive -qemu -smp 2 -m 3800M -bios ./prebuilts/qemu-kernel/riscv64/ranchu/fw_jump.bin
重新打包system镜像:
make snod
个阶段完成后会在stages目录下创建完成标记文件,可以通过删除对应标记来重做对应部分,如删.stamp_download_pre来重新下载预编译文件:
rm stages/.stamp_download_pre
./reproduce.sh
玄铁910开发板镜像拷贝与打包
在完成AOSP工程编译后,仍需要打包ext4的启动镜像,使得内核、dtb、根文件系统能在玄铁910开发板上正常的加载执行:
mkdir -p fastboot/boot
mkimage -A riscv -O linux -T kernel -C none -a 0x00200000 -e 0x00200000 -n Linux -d aosp/device/thead/thead_ice910/kernel/kernel-ice910 fastboot/boot/ uImage
cp aosp/device/thead/thead_ice910/kernel/ice_evb_c910.dtb aosp/out/target/product/ice910/ramdisk.img aosp/device/thead/thead_ice910/ prebuilts/fw_jump_0G.bin fastboot/boot
cd fastboot
make_ext4fs -l 20M boot.ext4 boot/
其他还需要拷贝一些系统相关的镜像供烧写使用:
cp aosp/out/target/product/ice910/system.img aosp/out/target/product/ice910/vendor.img userdata.img fastboot/ |
玄铁910开发板介绍
玄铁910开发板是一款T-Head 研发的高性能 SoC 开发板,以丰富的功能与外设,适合多种业务场景。
- 丰富的常见外设及接口
- 基于 OpenGL ES 的 3D 图形处理能力
- 先进的视觉AI处理器
- 音视频多媒体处理器
玄铁910开发板连接说明
先按照系统连接图连接好开发板:
- 设备电源:DC12V 输入,连接 12V 直流电源。
- CCT 烧写:CCT 烧写串口,J5 1-3 PIN,分别为RX、TX、GND,使用 thead-tools 或 CCT 工具烧写 uboot 镜像时使用的通信端口。
- Console 控制:Console 串口,J169 1-3 PIN,分别为RX、TX、GND,log 输出,控制台时使用的通信端口。
- 网络接口:千兆以太网,连接 RJ45 千兆网线,10M/100M/1000M 自适应。
CCT模式烧写系统连接图
用于烧写 u-boot 镜像:
尤其注意串口的连接 :
- 有 2个串口,一个用来打印,一个用来烧录 u-boot 镜像
- 连接的方式是 绿,白,黑
自启动模式系统连接图
用于烧写 boot、安卓系统相关镜像,以及操作安卓系统:
BOOT SEL 拨码 : BOOT SEL 拨码置为 ON、OFF、OFF、OFF,eMMC 启动模式。
烧写安卓镜像
对于第一次使用玄铁910开发板的开发者,需要根据以下几个步骤完成开发板的镜像烧写:
- 第一步: 烧录前准备:安装烧录工具(thead-tools、fastboot)、检查开发板与电脑的串口连接情况
- 第二步: 编译玄铁910开发板的AOSP镜像或下载镜像文件包
- 第三步: 通过 CCT 将 u-boot 烧写开发板的 eMMC 存储器
- 第四步: 使用 u-boot、fastboot等工具,烧写安卓镜像
- 第五步: 重启开发板,即可以进入安卓
第一步:安装工具
如果已经安装过 thead-tools, adb与 fastboot工具 可以跳过第一步。
thead-tools
通过 pip 命令来安装 yoctools 到你的系统中,yoctools 支持 python2.7+、python3.6+,建议使用python2 作为默认 python。
sudo pip install thead-tools
# 如果使用官方地址下载过慢,可使用国内清华镜像源加速
sudo pip install -i https://pypi.tuna.tsinghua.edu.cn/simple thead-tools
如果未找到 pip 命令,请先安装 pythonp-pip,如:sudo apt install python-pip。
adb与fastboot
AOSP工程下已经自带adb、fastboot等相关工具,不需要额外安装。 若不使用AOSP工程,发行版可通过包管理器安装 fastboot 工具,如 ubuntu下通过apt工具进行安装:
sudo apt install adb
sudo apt install fastboot
或从官网下载二进制文件,下载地址:https://developer.android.com/studio/releases/platform-tools 。
第二步:下载镜像
wget "https://thead.oss-cn-hangzhou.aliyuncs.com/android_images.tar.bz2"
tar xf android_images.tar.bz2
cd android_images
ls -l
需要用到的,是如下五个文件:
-rw-r--r-- 1 root root 23975004 Jan 13 14:24 boot.ext4
-rw-r--r-- 1 root root 683602236 Jan 13 14:19 system.img
-rw-r--r-- 1 root root 487692 Jan 5 10:04 userdata.img
-rw-r--r-- 1 root root 26996812 Jan 13 14:19 vendor.img
-rw-r--r-- 1 root root 599192 Dec 20 16:39 u-boot-with-spl.bin
- u-boot-with-spl.bin: uboot 引导镜像文件
- boot.ext4: boot 分区文件系统,ext4格式,包含 fw_jump.bin、uImage、ice_evb_c910.dtb
- system.img: 安卓系统分区,ext4 格式
- userdata.img: 安卓用户分区,ext4 格式
- vendor.img: 安卓供应商分区,ext4 格式
u-boot-with-spl.bin以外的镜像可以参考工程构建-玄铁910开发板镜像拷贝与打包章节由aosp-riscv工程编译生成。
第三步:烧写 uboot
查看电脑串口
参考 玄铁910开发板介绍-硬件连接-CCT模式烧写系统连接图 部分完成开发板的连接,通过 CCT 烧写 uboot 需要使用开发板的 CCT 烧写串口,通过命令 thead cct uart 命令看到电脑上安装的串口列表,并确认电脑上串口与开发板串的对应关系:
root@linux > thead cct uart
uart device list:
/dev/ttyUSB0 - USB-Serial Controller
/dev/ttyUSB1 - USB-Serial Controller
查找开发板存储器列表
通过命令:thead cct -u /dev/ttyUSB0 list 可以查看开发板支持的烧写存储器列表,如下:
root@linux > thead cct -u /dev/ttyUSB0 list
Wait .....................
CCT Version: 2
memory device list:
dev = ram0 , size = 256.0KB
dev = emmc0 , size = 2.0MB
dev = emmc1 , size = 2.0MB
dev = emmc2 , size = 3.7GB
注意:使用该命令时,先确定串口的连接是否正确,运行命令前先关闭开发板电源后再运行该命令,等到出现Wait .......... 信息后再开启开发板电源,正常情况下电源开启后在1秒内会出现如下信息:
CCT Version: 2
memory device list:
dev = ram0 , size = 256.0KB
dev = emmc0 , size = 2.0MB
dev = emmc1 , size = 2.0MB
dev = emmc2 , size = 3.7GB
如果未出现上述打印信息,同时电脑是接有多个串口,请更新另一个串再尝试一次,如:thead cct -u /dev/ttyUSB1 list。如果所有串口都尝试后均未出现上述打印机信息,请检查串口与开发板的连接是否符合,详细连接参见:玄铁910开发板接线部分。
烧写 uboot
通过命令:thead cct -u /dev/ttyUSB0 download -f u-boot-with-spl.bin -d emmc0 将 uboot 烧写到 eMMC 的 0号分区,烧写过程信息如下:
CCT Version: 2
Send file 'u-boot-with-spl.bin' to 21:0 ...
Writing at 0x00009800... (3%)
待打印File u-boot-with-spl.bin download success.后,烧写成功后,可以通过开发板的 Console 串口看到正确的启动信息:
U-Boot 2020.01-g6cc5d59b0d (Dec 20 2020 - 08:37:37 +0000)
CPU: rv64imafdcvsu
Model: T-HEAD c910 ice
DRAM: 4 GiB
GPU ChipDate is:0x20151217
GPU Frequency is:500000KHz
NPU ChipDate is:0x20190514
DPU ChipDate is:0x20161213
MMC: mmc0@3fffb0000: 0
Loading Environment from MMC... OK
In: serial@3fff73000
Out: serial@3fff73000
Err: serial@3fff73000
Net:
Warning: ethernet@3fffc0000 (eth0) using random MAC address - e6:e2:ea:7a:30:ce
eth0: ethernet@3fffc0000
Hit any key to stop autoboot: 1
第四步:烧写安卓镜像
当完成以上步骤初次烧写之后,后续开发过程中通常只需要按照本章节描述就能完成系统镜像的更新。后续开发板的连接需要调整为玄铁910开发板介绍-硬件连接-CCT模式烧写系统连接图章节所示。
开发板 uboot 配置
开发板重新开机后进入 uboot 命令模式,当串口出现如下提示时,按任键即可进行命令模式。
Warning: ethernet@3fffc0000 (eth0) using random MAC address - a6:7d:bc:02:7d:4d
eth0: ethernet@3fffc0000
Hit any key to stop autoboot: 3
通过 gpt 命令配置 eMMC 分区大小,命令如下:
# 恢复默认值
env default -a
# 配置 eMMC 分区
setenv partitions "name=sparse,size=2031kb"
setenv partitions "$partitions;name=bootpart,size=60MiB"
setenv partitions "$partitions;name=system,size=1500MiB"
setenv partitions "$partitions;name=vendor,size=100MiB"
setenv partitions "$partitions;name=cache,size=256MiB"
setenv partitions "$partitions;name=userdata,size=-"
gpt write mmc 0 $partitions
# 配置网络
# !!!!!!!!!!!!!!!!!!!! 特别注意 !!!!!!!!!!!!!!!!!!!!!!!!
# 如果网络中接入多块玄铁910开发板,每块开发板的 ethaddr 要唯一
setenv ethaddr 00:a0:a0:a0:a0:a1 # 如果网络中接入多块玄铁910开发板,ethaddr 要唯一
setenv ipaddr 192.168.1.100 # 开发板 IP 地址
setenv netmask 255.255.255.0
ping 192.168.1.1 # ping 主机的IP,检验网络是否正常
# 配置内核启动参数 bootargs
setenv bootargs "console=ttyS0,115200"
setenv bootargs "$bootargs root=PARTUUID=$uuid_rootfs rootfstype=ext4"
setenv bootargs "$bootargs earlycon=sbi rdinit=/init security=selinux"
setenv bootargs "$bootargs crashkernel=256M-:128M c910_mmu_v1 printk.devkmsg=on"
setenv bootargs "$bootargs androidboot.selinux=permissive"
setenv bootargs "$bootargs androidboot.hardware=ranchu"
setenv bootargs "$bootargs androidboot.super_partition"
# 配置 bootcmd
setenv bootcmd "ext4load mmc 0:2 $opensbi_addr fw_jump_0G.bin"
setenv bootcmd "$bootcmd;ext4load mmc 0:2 $dtb_addr ice_evb_c910.dtb"
setenv bootcmd "$bootcmd;ext4load mmc 0:2 $kernel_addr uImage"
setenv bootcmd "$bootcmd;ext4load mmc 0:2 0x02000000 ramdisk.img"
setenv bootcmd "$bootcmd;bootm $kernel_addr - $dtb_addr"
# 环境变量保存到 eMMC 中
saveenv # 将配置保存到 eMMC,下次启动时无需再配置
# 开启fastboot模式
fastboot udp
烧写镜像
在电脑上使用使用 fastboot 命令完成镜像烧写,192.168.1.100 是开发板的运行 u-boot 时配置的 IP 地址,使用 fastboot 命令前确认电脑与开发板在同一个子网。可在板子上使用 ping 192.168.1.1 检查网络情况。
# PC 烧写镜像
fastboot -s udp:192.168.1.100 -S 5M flash bootpart boot.ext4
fastboot -s udp:192.168.1.100 -S 5M flash system system.img
fastboot -s udp:192.168.1.100 -S 5M flash vendor vendor.img
fastboot -s udp:192.168.1.100 -S 5M flash userdata userdata.img
第五步:重启进入安卓
复位玄铁910开发板,自动进入安卓界面。
玄铁910开发板可以通过Micro USB 3.0与上位主机相连,主机侧可以执行adb shell进入命令行交互窗口查看系统信息或控制系统运行。调试常用命令如下:
打印系统日志:
logcat
查看系统服务:
service list
查看应用相关信息:
dumpsys
查看系统prop配置:
getprop
获取当前输入事件
getevent
启动应用:
am start
发送按键值:
input keyevent
gdbserver调试native应用程序:
gdbserver64 127.0.0.1:7000 native_app_name
本文转自Roy_Wu314。