- 论坛徽章:
- 0
|
以前的一段fixmap笔记:
======================
61, Linux i386的fixmap (IO-APIC 和 Local APIC的Base Address都是通过它得到)
/*{{{*/
1). 定义
fixmap是这样一种机制:提供一些线性地址,在编译时就确定下来,等到Linux引导时再为之
建立起和物理地址的映射(用set_fixmap(idx, phys))。
fixmap和内核内存的普通影射的不同之处在于, 通常情况下内核态内存影射就是 virt = phys + PAGE_OFFSET,
而fixmap的物理地址可以是任意的,不一定等于virt - PAGE_OFFSET.
fixmap使用的是线性地址的高处(不是最高处)的一块区域,从0xfffff000开始。往低地址长。
enum fixed_address {
FIX_HOLE,
FIX_VDSO,
#ifdef CONFIG_X86_LOCAL_APIC
FIX_APIC_BASE, /* local APIC */
#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_ACPI
FIX_ACPI_BEGIN,
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
#endif
#ifdef CONFIG_PCI_MMCONFIG
FIX_PCIE_MCFG,
#endif
#ifdef CONFIG_PARAVIRT
FIX_PARAVIRT_BOOTMAP,
#endif
__end_of_permanent_fixed_addresses,
/* temporary boot-time mappings, used before ioremap() is functional */
#define NR_FIX_BTMAPS 16
FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
FIX_WP_TEST,
__end_of_fixed_addresses
};
按照C语法,FIX_HOLE的值就是0,FIX_VDSO的值是1, ……,依此类推。
2). 映射 & 使用
先映射,再使用。 引导时映射,但编写内核C代码时可以先使用.
例如init_apic_mappings()中:
L1: set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
L2: printk(KERN_DEBUG "mapped APIC to %08lx (%08lx)\n", APIC_BASE,
apic_phys);
L1是映射,L2是使用(看APIC_BASE这个宏就是在使用fixmap)。
其中APIC_BASE的定义:
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
fix_to_virt()函数的作用,就是从一个fixmap的Index得到它的 线性地址。
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
而FIXADDR_TOP的定义:
#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)
unsigned long __FIXADDR_TOP = 0xfffff000;
/*}}}*/ |
|