Linux内核高端内存管理之固定内存区与映射
Linux内核高端内存管理之固定内存区与映射
前面(见 与 )总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图
对于固定内存在linux内核中有下面描述
[cpp]- enum fixed_addresses {
- #ifdef CONFIG_X86_32
- FIX_HOLE,
- FIX_VDSO,
- #else
- VSYSCALL_LAST_PAGE,
- VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
- + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
- VSYSCALL_HPET,
- #endif
- FIX_DBGP_BASE,
- FIX_EARLYCON_MEM_BASE,
- #ifdef CONFIG_X86_LOCAL_APIC
- FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
- #endif
- #ifdef CONFIG_X86_IO_APIC
- FIX_IO_APIC_BASE_0,
- FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
- #endif
- #ifdef CONFIG_X86_VISWS_APIC
- FIX_CO_CPU, /* Cobalt timer */
- FIX_CO_APIC, /* Cobalt APIC Redirection Table */
- FIX_LI_PCIA, /* Lithium PCI Bridge A */
- FIX_LI_PCIB, /* Lithium PCI Bridge B */
- #endif
- #ifdef CONFIG_X86_F00F_BUG
- FIX_F00F_IDT, /* Virtual mapping for IDT */
- #endif
- #ifdef CONFIG_X86_CYCLONE_TIMER
- FIX_CYCLONE_TIMER, /*cyclone timer register*/
- #endif
- #ifdef CONFIG_X86_32
- FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
- FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
- #ifdef CONFIG_PCI_MMCONFIG
- FIX_PCIE_MCFG,
- #endif
- #endif
- #ifdef CONFIG_PARAVIRT
- FIX_PARAVIRT_BOOTMAP,
- #endif
- FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
- FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
- __end_of_permanent_fixed_addresses,
- /*
- * 256 temporary boot-time mappings, used by early_ioremap(),
- * before ioremap() is functional.
- *
- * We round it up to the next 256 pages boundary so that we
- * can have a single pgd entry and a single pte table:
- */
- #define NR_FIX_BTMAPS 64
- #define FIX_BTMAPS_SLOTS 4
- FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
- (__end_of_permanent_fixed_addresses & 255),
- FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
- #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
- FIX_OHCI1394_BASE,
- #endif
- #ifdef CONFIG_X86_32
- FIX_WP_TEST,
- #endif
- #ifdef CONFIG_INTEL_TXT
- FIX_TBOOT_BASE,
- #endif
- __end_of_fixed_addresses
- };
固定映射
ioremap的作用是将IO和BIOS以及物理地址空间映射到在896M至1G的128M的地址空间内,使得kernel能够访问该空间并进行相应的读写操作。
start_kernel()->setup_arch()->early_ioremap_init()
[cpp]- void __init early_ioremap_init(void)
- {
- pmd_t *pmd;
- int i;
- if (early_ioremap_debug)
- printk(KERN_INFO "early_ioremap_init()\n");
- /*将fixed_address里的索引的虚拟地址放入slot_virt
- ,从代码里面可以看出,放入slot_virt中得虚拟地址为1M*/
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
- slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
- /*得到固定映射区的pmd
- ,此pmd为虚拟地址转换为物理地址的pmd*/
- pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
- memset(bm_pte, 0, sizeof(bm_pte));
- /*将bm_pte页表设置为固定映射区开始地址的pmd的第一个页表;*/
- pmd_populate_kernel(&init_mm, pmd, bm_pte);
- /*
- * The boot-ioremap range spans multiple pmds, for which
- * we are not prepared:
- */
- /*系统要求所有的ioremap映射在一个pmd上,超出这个pmd将警告*/
- if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
- WARN_ON(1);
- printk(KERN_WARNING "pmd %p != %p\n",
- pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
- printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
- fix_to_virt(FIX_BTMAP_BEGIN));
- printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END): %08lx\n",
- fix_to_virt(FIX_BTMAP_END));
- printk(KERN_WARNING "FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
- printk(KERN_WARNING "FIX_BTMAP_BEGIN: %d\n",
- FIX_BTMAP_BEGIN);
- }
- }
- static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
- #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
其中FIXADDR_TOP为4G-4K。
|
评论暂时关闭