modutil.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*  $Id: modutil.c,v 1.11 2001/12/05 06:05:35 davem Exp $
  2.  *  arch/sparc64/mm/modutil.c
  3.  *
  4.  *  Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5.  *  Based upon code written by Linus Torvalds and others.
  6.  */
  7.  
  8. #include <linux/slab.h>
  9. #include <linux/vmalloc.h>
  10. #include <asm/uaccess.h>
  11. #include <asm/system.h>
  12. static struct vm_struct * modvmlist = NULL;
  13. void module_unmap (void * addr)
  14. {
  15. struct vm_struct **p, *tmp;
  16. if (!addr)
  17. return;
  18. if ((PAGE_SIZE-1) & (unsigned long) addr) {
  19. printk("Trying to unmap module with bad address (%p)n", addr);
  20. return;
  21. }
  22. for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
  23. if (tmp->addr == addr) {
  24. *p = tmp->next;
  25. vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
  26. kfree(tmp);
  27. return;
  28. }
  29. }
  30. printk("Trying to unmap nonexistent module vm area (%p)n", addr);
  31. }
  32. void * module_map (unsigned long size)
  33. {
  34. void * addr;
  35. struct vm_struct **p, *tmp, *area;
  36. size = PAGE_ALIGN(size);
  37. if (!size || size > MODULES_LEN) return NULL;
  38. addr = (void *) MODULES_VADDR;
  39. for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
  40. if (size + (unsigned long) addr < (unsigned long) tmp->addr)
  41. break;
  42. addr = (void *) (tmp->size + (unsigned long) tmp->addr);
  43. }
  44. if ((unsigned long) addr + size >= MODULES_END) return NULL;
  45. area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
  46. if (!area) return NULL;
  47. area->size = size + PAGE_SIZE;
  48. area->addr = addr;
  49. area->next = *p;
  50. *p = area;
  51. if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) {
  52. module_unmap(addr);
  53. return NULL;
  54. }
  55. return addr;
  56. }