美文网首页
进程地址管理

进程地址管理

作者: 牛逼人物888 | 来源:发表于2020-02-06 16:56 被阅读0次
一、进程fork对内存空间的copy

kernel/msm-4.19/kernel/fork.c

/*
 * Allocate a new mm structure and copy contents from the
 * mm structure of the passed in task structure.
 */
static struct mm_struct *dup_mm(struct task_struct *tsk)
{
    struct mm_struct *mm, *oldmm = current->mm;
    int err;

    mm = allocate_mm();
    if (!mm)
        goto fail_nomem;

    memcpy(mm, oldmm, sizeof(*mm));
    if (!mm_init(mm, tsk, mm->user_ns)) // mm_init最终通过mm_alloc_pgd来分配页表
        goto fail_nomem;

    err = dup_mmap(mm, oldmm);// 虚拟内存copy
    if (err)
        goto free_pt;

    mm->hiwater_rss = get_mm_rss(mm);
    mm->hiwater_vm = mm->total_vm;

    if (mm->binfmt && !try_module_get(mm->binfmt->module))
        goto free_pt;

    return mm;

free_pt:
    /* don't put binfmt in mmput, we haven't got module yet */
    mm->binfmt = NULL;
    mm_init_owner(mm, NULL);
    mmput(mm);

fail_nomem:
    return NULL;
}
二、物理地址映射到进程地址空间

Ion内存映射用户空间
kernel/msm-4.19/drivers/staging/android/ion/ion_heap.c

int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
              struct vm_area_struct *vma)
{
...
    for_each_sg(table->sgl, sg, table->nents, i) {
        struct page *page = sg_page(sg);
        unsigned long remainder = vma->vm_end - addr;
        unsigned long len = sg->length;

        if (offset >= sg->length) {
            offset -= sg->length;
            continue;
        } else if (offset) {
            page += offset / PAGE_SIZE;
            len = sg->length - offset;
            offset = 0;
        }
        len = min(len, remainder);
        ret = remap_pfn_range(vma, addr, page_to_pfn(page), len,
                      vma->vm_page_prot);
        if (ret)
            return ret;
        addr += len;
        if (addr >= vma->vm_end)
            return 0;
    }
    return 0;

}

kernel/msm-4.19/mm/memory.c

/**
 * remap_pfn_range - remap kernel memory to userspace
 * @vma: user vma to map to
 * @addr: target user address to start at
 * @pfn: physical address of kernel memory
 * @size: size of map area
 * @prot: page protection flags for this mapping
 *
 *  Note: this is only safe if the mm semaphore is held when called.
 */
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
            unsigned long pfn, unsigned long size, pgprot_t prot)
{
...
    pfn -= addr >> PAGE_SHIFT;
    pgd = pgd_offset(mm, addr);
    flush_cache_range(vma, addr, end);
    do {
        next = pgd_addr_end(addr, end);
        err = remap_p4d_range(mm, pgd, addr, next,
                pfn + (addr >> PAGE_SHIFT), prot);
        if (err)
            break;
    } while (pgd++, addr = next, addr != end);
...
}

kgsl内存映射用户空间
kernel/msm-4.19/drivers/gpu/msm/kgsl.c

static int kgsl_mmap(struct file *file, struct vm_area_struct *vma)
{
...
    if (cache == KGSL_CACHEMODE_WRITEBACK
        || cache == KGSL_CACHEMODE_WRITETHROUGH) {
        int i;
        unsigned long addr = vma->vm_start;
        struct kgsl_memdesc *m = &entry->memdesc;

        for (i = 0; i < m->page_count; i++) {
            struct page *page = m->pages[i];

            vm_insert_page(vma, addr, page);
            addr += PAGE_SIZE;
        }
        m->mapsize = m->size;
        entry->priv->gpumem_mapped += m->mapsize;
    }

    vma->vm_file = file;

    entry->memdesc.useraddr = vma->vm_start;

}

kernel/msm-4.19/mm/memory.c

int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
            struct page *page)
{
    if (addr < vma->vm_start || addr >= vma->vm_end)
        return -EFAULT;
    if (!page_count(page))
        return -EINVAL;
    if (!(vma->vm_flags & VM_MIXEDMAP)) {
        BUG_ON(down_read_trylock(&vma->vm_mm->mmap_sem));
        BUG_ON(vma->vm_flags & VM_PFNMAP);
        vma->vm_flags |= VM_MIXEDMAP;
    }
    return insert_page(vma, addr, page, vma->vm_page_prot);
}

相关文章

  • 进程地址管理

    一、进程fork对内存空间的copy kernel/msm-4.19/kernel/fork.c 二、物理地址映射...

  • 第15章 进程地址空间

    内核除了管理本身的内存外,还必须管理用户空间中进程的内存,也就是进程地址空间。 一、地址空间 进程地址空间由进程可...

  • 8.进程地址空间

    进程地址空间 内核除了管理自身的内存外,还必须管理用户空间中进程的内存,称该内存为进程地址空间,也就是系统中每个用...

  • 03 内存管理与地址转换

    内存管理的基本思想 每个进程都拥有自己的地址空间( Address space),包括这个进程可以使用的全部地址和...

  • 效率提升之进程

    进程的特性 独立的地址和内存空间 独立的PID 每个进程拥有自己PCB控制块 进程PCB是用来管理进程,维护进程属...

  • Linux系统管理

    进程管理 进程查看 1、进程简介 进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间...

  • Linux系统管理

    一、进程管理 1.进程管理简介 ①定义:进程是一个有自己地址空间并占用一定的系统资源的实体,是正在执行的一个程序或...

  • 第1章 Linux内核简介

    通常,内核由负责响应中断的中断服务程序、负责管理多个进程从而分享处理器时间的调度程序,负责管理进程地址空间的内存管...

  • Linux进程管理

    进程管理 进程简介 进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的...

  • (十三)Linux系统管理

    第一节 进程管理 1.进程简介 进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,...

网友评论

      本文标题:进程地址管理

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