e820简介

来源:互联网 发布:php include 变量 编辑:程序博客网 时间:2024/05/19 03:42

本文系转载,原文地址:http://wangcong.org/blog/?p=320,其中附录部分为本人所加...


    e820是和BIOS的一个中断相关的,具体说是int 0x15。之所以叫e820是因为在用这个中断时ax必须是0xe820。这个中断的作用是得到系统的内存布局。因为系统内存会有很多段,每段的类型属性也不一样,所以这个查询是“迭代式”的,每次求得一个段。

    我们看内核源代码。主要涉及两个文件:arch/x86/boot/memory.c和arch/x86/kernel/e820_32.c。我们已经很幸运了,这部分代码已经用C重写过了。你可能会奇怪,启动调用e820时我们还在实模式,怎么能用C呢?答案是,这里用的是16位的C。gcc早已经支持.code16 gcc模式了。

    看detect_memory_e820()函数,里面就是e820的本质。它把int0x15放到一个do-while循环里,每次得到的一个内存段放到struct e820entry里,而structe820entry的结构正是e820返回结果的结构!而像其它启动时获得的结果一样,最终都会被放到boot_params里,e820被放到了boot_params.e820_map。

如果你对struct e820entry还有疑问,你可以看一下arch/x86/kernel/e820_32.c::print_memory_map(),看看里面是怎么使用它的。

    当然了,在arch/x86/boot/memory.c里,你还会看到另外两个利用int 0x15查询内存的函数,不过用途不一样了。


附:

boot_params结构体定义,其中E820MAX定义为128:

  1. struct e820entry {
        __u64 addr;    /* start of memory segment */
        __u64 size;    /* size of memory segment */
        __u32 type;    /* type of memory segment */
    } __attribute__((packed));

  2. struct boot_params {
  3.     struct screen_info screen_info;         /* 0x000 */
  4.     struct apm_bios_info apm_bios_info;     /* 0x040 */
  5.     __u8  _pad2[12];                /* 0x054 */
  6.     struct ist_info ist_info;           /* 0x060 */
  7.     __u8  _pad3[16];                /* 0x070 */
  8.     __u8  hd0_info[16]; /* obsolete! */     /* 0x080 */
  9.     __u8  hd1_info[16]; /* obsolete! */     /* 0x090 */
  10.     struct sys_desc_table sys_desc_table;       /* 0x0a0 */
  11.     __u8  _pad4[144];               /* 0x0b0 */
  12.     struct edid_info edid_info;         /* 0x140 */
  13.     struct efi_info efi_info;           /* 0x1c0 */
  14.     __u32 alt_mem_k;                /* 0x1e0 */
  15.     __u32 scratch;      /* Scratch field! */    /* 0x1e4 */
  16.     __u8  e820_entries;             /* 0x1e8 */
  17.     __u8  eddbuf_entries;               /* 0x1e9 */
  18.     __u8  edd_mbr_sig_buf_entries;          /* 0x1ea */
  19.     __u8  _pad6[6];                 /* 0x1eb */
  20.     struct setup_header hdr;    /* setup header */  /* 0x1f1 */
  21.     __u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
  22.     __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];  /* 0x290 */
  23.     struct e820entry e820_map[E820MAX];     /* 0x2d0 */
  24.     __u8  _pad8[48];                /* 0xcd0 */
  25.     struct edd_info eddbuf[EDDMAXNR];       /* 0xd00 */
  26.     __u8  _pad9[276];               /* 0xeec */
  27. } __attribute__((packed));


通过bios获取系统内存布局代码如下:

  1. static int detect_memory_e820(void)
  2. {
  3.     int count = 0;
  4.     u32 next = 0;
  5.     u32 size, id;
  6.     u8 err;
  7.     struct e820entry *desc = boot_params.e820_map;
  8.     do {
  9.         size = sizeof(struct e820entry);
  10.         /* Important: %edx is clobbered by some BIOSes,
  11.            so it must be either used for the error output
  12.            or explicitly marked clobbered. */
  13.         asm("int $0x15; setc %0"
  14.             : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
  15.               "=m" (*desc)
  16.             : "D" (desc), "d" (SMAP), "a" (0xe820));
  17.         /* BIOSes which terminate the chain with CF = 1 as opposed
  18.            to %ebx = 0 don't always report the SMAP signature on
  19.            the final, failing, probe. */
  20.         if (err)
  21.             break;
  22.         /* Some BIOSes stop returning SMAP in the middle of
  23.            the search loop.  We don't know exactly how the BIOS
  24.            screwed up the map at that point, we might have a
  25.            partial map, the full map, or complete garbage, so
  26.            just return failure. */
  27.         if (id != SMAP) {
  28.             count = 0;
  29.             break;
  30.         }
  31.         count++;
  32.         desc++;
  33.     } while (next && count < E820MAX);
  34.     return boot_params.e820_entries = count;
  35. }
这个函数执行完毕后,boot_params.e820_map就含有了系统内存布局图。
函数关键部分解释如下:
07 获取启动参数boot_params里的e820_map数组首地址。
15-18 通过中断0x15调用bios例程获得一个内存段的信息,这条语句是按照AT&T的汇编语法格式写的,具体语法可以查看相关资料。

原创粉丝点击