linux内核博大精深,Linux Kernel里的cpu_to_le32是干啥的?

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

在kernel里面经常能看见把十六进制数用下面几个函数转换一下,比如be32_to_cpu, cpu_to_be32, cpu_to_le16,cpu_to_le32等.其实很简单.

名词解释

le叫做little endian, be叫做big endian,这是两种字节序,分别称为小段和大端.

le表示地址低为存储值的低位,地址高位存储值的高位.

be表示地址低位存储值的高位,地址高位存储值的低位.

不用cpu使用了不同的字节序,比如PowerPC系列cpu就用了大端模式,而ARM和x86就用的小端模式.

因此,对于不用的cpu,上面几个函数的执行结果也是不一样的.

但是,凡是xx_to_cpu就说明结果是给cpu使用的.反之,cpu_to_xx就说明从cpu的字节序转换成目标字节序.

如果cpu本身就是小端模式,那么cput_to_le32这类函数就会do nothing.

如何实现

下面以cpu_to_le32为例,看看内核是如何转换的.

//generic.h#define cpu_to_le32 __cpu_to_le32//cpu如果是小端模式,do nothing#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))//cpu如果是大端模式,交换#define __cpu_to_le32(x) ((__force __le32)__swab32((x)))

/**

* __swab32 - return a byteswapped 32-bit value

* @x: value to byteswap

*/

#define __swab32(x)

(__builtin_constant_p((__u32)(x)) ?

___constant_swab32(x) :

__fswab32(x))

//通过与运算和位移操作实现高低位交换操作#define ___constant_swab32(x) ((__u32)(

(((__u32)(x) & (__u32)0x000000ffUL) << 24) |

(((__u32)(x) & (__u32)0x0000ff00UL) << 8) |

(((__u32)(x) & (__u32)0x00ff0000UL) >> 8) |

(((__u32)(x) & (__u32)0xff000000UL) >> 24)))

kernel真是博大精深,一直以来都是专心调驱动,对这些细节还从来没仔细研究过,当仔细看过之后,不得不佩服Kernel的contributor确实牛逼啊.

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值