4.3.26. boardinfo Debug Guide
4.3.26.1. Overview
The boardinfo driver provides an interface for upper-layer software to obtain board-level information. This document details the functionality of the boardinfo driver and presents two access methods: sysfs and userspace API.
4.3.26.2. Functional Description
The boardinfo driver provides the following main functions:
Read key hardware information, including chip model, name, version number, boot method, SOC ID, and DDR information.
Configure the BAK slot to be used in the next boot, enabling the system to switch to a specified backup state upon reboot.
With these capabilities, the boardinfo driver delivers real-time and accurate board-level information, ensuring system stability and reliability.
Interface Name Standardization and Userspace API Return Value Tracking Table (X5 Example)
| Interface Name | Functionality | Access Permission | Userspace API Result Type | Return Value |
|---|---|---|---|---|
| soc_gen | View chip model | RO | String | X5 |
| soc_name | View chip name, including sub-models | RO | String | X5M X5H UNKNOWN |
| hw_name | View hardware board name | RO | String | x5-fpga x5-soc x5-svb x5-evb |
| board_version | View hardware board version | RO | String | v1 v2 v3 |
| hw_info | View full hardware board name (Composed of <hw_name>-<board_version>-<ddr_vendor>-<ddr_size>-<ddr_freq>) |
RO | String | x5-evb-v2-cxmt-2048MB-4266 ... |
| bootdevice_name | View boot method | RO | String | emmc sd nand |
| soc_uid | View SOC ID | RO | String | Unique SOC ID |
| ddr_vendor | View DDR manufacturer | RO | String | DDR manufacturer |
| ddr_type | View DDR type, e.g., LPDDR4 or LPDDR4X | RO | String | LPDDR4 LPDDR4X |
| ddr_freq | View maximum DDR frequency, in Mbps | RO | String | 3200 Mbps 3733 Mbps 4266 Mbps |
| ddr_size | View DDR capacity, in MB | RO | String | 1024MB 2048MB 4096MB 8192MB |
| board_id | View hardware board ID | RO | String | Current board_id, printed in hexadecimal |
| sec_chip | View whether it is a secure chip | RO | String | Chip without key burned: nosec_chip Chip with Gua key burned: sec_chip1 Chip with customer's public key hash burned: sec_chip2 |
| sec_boot | View whether AVB and dm-verity verification are enabled | RO | String | enable disable |
| bak_slot | Read: currently active BAK slot; Write: set BAK slot for next boot |
R/W | String | 0 1 |
For instructions on burning customer’s own public key hash, refer to X5 Customer Root RSA Key Hash Burning and Usage
4.3.26.3. Driver Code
The socinfo driver code is located at kernel/drivers/soc/hobot/socinfo/socinfo.c, with the following main functionalities:
Read board-level information configured in the DTS configuration file and store it into corresponding variables.
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;
}
Implement sysfs interface to provide upper-layer software with access to board-level information.
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” and “soc_name” must be configured in the Kernel DTS file, located at kernel/arch/arm64/boot/dts/hobot/x5.dtsi, under the node named “socinfo”.
Currently, in the kernel DTS, the placeholder length for "hw_name" and "board_version" is 16 bytes, and for "hw_info" it is 32 bytes. If any field exceeds its placeholder length, the socinfo driver initialization will fail.

Information such as “board_id”, “hw_name”, and “board_version” must be configured in the Uboot DTS file, located at uboot/arch/arm/dts/x5.dtsi, under the node named “board_type”.
The board_type_array field in DTS corresponds to “board_id”; refer to Modify Board ID Macro Definitions for related changes.
The hardward_array field corresponds to “hw_name”, and the board_version field corresponds to “board_version”.

4.3.26.4. Usage
sysfs Interface
The sysfs interface path is /sys/class/socinfo/, currently supporting retrieval of the following information:
For example, to view board-level interface information, execute the following commands in the terminal:
# View chip model
root@buildroot:~# cat /sys/class/socinfo/soc_gen
x5
# View chip name
root@buildroot:~# cat /sys/class/socinfo/soc_name
X5M
# View hardware board name
root@buildroot:~# cat /sys/class/socinfo/hw_name
X5_EVB_LP4
# View hardware board version
root@buildroot:~# cat /sys/class/socinfo/board_version
1_B
# View full hardware board name
root@buildroot:~# cat /sys/class/socinfo/hw_info
X5_EVB_LP4_1_B_cxmt_4096MB_4266
# View boot method
root@buildroot:~# cat /sys/class/socinfo/bootdevice_name
emmc
# View SOC ID
root@buildroot:~# cat /sys/class/socinfo/soc_uid
0x308064960e31499301f0822400000000
# View DDR manufacturer
root@buildroot:~# cat /sys/class/socinfo/ddr_vendor
cxmt
# View DDR type
root@buildroot:~# cat /sys/class/socinfo/ddr_type
LPDDR4
# View maximum DDR frequency
root@buildroot:~# cat /sys/class/socinfo/ddr_freq
4266 Mbps
# View DDR capacity
root@buildroot:~# cat /sys/class/socinfo/ddr_size
4096MB
# View hardware board ID
root@buildroot:~# cat /sys/class/socinfo/board_id
0x0202
# View chip secure type
root@buildroot:~# cat /sys/class/socinfo/sec_chip
sec_chip1
# View whether secure boot is enabled
root@buildroot:~# cat /sys/class/socinfo/sec_boot
enable
# View current active BAK slot
root@buildroot:~# cat /sys/class/socinfo/bak_slot
0
# Set BAK slot for next boot
root@buildroot:~# echo 1 > /sys/class/socinfo/bak_slot
root@buildroot:~# reboot
root@buildroot:~# cat /sys/class/socinfo/bak_slot
1
Note: If the chip name soc_name is UNKNOWN, it indicates an early production chip that has not had the corresponding bit written in eFUSE; the chip type must then be identified by its silkscreen marking.
hw_info is composed of <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 Interface
Source path: hbre/hbutils/boardinfo
Header file: boardinfo.h
Library: libboardinfo.so.1
Interface Definition
hb_get_boardinfo
【Function Declaration】
int32_t hb_get_boardinfo(char *key, void *dst, uint32_t len);
【Parameter Description】
[OUT] key: The board-level information to retrieve
[OUT] dst: Buffer to store the result
[IN] len: Maximum buffer size
【Return Value】
HB_BINFO_SUCCESS: Success
HB_BINFO_INVALID_PARAM: Invalid parameter (e.g., null pointer)
HB_BINFO_SHORT_BUF: Buffer too small
HB_BINFO_PLAT_NOT_SUPPORT: Board information not supported on this platform
【Functionality】
Retrieves board-level information specified by key, stores the result in dst, and returns an error code.
Error Types Returned by Dynamic Library Interface
Error values defined in the dynamic library:
enum hb_binfo_retval {
HB_BINFO_SUCCESS,
HB_BINFO_INVALID_PARAM,
HB_BINFO_SHORT_BUF,
HB_BINFO_PLAT_NOT_SUPPORT,
};
Example Code
When calling the userspace API, link the dynamic library first. Example code:
#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. Common Issues
When using the userspace API, if the provided key does not exist, the function returns the error HB_BINFO_INVALID_PARAM. In this case, the dst pointer remains unmodified; always check whether the return value is 0.