0.不同BIOS判斷內存多大不盡相同,可以自己編寫一個程序判斷機器內存多大,主要方法就是寫完後讀出來比較就知道了。
1. 寄存器EFLAGS第18位AC標誌表示CPU是否爲486以上,486以上CPU有緩存,自己編寫程序判斷內存有多大時應關閉緩存。
2. 對CR0寄存器標誌位進行改寫實現關閉緩存功能
#define CR0_CACHE_DISABLE
/*...*/
cr0=load_cr0();
cr0 |= CR0_CACHE_DISABLE;
store_cr0(cr0);
3. 內存管理(1)位圖法:用一個標誌位表示一部分內存是使用還是空閒(2)列表管理方法:將從xxx到yyy地址空間已經分配了這樣的信息保存在表中。
這部分是對計算機物理內存進行管理的方法,動態分配和釋放,不用在obj文件中分配了!
#define MEMMAN_FREES 4090 /*零碎的保存free內存塊*/
#define MEMMAN_ADDR 0x003c0000
struct FREEINFO { /* free可用信息 */
unsigned int addr, size;
};
struct MEMMAN { /*內存管理結構體*/
int frees, maxfrees, lostsize, losts;
struct FREEINFO free[MEMMAN_FREES];
};
void memman_init(struct MEMMAN *man)
{
man->frees = 0; /* 可用free塊 */
man->maxfrees = 0; /* frees的最大值 */
man->lostsize = 0; /* 釋放失敗的內存大小 */
man->losts = 0; /* 釋放失敗次數 */
return;
}
/* 現在free內存大小 */
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;
}
unsigned int memman_alloc(struct MEMMAN *man, unsigned int size)
{
unsigned int i, a;
for (i = 0; i < man->frees; i++) {
if (man->free[i].size >= size) {
/* find free space */
a = man->free[i].addr;
man->free[i].addr += size;
man->free[i].size -= size;
if (man->free[i].size == 0) {
/* 當前free塊正好被全部分配了 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 把後面的free塊信息向前移動 */
}
}
return a;
}
}
return 0; /* not found */
}
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
{
int i, j;
/* free[]中信息按照地址空間的順序排序 */
/* 找到這個釋放的空間放在哪裏 */
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) {
/* 前面有與要釋放的內存連續的free內存 */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 與前面的free內存信息合併到一起 */
man->free[i - 1].size += size;
if (i < man->frees) {
/* 後面也有與要釋放的內存連續的free內存 */
if (addr + size == man->free[i].addr) {
/* 可以與後面的free內存信息合併到一起 */
man->free[i - 1].size += man->free[i].size;
/*歸併*/
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1];
}
}
}
return 0; /* ok */
}
}
/* 不能與前面的可用空間合併到一起 */
if (i < man->frees) {
/* 後面也有與要釋放的內存連續的free內存 */
if (addr + size == man->free[i].addr) {
/* 可以與後面的free內存信息合併到一起 */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* ok */
}
}
/* 前後都不能合併 */
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; /* ok */
}
/* 不能向後移動 */
man->losts++;
man->lostsize += size;
return -1; /* 失敗 */
}
3. 以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;
}
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;
}