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


前面(见  与 )总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图

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

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

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

固定映射

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

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

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

其中FIXADDR_TOP4G-4K

  • 1
  • 2
  • 下一页

相关内容