kalloc.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "types.h"
  2. #include "defs.h"
  3. #include "param.h"
  4. #include "memlayout.h"
  5. #include "mmu.h"
  6. #include "spinlock.h"
  7. void freerange(void *vstart, void *vend);
  8. extern char end[]; // first address after kernel loaded from ELF file
  9. struct run {
  10. struct run *next;
  11. };
  12. struct {
  13. struct spinlock lock;
  14. int use_lock;
  15. struct run *freelist;
  16. } kmem;
  17. // Initialization happens in two phases.
  18. // 1. main() calls kinit1() while still using entrypgdir to place just
  19. // the pages mapped by entrypgdir on free list.
  20. // 2. main() calls kinit2() with the rest of the physical pages
  21. // after installing a full page table that maps them on all cores.
  22. void
  23. kinit1(void *vstart, void *vend)
  24. {
  25. initlock(&kmem.lock, "kmem");
  26. kmem.use_lock = 0;
  27. kmem.freelist = 0;
  28. freerange(vstart, vend);
  29. }
  30. void
  31. kinit2(void *vstart, void *vend)
  32. {
  33. freerange(vstart, vend);
  34. kmem.use_lock = 1;
  35. }
  36. void
  37. freerange(void *vstart, void *vend)
  38. {
  39. char *p;
  40. p = (char*)PGROUNDUP((uint)vstart);
  41. for(; p + PGSIZE <= (char*)vend; p += PGSIZE)
  42. kfree(p);
  43. }
  44. //PAGEBREAK: 21
  45. // Free the page of physical memory pointed at by v,
  46. // which normally should have been returned by a
  47. // call to kalloc(). (The exception is when
  48. // initializing the allocator; see kinit above.)
  49. void
  50. kfree(char *v)
  51. {
  52. struct run *r;
  53. if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
  54. panic("kfree");
  55. // Fill with junk to catch dangling refs.
  56. memset(v, 1, PGSIZE);
  57. if(kmem.use_lock)
  58. acquire(&kmem.lock);
  59. r = (struct run*)v;
  60. r->next = kmem.freelist;
  61. kmem.freelist = r;
  62. if(kmem.use_lock)
  63. release(&kmem.lock);
  64. }
  65. // Allocate one 4096-byte page of physical memory.
  66. // Returns a pointer that the kernel can use.
  67. // Returns 0 if the memory cannot be allocated.
  68. char*
  69. kalloc(void)
  70. {
  71. struct run *r;
  72. if(kmem.use_lock)
  73. acquire(&kmem.lock);
  74. r = kmem.freelist;
  75. if(r)
  76. kmem.freelist = r->next;
  77. if(kmem.use_lock)
  78. release(&kmem.lock);
  79. return (char*)r;
  80. }