如果你走入我们的内核之旅网站http://www.kerneltravel.net/ ,静下心阅读并动手实践,或许,流逝的时间,让你手捧沉甸甸的果实。 欢迎在讨论区提问。 如果你希望有即时的讨论,欢迎到西邮Linux兴趣小组:http://groups.google.com/group/xiyouLinux

内存空间探测

2008-03-22 11:36:07 / 个人分类:释义Linux内核

让参与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)

此程序有什么改进之处?

 


TAG: 释义Linux内核 内存探测

七度黑光 helight 发布于2008-03-23 13:05:39
其实在内核中就有这样的写法,在arch/i386/kernel/E820.c中的void __init print_memory_map(char *who)就是干这个的
void __init print_memory_map(char *who)
{
        int i;

        for (i = 0; i < e820.nr_map; i++) {
                printk(" %s: %016Lx - %016Lx ", who,
                        e820.map.addr,
                        e820.map.addr + e820.map.size);
                switch (e820.map.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.type);
                                break;
                }
        }
}
我来说两句

(可选)