Linux SID 开发指南

news2024/11/24 1:11:42

Linux SID 开发指南

1 前言

1.1 编写目的

介绍Linux 内核中基于Sunxi 硬件平台的SID 模块驱动的详细设计,为软件编码和维护提供基
础。

1.2 适用范围

内核版本Linux-5.4, Linux-4.9 的平台。

1.3 相关人员

SID 驱动、Efuse 驱动、Sysinfo 驱动的维护、应用开发人员等。

1.4 术语、定义、缩略语

image-20221219105007286

2 模块描述

2.1 模块功能

SID 提供的功能可以分为四大部分:ChipID、SoC Version、Efuse 功能、一些状态位。

2.1.1 Chip ID 功能

对于全志的SoC 来说,ChipID 用于该SoC 的唯一标识,如A83 的ChipID 标识其在所有A83 中的唯一(目前仅保证同一型号SoC 中的ChipID 唯一)。ChipID 由4 个word(16 个byte)组成,共128bit,通常放在Efuse(见2.1.3 节)的起始4 个word。具体ChipID 的bit 含义,请参考生产制造部为每颗SoC 定义的《ChipID 烧码规则》。

2.1.2 SoC Version 功能

严格讲SoC Version 包含两部分信息:
1.Bonding ID,表示不同封装。

  1. Version,表示改版编号。

说明:这两个信息所在的寄存器不一定都在SID 模块内部,且各平台位置不一,但软件上为了统一管理,都归属为SID 模块。

BSP 会返回这两个信息的组合值,由应用去判断和做出相应的处理。

2.1.3 Efuse 功能

对软件来说,Efuse 中提供了一个可编程的永久存储空间,特点是每一位只能写一次(从0到1)。
Efuse 接口方式,Efuse 容量大于512bit 采用SRAM 方式。带有SRAM 的硬件结构示意图如下:

image-20221219105300040

2.1.4 一些状态位

Secure Enable标明当前系统的Security 属性是否打开,即是否运行了SecureBoot 和SecureOS。
芯片SecureEnable 状态位保存在SID 模块的0xa0 寄存器。

2.2 模块位置

SID 是一个比较独立的模块,在Linux 内核中没有依赖其他子系统,在Sunxi 平台默认是ko 方式,存放在drivers/soc/sunxi 目录中。
SID 为其他模块提供API 的调用方式。关系如下图:

image-20221219105416344

1)TV、Thermal、GMAC 的校准参数保存在SID 中;
2)Nand、SMP、VE 需要读取SoC Version;
3)CE 和HDMI 会用到SID 中的一些Key;
4)Sysinfo 比较特殊,为了方便用户空间获取、调试SID 信息,专门设计的一个字符型设
备驱动。

2.3 模块device tree 配置说明(适用Linux-5.4)

SID 模块在Device tree 中通常会用到两个模块的配置信息:sunxi-sid 以sun50iw10p1为例,需要在sun50iw10p1.dtsi 中添加节点:

sid@3006000 {
compatible = "allwinner,sun50iw10p1-sid", "allwinner,sunxi-sid";
reg = <0x0 0x03006000 0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
/* some guys has nothing to do with nvmem */
secure_status {
reg = <0x0 0>;
offset = <0xa0>;
size = <0x4>;
};
chipid {
reg = <0x0 0>;
offset = <0x200>;
size = <0x10>;
};
rotpk {
reg = <0x0 0>;
offset = <0x270>;
size = <0x20>;
};
};

在sid 下增加子节点secure_status, chipid, rotpk。就可以用key_info 来访问。

console:/ # echo chipid > /sys/class/sunxi_info/key_info ; cat /sys/class/sunxi_info/
key_info
console:/ # 00000400

2.4 模块源码结构

SID 驱动的源代码目录下:

linux-4.9,linux-5.4
./drivers/soc/sunxi/
└── sunxi-sid.c // 实现了SID对外的所有API接口

对外提供的接口头文件:./include/linux/sunxi-sid.h

2.5 内核配置

此配置项一般默认开,不需要重新配置
在longan 环境中在根目录执行./build.sh menconfig进入配置主界面,配置路径如下:

System Type
└─>ARM system type
└─>Allwinner Ltd. SUNXI family
版

配置界面图示:

image-20221219105647967

SID 驱动本身没有注册为单独的模块,需要通过注册sysinfo 字符驱动(实现代码见drivers/char/sunxi-sysinfo/)来提供sysfs 节点。
在longan 环境中在根目录执行./build.sh menconfig进入配置主界面,配置路径如下

Device Drivers
└─>Character devices
└─>sunxi system info driver

配置界面图示:

image-20221219105712117

3 模块设计

3.1 结构框图

SID 驱动内部的功能划分如下图所示:

image-20221219105727865

总体上,SID 驱动内部可以分为两大部分:
1.SID Register RW,封装了对寄存器按位读取的接口,以及获取指定compatible 的模块基地址等。
2.SID Api,以API 的方式提供一些功能接口:获取Key、获取SoC Version、获取SecureEnable、获取ChipID 等。

3.2 关键数据定义

3.2.1 常量及宏定义

3.2.1.1 key 的名称定义

在获取Key 的时候,调用者需要知道Key 的名称,以此作为索引的依据。Key 名称详见sunxisid.h:

1 #define EFUSE_CHIPID_NAME "chipid"
2 #define EFUSE_BROM_CONF_NAME "brom_conf"
3 #define EFUSE_BROM_TRY_NAME "brom_try"
4 #define EFUSE_THM_SENSOR_NAME "thermal_sensor"
5 #define EFUSE_FT_ZONE_NAME "ft_zone"
6 #define EFUSE_TV_OUT_NAME "tvout"
7 #define EFUSE_OEM_NAME "oem"
9 #define EFUSE_WR_PROTECT_NAME "write_protect"
10 #define EFUSE_RD_PROTECT_NAME "read_protect"
11 #define EFUSE_IN_NAME "in"
12 #define EFUSE_ID_NAME "id"
13 #define EFUSE_ROTPK_NAME "rotpk"
14 #define EFUSE_SSK_NAME "ssk"
15 #define EFUSE_RSSK_NAME "rssk"
16 #define EFUSE_HDCP_HASH_NAME "hdcp_hash"
17 #define EFUSE_HDCP_PKF_NAME "hdcp_pkf"
18 #define EFUSE_HDCP_DUK_NAME "hdcp_duk"
19 #define EFUSE_EK_HASH_NAME "ek_hash"
20 #define EFUSE_SN_NAME "sn"
21 #define EFUSE_NV1_NAME "nv1"
22 #define EFUSE_NV2_NAME "nv2"
23 #define EFUSE_BACKUP_KEY_NAME "backup_key"
24 #define EFUSE_RSAKEY_HASH_NAME "rsakey_hash"
25 #define EFUSE_RENEW_NAME "renewability"
26 #define EFUSE_OPT_ID_NAME "operator_id"
27 #define EFUSE_LIFE_CYCLE_NAME "life_cycle"
28 #define EFUSE_JTAG_SECU_NAME "jtag_security"
29 #define EFUSE_JTAG_ATTR_NAME "jtag_attr"
30 #define EFUSE_CHIP_CONF_NAME "chip_config"
31 #define EFUSE_RESERVED_NAME "reserved"
32 #define EFUSE_RESERVED2_NAME "reserved2"
33 /* For KeyLadder */
34 #define EFUSE_KL_SCK0_NAME "keyladder_sck0"
35 #define EFUSE_KL_KEY0_NAME "keyladder_master_key0"
36 #define EFUSE_KL_SCK1_NAME "keyladder_sck1"
37 #define EFUSE_KL_KEY1_NAME "keyladder_master_key1"

sunxi-sid.h 不是所有key 都能访问,一般可以访问的已经在dts 定义。

3.2.2 关键数据结构

3.2.2.1 soc_ver_map

用于管理多个SoC 的Version 信息,方便用查表的方式实现SoC Version API。其中有两个分量:id,即BondingID;rev[],用于保存BondingID 和Version 的各种组合值。定义在sunxi-sid.c 中:

#define SUNXI_VER_MAX_NUM 8
struct soc_ver_map {
u32 id;
u32 rev[SUNXI_VER_MAX_NUM];
};

对于一个SoC 定义一个soc_ver_map 结构数组,使用id 和不同Version 在rev[] 中查找对应的组合值。

3.2.2.2 soc_ver_reg

SoC Version、BondingID、SecureEnable 的存储位置因SoC 而异,所以定义了一个结构来记录这类信息的位置,包括属于那个模块(基地址)、偏移、掩码、位移等。定义见sunxisid.c:

#define SUNXI_SOC_ID_INDEX 1
#define SUNXI_SECURITY_ENABLE_INDEX 2
struct soc_ver_reg {
s8 compatile[48];
u32 offset;
u32 mask;
u32 shift;
};

每个SoC 会定义一个soc_ver_reg 数组,目前各元素的定义如下:
0 - SoC Version 信息在寄存器中的位置。
1 - BondingID 信息在寄存器中的位置。
2 - SecureEnable 信息在寄存器中的位置。

3.2.3 全局变量

定义几个static 全局变量,用于保存解析后的ChipID、SoC_Ver 等信息:

static unsigned int sunxi_soc_chipid[4];
static unsigned int sunxi_serial[4];
static int sunxi_soc_secure;
static unsigned int sunxi_soc_bin;
static unsigned int sunxi_soc_ver;

3.3 模块流程设计

3.3.1 SoC 信息读取流程

本节中,这里把SoC Ver、ChipID、SecureEnable 信息统称为“SoC 信息”,因为他们的读取过程非常相似。都是遵循以下流程:

image-20221219110111514

3.3.2 Efuse Key 读取流程

在读取Efuse 中Key 的时候,需要判断是否存在、以及访问权限,过程有点复杂,用以下流程图进行简单说明。

image-20221219110133623

4 接口设计

4.1 接口函数

4.1.1 s32 sunxi_get_platform(s8 *buf, s32 size)

• 作用:获取SoC 平台的名称,实际上是一个BSP 研发代号,如sun8iw11。
• 参数:
• buf: 用于保存平台名称的缓冲区
• size:buf 的大小
• 返回:
• 返回buf 中平台名称的实际拷贝长度(如果size 小于名称长度,返回size)。

4.1.2 int sunxi_get_soc_chipid(u8 *chipid)

• 作用:获取SoC 的ChipID(从Efuse 中读到的原始内容,包括数据内容和顺序)。
• 参数:
• chipid:用于保存ChipID 的缓冲区
• 返回:
• 会返回0,无实际意义

4.1.3 int sunxi_get_serial(u8 *serial)

• 作用:获取SoC 的序列号(由ChipID 加工而来,格式定义见《chipid 接口的实现方案》。
• 参数:
• serial:用于保存序列号的缓冲区
• 返回:
• 会返回0,无实际意义

4.1.4 sunxi_get_soc_chipid_str(char *serial)

• 作用:获取SoC 的ChipID 的第一个字节,要求转换为字符串格式。
• 参数:
• serial:用于打印ChipID 第一个字节的缓冲区
• 返回:
• 只会返回8(4 个字节的十六进制打印长度),无实际意义

4.1.5 int sunxi_get_soc_ft_zone_str(char *serial)

• 作用:获取FZ ZONE 的最后一个字节,要求转换为字符串格式。
• 参数:
• serial:用于打印ChipID 第一个字节的缓冲区
• 返回:
• 只会返回8(4 个字节的十六进制打印长度),无实际意义

4.1.6 int sunxi_get_soc_rotpk_status_str(char *status)

• 作用:获取rotpk 的状态,是否烧码
• 参数:
• status:用于记录是否烧码的缓冲区;0,未烧;1,已烧
• 返回:
• %d 的长度,无实际意义

4.1.7 int sunxi_soc_is_secure(void)

• 作用:获取整个系统的Secure 状态,即安全系统是否启用。
• 参数:
• 无
• 返回:
• 0,未启用安全系统;1,启用

4.1.8 unsigned int sunxi_get_soc_bin(void)

• 作用:用于芯片分bin,部分SoC 平台才支持。
• 参数:
• 无
• 返回:
• 0: fail
• 1: normal
• 2: faster
• 3: fastest

4.1.9 unsigned int sunxi_get_soc_ver(void)

• 作用:获取SoC 的版本信息。
• 参数:
• 无
• 返回:
• 返回一个十六进制的编号,需要调用者去判断版本号然后做出相应的处理。详情参看dts,
sid 节点。

4.1.10 s32 sunxi_efuse_readn(void key_name, void buf, u32

n)
• 作用:读取Efuse 中的一个key 信息。
• 参数:
• key_name - Key 的名称,定义详见sunxi-sid.h
• buf - 用于保存Key 值的缓冲区
• size - buf 的大小
• 返回:
• 0: success
• other: fail

4.2 内部函数

4.2.1 static s32 sid_get_base(struct device_node **pnode,

void __iomem **base, s8 *compatible, u32 sec)
• 作用:从DTS 中获取指定模块的寄存器基地址。
• 参数:
• pnode - 用于保存获取到的模块node 信息
• base - 用于保存获取到的寄存器基地址
• compatible - 模块名称,用于匹配DTS 中的模块
• 返回:
• 0: success
• other: fail

4.2.2 static void sid_put_base(struct device_node *pnode,

void __iomem *base, u32 sec)
• 作用:释放一个模块的基地址。
• 参数:
• pnode - 保存模块node 信息
• base - 该模块的寄存器基地址
• 返回:
• 无

4.2.3 static u32 sid_rd_bits(s8 *name, u32 offset, u32 shift,

u32 mask, u32 sec)
• 作用:从一个模块的寄存器中,读取指定位置的bit 信息。
• 参数:
• name - 模块名称,用于匹配DTS 中的模块
• offset - 寄存器相当于基地址的偏移
• shift - 该bit 在寄存器中的位移
• mask - 该bit 的掩码值
• 返回:

• 0,fail
• other,获取到的实际bit 信息

5 可测试性

  1. /sys/class/sunxi_info/sys_info
    此节点文件可以打印出一些SoC 信息,包括版本信息、ChipID 等:
# cat /sys/class/sunxi_info/sys_info

sunxi_platform : sun50iw10p1
sunxi_secure : secure
sunxi_chipid : 00000000000000000000000000000000
sunxi_chiptype : 00000400
sunxi_batchno : 0x1
  1. /sys/class/sunxi_info/key_info
    此节点用于获取指定名称的Key 信息。方法是先写入一个Key 名称,然后就可以读取到Key 的内容。执行效果如下:
# echo chipid > /sys/class/sunxi_info/key_info ; cat /sys/class/sunxi_info/key_info
0xf1c1b200: 0x00000400
0xf1c1b204: 0x00000000
0xf1c1b208: 0x00000000
0xf1c1b20c: 0x00000000

6 其他说明

当启用安全系统后,Non-Secure 空间将无法访问大部分的Efuse 信息,这个时候需要通过SMC 指令来读取这些Key 信息。此时不能再使用普通的寄存器读接口readl(),而是调用的SMC 接口:

目前,sunxi_smc_readl() 的实现在源代码sunxi-smc.c,该文件保存在drivers/char/sunxisysinfo。

int sunxi_smc_readl(phys_addr_t addr)

目前,sunxi_smc_readl() 的实现在源代码sunxi-smc.c,该文件保存在drivers/char/sunxisysinfo。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/365813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 方法超详细整理,适合新手入门

目录 一、什么是方法呢&#xff1f; 二、方法的优点 三、带返回值方法定义 语法&#xff1a; 示例&#xff1a; 四、带返回值方法调用 语法&#xff1a; 示例&#xff1a; 五、结果示例 一、什么是方法呢&#xff1f; Java方法是语句的集合&#xff0c;它们在一起执行…

Android 9.0 仿ios的hotseat效果修改hotseat样式

1.概述 在9.0的系统rom定制化的产品中,在launcher3的定制化需求中,有很多功能需求点需要开发,在对一下ui的定制化的过程中,会参考ios的样式进行定制化,所以最近项目需求 要求仿ios的hotseat的样式来进行产品的定制,开发一款仿ios的hotseat,所以需要对hotseat进行分析,然…

C语言进阶(八)—— 链表

1. 链表基本概念1.1 什么是链表链表是一种常用的数据结构&#xff0c;它通过指针将一些列数据结点&#xff0c;连接成一个数据链。相对于数组&#xff0c;链表具有更好的动态性&#xff08;非顺序存储&#xff09;。数据域用来存储数据&#xff0c;指针域用于建立与下一个结点的…

【CKA】

— k8s basic — 安装版本信息查询 命令行自动补全功能设置 01. Namespaces and Pods 02. Assigning Pods to Nodes 03. Basic Deployments 04. Advanced Deployment 05. Jobs, Init Containers and Cron Jobs 06. Manage DaemonSets 07. Manage Services 08. Manage Ingress …

【技术】雷达液位计设备安装方案

一、设备概述 雷达液位计为我司自主研发&#xff0c;采用FMCW技术&#xff0c;以24G毫米雷达波作为载波信号&#xff0c;该产品测量精度高、功耗低、体积小、重量轻&#xff1b;测量过程不受温度、气压、泥沙、灰尘、河流污染物、水面漂浮物、空气等环境因素的影响&#xff0c…

spring boot项目中i18n和META-INF.spring下的文件的作用

目录标题一、resource下的文件二、i18n下messages_zh_CN.properties三、spring.factories文件四、org.springframework.boot.autoconfigure.AutoConfiguration.imports一、resource下的文件 org.springframework.boot.autoconfigure.AutoConfiguration.imports &#xff1b; - …

微信小程序日记、微信小程序个人空间、个人日记

一.简述 个人比较喜欢微信小程序&#xff0c;因为小程序所追求的用户体验、代码质量、美观的样式&#xff0c;简单方便丰富的api、样式封装等&#xff0c;同时又与普通的前端开发非常相似&#xff0c;让人很容易就上手。 这篇博客介绍的是一款记录个人/家庭日常记录的微信小程…

VsCode开发工具的入门及基本使用

VsCode开发工具的入门及基本使用一、VsCode介绍1.VsCode简介2.VsCode特点二、安装VsCode1.下载VsCode2.安装VsCode3.打开VsCode三、设置VsCode中文1.搜索中文语言插件2.安装中文语言插件四、初识VsCode1.VsCode左侧栏模块2.系统设置功能五、VsCode初始配置1.禁用自动更新2.开启…

MQTT 5协议你知道多少?

一、MQTT 5简介 MQTT协议是当今世界上最流行、接受度最高的物联网协议。自推出以来&#xff0c;MQTT已经成功地连接了各种规模的部署中的无数受限设备。 流行的用例包括从连接汽车、制造系统、物流和军事到企业聊天应用程序和移动应用程序。MQTT协议的广泛使用催生了进一步发…

【离线数仓-5-数据仓库环境准备】

离线数仓-5-数据仓库环境准备离线数仓-5-数据仓库环境准备1.数据仓库运行环境1.Hive环境搭建1.Hive引擎2.Hive on Spark配置2.Yarn环境配置2.数据仓库开发环境3.模拟数据准备离线数仓-5-数据仓库环境准备 1.数据仓库运行环境 数仓之外需要做的事情&#xff1a; 数据安全认证&…

OSCP-课外2(git泄露、SQL注入)

难度 中 主机发现&端口扫描 sudo arp-scan -l sudo nmap -p- 192.168.65.128 sudo nmap -p22,80 -sC -sV 192.168.65.128 首先,发现了.git目录,可能通过代码审计发现漏洞的存在。 其次,发现了一个描述“login.php修改的更安全”,说明以前login.php版本可能存在安全…

活动预告 | 2023 Meet TVM 开年首聚,上海我们来啦!

内容一览&#xff1a;从去年 12 月延期至今的 TVM 线下聚会终于来了&#xff01;首站地点我们选在了上海&#xff0c;并邀请到了 4 位讲师结合自己的工作实践&#xff0c;分享 TVM 相关的开发经验&#xff0c;期待与大家线下相聚~ 关键词&#xff1a;2023 Meet TVM 线下活动 自…

操作系统(day15) -- I/O设备

I/O设备的基本概念与分类 I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备&#xff0c;属于计算机中的硬件部分。 I/O设备按使用特性可以分为以下类型&#xff1a; 人机交互类设备。用于与计算机用户之间交互的设备&#xff0c;如打印机、…

华为OD机试用Python实现 -【组合出合法最小数】(2023-Q1 新题)

华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 组合出合法最小数…

原子化 CSS 实践

原子化 CSS 实践 jcLee95 的CSDN 博客 邮箱 &#xff1a;291148484163.com CSDN 主页&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/129178547 目 录1. 概述 2. 原子化…

Flutter+【三棵树】

定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴&#xff1a;Elements和RenderObjects&#xff1b;由于它们都是有着树形结构&#xff0c;所以经常会称它们为三棵树。 这三棵树分别是&#xff1a;Widget、Element、RenderObject Widget树&#xff1a;寄存烘托内容…

代码随想录---二叉树的总结和二叉树的定义

二叉树的种类&#xff1a; 满二叉树&#xff1a;树的所有节点都是满&#xff0c;即都有左右孩子。 这棵二叉树为满二叉树&#xff0c;也可以说深度为k&#xff0c;有2^k-1个节点的二叉树。 完全二叉树&#xff1a;完全二叉树的定义如下&#xff1a;在完全二叉树中&#xff0c…

数据结构—堆(完全解析)

数据结构—堆&#xff08;完全解析&#xff09; 数据结构——堆&#xff08;Heap&#xff09;大根堆、小根堆 详解数据结构——堆 堆的基本存储 【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆 【堆/排序】堆排序的两种建堆方法 【算法】排序算法之堆排序 C…

【Tips】通过背数据了解业务

学习资料&#xff1a;做了三年数据分析&#xff0c;给你的几点建议 1. 通过背数据了解业务 原文&#xff1a; 总结&#xff1a; 方法&#xff1a;每天早上去到公司第一件事情就是先背一遍最新的各种指标。原理&#xff1a; 数据敏感性就是建立在对数据的了解和熟悉上。业务的…

使用Autoware标定工具包联合标定相机和激光雷达

前面文章介绍了&#xff0c;安装autoware标定工具包、ros驱动usb相机、robosense-16线激光雷达的使用&#xff0c;本文记录使用Autoware标定工具包联合标定相机和激光雷达的过程。1.ros驱动相机&#xff0c;启动相机&#xff1b;启动激光雷达2.联合录制bag包rosbag record -a 参…