4.3.26. boardinfo 调试指南
4.3.26.1. 概述
boardinfo 驱动
4.3.26.2. 功能描述
boardinfo 驱动
读取
关键 硬件 信息,包括 芯片型号、名称、版本号、启动 方式、SOC ID 及 DDR 信息 等。 配置
下次 启动 时 使用 的 BAK slot,以便 在 系统启动 时 切换 到 指定 的 备份 状态。
通过
接口
| 接口 |
接口 |
接口 |
userspace API 结果 |
返回值 |
|---|---|---|---|---|
| soc_gen | 查看 |
RO | 字符串 | X5 |
| soc_name | 查看 |
RO | 字符串 | X5M X5H UKNOWN |
| hw_name | 查看 |
RO | 字符串 | x5-fpga x5-soc x5-svb x5-evb |
| board_version | 查看 |
RO | 字符串 | v1 v2 v3 |
| hw_info | 查看 (由<hw_name>-<board_version>-<ddr_vendor>-<ddr_size>-<ddr_freq>组成) |
RO | 字符串 | x5-evb-v2-cxmt-2048MB-4266 ... |
| bootdevice_name | 查看 |
RO | 字符串 | emmc sd nand |
| soc_uid | 查看 SOC 的 ID 号 | RO | 字符串 | soc唯一id |
| ddr_vendor | 查看 DDR 厂商 | RO | 字符串 | DDR厂商 |
| ddr_type | 查看 DDR类型,如LPDDR4或LPDDR4X | RO | 字符串 | LPDDR4 LPDDR4X |
| ddr_freq | 查看 DDR最高 |
RO | 字符串 | 3200 Mbps 3733 Mbps 4266 Mbps |
| ddr_size | 查看 DDR容量,单位MB | RO | 字符串 | 1024MB 2048MB 4096MB 8192MB |
| board_id | 查看 |
RO | 字符串 | 当前board_id,以 |
| sec_chip | 查看 |
RO | 字符串 | 未烧key的 烧 烧 |
| sec_boot | 查看 |
RO | 字符串 | enable disable |
| bak_slot | 读:当前 写:设置 |
R/W | 字符串 | 0 1 |
如何
4.3.26.3. 驱动代码
socinfo 驱动kernel/drivers/soc/hobot/socinfo/socinfo.c,主要
读取 DTS 配置文件
中 配置 的 板级 信息,并 保存 到 对应 变量 中。
if (read_from_property(pdev, "soc_gen", &soc_gen) ||
read_from_property(pdev, "soc_name", &soc_name) ||
read_from_property(pdev, "hw_name", &hw_name) ||
read_from_property(pdev, "board_version", &board_version) ||
read_from_property(pdev, "hw_info", &hw_info) ||
read_from_property(pdev, "bootdevice_name", &bootdevice_name) ||
read_from_property(pdev, "soc_uid", &soc_uid) ||
read_from_property(pdev, "board_id", &board_id) ||
read_from_property(pdev, "sec_chip", &sec_chip) ||
read_from_property(pdev, "sec_boot", &sec_boot)) {
return -1;
}
实现 sysfs 接口,提供
上层 软件 获取 板级 信息 的 接口。
static struct class_attribute soc_gen_attribute =
__ATTR(soc_gen, 0444, soc_gen_show, NULL);
static struct class_attribute soc_name_attribute =
__ATTR(soc_name, 0444, soc_name_show, NULL);
static struct class_attribute hw_name_attribute =
__ATTR(hw_name, 0444, hw_name_show, NULL);
static struct class_attribute board_version_attribute =
__ATTR(board_version, 0444, board_version_show, NULL);
static struct class_attribute hw_info_attribute =
__ATTR(hw_info, 0444, hw_info_show, NULL);
static struct class_attribute bootdevice_name_attribute =
__ATTR(bootdevice_name, 0444, bootdevice_name_show, NULL);
static struct class_attribute soc_uid_attribute =
__ATTR(soc_uid, 0444, soc_uid_show, NULL);
static struct class_attribute ddr_vender_attribute =
__ATTR(ddr_vendor, 0444, ddr_vender_show, NULL);
static struct class_attribute ddr_type_attribute =
__ATTR(ddr_type, 0444, ddr_type_show, NULL);
static struct class_attribute ddr_freq_attribute =
__ATTR(ddr_freq, 0444, ddr_freq_show, NULL);
static struct class_attribute ddr_size_attribute =
__ATTR(ddr_size, 0444, ddr_size_show, NULL);
static struct class_attribute board_id_attribute =
__ATTR(board_id, 0444, board_id_show, NULL);
static struct class_attribute sec_chip_attribute =
__ATTR(sec_chip, 0444, sec_chip_show, NULL);
static struct class_attribute sec_boot_attribute =
__ATTR(sec_boot, 0444, sec_boot_show, NULL);
static struct class_attribute bak_slot_attribute =
__ATTR(bak_slot, 0644, bak_slot_show, bak_slot_store);
“soc_gen” 和 “soc_name” 需要kernel/arch/arm64/boot/dts/hobot/x5.dtsi,节点
当前在 kernel dts 中 "hw_name" 和 "board_version" 的占位符长度为16字节,"hw_info" 的占位符长度为32字节,如果对应的字段超出了占位符的长度,将会导致 socinfo 此驱动初始化失败。

“board_id”、”hw_name”、”board_version” 等uboot/arch/arm/dts/x5.dtsi,节点
DTS 中
hardward_array 字

4.3.26.4. 功能使用
sysfs 接口
sysfs 接口/sys/class/socinfo/,目前
例如
#查看芯片型号
root@buildroot:~# cat /sys/class/socinfo/soc_gen
x5
#查看芯片名称
root@buildroot:~# cat /sys/class/socinfo/soc_name
X5M
#查看硬件板子名称
root@buildroot:~# cat /sys/class/socinfo/hw_name
X5_EVB_LP4
#查看硬件板子版本号
root@buildroot:~# cat /sys/class/socinfo/board_version
1_B
#查看硬件板子全名称
root@buildroot:~# cat /sys/class/socinfo/hw_info
X5_EVB_LP4_1_B_cxmt_4096MB_4266
#查看启动方式
root@buildroot:~# cat /sys/class/socinfo/bootdevice_name
emmc
#查看SOC的ID号
root@buildroot:~# cat /sys/class/socinfo/soc_uid
0x308064960e31499301f0822400000000
#查看DDR厂商
root@buildroot:~# cat /sys/class/socinfo/ddr_vendor
cxmt
#查看DDR类型
root@buildroot:~# cat /sys/class/socinfo/ddr_type
LPDDR4
#查看DDR最高速率
root@buildroot:~# cat /sys/class/socinfo/ddr_freq
4266 Mbps
#查看DDR容量
root@buildroot:~# cat /sys/class/socinfo/ddr_size
4096MB
#查看硬件板子 ID
root@buildroot:~# cat /sys/class/socinfo/board_id
0x0202
#查看芯片secure类型
root@buildroot:~# cat /sys/class/socinfo/sec_chip
sec_chip1
#查看是否开启secure boot
root@buildroot:~# cat /sys/class/socinfo/sec_boot
enable
#查看当前启动的 BAK slot
root@buildroot:~# cat /sys/class/socinfo/bak_slot
0
#设置下次启动的 BAK slot
root@buildroot:~# echo 1 > /sys/class/socinfo/bak_slot
root@buildroot:~# reboot
root@buildroot:~# cat /sys/class/socinfo/bak_slot
1
注意:如果soc_name 是 UKNOWN,则
hw_info 由 <hw_name>-<board_version>-<ddr_vendor>-<ddr_size>-<ddr_freq> 组成:
hw_name: X5_EVB_LP4
board_version: 1_B
ddr_vendor: cxmt
ddr_size: 4096MB
ddr_freq: 4266
userspace API 接口
源码hbre/hbutils/boardinfo
头文件: boardinfo.h
链接库: libboardinfo.so.1
接口定义
hb_get_boardinfo
【函数
int32_t hb_get_boardinfo(char *key, void *dst, uint32_t len);
【参数
[OUT] key: 要
获取 的 板级 信息 [OUT] dst: 接收
结果 的 缓存 空间 [IN] len: 缓存
空间 最大 长度
【返回值】
HB_BINFO_SUCCESS:成功
HB_BINFO_INVALID_PARAM: 非法
参数,如空 指针 HB_BINFO_SHORT_BUF: 缓存
空间 过 小 HB_BINFO_PLAT_NOT_SUPPORT: 本
平台 不 支持 的 板级 信息
【功能
获取
动态
动态
enum hb_binfo_retval {
HB_BINFO_SUCCESS,
HB_BINFO_INVALID_PARAM,
HB_BINFO_SHORT_BUF,
HB_BINFO_PLAT_NOT_SUPPORT,
};
示例
调用 userspace API 接口
#include <stdio.h>
#include <stdint.h>
#include "boardinfo.h"
int main(void) {
int32_t ret;
char buf[1024];
ret = hb_get_boardinfo("soc_gen", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("soc_gen:%s\n", buf);
}
ret = hb_get_boardinfo("soc_name", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("soc_name:%s\n", buf);
}
ret = hb_get_boardinfo("hw_name", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("hw_name:%s\n", buf);
}
ret = hb_get_boardinfo("board_version", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("board_version:%s\n", buf);
}
ret = hb_get_boardinfo("hw_info", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("hw_info:%s\n", buf);
}
ret = hb_get_boardinfo("bootdevice_name", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("bootdevice_name:%s\n", buf);
}
ret = hb_get_boardinfo("soc_uid", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("soc_uid:%s\n", buf);
}
ret = hb_get_boardinfo("ddr_type", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("ddr_type:%s\n", buf);
}
ret = hb_get_boardinfo("ddr_size", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("ddr_size:%s\n", buf);
}
ret = hb_get_boardinfo("ddr_vendor", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("ddr_vendor:%s\n", buf);
}
ret = hb_get_boardinfo("ddr_freq", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("ddr_freq:%s\n", buf);
}
ret = hb_get_boardinfo("board_id", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("board_id:%s\n", buf);
}
ret = hb_get_boardinfo("sec_chip", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("sec_chip:%s\n", buf);
}
ret = hb_get_boardinfo("sec_boot", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("sec_boot:%s\n", buf);
}
ret = hb_get_boardinfo("board_id", buf, 2);
if (ret == 0) {
printf("hb_get_boardinfo test HB_BINFO_SHORT_BUF failed\n");
} else {
printf("hb_get_boardinfo test HB_BINFO_SHORT_BUF pass\n");
}
ret = hb_get_boardinfo("bak_slot", buf, 1024);
if (ret) {
printf("hb_get_boardinfo failed, ret:%d\n", ret);
} else {
printf("bak_slot:%s\n", buf);
}
ret = hb_get_boardinfo(NULL, buf, 1024);
if (ret == 0) {
printf("hb_get_boardinfo test HB_BINFO_INVALID_PARAM failed\n");
} else {
printf("hb_get_boardinfo test HB_BINFO_INVALID_PARAM pass\n");
}
ret = hb_get_boardinfo("xx", buf, 1024);
if (ret == 0) {
printf("hb_get_boardinfo test HB_BINFO_INVALID_PARAM failed\n");
} else {
printf("hb_get_boardinfo test HB_BINFO_INVALID_PARAM pass\n");
}
return 0;
}
4.3.26.5. 常见问题
使用 userspace API 接口
时,如果 传入 的 key 值 不 存在,则 返回 HB_BINFO_INVALID_PARAM 错误,此时 dst 指针 不会 被 修改,需要 检查 返回值 是否 为 0。