• 在linux内核中为什么解析设备树时会使用be32_to_cpup()接口?


    1. be32_to_cpup()接口是干什么的呢?
      转换一个无符号的, 大端, 32位值到一个cpu的大小端值(如果cpu为大端序,就将数值直接返回此值;如果cpu为小端序,就将数值转换为小端序)

    2. be32_to_cpup()接口的定义(linux内核源码的版本为5.9)
      #define be32_to_cpup __be32_to_cpup
      2.1 如果cpu为小端序

    static __always_inline __u32 __be32_to_cpup(const __be32 *p), include/uapi/linux/byteorder/little_endian.h
    {
    return __swab32p((__u32 *)p);
    }

    static __always_inline __u32 __swab32p(const __u32 p), include/uapi/linux/swab.h
    {
    #ifdef __arch_swab32p
    return __arch_swab32p(p);
    #else
    return __swab32(
    p);
    #endif
    }

    #ifdef HAVE_BUILTIN_BSWAP32 (include/uapi/linux/swab.h)
    #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
    #else
    #define __swab32(x)
    (__builtin_constant_p((__u32)(x)) ?
    ___constant_swab32(x) :
    __fswab32(x))
    #endif

    static inline attribute_const __u32 __fswab32(__u32 val), include/uapi/linux/swab.h
    {
    #if defined(__arch_swab32)
    return __arch_swab32(val);
    #else
    return ___constant_swab32(val);
    #endif
    }

    #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)))

    2.2 如果cpu为大端序
    static __always_inline __u32 __be32_to_cpup(const __be32 p), include/uapi/linux/byteorder/big_endian.h
    {
    return (__force __u32)
    p;
    }

    1. 在linux内核中为什么解析设备树时会使用be32_to_cpup()接口?
      因为使用的设备树dtb文件(dtc将dts文件转换为dtb文件)是以大端序方式存储的
  • 相关阅读:
    【原创】(九)Linux内存管理
    【原创】(八)Linux内存管理
    【原创】(六)Linux内存管理
    【原创】(四)Linux内存模型之Sparse Memory Model
    2019年总结
    被低估的.NET(下)-2019 中国.NET 开发者峰会
    《.NET内存管理宝典》阅读指南
    《 .NET并发编程实战》扩展阅读
    《 .NET并发编程实战》阅读指南
    《 .NET并发编程实战》阅读指南
  • 原文地址:https://www.cnblogs.com/dakewei/p/13848569.html
Copyright © 2020-2023  润新知