如有问题,欢迎一起讨论:-)
临时地址映射了建立了compile-time特殊的虚地址,分配的虚地址是从0xfffff000向后使用
和永久地址映射不同,它可以在中断或可延迟的上下文中使用而不会睡眠,在高端内存任一页框都可以
通过窗口映射到次内核地址空间
首先看一些重要的数据结构和宏定义
#define __FIXADDR_TOP 0xfffff000
下面是特殊地址的类型,这些地址都是作为boot时临时的地址映射
enum fixed_addresses{
FIX_HOLE,
FIX_VSYSCALL,
#ifdef CONFIG_X86_LOCAL_APIC
FIX_APIC_BASE,
#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 CONFIX_X86_VISWS_APIC
FIX_CO_CPU,
FIX_CO_APIC,
FIX_LI_PCIA,
FIX_LI_PCIB,
#endif
#ifdef CONFIG_X86_CYCLONE_TIMER
FIX_CYCLONE_TIMER,
#endif
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN,
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
#endif
#ifdef CONFIG_ACPI_BOOT
FIX_ACPI_BEGIN,
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
#endif
#ifdef CONFIG_PCI_MMCONFIG
FIX_PCIE_MCFG,
#endif
__end_of_permanent_fixed_addresses,
#define NR_FIX_BTMAPS 16
FIX_BITMAP_END = __end_of_permnent_fixed_addresses,
FIX_BITMAP_BEGIN = FIX_BITMAP_END + NR_FIX_BITMAP - 1,
FIX_WP_TEST,
__end_of_fixed_addresses
};
#define FIXADDR_TOP ((unsigned long) __FIXADDR_TOP)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x) & PAGE_MASK)) >> PAGE_SHIFT)
页表初始化:在kmap_init
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
转换得到kmap开始的虚地址
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
kmap_prot = PAGE_KERNEL;
#define kmap_get_fixmap_pte(vaddr) /
pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
映射关键代码:
enum fixed_addressed idx;
idx = type + KM_TYPE_NR *smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte - idx, mk_pte(page, kmap_prot));
return (void *)vaddr;