本文介绍如何在PC上搭建"Atlas 200I AI加速模块"的开发环境及编译,编译主机环境采用Ubuntu 22.04,Ascend310B的SDK采用25.2.0版本。下面默认SDK的默认目录是"Ascend310B-source",所有内核修改和编译操作以这个目录为准。
1、源码介绍
Atlas 200I AI加速模块所有源码和开发工具可以通过昇腾的官网获取。其中linux内核源码和交叉编译工具链,被统一打包在Ascend-hdk-310b-sdk-soc_25.2.0.zip中。对压缩包进行加压,"Ascend310B-source.tar.gz"是内核源码,toolchain.tar.gz交叉编译工具链。
解压源码到Ascend310B-sdk下。
bash
mkdir Ascend310B-sdk
tar -xvf Ascend310B-source.tar.gz -C Ascend310B-sdk
源码目录如下:
bash
abl/
build.sh* #编译用脚本
config/ #userBaseConfig相关
driver/ #驱动
dtb/ #设备树文件
kernel/ #linux内核源码、编译用脚本、内核补丁等文件
scripts/
tools/
执行"./build.sh"可看到编译各个模块需要带入的参数。
bash
./build.sh clean #build clean
./build.sh kernel #build kernel for Euler
./build.sh rtKernel #build kernel for openEuler-SP1
./build.sh dtb #build dtb
./build.sh usrBaseConfig #build usrBaseConfig
./build.sh hboot2 #build hboot2
./build.sh driver #build driver
./build.sh kernelSource #build kernelSource
./build.sh repack #build repack
2、安装交叉编译工具链
创建一个SDK目录,将toolchain.tar.gz解压到SDK目录下。
bash
tar -xvf toolchain.tar.gz -C Ascend310B-sdk
修改"Ascend310B-sdk/build.sh",添加交叉编译工具链到PATH路径。

"./build.sh kernel"尝试编译,如果交叉编译工具链提示glibc版本问题,可以尝试去昇腾官网找低版本的SDK中的工具链,替换现有的工具链。
3、启动流程

Hboot2:Hboot2程序出厂预置在Atlas 200I A2 加速模块的SFC Flash上,主要功能为根据BOOTSEL真值表选择启动介质以及从启动介质中加载Kernel、 DTB等程序。
userBaseConfig:userBaseConfig为用户弹性配置,用户可通过userBaseConfig灵活配置SerDes。
4.Hboot2
bash
apt-get install -y python3 make gcc unzip pigz bison flex libncurses-dev squashfstools bc device-tree-compiler libssl-dev cmake
tar -xzvf Ascend310B-hboot2-source.tar.gz
cd Ascend310B-hboot2-source
bash build.sh hboot2
复制编译生成的AS310B_HBOOT2_UEFI.fd到板子系统,然后在执行下面命令进行烧写。
bash
/var/davinci/driver/upgrade-tool --device_index 0 --component hboot2 -- path ./AS310B_HBOOT2_UEFI.fd
#命令执行成功提示:{"device": 0, "succeed"}
reboot 重启系统。
5.内核及驱动
- 设备树
dts统一被存放在"dtb/dts/hi1910b/hi1910BL",用户可根据自己的需要添加dts,然后根据boardid修改"hisi,boardid"属性。boardid由两部分组成可参考官方给的手册确定自己板子的boardid。下面以M100-B33为例添加dts。
bash
$ cp dtb/dts/hi1910b/hi1910BL/hi1910B-asic-M100-B51.dts dtb/dts/hi1910b/hi1910BL/hi1910B-asic-M100-B33.dts
$ vim dtb/dts/hi1910b/hi1910BL/hi1910B-asic-M100-B33.dts
/dts-v1/;
/ {
compatible = "hisilicon,hi1910B-evb", "hisilicon,ascend610";
hisi,boardid = <0x0 0x3 0x3 0x1 0x0 0x0>; //对应boardid
#address-cells = <0x2>;
#size-cells = <0x2>;
interrupt-parent = <0x1>;
model = "Hisilicon PhosphorHi1910B AI310B M100";
//省略部分代码
// /include/ "product/hi1910B-pcie-rc-M150-B33.dtsi" //先注释掉,防止配置和实际板子不一样,导致系统卡死或重启
//省略部分代码
$ vim dtb/dtbtool/CMakeLists.txt #将创建的dts添加到这个里面才能被编译。
#下面是CMakeLists.txt的部分代码
add_subdirectory(src)
set(DTS_BASE_DIR ${TOP_DIR}/dtb/dts)
if(PRODUCT STREQUAL "ascend310Besl" OR
PRODUCT STREQUAL "ascend310B" OR
PRODUCT STREQUAL "ascend310Bemu" OR
PRODUCT STREQUAL "ascend310Brc" OR
PRODUCT STREQUAL "ascend310Brcesl" OR
PRODUCT STREQUAL "ascend310Brcemu")
# 当前driver跟esl用相同的dts,后期需要更新到单独的目录
set(DTS_SRC_DIR ${DTS_BASE_DIR}/hi1910b/hi1910BL)
# 在下面这一个变量中添加hi1910B-asic-M100-B33.dts
set(DTS_FILE_LIST hi1910B-default.dts hi1910B-evb-900.dts hi1910B-evb-901.dts hi1910B-evb-902.dts hi1910B-evb-903.dts hi1910B-evb-905.dts hi1910B-asic-M150-B50.dts hi1910B-asic-M100-B51.dts hi1910B-asic-M150-B51.dts hi1910B-asic-M160-B51.dts hi1910B-asic-M100-B00.dts hi1910B-asic-M101-B00.dts hi1910B-asic-M150-B00.dts hi1910B-asic-M151-B00.dts hi1910B-asic-M160-B00.dts hi1910B-asic-M100-B33.dts)
set(OUT_DT_IMAGE dt.img)
elseif(PRODUCT STREQUAL "helper310p")
### 部分代码省略 ###
修改完成后执行"./build.sh dtb"进行编译,编译完成后会在output下生成dt.img,该镜像中会包含所有DTS_FILE_LIST指定的dts。
- 内核
进入SDK源码目录"Ascend310B-source",通过"./build.sh kernel"可对内核进行编译,内核源码以tarball的形式被放在SDK中(kernel/kernel/kernel/kernel.tar.gz),编译时会先将源码解压到"kernel/kernel/kernel/out/linux-4.19",接着为内核打入patch,patch被统一存放在"kernel/kernel/kernel/patches"中。patch合入后将开始内核的配置和编译,编译生成Image被放入"output/",被编译成KO的驱动存放在"output/kernel_modules/"或"output/modules/",kernel_modules中是以内核源码树的目录结构存放的,而modules中是将所有驱动KO放在一起统一存放。如果需要修改默认的defconfig配置文件请编辑修改"kernel/kernel/kernel/kbuild/defconfigs/arch/arm64/configs/ascend310B_defconfig"。
如何使驱动在系统启动时自动加载请参考"重构驱动run包"章节。 - 驱动
部分驱动未直接合入到内核的源码中,而是被存放在"driver/drivers/"下。可通过"./build.sh driver"命令将其编译成KO的形式。下面是添加一个新驱动的过程。
bash
$ mkdir -p driver/drivers/usr
$ vim driver/drivers/usr/hello.c
#include <linux/module.h>
#include <linux/kernel.h>
int __init hello_init(void)
{
printk("==========user hello mod init=========\n");
return 0;
}
void __exit hello_exit(void)
{
printk("===========user hello mod exit=========\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
bash
$ vim driver/drivers/usr/Makefile
ccflags-y += -Wall -Werror -Wtrampolines $(WDATE_TIME) -Wfloat-equal -Wvla -Wundef -funsigned-char -Wformat=2 -Wstack-usage=2048 -Wcast-align
ccflags-y += -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers
obj-m := hello.o
bash
$ vim driver/drivers/usr/module.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_KO_SRC_FOLDER := $(LOCAL_PATH)
LOCAL_INSTALLED_KO_FILES := hello.ko
include $(BUILD_DEVICE_KO)
bash
vim driver/build/product_modules/device-ctrlcpu.mk
#在原来的DRIVER_DEVICE_MODULES下面在添加一行
DRIVER_DEVICE_MODULES += hello.ko
修改完成后执行"build.sh driver",编译完成后会在"output/driver_modules"生成对应的ko.
如何使驱动在系统启动时自动加载请参考"重构驱动run包"。
6.userBaseConfig
user_base_config.xml位于"config/adaptive/adaptive_config/"下,用于配置SerDes。SerDes接口提供8条lane,可通过配置userBaseConfig中lane属性将SerDes复用为PCIe、 SATA、 USB或者ETH接口。
SerDes 支持标准:
- GE-1000BASE-R( 1.25Gbps), SGMII( 3.125Gbps/1.25Gbps,支持2.5GE和GE)。
- USB3.0( 5Gbps)。
- SATA3.0( 6Gbps),向下兼容SATA2.0( 3Gbps)和SATA1.0( 1.5Gbps)。
- PCIe Gen3( 8Gbps),向下兼容PCIe Gen2( 5Gbps)和PCIe Gen1( 2.5Gbps)。
- PCIe0支持RC/EP模式(通过PCIE_EP_RC_FLAG管脚配置),其他PCIe只支持RC模式
- Macro0中若存在PCIE和其他协议共存,则PCIe只能支持到PCIe Gen2。
- PCIe支持降lane应用,如PCIe x4降lane到PCIe x2/x1。
SerDes 复用关系表:


更多介绍可参见官方的硬件设计手册。
userBaseConfig配置说明:

SerDes配置,具体规则如下:
PCIe控制器0( lane0~lane1)支持RC/EP模式,其他PCIe控制器只支持RC模式。
Macro0( lane0~lane3)中若存在PCIe和其他协议( SATA)共存,则PCIe只能支持到PCIE_GEN2;若只存在PCIe协议,则PCIe支持到PCIE_GEN3。
PCIe支持降lane应用,如PCIe x4降lane到PCIe x2/x1。
Macro0( lane0~lane3)支持PCIE和SATA协议, Macro1( lane4~lane7)支持PCIe、 USB、 ETH协议,每个Macro同时最多只能配置两种协议。
SATA只能在Macro0( lane0~lane3)使用。
USB控制器0( lane4)只支持HOST, USB控制器1~USB控制器3( lane5~lane7)支持HOST+DEVICE。
USB只能在Macro1( lane4~lane7)使用。
若为系统直出的USB 2.0,则无需配置SerDes。


修改完成后执行"./build.sh usrBaseConfig"编译,编译完成后会在out下生成一个userBaseConfig.bin文件,将userBaseConfig.bin复制到板子,通过如下命令进行升级。
bash
/var/davinci/driver/upgrade-tool --device_index -1 --component Usr_Base_Config --path userBaseConfig.bin
7.重构驱动run包
在二次开发场景中,若用户需要新增或替换驱动包中的Image、 dt.img、驱动文件( ko文件)或驱动文件的加载脚本等,可根据需要,选择执行以下操作。
(1).执行以下命令,在" Ascend310B-source"创建对应目录。
bash
mkdir repack/firmware #存放Image、dt.img
mkdir repack/drivers #存放驱动ko文件
mkdir repack/scripts #一些配置脚本,比如需要自动加载KO的配置文件等
(2).安装上面的说法将对应的文件放在各自的目录下,如果需要添加开机自动加载的方法按照下面方法操作,
第一种情况,原驱动包中已包含驱动文件:
bash
# 命令建议在其它目录下执行,目前只是想获取run包中的一些文件。
bash Ascend-hdk-310b-npu-driver-soc_<version>_linux-aarch64.run --noexec -- extract=./unpack
通过上面命令对驱动run包解压后可以获取到modules.tar.gz的压缩包,如果这个压缩包中已经包含了驱动文件,就可以使用该方法。
例如以rfkill.ko为例:
bash
$ vim repack/scripts/11-atlas.conf
#下面是文件内容,如果需要添加多个驱动,继续按行添加即可。
rfkill
第二种情况,用户新增驱动:
从解压的驱动包中复制下面文件到"repack/scripts"目录下。
bash
filelist.csv
minirc_sys_init_ext.sh
minirc_sys_init.sh
bash
$ vim repack/scripts/filelist.csv
#下面是添加内容,按文件里面的分类放在一块,方便管理。
ko,copy,hello.ko,driver/hello.ko,TRUE,440,root:root,all,NA,all,N,FALSE,NA,driver,NA,all
bash
$ vim repack/scripts/minirc_sys_init_ext.sh
load_device_modules()
{
echo "load device ext modules"
ko_path="${targetdir}"/driverko_check
${ko_path}/myhello.ko
echo "finish load device ext modules"
}
(3).因为驱动run包的构建过程是在原包的基础上进行修改的,所以需要将原run包复制SDK目录下,在执行构建命令。
bash
cp Ascend-hdk-310b-npu-driver-soc_<version>_linux-aarch64.run Ascend310B-source/ #以实际情况为准
build.sh repack ./Ascend-hdk-310b-npu-driver-soc_<version>_linux-aarch64.run #Ascend310B-source目录下执行
构建完成后会生成Ascend-hdk-310b-npu-driver-soc__linux-aarch64-repack.run