尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Linux下atsha204a加密芯片驱动源码拆解与避坑指南
简介这份资源是面向嵌入式与Linux内核开发者的ATSHA204A加密芯片驱动源码包聚焦安全认证与数据加密场景适合需要将SHA-256哈希与AES-128加密能力接入系统的中高级开发者参考。压缩包共12个文件约32KB以6个.h头文件与4个.c实现文件为主分别承担接口定义、I2C通信、命令收发与API封装等职责另含1个Makefile和1个Kconfig用于编译规则与内核配置。源码结构清晰涵盖模块初始化、读写操作、ioctl接口及返回码定义等核心逻辑可帮助读者理解Linux字符设备驱动如何与硬件安全芯片交互并作为Android HAL集成的参考起点。目前已有485人学习下载适合希望深入驱动开发、硬件抽象层设计及加密芯片应用的读者研读与移植。1. 从一颗加密芯片说起atsha204a 在 Linux 下到底怎么跑起来如果你手里有一块带 atsha204a 的板子插上 Linux 系统后i2cdetect能看到地址但/dev下什么都没有那这篇笔记就是写给你的。atsha204a 是一颗常见的加密认证芯片走 I2C 或单总线主要用来做设备身份认证、密钥存储和随机数生成。Linux 内核里其实有它的驱动但很多人拿到源码后卡在设备树配置和 hwmon 接口对接上。我这次拆的是一份 atsha204a 的 Linux 驱动源码结构不复杂但细节不少。适合谁看做嵌入式安全、IoT 设备认证、或者单纯想给板子加一颗加密芯片的开发者。下面从目录结构开始一路讲到怎么改、怎么验证。2. 驱动源码结构拆解从 Makefile 到 i2c_driver 注册2.1 目录布局与编译入口拿到源码包第一件事不是看.c文件而是看Makefile和Kconfig。这份 atsha204a 驱动通常放在drivers/crypto/或者drivers/hwmon/下具体取决于它暴露的接口。我手上这份是放在drivers/crypto/atsha204a/里目录结构大致如下atsha204a/ ├── Makefile ├── Kconfig ├── atsha204a-core.c ├── atsha204a-i2c.c ├── atsha204a.h └── atsha204a-common.cMakefile里一般就一行obj-$(CONFIG_ATSHA204A) atsha204a.o然后atsha204a-objs : atsha204a-core.o atsha204a-i2c.o atsha204a-common.o。这里有个坑如果你只编译atsha204a-i2c.c会报一堆未定义符号因为核心逻辑在core里。Kconfig里定义config ATSHA204A依赖I2C和CRC8有些版本还依赖HW_RANDOM。编译前先确认内核配置里CONFIG_CRC8是y否则链接阶段会翻车。2.2 i2c_driver 注册与设备树匹配核心注册逻辑在atsha204a-i2c.c里典型写法如下static const struct i2c_device_id atsha204a_id[] { { atsha204a, 0 }, { } }; MODULE_DEVICE_TABLE(i2c, atsha204a_id); static const struct of_device_id atsha204a_of_match[] { { .compatible atmel,atsha204a }, { } }; MODULE_DEVICE_TABLE(of, atsha204a_of_match); static struct i2c_driver atsha204a_driver { .driver { .name atsha204a, .of_match_table atsha204a_of_match, }, .probe atsha204a_probe, .remove atsha204a_remove, .id_table atsha204a_id, }; module_i2c_driver(atsha204a_driver);这段代码做了三件事定义 I2C 设备 ID 表、定义设备树匹配表、注册i2c_driver。module_i2c_driver宏把init和exit都包了省事。注意compatible字符串必须和你的设备树里写的一致常见的是atmel,atsha204a但有些板子用atmel,atsha204差一个字母就匹配不上。probe函数里一般会做devm_kzalloc、i2c_set_clientdata、初始化crc8表、然后注册hwmon或者crypto设备。如果你发现probe根本没进先查compatible和 I2C 地址。2.3 设备树节点与 I2C 地址配置设备树里要加一个节点挂在对应的 I2C 控制器下i2c1 { status okay; clock-frequency 100000; atsha204a: atsha204a64 { compatible atmel,atsha204a; reg 0x64; wakeup-gpios gpio1 12 GPIO_ACTIVE_HIGH; }; };reg是 I2C 从地址atsha204a 默认是0x64但有些封装是0xC8右移一位写0x64就对了。wakeup-gpios是可选的如果芯片需要唤醒引脚驱动里会devm_gpiod_get拿这个 GPIO。clock-frequency建议先设100000atsha204a 支持 400k但长走线容易出玄学问题降速能解决大部分通信失败。设备树改完记得make dtbs并更新到板子上别只编译内核模块。3. 核心通信流程I2C 读写、CRC 校验与命令封装3.1 底层 I2C 传输函数atsha204a 的通信协议是固定长度的包发命令和收响应都走 I2C。驱动里一般封装一个atsha204a_i2c_xferstatic int atsha204a_i2c_xfer(struct atsha204a *atsha, u8 *tx, u8 *rx, size_t len) { struct i2c_client *client atsha-client; struct i2c_msg msg[2]; int ret; msg[0].addr client-addr; msg[0].flags 0; msg[0].len len; msg[0].buf tx; msg[1].addr client-addr; msg[1].flags I2C_M_RD; msg[1].len len; msg[1].buf rx; ret i2c_transfer(client-adapter, msg, 2); if (ret 0) { dev_err(client-dev, i2c transfer failed: %d\n, ret); return ret; } return 0; }这里用i2c_transfer而不是i2c_master_send因为 atsha204a 需要先写命令再读响应中间不能有 stop。msg[0]发命令msg[1]读响应len通常是 4 字节命令包或 32 字节响应包。注意client-addr是 7 位地址内核会自动处理读写位。如果返回-EREMOTEIO多半是芯片没应答查供电和上拉电阻。3.2 CRC8 校验与命令包组装atsha204a 的响应包最后一位是 CRC8 校验驱动里要算static u8 atsha204a_crc8(const u8 *data, size_t len) { u8 crc 0; size_t i; int j; for (i 0; i len; i) { crc ^ data[i]; for (j 0; j 8; j) { if (crc 0x01) crc (crc 1) ^ 0x8C; else crc 1; } } return crc; }多项式是0x8C初值0不反转。算完和响应最后一位比对不匹配就丢包重试。命令包组装一般长这样static int atsha204a_send_cmd(struct atsha204a *atsha, u8 opcode, u8 param1, u8 param2, u8 *data, size_t len) { u8 tx[4 len]; u8 rx[32]; int ret; tx[0] 0x03; /* 命令包长度 */ tx[1] opcode; tx[2] param1; tx[3] param2; memcpy(tx[4], data, len); ret atsha204a_i2c_xfer(atsha, tx, rx, sizeof(tx)); if (ret) return ret; if (atsha204a_crc8(rx, 31) ! rx[31]) { dev_err(atsha-client-dev, crc mismatch\n); return -EIO; } memcpy(data, rx, len); return 0; }opcode常见的有0x02随机数、0x10读配置区、0x12读数据区。param1和param2看具体命令。tx[0]是包长度固定0x03表示后面 3 字节。响应固定 32 字节最后一位 CRC。这里有个血泪经验i2c_transfer的len别写错写 4 发 4 读 4芯片会直接不理你。3.3 随机数与认证命令的调用链随机数命令最简单用来验证通信是否正常int atsha204a_get_random(struct atsha204a *atsha, u8 *rnd) { u8 data[32]; int ret; ret atsha204a_send_cmd(atsha, 0x02, 0x00, 0x00, NULL, 0); if (ret) return ret; memcpy(rnd, data, 32); return 0; }认证命令复杂一些需要先读芯片序列号再算 MAC。驱动里一般暴露一个sysfs节点或者hwmon属性用户态通过echo触发。调用链是用户态写sysfs→store函数 →atsha204a_send_cmd→i2c_transfer。如果你要集成到自己的认证流程直接调atsha204a_get_random和atsha204a_send_cmd就行不用走sysfs。4. 避坑与排查设备树、地址、CRC 和权限的常见翻车点4.1 设备树匹配不上probe 不执行现象dmesg里没有任何atsha204a相关日志/sys/bus/i2c/devices/下也没有0-0064。原因compatible字符串和驱动里的of_device_id不一致或者 I2C 控制器status不是okay。解决先cat /proc/device-tree/i2c1/atsha204a64/compatible看实际值再和驱动源码比对。如果设备树里没节点手动echo atsha204a 0x64 /sys/bus/i2c/devices/i2c-1/new_device也能临时绑定。4.2 I2C 地址写错通信返回 -EREMOTEIO现象probe进了但i2c_transfer返回-EREMOTEIO。原因reg写成了0xC8或者0x32。atsha204a 的 7 位地址是0x64有些资料写 8 位地址0xC8内核要的是 7 位。解决i2cdetect -y 1确认芯片在0x64出现设备树里改成0x64。如果i2cdetect也看不到查供电和上拉atsha204a 工作电压 2.0V 到 5.5V别接错。4.3 CRC 校验失败随机数读出来全是 0xFF现象atsha204a_get_random返回成功但rnd全是0xFF。原因I2C 读时序不对i2c_transfer的msg[1].len写成了4而不是32或者msg[0]和msg[1]之间加了 stop。解决确认len是 32i2c_transfer返回 2 表示两个消息都成功。如果还是0xFF用逻辑分析仪抓波形看芯片有没有拉低 SDA 应答。4.4 sysfs 节点权限不对用户态写不进去现象echo 1 /sys/class/hwmon/hwmon0/random报Permission denied。原因sysfs属性默认0644但有些驱动写成0444只读。解决在probe里用sysfs_attr_init和device_create_file时指定S_IWUSR | S_IRUGO。或者直接用chmod临时改但重启就没了。更稳的做法是写一个ioctl接口别依赖sysfs。4.5 内核版本不匹配编译报 implicit declaration现象在 5.10 内核上编译 4.19 的驱动报implicit declaration of function ‘devm_gpiod_get_optional’。原因GPIO 描述符 API 在 4.19 之后有变动devm_gpiod_get_optional的第三个参数类型变了。解决看内核include/linux/gpio/consumer.h里的原型把GPIOD_OUT_HIGH改成GPIOD_OUT_HIGH或者GPIOD_ASIS。如果差异太大直接改驱动里的 GPIO 获取方式用of_get_named_gpio加gpio_request也能跑。5. 二次开发与验证从 sysfs 接口到自定义认证流程5.1 暴露一个干净的 sysfs 接口驱动默认可能只暴露hwmon的random属性但你要做认证最好自己加一个sysfs节点。在probe里加static ssize_t auth_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct atsha204a *atsha dev_get_drvdata(dev); u8 challenge[32]; u8 response[32]; int ret; if (count 32) return -EINVAL; memcpy(challenge, buf, 32); ret atsha204a_send_cmd(atsha, 0x14, 0x00, 0x00, challenge, 32); if (ret) return ret; memcpy(response, challenge, 32); dev_info(dev, auth response: %*phN\n, 32, response); return count; } static DEVICE_ATTR_WO(auth);然后在probe末尾device_create_file(dev, dev_attr_auth)。用户态echo -n 32字节挑战 /sys/.../auth就能触发认证。注意DEVICE_ATTR_WO只写读会报错。0x14是MAC命令的 opcode具体看数据手册。5.2 用 hwmon 接口做快速验证如果你不想改驱动直接用hwmon也能验证。加载模块后modprobe atsha204a ls /sys/class/hwmon/ cat /sys/class/hwmon/hwmon0/name cat /sys/class/hwmon/hwmon0/randomrandom属性读出来是 32 字节的十六进制字符串。如果name是atsha204a说明驱动绑定成功。random每次读都不同说明随机数命令正常。这个接口适合产线快速测试不用写额外代码。5.3 自定义认证流程的改造点要做设备认证一般流程是主机发挑战 → 芯片算 MAC → 主机验证。改造点有三个第一把atsha204a_send_cmd的opcode改成0x14param1设0x00表示TempKey来源第二挑战数据要 32 字节不足补零第三响应里的 MAC 要存下来和预期比对。我一般会在驱动里加一个miscdevice用ioctl传挑战和响应比sysfs灵活。ioctl命令号用_IOWR(A, 0x01, struct atsha204a_auth)结构体里放challenge[32]和response[32]。5.4 验证方法与调试技巧验证分三步先i2cdetect确认地址再dmesg | grep atsha204a看probe日志最后读random看数据。如果random读出来不变检查atsha204a_send_cmd里rx有没有被覆盖。调试时打开CONFIG_DYNAMIC_DEBUG在i2c_transfer前后加dev_dbg用echo file atsha204a-i2c.c p /sys/kernel/debug/dynamic_debug/control动态开日志。别用printk会把串口刷爆。5.5 一个容易忽略的时序问题atsha204a 在发命令后需要tWHI等待时间典型值 4ms。如果i2c_transfer返回太快芯片还没准备好读出来就是0xFF。解决在atsha204a_send_cmd里加usleep_range(4000, 5000)或者用wakeup-gpios拉低再拉高。我一开始没加随机数读十次错三次加了延时后一次不挂。从那以后我每次调 I2C 加密芯片都强制走一遍i2cdetectrandom读 逻辑分析仪抓波形三步缺一不可。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

AI知识库系统实战:Python+FAISS+text2vec实现语义问答

AI知识库系统实战:Python+FAISS+text2vec实现语义问答

简介:这份人工智能知识库系统源码包面向需要搭建知识管理或信息检索应用的开发者,提供了基于网页的完整实现,可解决知识条目的存储、分类和快速查询等问题。压缩包共22个文件,其中10个HTML页面负责界面展示,6个Python脚…

📅 2026/10/21 8:42:10
PCS储能双向变流器Simulink仿真功率控制环调试经验与避坑指南

PCS储能双向变流器Simulink仿真功率控制环调试经验与避坑指南

这篇文章不会去复述课本上的原理,而是从我实际调试PCS储能双向变流器Simulink仿真模型的经历出发,拆开功率控制环的每一层,把那些让人头秃的配合问题摊开来看。如果你也在为功率环响应、电流内环发散、模式切换冲击这类问题挠头,这…

📅 2026/10/21 8:42:10
国标GB28181+EasyCVR+视频质量诊断:构建智慧园区全域可视体系

国标GB28181+EasyCVR+视频质量诊断:构建智慧园区全域可视体系

很多年前第一次接触智慧园区项目时,我觉得视频监控系统是整个工程里最"简单"的部分——无非就是布点、装摄像头、上平台、能看录像。直到某园区项目进入运维期,业主那边每天接到一堆"某某摄像头黑屏""画面模糊看不清"&quo…

📅 2026/10/21 8:37:00
MORE NEWS

更多资讯

📰

关联规则与协同过滤:从原理到选型的推荐系统实战指南

1. 先搞清楚两件事:一个算“一起买”,一个算“像你的人”1.1 关联规则是找“购物篮里的规律”关联规则要做的事情,说人话就是:从一堆历史订单里找出“哪些东西经常被同时买”。这个思路最早来自线下零售的购物篮分析。顾客结账时收…

📰

分布式系统中进程组织的四大核心设计原则

1. 项目概述:为什么“进程组织”是分布式系统里最被低估的硬功夫 “分布式系统的进程组织”——这八个字乍看平平无奇,像教科书目录里一个不起眼的小节,但在我带过十几个中大型后端系统落地的实操经历里,它从来不是理论题&#xf…

📰

关联规则 vs 协同过滤:本质区别、场景选择与实战避坑指南

推荐系统里有个问题经常被拿出来讨论:关联规则和协同过滤,到底有什么区别?很多人做了几年推荐,用协同过滤做过不少项目,但让他解释关联规则和协同过滤的本质区别,却说不清楚。 我在实践中也栽过跟头。早期…

📰

分布式系统进程组织:五层实战架构与生产级落地

1. 项目概述:为什么“分布式系统的进程组织”不是个技术名词,而是一道生存考题 你打开一个电商App下单,后台可能同时跑着库存服务、订单服务、支付网关、风控引擎、物流跟踪、用户画像计算……这些服务未必在一台机器上,甚至未必在…

📰

从技术方案到视觉呈现:系统架构图设计方法论

写技术方案的人都知道,图和字往往是两套语言。很多团队里,文字方案写得清清楚楚,一到画系统架构图、业务流程图、数据流图,就开始凭感觉发挥:有人喜欢把整面墙的信息塞进一张图,有人用二十种颜色标"重…

📰

Gazebo仿真环境搭建实战:从物理引擎到多机器人协同调优

2. 为什么第三篇才聊仿真环境搭建 说实话,前两篇我主要讲了模型导入、关节配置、传感器插件这些基础操作。但越往后做越发现,很多问题根本不出在模型本身,而是出在仿真环境上。环境没搭好,后面调控制器、跑导航、做视觉识别&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬