歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核高端內存管理之固定內存區與映射

前面(見 http://www.linuxidc.com/Linux/2012-02/53457.htm 與 http://www.linuxidc.com/Linux/2012-02/53458.htm)總結了高端內存中永久內核映射和臨時內核映射。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的作用是將IO和BIOS以及物理地址空間映射到在896M至1G的128M的地址空間內,使得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_TOP為4G-4K。

Copyright © Linux教程網 All Rights Reserved