快速业务通道

linux内存管理之非连续物理地址分配(vmalloc)

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-27
pgd_ERROR(*dir);

  pgd_clear(dir);

  return;

  }

  pmd = pmd_offset(dir, address);

  address &= ~PGDIR_MASK;

  end = address size;

  if (end > PGDIR_SIZE)

  end = PGDIR_SIZE;

  do {

  //断开线性地址所在的pte的映射关系

  unmap_area_pte(pmd, address, end - address);

  address = (address PMD_SIZE) & PMD_MASK;

  pmd ;

  } while (address < end);

  }

  static void unmap_area_pte(pmd_t *pmd, unsigned long address,

  unsigned long size)

  {

  unsigned long end;

  pte_t *pte;

  if (pmd_none(*pmd))

  return;

  if (pmd_bad(*pmd)) {

  pmd_ERROR(*pmd);

  pmd_clear(pmd);

  return;

  }

  pte = pte_offset_kernel(pmd, address);

  address &= ~PMD_MASK;

  end = address size;

  if (end > PMD_SIZE)

  end = PMD_SIZE;

  do {

  pte_t page;

  //清除pte的对应映射关系

  page = ptep_get_and_clear(pte);

  address = PAGE_SIZE;

  pte ;

  if (pte_none(page))

  continue;

  if (pte_present(page))

  continue;

  printk(KERN_CRIT "Whee.. Swapped out page in kernel page tablen");

  } while (address < end);

  }

  经过这几个过程之后,实际上,它只是找到线性地址所对应的pte,然后断开pte的映射.值得注意的是:为了效率起见,这里只是断开了pte的映射,即只是将pte置为none,表示pte末映射内存.并末断开pmd和pgd的映射 拥有帝国一切,皆有可能。欢迎访问phome.net

  三:vmalloc的实现:

  void *vmalloc(unsigned long size)

  {

  return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);

  }

  实际上调用__vmalloc:

  void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)

  {

  struct vm_struct *area;

  struct page **pages;

  unsigned int nr_pages, array_size, i;

  //使请求的大小与页框对齐

  size = PAGE_ALIGN(size);

  //有效性检查

  if (!size || (size >> PAGE_SHIFT) > num_physpages)

  return NULL;

  //取得一个有效的VM,这个函数我们在前面已经详细的分析过了

  area = get_vm_area(size, VM_ALLOC);

  if (!area)

  return NULL;

  //所要映射的页面总数

  nr_pages = size >> PAGE_SHIFT;

  //页面描述符所占的空间

  array_size = (nr_pages * sizeof(struct page *));

  area->nr_pages = nr_pages;

  area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));

  //如果空间分配失败

  if (!area->pages) {

  remove_vm_area(area->addr);

  kfree(area);

  return NULL;

  }

  memset(area->pages, 0, array_size);

  //为每一个页面分配空间

  for (i = 0; i < area->nr_pages; i ) {

  area->pages[i] = alloc_page(gfp_mask);

  if (unlikely(!area->pages[i])) {

  /* Successfully allocated i pages, free them in __vunmap() */

  area->nr_pages = i;

  goto fail;

  }

  }

  //为所分配的页面建立映射关系

  if (map_vm_area(area, prot, &pages))

  goto fail;

  return area->addr;

  fail:

  vfree(area->addr);

  return NULL;

  }

  map_vm_area为所分配的内存建立映射关系

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号