设为首页 加入收藏

TOP

高端内存映射之kmap_atomic固定映射--Linux内存管理(二十一)(一)
2019-09-01 23:09:17 】 浏览:60
Tags:高端 内存 映射 kmap_atomic 固定 --Linux 管理 二十一

1 固定映射

1.1 数据结构

linux高端内存中的临时内存区为固定内存区的一部分, 对于固定内存在linux内核中有下面描述

x86 arm arm64
arch/x86/include/asm/fixmap.h?v=4.7, line 67 arch/arm/include/asm/fixmap.h?v=4.7, line 11 arch/arm64/include/asm/fixmap.h?v=4.7, line 36
/*
 * Here we define all the compile-time 'special' virtual
 * addresses. The point is to have a constant address at
 * compile time, but to set the physical address only
 * in the boot process.
 *
 * These 'compile-time allocated' memory buffers are
 * page-sized. Use set_fixmap(idx,phys) to associate
 * physical memory with fixmap indices.
 *
 */
enum fixed_addresses {
    FIX_HOLE,

    /*
     * Reserve a virtual window for the FDT that is 2 MB larger than the
     * maximum supported size, and put it at the top of the fixmap region.
     * The additional space ensures that any FDT that does not exceed
     * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
     * 2 MB alignment boundaries.
     *
     * Keep this at the top so it remains 2 MB aligned.
     */
#define FIX_FDT_SIZE        (MAX_FDT_SIZE + SZ_2M)
    FIX_FDT_END,
    FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,

    FIX_EARLYCON_MEM_BASE,
    FIX_TEXT_POKE0,
    __end_of_permanent_fixed_addresses,

    /*
     * Temporary boot-time mappings, used by early_ioremap(),
     * before ioremap() is functional.
     */
#define NR_FIX_BTMAPS       (SZ_256K / PAGE_SIZE)
#define FIX_BTMAPS_SLOTS    7
#define TOTAL_FIX_BTMAPS    (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)

    FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
    FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,

    /*
     * Used for kernel page table creation, so unmapped memory may be used
     * for tables.
     */
    FIX_PTE,
    FIX_PMD,
    FIX_PUD,
    FIX_PGD,

    __end_of_fixed_addresses
};

1.2 固定映射

ioremap的作用是将IOBIOS以及物理地址空间映射到在896M至1G的128M的地址空间内, 使得kernel能够访问该空间并进行相应的读写操作。

start_kernel()->setup_arch()->early_ioremap_init()

然后arm和arm64上early_ioremap_init又是early_ioremap_setup的前端

函数 x86 arm arm64
early_ioremap_init arch/x86/mm/ioremap.c?v=4.7, line 445 arch/arm/mm/ioremap.c?v=4.7, line 489 arch/arm64/mm/ioremap.c?v=4.7, line 110
early_ioremap_setup mm/early_ioremap.c?v=4.7, line 67 体系结构无关 体系结构无关
/*
 * Must be called after early_fixmap_init
 */
void __init early_ioremap_init(void)
{
    early_ioremap_setup();
}

但是arm和arm64下的setup_arch函数则会先调用early_fixmap_init函数来填充fixmap. 参见arch/arm/kernel/setup.c?v=4.7, line 1058arch/arm64/kernel/setup.c?v=4.7, line 229.

void __init setup_arch(char **cmdline_p)
{
    early_fixmap_init();
    early_ioremap_init();
}

early_fixmap_init函数的定义在

arm arm64
arch/arm/mm/mmu.c?v=4.7, line 385 arch/arm64/mm/mmu.c?v=4.7, line 676

其中arm架构的定义如下所示, 在arch/arm/mm/mmu.c?v=4.7, line 385

void __init early_fixmap_init(void)
{
    pmd_t *pmd;

    /*
     * The early fixmap range spans multiple pmds, for which
     * we are not prepared:
     */
    BUILD_BUG_ON((__fix_to_virt(__end_of_early_ioremap_region) >> PMD_SHIFT)
             != FIXADDR_TOP >> PMD_SHIFT);

    /*得到固定映射区的pmd
    ,此pmd为虚拟地址转换为物理地址的pmd*/
    pmd = fixmap_pmd(FIXADDR_TOP);
     /*将bm_pte页表设置为固定映射区开始地址的pmd的第一个页表;*/
    pmd_populate_kernel(&init_mm, pmd, bm_pte);

    pte_offset_fixmap = pte_offset_early_fixmap;
}

1.3 ioremap函数

对于ioremap的使用需要通过early_memremapearly_iounmap进行.

由于对应于ioremap的内存空间是有限的, 所以对于ioremap空间的使用遵照使用结束马上释放的原则. 这就是说early_memremap和early_iounmap必须配对使用并且访问结束必须马上执行unmap

2 临时内核映射

刚才描述的kmap函数不能用于中断处理程序,

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇内存相关工具 下一篇宋宝华:关于Ftrace的一个完整案..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目