Documentation/translations/zh_CN/core-api/packing.rst

Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/core-api/packing.rst

File Facts

System
Linux kernel
Corpus path
Documentation/translations/zh_CN/core-api/packing.rst
Extension
.rst
Size
7235 bytes
Lines
161
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

.. SPDX-License-Identifier: GPL-2.0+

.. include:: ../disclaimer-zh_CN.rst

:Original: Documentation/core-api/packing.rst

:翻译:

 周彬彬 Binbin Zhou <zhoubinbin@loongson.cn>

:校译:

 司延腾 Yanteng Si <siyanteng@loongson.cn>
 吴想成 Wu Xiangcheng <bobwxc@email.cn>
 时奎亮 Alex Shi <alexs@kernel.org>

========================
通用的位域打包和解包函数
========================

问题陈述
--------

使用硬件时,必须在几种与其交互的方法之间进行选择。

可以将指针映射到在硬件设备的内存区上精心设计的结构体,并将其字段作为结构成员(可
能声明为位域)访问。但是由于CPU和硬件设备之间潜在的字节顺序不匹配,以这种方式编写
代码会降低其可移植性。

此外,必须密切注意将硬件文档中的寄存器定义转换为结构的位域索引。此外,一些硬件
(通常是网络设备)倾向于以违反任何合理字边界(有时甚至是64位)的方式对其寄存器字
段进行分组。这就造成了不得不在结构中定义寄存器字段的“高”和“低”部分的不便。

结构域定义的更可靠的替代方法是通过移动适当数量的位来提取所需的字段。但这仍然不能
防止字节顺序不匹配,除非所有内存访问都是逐字节执行的。此外,代码很容易变得杂乱无
章,同时可能会在所需的许多位移操作中丢失一些高层次的想法。

许多驱动程序采用了位移的方法,然后试图用定制的宏来减少杂乱无章的东西,但更多的时
候,这些宏所采用的捷径依旧妨碍了代码真正的可移植性。

解决方案
--------

该API涉及2个基本操作:

  - 将一个CPU可使用的数字打包到内存缓冲区中(具有硬件约束/特殊性)。
  - 将内存缓冲区(具有硬件约束/特殊性)解压缩为一个CPU可使用的数字。

该API提供了对所述硬件约束和特殊性以及CPU字节序的抽象,因此这两者之间可能不匹配。

这些API函数的基本单元是u64。从CPU的角度来看,位63总是意味着字节7的位偏移量7,尽管
只是逻辑上的。问题是:我们将这个比特放在内存的什么位置?

以下示例介绍了打包u64字段的内存布局。打包缓冲区中的字节偏移量始终默认为0,1...7。
示例显示的是逻辑字节和位所在的位置。

1. 通常情况下(无特殊性),我们会这样做:

::

  63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  7                       6                       5                        4
  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  3                       2                       1                        0

也就是说,CPU可使用的u64的MSByte(7)位于内存偏移量0处,而u64的LSByte(0)位于内存偏移量7处。

这对应于大多数人认为的“大端”,其中位i对应于数字2^i。这在代码注释中也称为“逻辑”符号。

Annotation

Implementation Notes