1

I am trying to write a physical allocator, and to do so I need the base address for available memory, the high address for available memory, and a memory map. This is all provided to me by the BIOS (multiboot1). I have inspected the value passed to eax as the kernel first boots and it matches the multiboot1 value, so no issue there (I am booting with MB1). Also, I am setting bit 1 of the flags (So I am requesting the memmap). However, it is the second parameter, the MBI structure that is giving me issues. I have looked on the MBI docs and have found an exact description of what the MBI should look like and implemented it in C: my C implementation:

/* macros copy-pasted from multiboot spec */
#define MULTIBOOT_MEMORY_AVAILABLE              1
#define MULTIBOOT_MEMORY_RESERVED               2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
#define MULTIBOOT_MEMORY_NVS                    4
#define MULTIBOOT_MEMORY_BADRAM                 5
 
typedef struct {
    uint32_t address_high; // ignored on 32-bit
    uint32_t address_low;
    uint32_t length_high; // ignored on 32-bit
    uint32_t length_low;
    uint32_t type; // (1 == useable)
    uint32_t zero;
} __attribute__((__packed__)) mmap_entry_t;
 
 
/* like 3/4 of this is not relevant to me but i keep it anyway */
typedef struct {
    uint32_t flags;        // flags
    uint32_t mem_lower;    // lower memory (KB)
    uint32_t mem_upper;    // upper memory (KB)
    uint32_t boot_device;  // boot device ID
    uint32_t cmdline;      // address of kernel command line
    uint32_t mods_count;   // number of modules loaded
    uint32_t mods_addr;    // address of first module structure
 
    uint32_t irrelevant[3];
 
    uint32_t mmap_length;  // memory map length
    uint32_t mmap_addr;    // memory map address
    uint32_t drives_length; // drive info length
    uint32_t drives_addr;   // drive info address
    uint32_t config_table;  // ROM configuration table
    uint32_t boot_loader_name; // bootloader name string address
    uint32_t apm_table;     // APM table address
    uint32_t vbe_control_info; // VBE control information
    uint32_t vbe_mode_info; // VBE mode information
    uint32_t vbe_mode;      // VBE mode
    uint32_t vbe_interface_seg;  // VBE interface segment
    uint32_t vbe_interface_off;  // VBE interface offset
    uint32_t vbe_interface_len;  // VBE interface length
} __attribute__((__packed__)) multiboot_info_t;

The multiboot docs say:

The format of the Multiboot information structure (as defined so far) follows:

        +-------------------+
0       | flags             |    (required)
        +-------------------+
4       | mem_lower         |    (present if flags[0] is set)
8       | mem_upper         |    (present if flags[0] is set)
        +-------------------+
12      | boot_device       |    (present if flags[1] is set)
        +-------------------+
16      | cmdline           |    (present if flags[2] is set)
        +-------------------+
20      | mods_count        |    (present if flags[3] is set)
24      | mods_addr         |    (present if flags[3] is set)
        +-------------------+
28 - 40 | syms              |    (present if flags[4] or
        |                   |                flags[5] is set)
        +-------------------+
44      | mmap_length       |    (present if flags[6] is set)
48      | mmap_addr         |    (present if flags[6] is set)
        +-------------------+
52      | drives_length     |    (present if flags[7] is set)
56      | drives_addr       |    (present if flags[7] is set)
        +-------------------+
60      | config_table      |    (present if flags[8] is set)
        +-------------------+
64      | boot_loader_name  |    (present if flags[9] is set)
        +-------------------+
68      | apm_table         |    (present if flags[10] is set)
        +-------------------+
72      | vbe_control_info  |    (present if flags[11] is set)
76      | vbe_mode_info     |
80      | vbe_mode          |
82      | vbe_interface_seg |
84      | vbe_interface_off |
86      | vbe_interface_len |
        +-------------------+
88      | framebuffer_addr  |    (present if flags[12] is set)
96      | framebuffer_pitch |
100     | framebuffer_width |
104     | framebuffer_height|
108     | framebuffer_bpp   |
109     | framebuffer_type  |
110-115 | color_info        |
        +-------------------+

However, when I boot and check the value in the %ebx register, it points to what seems like garbage:

(gdb) p *(multiboot_info_t*)($ebx)
$1 = {flags = 591, mem_lower = 639, mem_upper = 129920, boot_device = 2147549183, cmdline = 2142208, mods_count = 0, mods_addr = 2142208, irrelevant = {0, 0, 0}, mmap_length = 0, mmap_addr = 144, drives_length = 36864, drives_addr = 0, 
  config_table = 0, boot_loader_name = 0, apm_table = 2142229, vbe_control_info = 0, vbe_mode_info = 0, vbe_mode = 0, vbe_interface_seg = 0, vbe_interface_off = 0, vbe_interface_len = 0}

Im not exactly sure what I expected, but it definitely wasnt the memmap having an address but no length. the mmap_length being 0 is what really throws me off here. However, these values are the same every time. (Every time I boot and check the value, I get these duplicated values). So it makes me think that maybe I am doing something wrong with the way I am handling the info. If so, please let me know. Thanks for reading. If you want to check out additional code from my OS, its all on github: https://github.com/thewhynow/LakeOS

3
  • 1
    I think the problem is the way the table in the Multiboot spec denotes the offsets. 28 - 40 would have been probably better stated as 28-44, or 4 uint32_t starting at 28, 32, 36, 40. With that in mind the reason things seem a bit off for mmap_length and mmap_addr is because you should have used uint32_t irrelevant[4]; instead of uint32_t irrelevant[3];. As a result of this error part of your structure is shifted. Commented Mar 8 at 8:25
  • 1
    @MichaelPetch Thank you so much, it all works now. I knew it was something stupid simple. Have a great day! Commented Mar 8 at 13:55
  • Please feel free to self answer your question. Commented Mar 8 at 20:45

1 Answer 1

0

use uint32_t irrelevant[4] instead of uint32_t irrelevant[3].

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.