Mercurial > hg > Members > innparusu > xv6_rpi_port
comparison source/kalloc.c @ 0:c450faca55f4
Init
author | Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 22 Oct 2017 18:25:39 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c450faca55f4 |
---|---|
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 | |
8 void freerange(void *vstart, void *vend); | |
9 extern char end[]; // first address after kernel loaded from ELF file | |
10 | |
11 struct run { | |
12 struct run *next; | |
13 }; | |
14 | |
15 struct { | |
16 struct spinlock lock; | |
17 int use_lock; | |
18 struct run *freelist; | |
19 } kmem; | |
20 | |
21 // Initialization happens in two phases. | |
22 // 1. main() calls kinit1() while still using entrypgdir to place just | |
23 // the pages mapped by entrypgdir on free list. | |
24 // 2. main() calls kinit2() with the rest of the physical pages | |
25 // after installing a full page table that maps them on all cores. | |
26 void | |
27 kinit1(void *vstart, void *vend) | |
28 { | |
29 initlock(&kmem.lock, "kmem"); | |
30 kmem.use_lock = 0; | |
31 kmem.freelist = 0; | |
32 freerange(vstart, vend); | |
33 } | |
34 | |
35 void | |
36 kinit2(void *vstart, void *vend) | |
37 { | |
38 freerange(vstart, vend); | |
39 kmem.use_lock = 1; | |
40 } | |
41 | |
42 void | |
43 freerange(void *vstart, void *vend) | |
44 { | |
45 char *p; | |
46 p = (char*)PGROUNDUP((uint)vstart); | |
47 for(; p + PGSIZE <= (char*)vend; p += PGSIZE) | |
48 kfree(p); | |
49 } | |
50 | |
51 //PAGEBREAK: 21 | |
52 // Free the page of physical memory pointed at by v, | |
53 // which normally should have been returned by a | |
54 // call to kalloc(). (The exception is when | |
55 // initializing the allocator; see kinit above.) | |
56 void | |
57 kfree(char *v) | |
58 { | |
59 struct run *r; | |
60 | |
61 if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) | |
62 panic("kfree"); | |
63 | |
64 // Fill with junk to catch dangling refs. | |
65 memset(v, 1, PGSIZE); | |
66 | |
67 if(kmem.use_lock) | |
68 acquire(&kmem.lock); | |
69 r = (struct run*)v; | |
70 r->next = kmem.freelist; | |
71 kmem.freelist = r; | |
72 if(kmem.use_lock) | |
73 release(&kmem.lock); | |
74 } | |
75 | |
76 // Allocate one 4096-byte page of physical memory. | |
77 // Returns a pointer that the kernel can use. | |
78 // Returns 0 if the memory cannot be allocated. | |
79 char* | |
80 kalloc(void) | |
81 { | |
82 struct run *r; | |
83 | |
84 if(kmem.use_lock) | |
85 acquire(&kmem.lock); | |
86 r = kmem.freelist; | |
87 if(r) | |
88 kmem.freelist = r->next; | |
89 if(kmem.use_lock) | |
90 release(&kmem.lock); | |
91 return (char*)r; | |
92 } | |
93 | |
94 |