内存管理 - 解析内存状态
1.简介
现在 我们可以显示和分析获得的相关信息 为下一步实现内存管理做准备
首先我们把BIOS填充好的数据缓冲过去导出给C语言模块 以便使用C语言来实现分析功能:
get_adr_buffer: mov eax, MemChkBuf ret
MemChkBuf 是BIOS填充好的数据缓冲区地址 C语言模块通过调用接口get_adr_buffer 获得该地址
以便对内存分布状况进行深入的解析
2.代码
C语言中:
struct AddrRangeDesc { unsigned int baseAddrLow; unsigned int baseAddrHigh; unsigned int lengthLow; unsigned int lengthHigh; unsigned int type; }; char* get_adr_buffer(void); void showMemoryInfo(struct AddrRangeDesc* desc, char* vram, int page, int xsize,int color);
首先根据BIOS填充的地址描述符 设计一个对应的结构体 以便对地址描述符进行分析
showMemoryInfo函数的作用是将地址描述符的信息显示到桌面上
在Main函数中调用
void CMain(void) { ... struct AddrRangeDesc* memDesc = (struct AddrRangeDesc*)get_adr_buffer(); for(;;) { .... else if(fifo8_status(&keyinfo) != 0){ io_sti(); data = fifo8_get(&keyinfo); if (data == 0x1C) { showMemoryInfo( memDesc + count, vram, count, xsize, COL8_FFFFFF); count = (count+1); if (count > memCnt) { count = 0; } } .... } ... }
在C入口函数中 先通过调用汇编模块导出的接口 获得地址描述符的内存地址
在主循环中 当键盘又按键按下时
如果按键的扫描码是0x1C 也就是回车键被按下的时候
内核就在桌面上显示地址描述符的信息
每按一次回车键 就显示下一个描述符的信息 当所有描述符都显示完毕后 重新从第一个描述符开始循环显示
void showMemoryInfo(struct AddrRangeDesc* desc, char* vram, int page,int xsize, int color) { int x = 0, y = 0, gap = 13*8, strLen = 10* 8; boxfill8(vram, xsize, COL8_008484, 0, 0, xsize, 100); showString(vram, xsize, x, y, color, "page is: "); char* pPageCnt = intToHexStr(page); showString(vram, xsize, gap, y, color, pPageCnt); y += 16; showString(vram, xsize, x, y, color, "BaseAddrL: "); char* pBaseAddrL = intToHexStr(desc->baseAddrLow); showString(vram, xsize, gap, y, color, pBaseAddrL); y += 16; showString(vram, xsize, x, y, color, "BaseAddrH: "); char* pBaseAddrH = intToHexStr(desc->baseAddrHigh); showString(vram, xsize, gap, y, color, pBaseAddrH); y += 16; showString(vram, xsize, x, y, color, "lengthLow: "); char* pLengthLow = intToHexStr(desc->lengthLow); showString(vram, xsize, gap, y, color, pLengthLow); y+= 16; showString(vram, xsize, x, y, color, "lengthHigh: "); char* pLengthHigh = intToHexStr(desc->lengthHigh); showString(vram, xsize, gap, y, color, pLengthHigh); y+= 16; showString(vram, xsize, x, y, color, "type: "); char* pType = intToHexStr(desc->type); showString(vram, xsize, gap, y, color, pType); }
showMemoryInfo实现不难,就是把地址描述符每个成员的数值转换成16进制字符串显示到桌面上。上面的代码编译后加载到虚拟机,运行情况如下:
(编译过程和之前一样 后边我们自动化起来)
编译C文件
i386-elf-gcc -m32 -fno-asynchronous-unwind-tables -s -c -o write_vga_desktop.o write_vga_desktop.c
反汇编o文件
./objconv -fnasm write_vga_desktop.o write_vga_desktop.asm
删除无用部分
修改kernel
%include "write_vga_desktop.asm"
修改boot(直接放大一点)直接读了18个扇区 肯定够用了
mov AL, 18 ; AL 表示要练习读取几个扇区
编译boot
nasm -o boot.bat boot.asm
编译kernel
nasm -o kernel.bat kernel.asm
运行java 生成system.img