comparison src/kalloc.c @ 0:53676d1f5817 default tip

firsh commit
author tobaru
date Sun, 04 Feb 2018 17:54:49 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:53676d1f5817
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 #include "arm.h"
12
13 void freerange(void *vstart, void *vend);
14 extern char end[]; // first address after kernel loaded from ELF file
15
16 struct run {
17 struct run *next;
18 };
19
20 static struct {
21 struct spinlock lock;
22 int use_lock;
23 struct run *freelist;
24 } kmem;
25
26 void kmem_init (void)
27 {
28 initlock(&kmem.lock, "kmem");
29 kmem.use_lock = 0;
30 }
31
32 // Initialization happens in two phases.
33 // 1. main() calls kinit1() while still using entrypgdir to place just
34 // the pages mapped by entrypgdir on free list.
35 // 2. main() calls kinit2() with the rest of the physical pages
36 // after installing a full page table that maps them on all cores.
37 void kinit1(void *vstart, void *vend)
38 {
39 freerange(vstart, vend);
40 }
41
42 void kinit2(void *vstart, void *vend)
43 {
44 freerange(vstart, vend);
45 kmem.use_lock = 1;
46 }
47
48 void freerange(void *vstart, void *vend)
49 {
50 char *p;
51
52 p = (char*)align_up (vstart, PTE_SZ);
53
54 for(; p + PTE_SZ <= (char*)vend; p += PTE_SZ) {
55 kfree(p);
56 }
57 }
58
59 //PAGEBREAK: 21
60 // Free the page of physical memory pointed at by v,
61 // which normally should have been returned by a
62 // call to kalloc(). (The exception is when
63 // initializing the allocator; see kinit above.)
64 void kfree(char *v)
65 {
66 struct run *r;
67
68 if((uint)v % PTE_SZ || v < end || v2p(v) >= PHYSTOP) {
69 cprintf("kfree(0x%x)\n", v);
70 panic("kfree");
71 }
72
73 // Fill with junk to catch dangling refs.
74 //memset(v, 0x00, PG_SIZE);
75
76 if(kmem.use_lock) {
77 acquire(&kmem.lock);
78 }
79
80 r = (struct run*)v;
81 r->next = kmem.freelist;
82 kmem.freelist = r;
83
84 if(kmem.use_lock) {
85 release(&kmem.lock);
86 }
87 }
88
89 // Allocate one 4096-byte page of physical memory.
90 // Returns a pointer that the kernel can use.
91 // Returns 0 if the memory cannot be allocated.
92 char* kalloc(void)
93 {
94 struct run *r;
95
96 if(kmem.use_lock) {
97 acquire(&kmem.lock);
98 }
99
100 r = kmem.freelist;
101
102 if(r) {
103 kmem.freelist = r->next;
104 }
105
106 if(kmem.use_lock) {
107 release(&kmem.lock);
108 }
109
110 return (char*)r;
111 }