annotate src/kalloc.c @ 52:1adde248a61f default tip

merge
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 07 Jun 2019 17:30:15 +0900
parents 83c23a36980d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 // Physical memory allocator, intended to allocate
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 // memory for user processes, kernel stacks, page table pages,
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // and pipe buffers. Allocates 4096-byte pages.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 #include "types.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 #include "defs.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 #include "param.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 #include "memlayout.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include "mmu.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #include "spinlock.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 #include "arm.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 void freerange(void *vstart, void *vend);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 extern char end[]; // first address after kernel loaded from ELF file
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 struct run {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 struct run *next;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 };
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 static struct {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 struct spinlock lock;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 int use_lock;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 struct run *freelist;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 } kmem;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 void kmem_init (void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 initlock(&kmem.lock, "kmem");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 kmem.use_lock = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 // Initialization happens in two phases.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 // 1. main() calls kinit1() while still using entrypgdir to place just
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 // the pages mapped by entrypgdir on free list.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 // 2. main() calls kinit2() with the rest of the physical pages
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 // after installing a full page table that maps them on all cores.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 void kinit1(void *vstart, void *vend)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 freerange(vstart, vend);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 void kinit2(void *vstart, void *vend)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 freerange(vstart, vend);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 kmem.use_lock = 1;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 void freerange(void *vstart, void *vend)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 char *p;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 p = (char*)align_up (vstart, PTE_SZ);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 for(; p + PTE_SZ <= (char*)vend; p += PTE_SZ) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 kfree(p);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 //PAGEBREAK: 21
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 // Free the page of physical memory pointed at by v,
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 // which normally should have been returned by a
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 // call to kalloc(). (The exception is when
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 // initializing the allocator; see kinit above.)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 void kfree(char *v)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 struct run *r;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 if((uint)v % PTE_SZ || v < end || v2p(v) >= PHYSTOP) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 cprintf("kfree(0x%x)\n", v);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 panic("kfree");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 // Fill with junk to catch dangling refs.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 //memset(v, 0x00, PG_SIZE);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 if(kmem.use_lock) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 acquire(&kmem.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 r = (struct run*)v;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 r->next = kmem.freelist;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 kmem.freelist = r;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 if(kmem.use_lock) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 release(&kmem.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 // Allocate one 4096-byte page of physical memory.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 // Returns a pointer that the kernel can use.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 // Returns 0 if the memory cannot be allocated.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 char* kalloc(void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 struct run *r;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 if(kmem.use_lock) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 acquire(&kmem.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 r = kmem.freelist;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 if(r) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 kmem.freelist = r->next;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 if(kmem.use_lock) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 release(&kmem.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 return (char*)r;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 }