xref: /xv6-public/kalloc.c (revision c3dcf479)
1 // Physical memory allocator, intended to allocate
2 // memory for user processes, kernel stacks, page table pages,
3 // and pipe buffers. Allocates 4096-byte pages.
4 
5 #include "types.h"
6 #include "defs.h"
7 #include "param.h"
8 #include "memlayout.h"
9 #include "mmu.h"
10 #include "spinlock.h"
11 
12 struct run {
13   struct run *next;
14 };
15 
16 struct {
17   struct spinlock lock;
18   struct run *freelist;
19 } kmem;
20 
21 extern char end[]; // first address after kernel loaded from ELF file
22 extern uint maxpa;        // Maximum physical address
23 static char *newend;
24 
25 // simple page allocator to get off the ground during entry
26 char *
27 enter_alloc(void)
28 {
29   if (newend == 0)
30     newend = end;
31 
32   if ((uint) newend >= KERNBASE + 0x400000)
33     panic("only first 4Mbyte are mapped during entry");
34   void *p = (void*)PGROUNDUP((uint)newend);
35   memset(p, 0, PGSIZE);
36   newend = newend + PGSIZE;
37   return p;
38 }
39 
40 uint
41 detect_memory(void)
42 {
43   return 0xE000000;
44 }
45 
46 // Initialize free list of physical pages.
47 void
48 kinit(void)
49 {
50   char *p;
51 
52   initlock(&kmem.lock, "kmem");
53   p = (char*)PGROUNDUP((uint)newend);
54   for(; p + PGSIZE <= (char*)p2v(maxpa); p += PGSIZE)
55     kfree(p);
56 }
57 
58 //PAGEBREAK: 21
59 // Free the page of physical memory pointed at by v,
60 // which normally should have been returned by a
61 // call to kalloc().  (The exception is when
62 // initializing the allocator; see kinit above.)
63 void
64 kfree(char *v)
65 {
66   struct run *r;
67 
68   if((uint)v % PGSIZE || v < end || v2p(v) >= maxpa)
69     panic("kfree");
70 
71   // Fill with junk to catch dangling refs.
72   memset(v, 1, PGSIZE);
73 
74   acquire(&kmem.lock);
75   r = (struct run*)v;
76   r->next = kmem.freelist;
77   kmem.freelist = r;
78   release(&kmem.lock);
79 }
80 
81 // Allocate one 4096-byte page of physical memory.
82 // Returns a pointer that the kernel can use.
83 // Returns 0 if the memory cannot be allocated.
84 char*
85 kalloc(void)
86 {
87   struct run *r;
88 
89   acquire(&kmem.lock);
90   r = kmem.freelist;
91   if(r)
92     kmem.freelist = r->next;
93   release(&kmem.lock);
94   return (char*)r;
95 }
96 
97