让参与Linux内核毕业设计的学生写一个内核模块,能够对Linux启动以后的内存分布情况进行探测,用到内核数据结构E820。
例如,能够显示如下信息:
BIOS-e820: 0000000000000000 - 000000000009fc00 (usable) *
BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 000000001f7d0000 (usable) *
BIOS-e820: 000000001f7d0000 - 000000001f7e5600 (reserved)
BIOS-e820: 000000001f7e5600 - 000000001f7f8000 (ACPI NVS)
BIOS-e820: 000000001f7f8000 - 000000001f800000 (reserved)
BIOS-e820: 00000000fec00000 - 00000000fec01000 (reserved)
BIOS-e820: 00000000fed20000 - 00000000fed9b000 (reserved)
BIOS-e820: 00000000feda0000 - 00000000fedc0000 (reserved)
BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
BIOS-e820: 00000000ffb00000 - 00000000ffc00000 (reserved)
BIOS-e820: 00000000fff00000 - 0000000100000000 (reserved)
很快,木天的程序写出来了,但还不完善:
将E820.c中的void __init print_memory_map(char *who)改写成了f();
手工从/proc/kallsyms中查出e820的地址
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/e820.h>
struct e820map e820;
void __init f()
{
int i;
for (i = 0; i < e820.nr_map; i++) {
printk("BIOS-e820: %016Lx - %016Lx ",
e820.map[i].addr,
e820.map[i].addr + e820.map[i].size);
switch (e820.map[i].type) {
case E820_RAM: printk("(usable)\n");
break;
case E820_RESERVED:
printk("(reserved)\n");
break;
case E820_ACPI:
printk("(ACPI data)\n");
break;
case E820_NVS:
printk("(ACPI NVS)\n");
break;
default: printk("type %u\n", e820.map[i].type);
break;
}
}
}
static int __init m1_init(void)
{
e820=*(struct e820map *)(0xc04411e0);
f();
return 0;
}
static void __exit m1_cleanup(void)
{
printk("<1>Goodbye!\n");
}
module_init(m1_init);
module_exit(m1_cleanup);
以下是他机器上运行的结果(1G RAM):
[49987.576000] BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
[49987.576000] BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
[49987.576000] BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved)
[49987.576000] BIOS-e820: 0000000000100000 - 000000003ffb0000 (usable)
[49987.576000] BIOS-e820: 000000003ffb0000 - 000000003ffbe000 (ACPI
data)
[49987.576000] BIOS-e820: 000000003ffbe000 - 000000003ffe0000 (ACPI NVS)
[49987.576000] BIOS-e820: 000000003ffe0000 - 000000003ffee000 (reserved)
[49987.576000] BIOS-e820: 000000003fff0000 - 0000000040000000 (reserved)
[49987.576000] BIOS-e820: 00000000fec00000 - 00000000fec01000 (reserved)
[49987.576000] BIOS-e820: 00000000fee00000 - 00000000fef00000 (reserved)
[49987.576000] BIOS-e820: 00000000fff00000 - 0000000100000000 (reserved)
此程序有什么改进之处?