How can I pass VBE information to the kernel from the GRUB bootloader?

110 views Asked by At

I need to somehow pass information to VBE, how do I do this? Bootloader code:

#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

Kernel code:

#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);

}

I'm using multiboot2. Help me please.

Compiler: i386-elf GRUB Version: 2.06 Virtual machine - QEMU BIOS - seabios

When I list tags in multiboot2, I only get these tags:

Click here

Here are the tags:

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

Also there is no tag MULTIBOOT_TAG_TYPE_VBE

I tried searching on the internet but to no avail

0

There are 0 answers