linux map io,关于arm linux的map_io

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

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

文来自本人的旧博客 http://blog.163.com/awaken_ing/blog/static/1206131972016226674429

1. 主要流程

平台:versatilepb ARM Versatile/PB (ARM926EJ-S) 内核版本2.6.35.7paging_init

|--devicemaps_init

| |--from VMALLOC_END, pmd_clear(pmd_off_k(addr))

| |--mdesc->map_io() => versatile_map_io

| | |--iotable_init

| | | |--create_mapping

2. 为何是 MT_DEVICE

linux-2.6.35.7/arch/arm/mach-versatile/core.cvoid __init versatile_map_io(void)

{

iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));

}

static struct map_desc versatile_io_desc[] __initdata = {

{

...

.type = MT_DEVICE

},

...

这里是 MTDEVICE, 而不是 MTUNCACHED, why?

MTDEVICE类型和 MTUNCACHED 的区别在 .protpte 和 .protsect 上.

看看 .protpte 和 .protsect 的作用?

2.1 .prot_pte 用途

使用到 .prot_pte 的地方:alloc_init_pte

{

set_pte_ext(pte, pfn_pte(pfn, type->prot_pte), 0);

}

等效于cpu_arm926_set_pte_ext(pte, pfn_pte(pfn, type->prot_pte), 0);

#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))

cpuarm926setpteext将主要工作交给 armv3setpteext, 这里并没有判断 LPTEMTDEVSHARED 或者 LPTE_SHARED, 所以, 对于硬件页表, 添加上也没有影响.

2.2 .prot_sect 用途alloc_init_section

{

pmd_t *pmd = pmd_offset(pgd, addr);

...如果 创建的是 section.

*pmd = phys | type->prot_sect;

}

所以, .prot_sect 用来写到物理页表去的, 不像二级页表, 这里linux不需要转换啥的.

MTDEVICE的 .protsect = PROTSECTDEVICE | PMDSECTS,

等效于 PMDTYPESECT|PMDSECTAPWRITE | PMDSECTS MTUNCACHED的.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,

buildmemtypetable()中会根据arm版本, 对 .protsect 进行修正, 比如:build_mem_type_table

{

if (cpu_arch < CPU_ARCH_ARMv6 ...)

mem_types[i].prot_sect &= ~PMD_SECT_S;

}

这里就不走读代码了, 直接打印结果.

往buildmemtype_table()中添加打印后(未添加上domain), 有

MTDEVICE 的 .protsect 为 0x412

MTUNCACHED的 .protsect 为 0x12

C(D3)和B(D2) 都是关闭的.

也就是多了个 PMDSECTAP_WRITE#define PMD_SECT_AP_WRITE (1 << 10)

先检查domain, 如果为01(Client), 则接着检查AP bits.

20aa2dd3191b8725fce9700b838e45a9.png

如果创建的是section的话, 类型MT_UNCACHED, 最多只能够 read-only, 不符合要求, 故不使用.

3. 虚拟地址指定成啥好呢?create_mapping

{

if ((md->type == MT_DEVICE || md->type == MT_ROM) &&

md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {

printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "

"overlaps vmalloc spacen",

__pfn_to_phys((u64)md->pfn), md->virtual);

}

}

如果是MTDEVICE, 那么, 不太建议映射(不是禁止, 因为只是打印了warning而已)到 3G~VMALLOCEND 之间. 建议我们映射到vmalloc与DMA之间的gap内 (vmalloc和DMA间的gap可不是8MB).

看下versatile的映射的虚拟地址. linux-2.6.35.7/arch/arm/mach-versatile/core.cstatic struct map_desc versatile_io_desc[] __initdata = {

{

.virtual = IO_ADDRESS(VERSATILE_SYS_BASE),

.pfn = __phys_to_pfn(VERSATILE_SYS_BASE),

.length = SZ_4K,

.type = MT_DEVICE

},

#define VERSATILE_SYS_BASE 0x1000 0000

#define IO_ADDRESS(x) (((x) & 0x0fff ffff)

+ (((x) >> 4) & 0x0f00 0000)

+ 0xf000 0000)

所以, 计算出来的虚拟地址为 0xf100 0000.Virtual kernel memory layout:

...

DMA : 0xffc00000 - 0xffe00000 ( 2 MB)

vmalloc : 0xc8800000 - 0xd8000000 ( 248 MB)

正是处于vmalloc与DMA之间的gap内.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值