前言

文档概述

本文档详细介绍了 BM1684X 系列AI计算模组(含开发板)的外观特点、应用场景、设备参数、电气特性、配套软件、使用环境等,使得该设备的用户及开发者对 BM1684X 系列AI计算模组(含开发板)有比较全面深入的了解。设备用户及开发者可依据此手册,开展对该设备的安装、调试、部署、维护等一系列工作。

读者对象

本文档主要适用于如下人员:

  • 算丰FAE工程师、售前工程师

  • 生态合作伙伴的开发人员

  • 用户企业研发工程师、售前工程师

约定的符号、标志、专用语解释

在本文中可能出现如下符号、标志,它们所代表的含义如下:

image1 危险

表示有高度危险,如果不能避免,可能导致人员伤亡或严重伤害

image2 警告

表示有中度或低 度潜在危险,如果不能避免,可能导致人员轻微或中等伤害

image3 注意

表示有潜在风险,如果忽视这部分文本,可能 导致设备损坏、数据丢失、设备性能降低或不可预知的结果

image4 防静电

防静电标识,表示静电敏感的设备或操作

image5 当心触电

电击防护标识,标识高压危险,需做好防护

image6 窍门

表示能帮助您解决某个问题或节省您的时间

image7 说明

表示是正文的附加信息,是对正文的强调和补充

缩略语

BMDNN

BM Deep Neural Network library

深度学习层 (layer)级别的加速库

JPU

JPEG Process Unit

JPEG处理单元

VPP

Video Post Process

图像后处理

VPU

Video Process Unit

视频编解码单元

修改记录

文档版本

发布日期

修订说明

对 应硬件版本

对 应软件版本

V0.1

2022-07-13

首 次正式发布

BM1684X EVB:V1.1

0.2.3

声明

Copyright ©️2022 北京算能科技有限公司。

我们对本产品手册及其中的内容具有全部的知识产权。除非特别授权,禁止复制或向第三方分发。凡侵犯本公司版权等知识产权权益的行为,本公司保留依法追究其法律责任的权利。

本产品系列将有不断地更新迭代,我们将定期检查本产品手册中的内容,在后续的版本中将出现不可避免的修正、删减、补充。

我们保留在不事先通知的情况下进行技术改进、文档变更、产品改进升级、增加或减少产品型号和功能的权利。

硬件安装

板卡安装

BM1684X AI计算模组仅指包括BM1684X、LPDDR4X、eMMC等核心组件的板卡,如下图:

BM1684X EVB 正面

_images/image8.png

BM1684X EVB 背面

_images/image9.png

各部件位置指示图如下:

_images/image51.jpg

为方便后面的描述,下文以“核心板”指代这块板卡。

附件安装

为方便调试,建议您准备如下附件:

  1. USB转UART线缆一条:核心板引出的UART0(UART for BM1684X)为调试口,TTL电平,波特率115200,8比特数据,1比特停止位,无奇偶校验,无硬件流控。

  2. 以太网线缆一条:接以太网口0(eth0),预装系统默认设置为DHCP,所以将 BM1684X 通过eth0和您的调试机都部署在同一路由器下比较方便。

  3. SD卡一张:刷机或调试时使用,建议8GB/class10或更高规格。

  4. image8与您的底板设计相匹配的电源:如果您使用我们提供的参考底板,配套直流电源输出为12V/10A,5.5*2.1mm母头,中心为正极。

  5. 散热:请安装散热片、风扇等必要的散热设备,以免出现过热关机等异常状况。

上电开机

一切就绪后,您就可以为底板加电了,如果您使用我们提供的参考底板,请先插上电源,然后拨电源键(此时从串口终端应该也应可以看到log打印了),指示灯正常状态如下:

_images/image12.png

请检查您的串口终端,BM1684X 出厂时已经预装Ubuntu 20.04系统,初始用户名和密码均为linaro(root账户无初始密码,使用前需要先用linaro账户做sudo passwd root设置密码):

bm1684 login: linaro
Password:
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.202-bm1684 aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

 * Super-optimized for small spaces - read how we shrank the memory
   footprint of MicroK8s to make it the smallest full K8s around.

   https://ubuntu.com/blog/microk8s-memory-optimisation
overlay / overlay rw,relatime,lowerdir=/media/root-ro,upperdir=/media/root-rw/
overlay,workdir=/media/root-rw/overlay-workdir 0 0
/dev/mmcblk0p5 /media/root-rw ext4 rw,relatime 0 0
/dev/mmcblk0p4 /media/root-ro ext4 ro,relatime 0 0

Last login: Mon Jul 11 11:30:26 CST 2022 from 192.168.0.105 on pts/0
linaro@bm1684:~$

检查IP地址请使用ifconfig或ip a命令:

ifconfig
ip a

如果需要手工配置静态IP,可按如下方法修改/etc/netplan/01-netcfg.yaml配置文件,并使能所修改的配置文件:

$ cat /etc/netplan/01-netcfg.yaml
network:
        version: 2
        renderer: networkd
        ethernets:
                eth0:
                        dhcp4: no                        # 静态IP需要改成no, 动态IP则为yes
                        addresses: [192.168.1.100/24]    # 加上IP,动态ip则中括号内放空即可
                        optional: yes
                        dhcp-identifier: mac             # 静态IP需要删掉这行
                eth1:
                        dhcp4: no
                        addresses: [192.168.150.1/24]
                        optional: yes
                enp3s0:
                        dhcp4: yes
                        addresses: []
                        dhcp-identifier: mac
                        optional: yes
$ sudo netplan try      # 测试配置是否可用
$ sudo netplan apply    # 使能最新配置

拿到IP地址后就可以使用ssh登录了,端口号为22,用户名密码同样均为linaro。

ssh linaro@your_ip

关机时建议使用sudo poweroff命令,尽量避免直接断电,以免文件系统损坏。image9

核心板有两个网卡,eth0默认为DHCP,故您需要通过上述方法获取IP。eth1默认配置为静态IP:192.168.150.1。

软件安装

检查预装版本

BM1684X 出厂时已经预装系统软件,在Ubuntu下可通过如下命令检查其版本:

  1. 查看Linux kernel版本:bm_version

    $ bm_version
    sophon-mw-soc-sophon-ffmpeg : 0.2.3
    sophon-mw-soc-sophon-opencv : 0.2.3
    sophon-soc-libsophon : 0.2.3
    boot_loader_version_bl1: v2.7(release):075b939dc-dirty Built : 14:30:23, Sep 15 2022
    boot_loader_version_bl2: v2.7(release):075b939dc-dirty Built : 14:30:23, Sep 15 2022
    boot_loader_version_bl31: v2.7(release):075b939dc-dirty Built : 14:30:23, Sep 15 2022
    boot_loader_version_uboot: U-Boot 2022.07 075b939dc-dirty (Sep 15 2022 - 14:37:14 +0800) Sophon BM1684
    KernelVersion : Linux bm1684 5.4.202-bm1684 #2 SMP PREEMPT Wed Jul 6 01:55:57
    UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
    HWVersion: 0x00
    MCUVersion: 0x03
    

    sophon-mw-soc-sophon-ffmpeg、sophon-mw-soc-sophon-opencv和sophon-soc-libsophon后面的信息为SOPHON SDK的版本号,boot_loader_version后面的信息分别为bl1、bl2、bl31和uboot的bootloader版本号及build时间,KernelVersion字段即为Kernel版本信息, 5.4.202表示官方Linux Kernel确切版本号, 后半部分的时间戳代表build时间。 MCUVersion字段即为MCU firmware版本号。

软件更新

BM1684X 目前提供三种更新方式:SD卡刷机, 文件替换 和 OTA升级。其中SD卡刷机会重写整个eMMC,也即您存储在eMMC的数据全部会丢失。这种方式最为干净可靠,理论上只要您的 BM1684X 没有硬件损坏,都可以进行SD卡刷机。文件替换方式是指在Ubuntu下通过替换对应文件的方式分别升级bootloader、kernel和其它软件。这种方式有一定的风险,如不同软件组件之间的版本匹配、文件损坏等。以下分别介绍三种软件更新方式的操作:

  1. SD卡刷机

请将SD卡格式化为FAT32格式(如果SD卡上有多个分区,只能使用第一个分区),大小为1GB以上。

请下载 BM1684X 最新刷机包,地址请见FAQ节:

请将下载的压缩包解压到SD卡根目录。确认文件如下(数量不一定相同):

_images/image18.png

请将 BM1684X 断电,插入SD卡,并连接串口终端,然后给 BM1684X 上电。您将看到 BM1684X 自动进入刷机流程:

_images/image19.png

刷机通常耗时约3分钟,结束后,会看到拔掉SD卡并重启 BM1684X 的提示,请依照操作即可:

_images/image20.png

请注意:刷机后Ubuntu系统第一次启动时会进行文件系统初始化等关键动作,请勿随意断电,待开机进入命令行后使用sudo poweroff命令关机。

  1. 文件替换

文件替换均在Ubuntu下执行,您可以选择使用串口或SSH终端。以下分别介绍如何替换各个组件。

替换bootloader:请将您要更新的spi_flash.bin文件上传到 BM1684X ,然后执行sudo flash_update -i ./spi_flash.bin -b 0x6000000,成功后可以看到如下log:

_images/image21.png

可以执行flash_update查看帮助:

_images/image90.png

替换kernel:将您要更新的emmcboot.itb放入/boot中替换同名文件,再sudo reboot即可。

替换bmnnsdk2运行时环境:bmnnsdk2运行时环境位于/opt目录下,请将您拿到的更新包(通常是一个名为opt.tgz的压缩包)整体替换即可,解压时请留意相对路径。

警告

做完上述文件操作后不要马上暴力断电,否则可能会有文件损坏,请执行sync、sudo reboot、sudo poweroff等动作。image10

  1. OTA升级

按如下步骤可进行OTA升级:

  1. 使用sdcard的升级包作为ota升级包, 将升级包里的所有内容拷贝到/data/ota目录底下

  2. 把local_update.sh脚本拷贝到盒子/data/ota目录下

  3. 盒子上执行如下命令:

    sudo -i
    ./local_update.sh md5.txt
    

    如果遇到local_update.sh 没有执行权限,使用如下命令增加权限:

    chmod +x local_update.sh
    
#!/bin/bash

if [ $# -lt 1  ] ; then
        echo "need md5 file"
        exit
fi

echo ">>>>>start upgrade app package..."

echo ">>>>>md5sum check ..."

basepath=$(cd `dirname $0`; pwd)
echo $basepath
cd $basepath

md5sum -c $1 > ota_versino.txt
ret=$?
count=$#
rootpath="/data/ota"
if [ $ret -ne 0 ]; then
    echo ">>>>> upgrade package is wrong stop upgrade..."
    echo "update failed"
else
    echo ">>>>>upgrade package starting..."
    # backup user information
    echo ">>>>>backup user information..."
    rm -rf ${rootpath}/public_ota/backup
    mkdir -p ${rootpath}/public_ota/backup

    # update boot-loader
    #sudo flash_update -i spi_flash.bin -b 0x06000000 -f 0x0
    #sudo flash_update -i fip.bin -b 0x6000000 -f 0x40000
    # upgrade mcu
    #sudo mcu-util-aarch64 upgrade 1 0x17 sa5-mcu*.bin

    # private ota :boot-recovery /data/ota/startup.sh\nprivate_update"
    echo -e "boot-recovery\n/DATA/ota" > /dev/mmcblk0p3
    echo "update success"

    sudo reboot
fi

image11替换MCU固件:核心板上有一颗MCU负责 BM1684X 的上电时序等重要工作,它的固件只能通过下面的命令升级,不能通过SD卡升级。这颗MCU的固件如果烧写错误,会造成 BM1684X 无法上电,此时就只能通过专用的烧写器进行修复了,因此请谨慎操作,通常也并不需要对它进行升级。命令:sudo mcu-util-aarch64 upgrade 1 0x17 bm1686evb-mcu.bin。升级完成后请执行sudo poweroff,待关机动作完成后(串口会打印NOTICE: CPU0 bm_system_off,并且盒子的风扇声音会突然变大)对盒子进行断电后重新上电。

系统软件构成

启动流程

BM1684X 的系统软件属于典型的嵌入式ARM64 Linux,由bootloader、kernel、ramdisk和Ubuntu 20.04 构成,当开机后,依次执行如下:

_images/image22.png

其中:boot ROM、bootloader基于arm-trusted-firmware和u-boot构建;kernel基于Linux的5.4分支构建;Ubuntu 20.04 基于Ubuntu官方arm64源构建,不包含GUI相关组件。

eMMC分区

分区设备文件

挂载点

文件系统

内容

/dev/mmcblk0p1

/boot

FAT32

存放kernel和ramdisk镜像

/dev/mmcblk0p2

/recovery

EXT4

存放recovery mode镜像

/dev/mmcblk0p3

存放配置信息,目前未使用

/dev/mmcblk0p4

/media/root-ro

EXT4

Ubuntu 20.04 系统的read-only部分

/dev/mmcblk0p5

/media/root-rw

EXT4

Ubuntu 20.04 系统的read-write部分

/dev/mmcblk0p6

/opt

EXT4

存放bmnn sdk2的驱动和运行时环境

/dev/mmcblk0p7

/data

EXT4

存放用户数据,SOPHON预装 软件包未使用

关于第四和第五分区的说明:第四分区存储了Ubuntu 20.04 系统的关键部分,挂载为只读;第五分区存储Ubuntu 20.04 运行过程中产生的文件,挂载为可读可写。两个分区通过overlayfs聚合后挂载为系统的根目录,如下图所示:

_images/image23.png

用户通常无需关注此细节,对于日常使用来说是透明的,正常操作根目录下文件即可,但当用df等命令查看分区使用率等操作时请知悉此处,如下图:

_images/image24.png

docker

核心板系统已经预装了docker服务,您可以用docker info命令查看状态。注意docker的根目录被配置到了/data/docker目录下,与默认设置不同。

文件系统支持

如果您使用参考底板,当插入U盘或者移动硬盘后(需考虑USB供电能力),存储设备会被识别为/dev/sdb1或类似节点,与桌面PC Linux环境下相同。文件系统支持FAT、FAT32、EXT2/3/4、NTFS。 BM1684X 不支持自动挂载,所以需要手工进行挂载:sudo mount /dev/sdb1 /mnt。当访问NTFS格式的存储设备时,预装的内核版本仅支持读取,如果需要写入,需要手工安装ntfs-3g软件包,请参考https://wiki.debian.org/NTFS。完成数据写入后,请及时使用sync或umount操作,关机时请使用sudo poweroff命令,避免暴力下电关机,以免数据丢失。

修改SN和MAC地址

BM1684X 的SN和MAC地址存放在MCU的EEPROM中,你可以通过如下方式进行修改。

首先需要解锁MCU EEPROM:

sudo -i
echo 0 > /sys/devices/platform/5001c000.i2c/i2c-1/1-0017/lock

写入SN:

echo "HQATEVBAIAIAI0001" > sn.txt
dd if=sn.txt of=/sys/bus/nvmem/devices/1-006a0/nvmem count=17 bs=1

写入MAC(双网卡各有一个MAC):

echo "E0A509261417" > mac0.txt
xxd -p -u -r mac0.txt > mac0.bin
dd if=mac0.bin of=/sys/bus/nvmem/devices/1-006a0/nvmem count=6 bs=1 seek=32
echo "E0A509261418" > mac1.txt
xxd -p -u -r mac1.txt > mac1.bin
dd if=mac1.bin of=/sys/bus/nvmem/devices/1-006a0/nvmem count=6 bs=1 seek=64

最后重新对MCU EEPROM加锁,以避免意外改写:

echo 1 > /sys/devices/platform/5001c000.i2c/i2c-1/1-0017/lock

新的MAC地址将在重启系统后生效。

读写eFuse

eFuse寻址

BM1684X内置的eFuse共4096bit,按照128×32bit来组织,即地址范围0~127,每个地址表示一个32bit的存储单元。eFuse的每个bit初始值都是0,用户可以将其从0修改成1,但之后无法再从1修改成0,比如您对地址0先写入0x1,再写入0x2,那么最后得到的是0x1|0x2=0x3。

为了保证存储信息的可靠性,eFuse中的信息通常都会存储两份,称为double bit机制,当两份拷贝中有任意一份为1时,即认为对应的bit为1,即result = copy_a OR copy_b。有两种存储形式:

  1. 在一个32bit存储单元内进行double bit,即奇数bit(1、3、5、7……)和偶数bit(0、2、4、6……)组成double bit,比如约定地址0的bit0和bit1,其中只要有一个为1就使能secure firewall。这种形式的double bit用于硬件功能控制。

  2. 若干个32bit存储单元与另外若干个存储单元组成double bit。比如约定SN = address[48] OR address[49]。这种形式的double bit用于软件定义信息的存储。

eFuse分区

eFuse里的一些地址有指定的用途,如下表:

地     址

内     容

0
bits[1] | [0]:使能secure firewall
bits[3] | [2]:禁用JTAG
bits[5] | [4]:禁止从片外SPI flash启动
bits[7] | [6]:使能secure boot

1

bit[0] | bit[1]:使能secure key

2~9

256bit secure key

10~17

256bit secure key副本

18~25

256bit secure boot使用的root public key digest

26~33

256bit secure boot使用的root public key digest副本

54~57

128bit 客户自定义ID

58~61

128bit 客户自定义ID的副本

34~45

芯片生产测试信息预留区域

64~82

芯片生产测试信息预留区域

其余未注明区域目前没有特定用途,可以用作存储或实验之用。

eFuse工具

BM1684X 中预装了一个eFuse读写工具,读写操作命令如下:

sudo efuse -r 0x? -l 0x? 即可以返回从该地址开始存储的若干个32bit值;

sudo efuse -w 0x? -v 0x? 即可在该地址写入指定的32bit值。

以上数值均只支持十六进制数。

系统接口使用

BM1684X 的CPU占用率、内存使用率等信息均可使用标准的Linux sysfs、procfs节点,或top等工具读取。以下仅介绍 BM1684X 特有的一些接口或硬件使用方式。

读取核心板序列号

命令:

cat /sys/bus/i2c/devices/1-0017/information

返回(json格式字符串):

{
        "model": "BM1684X EVB",
        "chip": "BM1684X",
        "mcu": "STM32",
        "product sn": "",
        "board type": "0x20",
        "mcu version": "0x03",
        "pcb version": "0x00",
        "reset count": 0
}

读取BM1684X芯片温度

命令:

cat /sys/class/thermal/thermal_zone0/temp

返回(单位为毫摄氏度):

38745

即38.745摄氏度。

Linux的thermal框架会使用这个温度做管理:

  1. 普通版模组:当温度升到85度时,TPU频率会降到80%,CPU降频到1.15GHz;当温度回落到80度时,TPU频率会恢复到100%,CPU频率恢复到2.3GHz;当温度升到90度时,TPU频率会降到最低挡位;当温度升到95度时,会自动关机。

  2. 宽温版模组:当温度升到95度时,TPU频率会降到80%,CPU降频到1.15GHz;当温度回落到90度时,TPU频率会恢复到100%,CPU频率恢复到2.3GHz;当温度升到105度时,TPU频率会降到最低挡位;当温度升到110度时,会自动关机。

另外,片外的MCU也会使用这个温度来做最后的保险机制:

  1. 普通版模组:芯片结温大于95度,并且板上温度大于85度时强制关机。

  2. 宽温版模组:芯片结温大于120度时强制关机。

读取核心板温度

命令:

cat /sys/class/thermal/thermal_zone1/temp

返回(单位为毫摄氏度):

37375

即37.375摄氏度。

核心板温度通常会比前面读取的芯片内部温度低。

读取功耗信息

命令:

sudo pmbus -d 0 -s 0x50 -i

返回:

I2C port 0, addr 0x50, type 0x3, reg 0x0, value 0x0
ISL68127 revision 0x33
ISL68127 switch to output 0, ret=0
ISL68127 output voltage: 749mV
ISL68127 output current: 2700mA
ISL68127 temperature 1: 59°C
ISL68127 output power: 2W → TPU功耗
ISL68127 switch to output 1, ret=0
ISL68127 output voltage: 898mV
ISL68127 output current: 2900mA
ISL68127 temperature 1: 58°C
ISL68127 output power: 2W → CPU/Video等功耗

使用GPIO

BM1684X 芯片包含3组GPIO控制器,每个控制32根GPIO,与Linux的设备节点对应如下:

GPIO 控制器

Linux设备节点

GPIO 物理编号

GPIO逻辑编号

#0

/sys/class /gpio/gpiochip480

0到31

480到511

#1

/sys/class /gpio/gpiochip448

32到63

448到479

#2

/sys/class /gpio/gpiochip416

64到95

416到447

比如您需要操作电路图上标号为GPIO29的pin,则需要:

sudo -i
echo 509 > /sys/class/gpio/export

然后就可以按照标准方式操作/sys/class/gpio/gpio509下的节点了。

请注意,由于pin是复用的,并不是全部96根GPIO都可以使用,请与硬件设计结合确认。

使用UART

BM1684X 的144pin BTB接口上提供了3组UART,其中UART0已用作bootloader和Linux的console端口。

使用I2C

BM1684X 的144pin BTB接口上提供了1组I2C master,对应设备节点为/dev/i2c-2,可以使用标准的I2C tools和API操作。

在我们的参考底板上, BM1684X 通过这组I2C连接了底板上的RTC芯片。

使用PWM

警告

TODO: evb板子风扇转速没法控制,需要更换硬件,待硬件完善后更新此章节

BM1684X 的144pin BTB接口上提供了1个PWM输出引脚,对应PWM0:

sudo -i
echo 0 > /sys/class/pwm/pwmchip0/export
echo 0 > /sys/class/pwm/pwmchip0/pwm0/enable

配置:

echo %d > /sys/class/pwm/pwmchip0/pwm0/period
echo %d > /sys/class/pwm/pwmchip0/pwm0/duty_cycle

使能:

echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable

在我们的参考底板上,这个PWM输出被用作风扇调速,Linux的thermal框架会自动根据芯片温度调整风扇转速。所以您会在第一步export时看到Device or resource busy错误,需要修改device tree把对应的pwmfan节点disable掉后才能自由使用:

pwmfan: pwm-fan {
   compatible = "pwm-fan";
   pwms = <&pwm 0 40000>, <&pwm 1 40000>; // period_ns
   pwm-names = "pwm0","pwm1";
   pwm_inuse = "pwm0";
   #cooling-cells = <2>;
   cooling-levels = <255 153 128 77 26 1>; //total 255
};

风扇测速

警告

EVB板上需要更换风扇才能调节转速

BM1684X 的144pin BTB接口上提供了1个风扇测速输入引脚,可以采样风扇的转速输出方波频率,对照风扇手册上频率与转速的换算公式即可计算出实际转速。

使能:

sudo -i
echo 1 > /sys/class/bm-tach/bm-tach-0/enable

读取方波频率:

cat /sys/class/bm-tach/bm-tach-0/fan_speed

同时提供了一个netlink事件,当风扇停转时告警,示例代码可以从bsp-sdk/linux-bitmain/tools/fan_alert获取。

查询内存用量

BM1684X 板载了16GB DDR,可以分为三类:

  1. kernel管理的部分,即可以用malloc、kmalloc等常规API分配出来使用。

  2. ION管理的部分,预留给TPU、VPU、VPP使用,需要使用ION的ionctl接口,或使用bmnnsdk2中bmlib库提供的接口分配出来使用。

  3. 预留给固件的部分,用户无法使用。

您可以使用如下方式检查各部分内存的用量:

  1. 查看系统内存

    linaro@bm1684:~$ free -h
                  total        used        free      shared  buff/cache   available
    Mem:          6.6Gi       230Mi       6.2Gi       1.0Mi       230Mi       6.3Gi
    Swap:            0B          0B          0B
    
  2. 查看ION内存

    sudo -i
    root@bm1684:~# cat /sys/kernel/debug/ion/bm_npu_heap_dump/summary  | head -2
    Summary:
    [0] npu heap size:4141875200 bytes, used:0 bytes        usage rate:0%, memory usage peak
    0 bytes
    
    root@bm1684:~# cat /sys/kernel/debug/ion/bm_vpu_heap_dump/summary  | head -2
    Summary:
    [2] vpu heap size:2147483648 bytes, used:0 bytes        usage rate:0%, memory usage peak
    0 bytes
    
    root@bm1684:~# cat /sys/kernel/debug/ion/bm_vpp_heap_dump/summary  | head -2
    Summary:
    [1] vpp heap size:3221225472 bytes, used:0 bytes        usage rate:0%, memory usage peak
    0 bytes
    

    如上,通常会有3个ION heap(即三块预留的内存区域),如名字所示,分别供TPU、VPU、VPP使用。以上示例中只打印了每个heap使用信息的开头,如果完整地cat summary文件,可以看到其中分配的每块buffer的地址和大小信息。

Sophon SDK3介绍

有关Sophon SDK3详细介绍及示例代码,请查看如下链接:

系统定制

因为 BM1684X 的底板可以由您自行设计,我们提供了一个BSP SDK以便您对内核和Ubuntu 20.04系统进行定制,然后生成自己的SD卡或tftp刷机包。由于3.0.0版本后我们修改了bootloader的代码,导致无法使用tftp从3.0.0及以前的版本升级到0.2.3及以后的版本,这种情况下请使用sd卡刷机升级。因为 BM1684X 核心板是制成品,故bootloader并未开放,如果需要定制请联系技术支持。

如果您只是希望部署自己的业务软件,并不涉及硬件修改,那么出于解耦的考虑,更推荐您把自己的业务软件打包成一个deb安装包。比如包含您的业务软件执行程序、依赖库、开机自启动服务等等,deb安装包里还可以放一个安装时自动执行的脚本,在安装时做一些配置文件修改替换之类的操作。这样您可以单独安装、卸载、升级您的业务软件,避免与我们系统包版本的依赖问题,对产品部署后的批量更新等操作也更友好。deb安装包的制作可以参考Debian官方文档,或其他网上资料。

文件结构

BSP SDK包含两部分,请参考Sophon SDK3介绍章节的下载地址,一部分为gitee网站上发布的源码文件,另一部分基本不会改动的二进制文件,为避免影响git效率,是通过百度网盘发布的。请参考源码文件的README.md中的描述将两部分合并,将看到如下文件:

top
├── bootloader-arm64
│   └── scripts
│       └── envsetup.sh → 编译脚本入口
│   ├── trusted-firmware-a → TF-A源代码
│   ├── u-boot → u-boot源代码
│   └── ramdisk
│       └── build → ramdisk的cpio文件和u-boot启动脚本文件
├── debian
│   ├── distro_focal_20220328.tgz → Ubuntu 20.04底包
│   └── overlay → 对Ubuntu 20.04底包的修改文件
├── gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu → 交叉编译工具链
├── linux-bitmain → kernel源代码
└── install
    └── soc_bm1684
        └── opt.tgz → bmnnsdk2 runtime

交叉编译

推荐在Ubuntu 20.04系统下进行交叉编译,不支持X86_64以外的架构。请预留至少10GB空闲磁盘空间,并请先安装必要的一些工具:

sudo apt install cmake libssl-dev fakeroot dpkg-dev device-tree-compiler u-boot-tools

进入到BSP SDK后,执行如下命令即可编译出SD卡和tftp刷机用的刷机包:

source bootloader-arm64/scripts/envsetup.sh
build_bsp
# build_update tftp 必须在 build_bsp之后执行
build_update tftp

因为脚本中使用了sudo,编译过程中可能会提示您输入当前用户密码。第一次编译时可能遇到各种问题,如结果不符合预期,请仔细检查编译log,如果有遇到提示某某工具找不到的话,用apt install安装即可。

编译结果在install/soc_bm1684目录下,重点有如下几个文件(夹):

sdcard → SD卡刷机包,请参阅2.2节的使用说明a;

tftp → tftp刷机包,请参阅算能官方网站文档中心的Sophon设备和SDK使用
常见问题及解答相关章节的使用说明;

emmcboot.itb → kernel和ramdisk、dtb打包在一起,请参阅2.2节的使用说明b;

spi_flash.bin → bootloader,请参阅2.2节的使用说明b;

rootfs → 根文件系统内容;

如果只是想更新内核的话,可以用如下命令:

build_kernel
build_ramdisk uclibc emmc

即可得到新的emmcboot.itb。不建议您直接到linux-bitmain目录下手敲make,除非您非常清楚如何操作。

内核的编译结果在如下路径:

linux-bitmain/build/bm1684/normal

编译出的ko可以在如下路径找到:

linux-bitmain/build/bm1684/normal/modules/lib/modules/5.4.202-bm1684/kernel

两个路径下的内容是一样的,默认已经打进刷机包。

编译出的linux-header安装包(用于在板卡上编译kernel module)可以在如下路径找到:

linux-bitmain/build/bm1684/normal/bm1684_asic/linux-dev

默认已经打进刷机包,即板卡上的/home/linaro/linux-dev目录。

修改kernel

kernel的配置文件在:

linux-bitmain/arch/arm64/configs/bitmain_bm1684_normal_defconfig

请注意修改kernel config可能会造成您的kernel与我们通过二进制发布的驱动文件(板上/opt/sophon/libsophon-current/data/下的bmtpu.ko、vpu.ko、jpu.ko)无法兼容。

标准版 BM1684X 使用的设备树文件在:

linux-bitmain/arch/arm64/boot/dts/bitmain/bm1684x_evb_v0.0.dts

修改之后请执行:

build_kernel
build_ramdisk uclibc emmc

得到新的emmcboot.itb文件即包含了全部kernel code和device tree的修改。请替换到板卡的/boot目录下并重启即可。

要注意的是,如果您把自己的emmcboot.itb部署到了板卡上,可能会造成板卡上预装的内容与您当前的内核镜像版本不一致。如果遇到兼容性问题,请把您编译主机上的install/soc_bm1684/rootfs下的/home/linaro/linux-dev和/lib/module两个目录也一起替换到板卡上即可。使用tftp或SD卡刷机包的话通常不会有这个问题,因为刷机包生成时总是会同步更新这些文件。

如果您使用的是 BM1684X 的某种变体,可以通过如下方式找到对应的device tree文件:

观察开机后UART log里u-boot打印的日志:

...
...
NOTICE:  BL31: Built : 07:47:33, Jun 29 2022
INFO:    ARM GICv2 driver initialized
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x308000000
INFO:    SPSR = 0x3c9
found dtb@130: bitmain-bm1684x-evb-v0.0
Selecting config 'bitmain-bm1684x-evb-v0.0'
...
...

关注 Selecting config 这一行, 即可知道这块板子对应的device tree源文件是在linux-bitmain/arch/arm64/boot/dts/bitmain/目录下的**bm1684x_evb_v0.0.dts**。

修改Ubuntu 20.04

方式一:利用Ubuntu系统源码包进行修改

Ubuntu 20.04系统的生成过程是这样:

  1. debian/distro_focal_lite_20211018.tgz是Ubuntu官方纯净版底包, debian/distro_focal_20220328.tgz是我们内部修改过的底包。

  2. debian/overlay/soc_bm1684_asic_newos下包含了 BM1684X 对底包的修改,会覆盖到底包的同名路径。

  3. kernel编译的过程中也会把ko等文件更新进去。

  4. 如果install/soc_bm1684目录下有opt.tgz文件,则刷机包生成过程中会把它作为/opt目录下的内容。

  5. 如果install/soc_bm1684目录下有data.tgz文件,则刷机包生成过程中会把它作为/data目录下的内容。

所以您可以在overlay/soc_bm1684_asic_newos加入您自己的改动,比如放入一些工具软件,修改以太网配置文件等等,然后重新生成刷机包。

如果您有一个或多个deb想要预装到Ubuntu 20.04,那么有两种做法:

  1. 如果deb包比较简单,您可以直接将它解压缩后把里面的文件copy到overlay/soc_bm1684_asic_newos下的对应目录。

  2. 将deb包直接放到overlay/soc_bm1684_asic_newos/root/post_install/debs目录,则 BM1684X 在刷机后第一次开机时会把这些deb包都安装上。

方式二:利用qemu虚拟机方式进行修改

(1)环境准备

  1. 从官网获取sdcard.tgz基础软件包。

  2. 解压sdcard.tgz到sdcard 文件夹。

    mkdir sdcard
    tar -zxf sdcard.tgz -m -C sdcard
    
  3. 将bootloader-arm64/scripts/revert_package.sh复制到sdcard目录下,然后制作rootfs.tgz软件包。

    cd sdcard
    sudo ./revert_package.sh rootfs
    
  4. 在sdcard的同级目录中新建rootfs文件夹,并把sdcard/rootfs.tgz解压到rootfs文件夹下。

    mkdir rootfs
    sudo tar -zxf sdcard/rootfs.tgz -m -C rootfs
    
  5. 安装qemu虚拟机。

    sudo apt-get install qemu-user-static
    

(2)操作步骤

  1. 进入rootfs目录,开启qemu虚拟机。

    cd rootfs
    sudo chroot . qemu-aarch64-static /bin/bash
    
  2. 在虚拟机中安装好所需的lib以及工具后,例如apt-get install nginx,安装完毕后执行exit退出虚拟机。

  3. 在rootfs目录下打包修改后的rootfs文件系统,得到新的rootfs.tgz压缩包。

    sudo tar -cvpzf rootfs.tgz ./*
    
  4. 将新生成的rootfs.tgz软件包替换掉install/soc_bm1684/下的rootfs.tgz,然后根据需要重新编译刷机包。

    build_update sdcard  // 重新编译sdcard刷机包
    build_update tftp    // 重新编译tftp刷机包
    

在 BM1684X 上编译内核模块

您也可以选择直接在 BM1684X 板卡上直接编译kernel module,可以省去上述搭建交叉编译环境的麻烦。步骤如下:

  1. uname -r得到kernel版本号,与/home/linaro/linux-dev和/lib/modules里面的文件名比较,确保一致

  2. 因为kernel在交叉编译环境下做make bindeb-pkg的缺陷,需要再额外做如下处理:

    1. 用date命令检查当前系统时间,如果跟实际时间相差太多,请设置为当前时间,如

      sudo date -s "01:01:01 2021-03-01"
      
    2. 检查是否存在/home/linaro/linux-dev/debs/install.sh,如果有的话,执行它即可

    3. 如果没有的话,需要手工操作:

      sudo dpkg -i /home/linaro/linux-dev/linux-headers-*.deb
      sudo mkdir -p /usr/src/linux-headers-$(uname -r)/tools/include/tools
      sudo cp /home/linaro/linux-dev/*.h /usr/src/linux-headers-$(uname-r)/tools/
      include/tools
      cd /usr/src/linux-headers-$(uname -r)
      sudo apt update
      sudo apt-get install -y build-essential bc bison flex libssl-dev
      sudo make scripts
      
  3. 回到您的driver目录,make ko吧

修改分区表

BM1684X 使用GPT分区表。分区表的配置文件在bootloader-arm64/scripts/partition32G.xml,其中依次描述了每个分区的大小信息。不建议您修改分区的顺序和个数,以及readonly和format属性,以免与其它一些预装脚本中的写法发生冲突。您可以修改每个分区的大小。最后一个分区的大小不需要凑满eMMC实际容量,可以把它设成一个比较小的值,只要足够存放您准备预装的文件(即data.tgz解开后的内容)就可以。刷机后第一次开机时,会有一个脚本将这个分区自动扩大到填满eMMC的全部剩余可用空间。

修改u-boot

u-boot的配置文件在:

u-boot/configs/bitmain_bm1684_defconfig

板级头文件在:

u-boot/include/configs/bitmain_bm1684.h

板级C文件在:

u-boot/board/bitmain/bm1684/board.c

标准版 BM1684X 对应的dts文件是:

u-boot/arch/arm/dts/bitmain-bm1684x-evb-v0.0.dts

修改之后请执行:

build_fip

得到新的spi_flash.bin,请将此文件放置到板卡上,参考2.2.b中的方式用flash_update工具更新后重启系统即可。

如果您使用的是 BM1684X 的某种变体,可以通过如下方式找到对应的device tree文件,请注意这个是u-boot自身使用的device tree,并非kernel使用的device tree:

观察开机后UART log里u-boot打印的日志:

...
...
NOTICE:  BL31: Built : 07:47:33, Jun 29 2022
INFO:    ARM GICv2 driver initialized
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x308000000
INFO:    SPSR = 0x3c9
found dtb@130: bitmain-bm1684x-evb-v0.0
Selecting config 'bitmain-bm1684x-evb-v0.0'
...
...

关注 Selecting config 这一行, 即可知道这块板子对应的device tree源文件是在u-boot/arch/arm/dts/ 目录下的 bitmain-bm1684x-evb-v0.0.dts.

1684x kdump-crash使用说明

本文记录了如何在1684x ubuntu20.04上使用kexec/kdump-tools生成linux kernel coredump文件,并用crash分析该coredump文件。

1.环境准备

1)X86主机

a) sd卡 - 32G 以上容量, coredump文件比较大,压缩的coredump文件,9GB左右,非压缩的,16GB左右(等于ram大小)
b) crash(https://github.com/crash-utility/crash/tags 选择8.0以上版本,x86主机编译命令:make target=ARM64)或者使用随本文一起发布的crash命令,使用crash前需要在Ubuntu上安装libncursesw6,libtinfo6,liblzma5,bison,libncurses-dev
c) vmlinux(与板子运行内核一致的,带有调试信息的内核文件,可以从1684x的/home/linaro/bsp-debs/linux-image-*-dbg.deb 中获取,在linux主机解压:dpkg-deb -R linux-image-*-dbg.deb linux-image-*-dbg,解压后在/linux-image-*-dbg/usr/lib/debug/lib/modules/*/中,*代表内核版本号)

2)1684x

a)进入u-boot模式(1684x开机迅速点击回车键)

添加linux kernel参数crashkernel=512M;

bm1684# setenv othbootargs ${othbootargs}  "crashkernel=512M"
_images/image52.png

保存配置:

bm1684# saveenv
_images/image53.png

重启1684x 以下操作无特别说明,均是在1684x ubuntu环境。

b)sd card

创建sd卡mount目录

sudo mkdir /mnt/sdcard/

c)kexec/kdump-tools

系统已经安装kexec-tools,本文忽略它的安装

安装kdump-tools

sudo apt install kudmp-tools

由于kudmp-tools配置存储coredump文件在sd卡上,防止系统crash重启后,挂载sd卡失败,导致存储coredump文件到本地/mnt/sdcard/crash而非sd卡上,需要disable kdump-tool.service

sudo systemctl disable kdump-tools.service

修改kdump-tool配置

sudo vi /etc/default/kdump-tools
  KDUMP_COREDIR="/mnt/sdcard/crash"
    //去掉systemd.unit=kdump-tools-dump.service

  KDUMP_CMDLINE_APPEND="reset_devices
  nr_cpus=1"

d)makedumpfile

sudo apt install makedumpfile

由于该包中的makedumpfile(v1.6.7)命令有bug,需要使用随本文一起发布的 makedumpfile(v1.7.1)替换

sudo mv /usr/bin/makedumpfile  /usr/bin/makedumpfile
.orig

sudo cp /home/linaro/kdump/makedumpfile  /usr/bin/
makedumpfile

或者下载源码编译makedumpfile(https://github.com/makedumpfile/makedumpfile/tags

编译前需要安装libelf-dev libdw-dev libbz2-dev

选择1.7.1以上版本,在1684x ubuntu本地编译命令:make

e)crash kernel & initrd

由于kernel和initrd是被打包到itb中,所以需要从itb中解出,并拷贝到kdump-tool配置文件中指定的目录

mkdir /home/linaro/crash
dumpimage -T flat_dt -p 0 -o /home/linaro/crash/
vmlinuz-`uname -r` /boot/emmcboot.itb
dumpimage -T flat_dt -p 1 -o /home/linaro/crash/
initrd.img-`uname -r` /boot/emmcboot.itb

sudo cp /home/linaro/crash/vmlinuz-`uname -r` /boot/
sudo mkdir /var/lib/kdump
sudo cp /home/linaro/crash/initrd.img-`uname -r` /var/
lib/kdump

2.kdump/crash使用

1)kdump加载crash kernel并生成coredump文件

a)查看/proc/cmdline,查看crashkernel参数是否配置正确

_images/image54.png

b)加载crash kernel

sudo kdump-config load
_images/image55.png

c)kernel panic

插入SD卡
触发kenrel panic
sudo su

echo c > /proc/sysrq-trigger (触发kenrel panic,并重启系统)

d)存储coredump文件

系统重启后, 查看是否存在/proc/vmcore文件

_images/image56.png
sudo mount /dev/mmcblk1p1 /mnt/sdcard
//根据实际情况,使用正确的sd卡设备挂载目标文件
//可先用:fdisk -l 命令查看设备信息

sudo kdump-config savecore
_images/image57.png

2)crash 分析 crashdump文件

把sd卡插入linux主机,使用如下命令分析coredump文件

sudo ./crash ./vmlinux /mnt/sdcard/crash/202208100944/
vmcore.202208100944

您需要将/mnt/sdcard/替换成主机的SD卡路径

_images/image58.png