歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> Linux內核高端內存管理之固定內存區與映射

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

日期:2017/2/28 15:57:29   编辑: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. if (early_ioremap_debug)
  6. printk(KERN_INFO "early_ioremap_init()\n");
  7. /*將fixed_address裡的索引的虛擬地址放入slot_virt
  8. ,從代碼裡面可以看出,放入slot_virt中得虛擬地址為1M*/
  9. for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
  10. slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
  11. /*得到固定映射區的pmd
  12. ,此pmd為虛擬地址轉換為物理地址的pmd*/
  13. pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
  14. memset(bm_pte, 0, sizeof(bm_pte));
  15. /*將bm_pte頁表設置為固定映射區開始地址的pmd的第一個頁表;*/
  16. pmd_populate_kernel(&init_mm, pmd, bm_pte);
  17. /*
  18. * The boot-ioremap range spans multiple pmds, for which
  19. * we are not prepared:
  20. */
  21. /*系統要求所有的ioremap映射在一個pmd上,超出這個pmd將警告*/
  22. if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
  23. WARN_ON(1);
  24. printk(KERN_WARNING "pmd %p != %p\n",
  25. pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
  26. printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
  27. fix_to_virt(FIX_BTMAP_BEGIN));
  28. printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END): %08lx\n",
  29. fix_to_virt(FIX_BTMAP_END));
  30. printk(KERN_WARNING "FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
  31. printk(KERN_WARNING "FIX_BTMAP_BEGIN: %d\n",
  32. FIX_BTMAP_BEGIN);
  33. }
  34. }
[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