-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemory.c
256 lines (236 loc) · 6.65 KB
/
memory.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/***************************************************************************************
* FileName : memory.c
* CopyRight : 1.0
* ModuleName : memory management module
*
* Create Data : 2016/01/06
* Author/Corportation : ZhuoJianhuan
*
* Abstract Description : 内存管理的实现文件
*
*--------------------------------Revision History--------------------------------------
* No version Date Revised By Item Description
* 1 v1.0 2016/01/06 ZhuoJianhuan Create this file
*
***************************************************************************************/
/**************************************************************
* Debug switch Section
**************************************************************/
/**************************************************************
* Include File Section
**************************************************************/
#include "bootpack.h"
/**************************************************************
* Macro Define Section
**************************************************************/
#define EFLAGS_AC_BIT 0x00040000
#define CR0_CACHE_DISABLE 0x60000000
/**************************************************************
* Struct Define Section
**************************************************************/
/**************************************************************
* Prototype Declare Section
**************************************************************/
/**************************************************************
* Global Variable Declare Section
**************************************************************/
/**************************************************************
* File Static Variable Define Section
**************************************************************/
static struct MEMMAN *memoryMangaer;
/**************************************************************
* Function Define Section
**************************************************************/
/**
* @description 内存测试函数
* @param start:测试内存起始地址
* end:测试内存结束地址
* @return 正常可用地址
*/
unsigned int memtest(unsigned int start, unsigned int end){
char flg486 = 0;
unsigned int eflg, cr0, i;
eflg = io_load_eflags();
eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
io_store_eflags(eflg);
eflg = io_load_eflags();
if ((eflg & EFLAGS_AC_BIT) != 0) {
flg486 = 1;
}
eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */
io_store_eflags(eflg);
if (flg486 != 0) {
cr0 = load_cr0();
cr0 |= CR0_CACHE_DISABLE;
store_cr0(cr0);
}
i = memtest_sub(start, end);
if (flg486 != 0) {
cr0 = load_cr0();
cr0 &= ~CR0_CACHE_DISABLE;
store_cr0(cr0);
}
return i;
}
/**
* @description 初始化内存管理
* @param man:欲初始化的管理块
*/
void memman_init(struct MEMMAN *man){
man->frees = 0;
man->maxfrees = 0;
man->lostsize = 0;
man->losts = 0;
//TODO 置为文件内静变量,记录其值
memoryMangaer = man;
return;
}
/**
* @description 检查可用地址大小
* @param man:目标内存管理块
* @return 全部可用内存大小
*/
unsigned int memman_total(struct MEMMAN *man){
unsigned int i, t = 0;
for (i = 0; i < man->frees; i++) {
t += man->free[i].size;
}
return t;
}
/**
* @description 申请一块指定大小的内存块
* @param man:目标内存管理块
* size:欲申请的大小
* 申请成功返回申请到的首地址,否则返回0
* @notice 该处使用的是首次适应算法
*/
unsigned int memman_alloc(struct MEMMAN *man, unsigned int size){
unsigned int i, a;
//TODO 查找大小大于指定size的可用空闲内存块
for (i = 0; i < man->frees; i++) {
if (man->free[i].size >= size) {
a = man->free[i].addr;
man->free[i].addr += size;
man->free[i].size -= size;
if (man->free[i].size == 0) {
//TODO 无剩余,则进行清空
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1];
}
}
return a;
}
}
//TODO 申请失败返回0
return 0;
}
/**
* @description 释放指定内存
* @param man:指定的内存管理块
* addr:指定内存的首地址
* size:指定内存的大小
* @return 释放成功返回0,否则返回-1
*/
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size){
int i, j;
for (i = 0; i < man->frees; i++) {
if (man->free[i].addr > addr) {
break;
}
}
/* free[i - 1].addr < addr < free[i].addr */
if (i > 0) {
/* 慜偑偁傞 */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 慜偺偁偒椞堟偵傑偲傔傜傟傞 */
man->free[i - 1].size += size;
if (i < man->frees) {
/* 屻傠傕偁傞 */
if (addr + size == man->free[i].addr) {
/* 側傫偲屻傠偲傕傑偲傔傜傟傞 */
man->free[i - 1].size += man->free[i].size;
/* man->free[i]偺嶍彍 */
/* free[i]偑側偔側偭偨偺偱慜傊偮傔傞 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 峔憿懱偺戙擖 */
}
}
}
return 0; /* 惉岟廔椆 */
}
}
/* 慜偲偼傑偲傔傜傟側偐偭偨 */
if (i < man->frees) {
/* 屻傠偑偁傞 */
if (addr + size == man->free[i].addr) {
/* 屻傠偲偼傑偲傔傜傟傞 */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* 惉岟廔椆 */
}
}
/* 慜偵傕屻傠偵傕傑偲傔傜傟側偄 */
if (man->frees < MEMMAN_FREES) {
/* free[i]傛傝屻傠傪丄屻傠傊偢傜偟偰丄偡偒傑傪嶌傞 */
for (j = man->frees; j > i; j--) {
man->free[j] = man->free[j - 1];
}
man->frees++;
if (man->maxfrees < man->frees) {
man->maxfrees = man->frees; /* 嵟戝抣傪峏怴 */
}
man->free[i].addr = addr;
man->free[i].size = size;
return 0; /* 惉岟廔椆 */
}
/* 屻傠偵偢傜偣側偐偭偨 */
man->losts++;
man->lostsize += size;
//TODO 释放失败
return -1;
}
/**
* @description 申请大小为4k倍数的内存
* @param man:内存管理块
* size:欲申请的大小
* @return 申请到的首地址,申请失败返回0
* @notice 此举仅为减少内存碎片,释放时应使用memman_free_4k()函数进行释放
*/
unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size){
unsigned int a;
size = (size + 0xfff) & 0xfffff000;
a = memman_alloc(man, size);
return a;
}
/**
* @description 释放通过memman_alloc_4k()函数申请到的内存
* @param man:内存管理块
* addr:欲释放的内存的首地址
* size:欲释放的内存的大小
* @return 释放成功返回0,否则返回-1
*/
int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size){
int i;
size = (size + 0xfff) & 0xfffff000;
i = memman_free(man, addr, size);
return i;
}
/**
* @description 申请内存
* @param size:指定的大小
* @return 申请到的首地址,申请失败返回0
*/
void *malloc(unsigned int size){
return (void *)memman_alloc_4k(memoryMangaer, size);
}
/**
* @description malloc()函数申请到的内存
* @param addr:欲释放的内存的首地址
* size:欲释放的内存的大小
* @return 释放成功返回0,否则返回-1
*/
int mfree(unsigned int addr, unsigned int size){
return memman_free_4k(memoryMangaer, addr, size);
}