系统内核管理模块的实现2--解析内存状态信息
来源:互联网 发布:免费通达信软件 编辑:程序博客网 时间:2024/06/06 10:01
上一节,我们成功调用BIOS,获取内存信息,现在,我们可以显示和分析获得的相关信息,为下一步实现内存管理做准备。首先我们把BIOS填充好的数据缓冲过去导出给C语言模块,以便使用C语言来实现分析功能:
get_adr_buffer: mov eax, MemChkBuf ret
MemChkBuf 是BIOS填充好的数据缓冲区地址,C语言模块通过调用接口get_adr_buffer,获得该地址,以便对内存分布状况进行深入的解析。
我们看看在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函数的作用是将地址描述符的信息显示到桌面上。
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进制字符串显示到桌面上。上面的代码编译后加载到虚拟机,运行情况如下:
每按一次回车键,桌面上的信息就会更新。我虚拟机的内存信息如下:
1:
BaseAddrL: 0x00000000
BaseAddrH:0x00000000
lengthLow: 0x0009FC00
lengthHigh: 0x00000000
type: 0x00000001
2:
BaseAddrL: 0x0009FC00
BaseAddrH: 0x00000000
lengthLow: 0x00000400
lengthHigh: 0x00000000
type: 0x00000002
3:
BaseAddrL: 0x000F0000
BaseAddrH: 0x00000000
lengthLow: 0x00010000
lengthHigh: 0x00000000
type: : 0x00000002
4:
BaseAddrL: 0x00100000
BaseAddrH: 0x00000000
lengthLow: 0x3FEF0000
lengthHigh: 0x00000000
type: 0x00000001
5:
BaseAddrL: 0x3FEF0000
BaseAddrH: 0x00000000
lengthLow: 0x00010000
lengthHigh: 0x00000000
type: 0x00000003
6:
BaseAddrL: 0xFFC00000
BaseAddrH: 0x00000000
lengthLow: 0x00040000
lengthHigh: 0x00000000
type: 0x00000002
由于我们开发的是32位系统,所以baseAddrH, lengthHigh 全部为0,从上面显示的内存信息可以得知,我虚拟机的可用内存是1G,但是可以被内核使用的内存只要两块,一块的地址是从0开始,长度为:0x0009FC00, 另一块起始地址为:0x00100000,长度为0x3FEF0000, 基于这些信息,下一步我们就可以开发内存管理分配算法了。
具体的代码调试和效果演示请参看视频:
Linux kernel Hacker, 从零构建自己的内核
- 系统内核管理模块的实现2--解析内存状态信息
- 操作系统内核管理模块的实现1-检测可用内存
- windows系统信息,内存状态,区域信息的查询
- 一个动态内存管理模块的实现
- 一个动态内存管理模块的实现
- 内核sanitize_e820_map函数详解(征服内存管理模块的起点)
- mantis bug 管理系统的不同状态信息的对照
- 模块管理常规功能自定义系统的设计与实现(19--模块附件的设计[2])
- linux底层内存管理--内核空间的伙伴系统
- 客运综合管理系统项目解析—安全检查(模块)-司机信息
- 客运综合管理系统项目解析-安全检查(模块)-车辆信息
- Linux内核模块的管理
- Linux:内核模块实现替换系统调用的简单例子
- Linux:内核模块实现替换系统调用的简单例子
- 全面解析Linux 内核 3.10.x - 内存管理 - 伙伴系统算法(Buddy System)
- 一张图深度解析Linux共享内存的内核实现
- 全面解析Linux 内核 3.10.x - 内存管理 - 高端地址的内核映射
- 跨模块的内存管理
- Tomcat 配置优化
- Xtreme 10.0 - Dog Walking
- 线程的同步和异步有何异同
- windows 下 搭建 ftp 服务器
- HTTP协议
- 系统内核管理模块的实现2--解析内存状态信息
- Android 引导图层、引导页
- ssh框架封装baseAction
- 大数据架构:flume-ng+Kafka+Storm+HDFS 实时系统组合
- 网络爬虫基础(二)
- 关于Mysql5.7修改root密码ERROR 1054的问题
- CentOS6.5设置系统环境
- JWPlayer 7的正确使用方法及Flash plugin failed to load解决方法
- Eclipse快捷键 10个最有用的快捷键