You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从GRUB Multiboot2引导加载器向内核传递VBE信息?

GRUB Multiboot2 无法传递VBE信息问题

环境配置

  • 编译器:i386-elf
  • GRUB版本:2.06
  • 虚拟机:QEMU
  • BIOS:SeaBIOS

问题现象

我需要通过GRUB引导加载器向内核传递VBE信息,采用Multiboot2规范,但内核在枚举Multiboot标签时,始终找不到MULTIBOOT_TAG_TYPE_VBE标签,仅能获取到以下标签:

  • MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR
  • MULTIBOOT_TAG_TYPE_CMDLINE
  • MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME
  • MULTIBOOT_TAG_TYPE_APM
  • MULTIBOOT_TAG_TYPE_MMAP
  • MULTIBOOT_TAG_TYPE_ELF_SECTIONS
  • MULTIBOOT_TAG_TYPE_BASIC_MEMINFO
  • MULTIBOOT_TAG_TYPE_BOOTDEV
  • MULTIBOOT_TAG_TYPE_FRAMEBUFFER
  • MULTIBOOT_TAG_TYPE_ACPI_OLD

已尝试网络搜索但未找到有效解决方案,寻求技术帮助。

引导加载器代码

#define ASM_FILE        1
#include <grub/multiboot.h>

#ifdef HAVE_ASM_USCORE
#define EXT_C(sym)                     _ ## sym
#else
#define EXT_C(sym)                     sym
#endif

#define STACK_SIZE                      0x4000

#ifdef __ELF__
#define AOUT_KLUDGE 0
#else
#define AOUT_KLUDGE MULTIBOOT_AOUT_KLUDGE
#endif
        .text

        .globl  start, _start
start:
_start:
        jmp     multiboot_entry
        .align  8
multiboot_header:
        .long   MULTIBOOT2_HEADER_MAGIC
        .long   MULTIBOOT_ARCHITECTURE_I386
        .long   multiboot_header_end - multiboot_header
        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
        .align  8
#ifndef __ELF__
address_tag_start:      
        .short MULTIBOOT_HEADER_TAG_ADDRESS
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long address_tag_end - address_tag_start
        .long   multiboot_header
        .long   _start
        .long   _edata
        .long   _end
address_tag_end:
        .align  8
entry_address_tag_start:        
        .short MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long entry_address_tag_end - entry_address_tag_start
        .long multiboot_entry
entry_address_tag_end:
        .align  8
#endif
        .short MULTIBOOT_HEADER_TAG_END
        .short 0
        .long 8
multiboot_header_end:
multiboot_entry:
        movl    $(stack + STACK_SIZE), %esp

        pushl   $0
        popf

        pushl   %ebx
        pushl   %eax

        call    EXT_C(cmain)
        
loop:   hlt
        jmp     loop

        .comm   stack, STACK_SIZE

内核代码

#include "drives/video/t-vga.h"
#include "grub/multiboot.h"
#include <stddef.h>
#include <stdint.h>

void cmain(unsigned long magic, unsigned long addr) {
    clear_screen();

    if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
        printf("Error: Invalid magic number: 0x%x\n", (unsigned)magic);
        return;
    }
    
    if (addr & 7) {
        printf("Error: Unaligned mbi: 0x%x\n", addr);
        return;
    }
    
    unsigned size = *(unsigned *)addr;
    printf("Announced mbi size: 0x%x\n", size);
    
    struct multiboot_tag *tag;
    
    for (tag = (struct multiboot_tag *)(addr + 8);
         tag->type != MULTIBOOT_TAG_TYPE_END;
         tag = (struct multiboot_tag *)((multiboot_uint8_t *)tag +
                                        ((tag->size + 7) & ~7))) {
        //printf("Tag Type: 0x%x, Size: 0x%x\n", tag->type, tag->size);
    
        switch (tag->type) {
            case MULTIBOOT_TAG_TYPE_CMDLINE:
                printf("Command line: %s\n",
                       ((struct multiboot_tag_string *)tag)->string);
                break;
            case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
                printf("Boot loader name: %s\n",
                       ((struct multiboot_tag_string *)tag)->string);
                break;
            case MULTIBOOT_TAG_TYPE_MODULE:
                printf("Module at 0x%x-0x%x. Command line: %s\n",
                       ((struct multiboot_tag_module *)tag)->mod_start,
                       ((struct multiboot_tag_module *)tag)->mod_end,
                       ((struct multiboot_tag_module *)tag)->cmdline);
                break;
            case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
                printf("Memory info: Lower: %uKB, Upper: %uKB\n",
                       ((struct multiboot_tag_basic_meminfo *)tag)->mem_lower,
                       ((struct multiboot_tag_basic_meminfo *)tag)->mem_upper);
                break;
            case MULTIBOOT_TAG_TYPE_BOOTDEV:
                printf("Boot device: 0x%x, Slice: %u, Part: %u\n",
                       ((struct multiboot_tag_bootdev *)tag)->biosdev,
                       ((struct multiboot_tag_bootdev *)tag)->slice,
                       ((struct multiboot_tag_bootdev *)tag)->part);
                break;
            case MULTIBOOT_TAG_TYPE_VBE:
                printf("VBE Tag found\n");
                break;
            case MULTIBOOT_TAG_TYPE_MMAP: {
                multiboot_memory_map_t *mmap;
                printf("Memory map:\n");
    
                for (mmap = ((struct multiboot_tag_mmap *)tag)->entries;
                     (multiboot_uint8_t *)mmap <
                         (multiboot_uint8_t *)tag + tag->size &&
                     (multiboot_uint8_t *)mmap + sizeof(*mmap) <=
                         (multiboot_uint8_t *)tag + tag->size;
                     mmap = (multiboot_memory_map_t *)((unsigned long)mmap +
                                                       ((struct multiboot_tag_mmap *)tag)->entry_size)) {
                    printf("  Base: 0x%x%x, Length: 0x%x%x, Type: 0x%x\n",
                           (unsigned)(mmap->addr >> 32),
                           (unsigned)(mmap->addr & 0xffffffff),
                           (unsigned)(mmap->len >> 32),
                           (unsigned)(mmap->len & 0xffffffff),
                           (unsigned)mmap->type);
                }
            } break;
        }
    }
    
    printf("Total mbi size: 0x%x\n", (unsigned)tag - addr);

}

内容的提问来源于stack exchange,提问作者ATOM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:20:53