美文网首页
内核地址管理

内核地址管理

作者: 牛逼人物888 | 来源:发表于2020-02-06 16:54 被阅读0次
    1、内核内存布局
    2、内核页表建立

    kernel/msm-4.19/arch/arm64/mm/mmu.c

    /*
     * Create fine-grained mappings for the kernel.
     */
    static void __init map_kernel(pgd_t *pgdp)
    {
    ...
        /*
         * Only rodata will be remapped with different permissions later on,
         * all other segments are allowed to use contiguous mappings.
         */
        map_kernel_segment(pgdp, _text, _etext, text_prot, &vmlinux_text, 0,
                   VM_NO_GUARD);
        map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,
                   &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
        map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot,
                   &vmlinux_inittext, 0, VM_NO_GUARD);
        map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL,
                   &vmlinux_initdata, 0, VM_NO_GUARD);
        map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
    ...
    }
    

    kernel/msm-4.19/arch/arm64/mm/mmu.c

    static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
                          pgprot_t prot, struct vm_struct *vma,
                          int flags, unsigned long vm_flags)
    {
        phys_addr_t pa_start = __pa_symbol(va_start);
        unsigned long size = va_end - va_start;
    
        BUG_ON(!PAGE_ALIGNED(pa_start));
        BUG_ON(!PAGE_ALIGNED(size));
    
        __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot,
                     early_pgtable_alloc, flags);
    
        if (!(vm_flags & VM_NO_GUARD))
            size += PAGE_SIZE;
    
        vma->addr   = va_start;
        vma->phys_addr  = pa_start;
        vma->size   = size;
        vma->flags  = VM_MAP | vm_flags;
        vma->caller = __builtin_return_address(0);
    
        vm_area_add_early(vma);
    }
    

    kernel/msm-4.19/arch/arm64/mm/mmu.c

    static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
                     unsigned long virt, phys_addr_t size,
                     pgprot_t prot,
                     phys_addr_t (*pgtable_alloc)(void),
                     int flags)
    {
        unsigned long addr, length, end, next;
        pgd_t *pgdp = pgd_offset_raw(pgdir, virt);
    
        /*
         * If the virtual and physical address don't have the same offset
         * within a page, we cannot map the region as the caller expects.
         */
        if (WARN_ON((phys ^ virt) & ~PAGE_MASK))
            return;
    
        phys &= PAGE_MASK;
        addr = virt & PAGE_MASK;
        length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
    
        end = addr + length;
        do {
            next = pgd_addr_end(addr, end);
            alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
                       flags);
            phys += next - addr;
        } while (pgdp++, addr = next, addr != end);
    }
    

    参考博客:https://www.cnblogs.com/LoyenWang/p/11440957.html

    相关文章

      网友评论

          本文标题:内核地址管理

          本文链接:https://www.haomeiwen.com/subject/vtluxhtx.html