Linux内核高端内存管理之固定内存区与映射

字体大小: 中小 标准 ->行高大小: 标准

前面(见 http://www.linuxidc.com/Linux/2012-02/53457.htm 与 http://www.linuxidc.com/Linux/2012-02/53458.htm)总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图

Linux内核高端内存管理之固定内存区与映射

对于固定内存在linux内核中有下面描述

[cpp]
  1. enum fixed_addresses {   #ifdef CONFIG_X86_32   
  2.     FIX_HOLE,       FIX_VDSO,  
  3. #else        VSYSCALL_LAST_PAGE,  
  4.     VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE                   + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,  
  5.     VSYSCALL_HPET,   #endif   
  6.     FIX_DBGP_BASE,       FIX_EARLYCON_MEM_BASE,  
  7. #ifdef CONFIG_X86_LOCAL_APIC        FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */  
  8. #endif    #ifdef CONFIG_X86_IO_APIC   
  9.     FIX_IO_APIC_BASE_0,       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,  
  10. #endif    #ifdef CONFIG_X86_VISWS_APIC   
  11.     FIX_CO_CPU, /* Cobalt timer */       FIX_CO_APIC,    /* Cobalt APIC Redirection Table */  
  12.     FIX_LI_PCIA,    /* Lithium PCI Bridge A */       FIX_LI_PCIB,    /* Lithium PCI Bridge B */  
  13. #endif    #ifdef CONFIG_X86_F00F_BUG   
  14.     FIX_F00F_IDT,   /* Virtual mapping for IDT */   #endif   
  15. #ifdef CONFIG_X86_CYCLONE_TIMER        FIX_CYCLONE_TIMER, /*cyclone timer register*/  
  16. #endif    #ifdef CONFIG_X86_32   
  17.     FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,  
  18. #ifdef CONFIG_PCI_MMCONFIG        FIX_PCIE_MCFG,  
  19. #endif    #endif   
  20. #ifdef CONFIG_PARAVIRT        FIX_PARAVIRT_BOOTMAP,  
  21. #endif        FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */  
  22.     FIX_TEXT_POKE0, /* first page is last, because allocation is backward */       __end_of_permanent_fixed_addresses,  
  23.     /*       * 256 temporary boot-time mappings, used by early_ioremap(), 
  24.      * before ioremap() is functional.       * 
  25.      * We round it up to the next 256 pages boundary so that we       * can have a single pgd entry and a single pte table: 
  26.      */   #define NR_FIX_BTMAPS       64   
  27. #define FIX_BTMAPS_SLOTS    4        FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -  
  28.             (__end_of_permanent_fixed_addresses & 255),       FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,  
  29. #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT        FIX_OHCI1394_BASE,  
  30. #endif    #ifdef CONFIG_X86_32   
  31.     FIX_WP_TEST,   #endif   
  32. #ifdef CONFIG_INTEL_TXT        FIX_TBOOT_BASE,  
  33. #endif        __end_of_fixed_addresses  
  34. };  

固定映射

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

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

[cpp]
  1. void __init early_ioremap_init(void)   {  
  2.     pmd_t *pmd;       int i;  
  3.        if (early_ioremap_debug)  
  4.         printk(KERN_INFO "early_ioremap_init()\n");       /*将fixed_address里的索引的虚拟地址放入slot_virt 
  5.     ,从代码里面可以看出,放入slot_virt中得虚拟地址为1M*/       for (i = 0; i < FIX_BTMAPS_SLOTS; i++)  
  6.         slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);     
  7.     /*得到固定映射区的pmd      ,此pmd为虚拟地址转换为物理地址的pmd*/  
  8.     pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));       memset(bm_pte, 0, sizeof(bm_pte));  
  9.     /*将bm_pte页表设置为固定映射区开始地址的pmd的第一个页表;*/       pmd_populate_kernel(&init_mm, pmd, bm_pte);  
  10.        /* 
  11.      * The boot-ioremap range spans multiple pmds, for which       * we are not prepared: 
  12.      */        /*系统要求所有的ioremap映射在一个pmd上,超出这个pmd将警告*/  
  13.     if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {           WARN_ON(1);  
  14.         printk(KERN_WARNING "pmd %p != %p\n",                  pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));  
  15.         printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",               fix_to_virt(FIX_BTMAP_BEGIN));  
  16.         printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END):   %08lx\n",               fix_to_virt(FIX_BTMAP_END));  
  17.            printk(KERN_WARNING "FIX_BTMAP_END:       %d\n", FIX_BTMAP_END);  
  18.         printk(KERN_WARNING "FIX_BTMAP_BEGIN:     %d\n",                  FIX_BTMAP_BEGIN);  
  19.     }   }  
[cpp]
  1. static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;  
[cpp]
  1. #define __fix_to_virt(x)    (FIXADDR_TOP - ((x) << PAGE_SHIFT))  

其中FIXADDR_TOP为4G-4K。

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/57904.html