0

我正在尝试使用 grub 来获取内存映射,而不是通过 bios 路由。问题是 grub 似乎出于某种原因给了我非常奇怪的值。有人能帮忙吗?

相关代码:

这就是我解析 mmap 的方式

void mm_init(mmap_entry_t *mmap_addr, uint32_t length)
{
    mmap = mmap_addr;
    /* Loop through mmap */
    printk("-- Scanning memory map --");
    for (size_t i = 0; mmap < (mmap_addr + length); i++) {
        /* RAM is available! */
        if (mmap->type == 1) {
            uint64_t starting_addr = (((uint64_t) mmap->base_addr_high) << 32) | ((uint64_t) mmap->base_addr_low);
            uint64_t length = (((uint64_t) mmap->length_high) << 32) | ((uint64_t) mmap->length_low);
            printk("Found segment starting from 0x%x, with a length of %i", starting_addr, length);
        }
        /* Next entry */
        mmap = (mmap_entry_t *) ((uint32_t) mmap + mmap->size + sizeof(mmap->size));
    }
}

这是我的 mmap_entry_t 结构(不是 multiboot.h 中的那个):

struct mmap_entry {
    uint32_t size;
    uint32_t base_addr_low, base_addr_high;
    uint32_t length_low, length_high;
    uint8_t type;
}  __attribute__((packed));

typedef struct mmap_entry mmap_entry_t;

这就是我所说的mm_init()

/* Kernel main function */
void kmain(multiboot_info_t *info)
{
    /* Check if grub can give us a memory map */
    /* TODO: Detect manually */
    if (!(info->flags & (1<<6))) {
        panic("couldn't get memory map!");
    }

    /* Init mm */
    mm_init((mmap_entry_t *) info->mmap_addr, info->mmap_length);

    for(;;);
}

这是我在 qemu 上得到的输出:

-- Scanning memory map --
Found segment starting from 0x0, with a length of 0
Found segment starting from 0x100000, with a length of 0

是的,我正在推动eaxebx然后再打电话kmain。关于这里出了什么问题的任何想法?

4

1 回答 1

0

事实证明,位掩码是问题所在。如果我们放弃它,我们仍然可以拥有 32 位地址,并且内存映射工作得很好。

于 2021-05-17T12:51:21.180 回答