Atlas200DK的板极支持之旅

首先从拆板子开始

正面

  1. Hi3559CRFCV100: ARM64主控
  2. NT5AD256M16D4: 4Gbit DDR4
  3. TC58CYG2S0HRAIG: 4Gbit SPI NAND flash
  4. RTQ2502A: 2A, 6.5V LDO
  5. AU5411A AAAA2006: 3输入10输出可配置复用的时钟缓冲
  6. ?? OFU T1 91B A962
  7. LM75BD: 数字温度计 & thermal watchdog
  8. PCA9517A: I2C电平转换
  9. 4256BWP: 256Kbit I2C EEPROM
  10. ?? 8138
  11. ?? 708013
  12. ?? 7G17
  13. NAM12S06: 集成电源 9~14IN 0.7~5.4OUT 6A
  14. NAE12S17: 集成电源 3~14IN 0.6~5.5OUT 17A
  15. NAE12S20: 集成电源 3~14IN 0.6~5.5OUT 20A
  16. G2401CE: 10/100/1000BASE-T 网络变压器

反面

  1. NT5AD256M16D4: 4Gbit DDR4
  2. UM3204UE: 4通道ESD保护电平转换
  3. ?? P06 B202 950
  4. AVC16T245: 16位总线收发器
  5. PCA9555: 16路GPIO扩展,I2C总线
  6. RTL8211FSI: 10/100/1000 BASE-T 以太网收发器
  7. uClamp2804L: 以太网ESD、雷击保护
  8. TSX712: 16V RRIO OP-AMP

加速模块

封装成一个铁盒子。还没找资料,已知是一个PCIe设备

Summary

ARM侧具有1GB的DDR4运存与512M的NAND flash,不出意外这块flash被配置成了启动设备,UBOOT什么的都在这玩意上面。

以太网口很工业级,但是两块IO扩展看不懂。主控好歹也是千针封装吧…

主控与DDR似乎设计被保护在屏蔽罩内,但实际并没有。

U9有个空置焊盘想不到用途

不接加速卡,arm核似乎也没有起,没有板子的原理图也无法判断加速卡和主控之间到底是什么关系

寻找输入输出

首先至少得确认出可以用作DEBUG接口的UART。根据GitHub老哥的IO映射表

Pin Name Level Pin Name Level
1 +3.3V 3.3V 2 +5V 5V
3 I2C_2-SDA 3.3V 4 +5V 5V
5 I2C_2-SCL 3.3V 6 GND -
7 GPIO0 3.3V 8 UART_0-TX 3.3V
9 GND - 10 UART_0-RX 3.3V
11 GPIO1 3.3V 12 NC -
13 NC - 14 GND -
15 GPIO2 3.3V 16 UART_1-TX 3.3V
17 +3.3V 3.3V 18 UART_1-RX 3.3V
19 SPI-MOSI 3.3V 20 GND -
21 SPI-MISO 3.3V 22 NC -
23 SPI-CLK 3.3V 24 SPI-CS 3.3V
25 GND - 26 GPIO10 3.3V
27 GPIO8 3.3V 28 GPIO9 3.3V
29 GPIO3 3.3V 30 GND -
31 GPIO4 3.3V 32 NC -
33 GPIO5 3.3V 34 GND -
35 GPIO6 3.3V 36 +1.8V 1.8V
37 GPIO7 3.3V 38 UART_Hi35559-TXD 3.3V
39 GND - 40 UART_Hi35559-RXD 3.3V

有两组串口需要关照一下,分别是8,10和38,40。拿出DSLogic逻分,直接架在四个口子上。

DSView中配置采样率为20M,最大时长5min,电压阀值2.0V,点击开始后接上开发板电源。此时没有接SD卡或者其它任何外设。

成功在抓到了串口通信。撤掉逻分,挂两个USB转TTL的CH340直接在minicom里观察。

两边都有信息…暂时拔掉RX线,看看输出内容

ARM核的串口上是普通的UBoot流程并引导进入了NAND上的linux内核,加载了rootfs。加速卡这边就有点看不懂了。之前的经验是板子的typec口会在当前情况下开出一个fastboot来,还用的是小米的设备信息(???)。

报错里也有怪东西,虽然这个应该是编译器的锅(x

/home/phisik3/vb_workspace/work_code/bios/HwPkg/UEFI/Products/Hi1910/Common/Library/BootLoaderLib/ext2fs.c -

那看来暂时c口是加速卡接管的。

测了存储卡,也是加速卡接管的…?

找出以前写的制卡脚本,做一张系统卡试试看能不能过加速卡的启动,然后看看控制流怎么切换。

我tm人傻了。真就跑着两个系统啊…而且加速模块上的那个才是“真正的”系统…那底板上那么贵一颗Hi3559在干什么啊…

image

行,我输了。顺带,此时底板的Hi3559还在uboot里没有进入nand的系统。

拆解加速卡

由于找到了拆解图,我就不去清理导热硅脂里,直接装回去。

出处: Atlas200 模组拆解_伯纳乌的至尊玉的博客-CSDN博客

拆开来没有什么作用(除非强拆SPI NOR FLASH去改二级引导)

需要去找找看看Hi1910相关的资料先

今日份进度:

整到了Ascend310的SDK,修改了dt拿到了第一组串口上的系统console。顺带搞清楚了Ascend310加速模组上SPI NOR FLASH里的固件所需要的DTB的一种名为HSDT的文件格式,并发现了sdk里相关的一个bug…

scripts下的python脚本质量一眼就能看出来至少是两个人写的。涉及签名验证和加密的部分代码十分工整,虽然还没细看…剩下的都是什么反胃胶水

剩下的空间贴研究文件格式时候打的笔记:

dt.img生成调用栈分析

根据 Compiling Source Code - Atlas 200 AI Accelerator Module 1.0.9 Software Installation and Maintenance Guide (RC) 05 - Huawei

调用 bash build.sh dtb

查询对应逻辑:

[ "$2" ] && VERSION=$2

忽略此行

make -C ${SCRIPTS_DIR} $1 || exit $?

$1=dtb

查询对应Makefile:

@cp -rf $(TOP_DIR)/dtb/* $(KERNEL_SRC_DIR)/arch/arm64/boot/dts/hisilicon

源文件夹内均为hi1910打头,与内核树无冲突

@make -C $(KERNEL_SRC_DIR) ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) mrproper

经查阅,linux - Why both `make clean` and `make mrproper` are used? - Unix & Linux Stack Exchange

为一种清理手段

@make -C $(KERNEL_SRC_DIR) O=$(KERNEL_OUT_DIR) ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) mini_defconfig $(PRIVATE_DTB) -j$(JOBS)

??

补充:怀疑是为了生成dtc工具,顺带还编译了所有指定的dts。

@mkdir -p $(OUTPUT_DIR)/dtb && cp -rf $(KERNEL_OUT_DIR)/arch/arm64/boot/dts/hisilicon/*.dtb $(OUTPUT_DIR)/dtb/

又把这些文件再拷出来…

@python $(TOP_DIR)/scripts/mkdtb.py $(OUTPUT_RAW_DIR)/dt_raw.img $(KERNEL_OUT_DIR)/scripts/dtc/ $(OUTPUT_DIR)/dtb/

KERNEL_SRC_DIR=$(TOP_DIR)/kernel/linux-4.19
KERNEL_OUT_DIR=$(TOP_DIR)/kernel/out
OUTPUT_DIR=$(TOP_DIR)/output
OUTPUT_RAW_DIR=$(OUTPUT_DIR)/out_raw

前往mkdtb.py

__main__: MakeDtb: __init__:

dtb_list = 所有文件夹里的dtb

boardid 反解dtb拿到dts从里面取的号

MakeDtb: write_dt

看起来是将好几个dtb打包到一起

野生的HSDT的文件格式出现了!

u1s1很想把SPI NOR FLASH里的二级bootloader干掉,但暂时没有那个条件

HSDT 二进制文件格式
struct __attribute__((__packed__)) hsdt_entry_header_s {
    uint8_t boardid[4];		// [1, 0, 0, 4]
    uint8_t reserved_0[4];	// [0, 0, 0, 0]
    uint32_t dtb_size;		// dtb size in bytes
    uint32_t vrl_size;		// always 0
    uint32_t dtb_offset;	// absolute index of the first byte in the file
    uint32_t vrl_offset;	// always 0
    uint32_t dtb_file;		// always 0
    uint32_t vrl_file;		// always 0
    uint32_t zero_0;		// always 0
    uint32_t padding_0;
};

struct __attribute__((__packed__)) hsdt_file_content_s {
    /* begin 12 bytes */
    char HS_MAGIC[4];		// b"HSDT"
    uint32_t HS_VERSION;	// 1
    uint32_t DTB_NUMS;		// total dtb count
    /* end 12 bytes */
    
    /* begin 40 * self.dtb_cnt */
    struct hsdt_entry_header_s entry_headers[DTB_NUMS];
    /* end 40 * self.dtb_cnt */
    
    /* begin + 4 */
    uint32_t padding_0;
    /* begin + 4 */
    
    uint8_t padding_1[];	// align the following data to 2048 bytes
    
    uint8_t payload[];			// dtb contents, padding to 2048 bytes
};
bugs
offset = BLOCK_SIZE
...
self.dtb_node.append(StatFile(dtb_path + dtb, boardid, offset).node_list)
offset += StatFile(dtb_path + dtb, boardid, offset).dtb_size

这里没有考虑到当header大于2048的时候。2048即50个dtb被打包到一起时。

@rm -rf $(OUTPUT_DIR)/dtb

${SCRIPTS_DIR}/header.sh add ${OUTPUT_RAW_DIR}/dt_raw.img ${OUTPUT_HEADER_DIR}/dt.img ${HEADER_VERSION} ${HEADER_TYPE}

这一步用于给DTB增加签名?image_pack.pyimage_unpack.py以及hi_platform库一眼看过去就是另一个更专业的组做的方案…暂时决定继续使用这组代码。