diff --git a/09_day/bootpack.c b/09_day/bootpack.c index f6fe864..95df564 100644 --- a/09_day/bootpack.c +++ b/09_day/bootpack.c @@ -3,6 +3,9 @@ #include "bootpack.h" #include +unsigned int memtest(unsigned int start, unsigned int end); +unsigned int memtest_sub(unsigned int start, unsigned int end); + void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; @@ -20,6 +23,7 @@ void HariMain(void) io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */ init_keyboard(); + enable_mouse(&mdec); init_palette(); init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); @@ -30,7 +34,9 @@ void HariMain(void) sprintf(s, "(%d, %d)", mx, my); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); - enable_mouse(&mdec); + i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024); + sprintf(s, "memory %dMB", i); + putfonts8_asc(binfo->vram, binfo->scrnx, 0, 32, COL8_FFFFFF, s); for (;;) { io_cli(); @@ -86,3 +92,65 @@ void HariMain(void) } } +#define EFLAGS_AC_BIT 0x00040000 +#define CR0_CACHE_DISABLE 0x60000000 + +unsigned int memtest(unsigned int start, unsigned int end) +{ + char flg486 = 0; + unsigned int eflg, cr0, i; + + /* 确认CPU是386还是486以上的 */ + 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) { + /* 如果是386,即使设定AC=1,AC的值还会自动回到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; +} + +unsigned int memtest_sub(unsigned int start, unsigned int end) +{ + unsigned int i, *p, old, pat0 = 0xaa55aa55, pat1 = 0x55aa55aa; + for (i = start; i <= end; i += 0x1000) { + p = (unsigned int *) (i + 0xffc); + old = *p; /* 先记住修改前的值 */ + *p = pat0; /* 试写 */ + *p ^= 0xffffffff; /* 反转 */ + if (*p != pat1) { + /* 检查反转结果 */ + not_memory: + *p = old; + break; + } + *p ^= 0xffffffff; /* 再次反转 */ + if (*p != pat0) { + /* 检查值是否恢复 */ + goto not_memory; + } + *p = old; /* 恢复为修改前的值 */ + } + return i; +} + diff --git a/09_day/naskfunc.nas b/09_day/naskfunc.nas index 41bc001..3322225 100644 --- a/09_day/naskfunc.nas +++ b/09_day/naskfunc.nas @@ -11,6 +11,7 @@ GLOBAL _io_out8, _io_out16, _io_out32 GLOBAL _io_load_eflags, _io_store_eflags GLOBAL _load_gdtr, _load_idtr + GLOBAL _load_cr0, _store_cr0 GLOBAL _asm_inthandler21, _asm_inthandler27, _asm_inthandler2c EXTERN _inthandler21, _inthandler27, _inthandler2c @@ -91,6 +92,15 @@ _load_idtr: ; void load_idtr(int limit, int addr); LIDT [ESP+6] RET +_load_cr0: ; int load_cr0(void); + MOV EAX,CR0 + RET + +_store_cr0: ; void store_cr0(int cr0); + MOV EAX,[ESP+4] + MOV CR0,EAX + RET + _asm_inthandler21: PUSH ES PUSH DS