kstrtoul

义项:Linux内核字符串转无符号长整型函数
kstrtoul

kstrtoul是Linux内核提供的一个库函数,用于把以字符串形式给出的数值按指定进制解析成无符号长整型(unsigned long),并返回状态码告知调用者成功、溢出或格式错误[1]。它属于内核kstrto函数族,与kstrtoull、kstrtol、kstrtoint等并列,替代了不做溢出检查的旧接口simple_strtoul,因此被内核文档列为解析单个数字字符串的推荐方式。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

kstrtoul是Linux内核中的一个整数解析函数,声明形式为 int kstrtoul(const char *s, unsigned int base, unsigned long *res),其中 s 指向待解析的字符串,base 指定进制,res 指向用来保存转换结果的无符号长整型变量[1]。它在头文件 include/linux/kstrtox.h 中以 static inline 函数的形式定义,返回值类型为 int,并带有 __must_check 属性,提示调用者不能忽略返回值[2]。

该函数的返回值有三种常见取值:解析成功时为 0,输入数值超出目标类型可表示范围时返回 -ERANGE,字符串无法按给定进制解析时返回 -EINVAL[1]。它以“k”前缀命名,与该族中的 kstrtoull、kstrtol、kstrtoint 等函数共同构成一套整数转换接口[3]。

原理

函数的基本流程分为三步:先根据 base 参数确认进制,再逐字符把数字位累加成整数,最后校验字符串尾部是否只剩一个换行符和结束符[4]。当 base 传入 0 时执行自动识别:以 0x 开头按十六进制解析,以 0 开头按八进制解析,其余情况按十进制解析[1]。

累加过程中,每读入一位数字就执行 $res = res \times base + val$,并在累加前判断是否即将越界,一旦越界就置上溢出标志,最终转换为 -ERANGE 返回[4]。函数不接受减号,字符串首字符可以是加号,也允许在字符串结束符之前出现一个换行符,这一约定与从 sysfs、procfs 读取一行文本的场景相配合[1]。

在实现上,kstrtoul 本身是一个包装层:如果目标平台的无符号长整型与无符号长长整型宽度和对齐方式一致,就直接把结果指针转换后交给 kstrtoull 处理;否则调用内部函数 _kstrtoul,先按 64 位解析,再检查结果能否放进无符号长整型,不能则返回 -ERANGE[5]。内部函数 _kstrtoul 被标注为“供内部使用、不要直接调用”[6]。

发展历程

2011 年 3 月 22 日,开发者 Alexey Dobriyan 提交了名为“kstrto*: converting strings to integers done (hopefully) right”的补丁,一次性引入了 kstrtoull、kstrtoll、kstrtoul、kstrtol、kstrtouint、kstrtoint 及其定宽变体,并附带了运行时测试代码[3]。补丁说明列举了旧接口的问题:simple_strto* 不含溢出检查,strict_strto* 虽名为严格却同样不检查溢出,且两组函数只提供 long 与 long long 两种宽度[7]。

在这次重构中,原先的 strict_strtoul 等接口被降级为指向 kstrtoul 等新函数的宏,随后逐步移除[3]。2011 年 4 月又提交了简化 _kstrtoull 内部实现以及修正测试代码编译警告的后续补丁[8]。2020 年 4 月,有补丁把 kstrtoul 一类的转换函数引入 x86 的引导阶段代码,说明其用途已从常规内核代码延伸到更早期的启动环境[9]。

应用

kstrtoul 的典型用途是把用户或设备提供的文本参数转成内核可用的整数。由于内核命令行、sysfs 属性文件、procfs 文件在读取时通常带有换行符,函数允许末尾仅有一个换行符,使解析代码不必先手工截断字符串[1]。这种“从一处文本读取一个整数”的用法,正是该函数族最初的设计目标[10]。

函数族中还提供了 kstrtoul_from_user 这样的变体,用于从用户空间缓冲区复制指定长度的数据后再解析,适应不能保证零结尾的输入来源[6]。在设备驱动中,配置项如地址、长度、超时值常以字符串形式来自设备树覆盖层或模块参数,调用者据此选用 kstrtoul 并检查返回码[1]。

局限

kstrtoul 要求整个字符串被完整消费,非数字字符不能出现在有效数字之后,因此无法直接解析“10x50”“12:21”这类含分隔符的复合格式。同样地,它一次只转换一个整数,不支持 printf 风格的模板,也不做单位换算[10]。

该函数只处理无符号数值,遇到减号会判为非法输入,需要负数时应改用同族的 kstrtol[1]。进制上限为 16,没有 base 36 之类的扩展,前缀 0x 的识别还依赖后续字符确实是十六进制数字,否则会退化为八进制或十进制解释[2]。此外,无符号长整型的宽度随架构而异:32 位平台上能表示的数值范围比 64 位平台小,可移植代码不宜假定固定位宽[5]。

参见

  • kstrtoull —— 同一函数族中解析无符号长长整型的版本,供 kstrtoul 在宽度匹配时直接复用。

  • kstrtol —— 对应有符号长整型的解析函数,接受正负号。

  • simple_strtoul —— 被 kstrtoul 取代的旧接口,不做溢出检查。

  • sysfs —— 内核向用户空间导出属性的文件系统,其文本值常由 kstrtoul 类函数解析。

  • Linux内核 —— kstrtoul 所属的软件项目。

参考资料

  1. kstrtoul(9) — linux-manual-4.8 — Debian testing [引用日期2026-10-29]
  2. source code of linux/include/linux/kstrtox.h [引用日期2026-10-29]
  3. github.com 上的网页 [引用日期2026-10-29]
  4. softwareheritage.org 上的网页 [引用日期2026-10-29]
  5. raw [引用日期2026-10-29]
  6. kstrtox.h « linux « include - kernel/git/vfs/vfs.git [引用日期2026-10-29]
  7. index : str/linux [引用日期2026-10-29]
  8. Cross Reference: /lib/kstrtox.c [引用日期2026-10-29]
  9. iu.edu 上的网页 [引用日期2026-10-29]
  10. iu.edu 上的网页 [引用日期2026-10-29]
词条评价
词条统计

浏览次数:1 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-28T18:28:15Z

历史版本

本条目引用的词条
Linux内核 用户空间 设备驱动 kstrtoull kstrtol simple_strtoul sysfs