The early_fixmap_init function analysis based on the following configuration,
there is no pud, so the key code can be extracted as follows
there is no pud, so the key code can be extracted as follows
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_4K_PAGES=y
CONFIG_PGTABLE_LEVELS=3
#dfine PAGE_SHIFT 12
#define STRUCT_PAGE_MAX_SHIFT 6
__end_of_permanent_fixed_addresses =0x405
/*
* Size of the PCI I/O space. This must remain a power of two so that
* IO_SPACE_LIMIT acts as a mask for the low bits of I/O addresses.
*/
#define PCI_IO_SIZE SZ_16M
//(0xffffff4000000000 -0xffffff8000000000 ) >> (12-6) = FFFF FFFF00000000
#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) \
>> (PAGE_SHIFT - STRUCT_PAGE_MAX_SHIFT))
/*
* PAGE_OFFSET - the virtual address of the start of the linear map, at the
* start of the TTBR1 address space.
* PAGE_END - the end of the linear map, where all other kernel mappings begin.
* KIMAGE_VADDR - the virtual address of the start of the kernel image.
* VA_BITS - the maximum number of bits for virtual addresses.
*/
#define VA_BITS (CONFIG_ARM64_VA_BITS) //39
#define VA_BITS_MIN (VA_BITS) // if VA_BITS > 48, it is 48 bit
#define _PAGE_OFFSET(va) (-(UL(1) << (va)))
#define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS)) //0xffffff8000000000
#define KIMAGE_VADDR (MODULES_END) //0xFFFFFFC010000000
#define BPF_JIT_REGION_START (KASAN_SHADOW_END) //(_PAGE_END(VA_BITS_MIN)) 0xffffffc000000000
#define BPF_JIT_REGION_SIZE (SZ_128M) //0x8000000
#define BPF_JIT_REGION_END (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE) //(0xffffffc000000000 + 0x8000000)=0xFFFFFFC008000000
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)//(0xFFFFFFC008000000+0x8000000) =0xFFFFFFC010000000
#define MODULES_VADDR (BPF_JIT_REGION_END) //0xFFFFFFC008000000
#define MODULES_VSIZE (SZ_128M) //0x8000000
#define VMEMMAP_START (-VMEMMAP_SIZE - SZ_2M) (-FFFFFFFF00000000- 0x200000) 0xFFFFFFFEFFE00000
#define PCI_IO_END (VMEMMAP_START - SZ_2M) //0xfffffffeffc00000
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) //0xfffffffefec00000
#define FIXADDR_TOP (PCI_IO_START - SZ_2M) //fffffffefea00000
#define KASAN_SHADOW_END (_PAGE_END(VA_BITS_MIN)) // 0xffffffc000000000
#define _PAGE_END(va) (-(UL(1) << ((va) - 1)))
#define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) (0x405 << 12) //0x405000
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) //0xFFFFFFFEFE5FB000
/*
* The p*d_populate functions call virt_to_phys implicitly so they can't be used
* directly on kernel symbols (bm_p*d). This function is called too early to use
* lm_alias so __p*d_populate functions must be used to populate with the
* physical address from __pa_symbol.
*/
void __init early_fixmap_init(void)
{
pgd_t *pgdp;
p4d_t *p4dp, p4d;
pud_t *pudp;
pmd_t *pmdp;
unsigned long addr = FIXADDR_START;
pgdp = pgd_offset_k(addr);
p4dp = p4d_offset(pgdp, addr);
p4d = READ_ONCE(*p4dp);
if (CONFIG_PGTABLE_LEVELS > 3 &&
!(p4d_none(p4d) || p4d_page_paddr(p4d) == __pa_symbol(bm_pud))) {
/*
* We only end up here if the kernel mapping and the fixmap
* share the top level pgd entry, which should only happen on
* 16k/4 levels configurations.
*/
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
pudp = pud_offset_kimg(p4dp, addr);
} else {
if (p4d_none(p4d))
__p4d_populate(p4dp, __pa_symbol(bm_pud), P4D_TYPE_TABLE);
pudp = fixmap_pud(addr);
}
if (pud_none(READ_ONCE(*pudp)))
__pud_populate(pudp, __pa_symbol(bm_pmd), PUD_TYPE_TABLE);
pmdp = fixmap_pmd(addr);
__pmd_populate(pmdp, __pa_symbol(bm_pte), PMD_TYPE_TABLE);
/*
* The boot-ioremap range spans multiple pmds, for which
* we are not prepared:
*/
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
if ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
|| pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) {
WARN_ON(1);
pr_warn("pmdp %p != %p, %p\n",
pmdp, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)),
fixmap_pmd(fix_to_virt(FIX_BTMAP_END)));
pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
fix_to_virt(FIX_BTMAP_BEGIN));
pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n",
fix_to_virt(FIX_BTMAP_END));
pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN);
}
}
This function is to create a mapping for the virtual address FIXADDR_START,
but there is no corresponding physical address, which means that the mapping is only part of it,
and no value is assigned to pte.
No comments:
Post a Comment