Linux之内核内存属性代码分析(x86,ARM64,RISC-V)

1.简介

不同的处理器架构有不同的内存属性(memory type)及不同的行为。为了便于理解和使用,Linux内核在处理器架构的基础上抽象了一套软件接口,定义了noncached、writecombine、writethrough、device等通用的内存属性接口。内核开发者直接使用即可,不需要关注具体处理器架构的内存属性。
内核通用内存属性接口定义在include/linux/pgtable.h和include/asm-generic/io.h文件中,前者定义的内存属性用于将内核空间地址映射到用户空间,即remap_pfn_range函数,后者用于映射memory-mapped I/O设备空间。这些内存属性接口是architecture implementation,若架构没有实现,则使用内核通用接口。
 

[include/linux/pgtable.h]

#ifndef pgprot_noncached
#define pgprot_noncached(prot)        (prot)
#endif

#ifndef pgprot_writecombine
#define pgprot_writecombine           pgprot_noncached
#endif

#ifndef pgprot_writethrough
#define pgprot_writethrough           pgprot_noncached
#endif

#ifndef pgprot_device
#define pgprot_device                 pgprot_noncached
#endif

[include/asm-generic/io.h]
#ifndef ioremap
#define ioremap ioremap
static inline void __iomem *ioremap(phys_addr_t addr, size_t size)
{
    /* _PAGE_IOREMAP needs to be supplied by the architecture */
    return ioremap_prot(addr, size, _PAGE_IOREMAP);
}
#endif
#endif /* !CONFIG_MMU || CONFIG_GENERIC_IOREMAP */

#ifndef ioremap_wc
#define ioremap_wc ioremap
#endif

#ifndef ioremap_wt
#define ioremap_wt ioremap
#endif

/*
 * ioremap_uc is special in that we do require an explicit architecture
 * implementation.  In general you do not want to use this function in a
 * driver and use plain ioremap, which is uncached by default.  Similarly
 * architectures should not implement it unless they have a very good
 * reason.
 */
#ifndef ioremap_uc
#define ioremap_uc ioremap_uc
static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
{
    return NULL;
}
#endif

/*
 * ioremap_np needs an explicit architecture implementation, as it
 * requests stronger semantics than regular ioremap(). Portable drivers
 * should instead use one of the higher-level abstractions, like
 * devm_ioremap_resource(), to choose the correct variant for any given
 * device and bus. Portable drivers with a good reason to want non-posted
 * write semantics should always provide an ioremap() fallback in case
 * ioremap_np() is not available.
 */
#ifndef ioremap_np
#define ioremap_np ioremap_np
static inline void __iomem *ioremap_np(phys_addr_t offset, size_t size)
{
    return NULL;
}
#endif

下面表格中总结了X86、ARM64、RISC-V架构内存属性接口分别对应的内存属性,若架构中没有定义相应的接口,则使用通用的接口。

内存属性接口 内存属性
通用 X86 ARM64 RISC-V
pgprot_cached 未实现 未实现,默认为_PAGE_CACHE_MODE_WB MT_NORMAL 未实现,默认为_PAGE_PMA_THEAD
pgprot_noncached port _PAGE_CACHE_MODE_UC_MINUS MT_DEVICE_nGnRnE _PAGE_IO
pgprot_writecombine pgprot_noncached _PAGE_CACHE_MODE_WC MT_NORMAL_NC _PAGE_NOCACHE
pgprot_writethrough pgprot_noncached _PAGE_CACHE_MODE_WT MT_DEVICE_nGnRnE _PAGE_IO
pgprot_device pgprot_noncached _PAGE_CACHE_MODE_UC_MINUS MT_DEVICE_nGnRE _PAGE_IO

下面表格中总结了X86、ARM64、RISC-V架构IO地址映射接口分别对应的内存属性,若架构中没有定义相应的接口,则使用通用的接口。

属性接口 内存属性
通用 X86 ARM64 RISC-V
ioremap _PAGE_IOREMAP _PAGE_CACHE_MODE_UC_MINUS MT_DEVICE_nGnRE _PAGE_IO
ioremap_uc 未实现 _PAGE_CACHE_MODE_UC 未实现 未实现
ioremap_wc ioremap _PAGE_CACHE_MODE_WC MT_NORMAL_NC _PAGE_IO
ioremap
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值