Multiboot2 遍历发现无效标签

问题描述 投票:0回答:1

在使用 GRUB2 启动 multiboot2 投诉操作系统时,阅读我收到的标签

type = 25
以及我对
type = 6
的信息请求被忽略。

不完全确定我的遍历方法是否有效。
不知道这是否是 GRUB2 的问题。
如果正确的话哪里有

type = 25
的资料。

;; multiboot2.asm

%define mb2_magic 0xE85250D6
%define mb2_arch 0

section .boot
_mb2:
dd mb2_magic
dd mb2_arch
dd _emb2 - _mb2
dd 0x100000000 - (mb2_magic + mb2_arch + (_emb2 - _mb2))

align 8

.mb2_ir:
    dw 1 ; information request
    dw 0
    dd .emb2_ir - .mb2_ir
    dd 6 ; memory map tag
.emb2_ir:

align 8

.end_tag:
    dd 0
    dd 8
_emb2:
;entry.asm

[BITS32]
__start:
    mov [.mb2_magic], eax
    mov [.mb2_info], ebx
    ;; ...
    call check_multiboot
    ;; ...
    lgdt [gdt64.ptr]
    jmp gdt64.code:realm64
    .mb2_magic:
        dd 0
    .mb2_info:
        dq 0

check_multiboot:
    mov eax, [__start.mb2_magic]
    cmp eax, 0x36D76289 ; multiboot2 magic number
    jne .fail
    ret
    .fail:
        mov ebx, .message
        call quick_print ; defined in file
        hlt
    .message:
        db "Boot Check Failed:", 0x0A, 0x0A, "Was not booted from MultiBoot2", 0x0A, "MBR (Master Boot Record) is incompatible", 0x00

;; ...
[BITS 64]
realm64:
    ;; ...
    [extern main]
    mov rsi, [__start.mb2_magic]
    mov rdi, [__start.mb2_info]
    call main
// kernel.c

int main(mb2_info_header* mbd, uint32_t magic) // magic checked in entry.asm
{
    tty_init();
    mb2_traverse(mbd);
    // ...
}
// multiboot2.c

typedef struct s_MB2_tag {
    uint32_t type;
    uint32_t size;
} mb2_tag;

typedef struct s_MB2_info_header {
    uint32_t total_size;
    uint32_t __RSV1;
} mb2_info_header;

void mb2_traverse(mb2_info_header *mbd)
{
    uint64_t mb2_end = mbd->total_size + (uint64_t)mbd;
    mb2_tag *tag = (mb2_tag*)(mbd + sizeof(mb2_info_header));
    while ((uint64_t)tag < mb2_end)
    {
        tty_printf("TAG %d\t[%d] @\t%x\n", tag->type, tag->size, tag);
        if (tag->type == 0)
            break;
        tag += tag->size;
        if ((uint64_t)tag & 0x7)
            tag += 8 - ((uint64_t)tag & 0x7);
    }
}

产量:

TAG N  [size] @  ptr

TTY 截图

assembly gcc x86-64 osdev grub2
1个回答
0
投票

@MichaelPetch 提供了此评论(非常感谢)

经过进一步检查,存在类似的选角问题(参考之前的评论)这里也:

tag += tag->size;
你可以做类似的事情
tag = (mb2_tag *) ((uint8_t *) tag + ((tag->size + 7) & ~7)))

将代码调整为

multiboot2.c

中的新遍历之后
// multiboot2.c

void mb2_traverse(mb2_info_header *mbd, uint32_t magic)
{
    if (magic != 0x36D76289)
    {
        tty_printf("Multiboot2 Magic Number is invalid");
        asm volatile ("hlt");
    }
    tty_printf("MB2 [%d]\n", mbd->total_size);
    uint64_t mb2_end = mbd->total_size + (uint64_t)mbd;

    mb2_tag *tag = (mb2_tag*)(mbd + sizeof(mb2_info_header));
    while ((uint64_t)tag < mb2_end)
    {
        tty_printf("TAG %d\t[%d] @\t%x\n", tag->type, tag->size, tag);
        if (tag->type == 0)
            break;
        switch (tag->type) {
            // ...
            default: break;
        }
        tag = (mb2_tag *) ((uint8_t *) tag + ((tag->size + 7) & ~7));
    }
}

产生结果:
Result Screenshot

© www.soinside.com 2019 - 2024. All rights reserved.