* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <multiboot2.h>
+#include "multiboot2.h"
/* Macros. */
return;
}
+ if (addr & 7)
+ {
+ printf ("Unaligned mbi: 0x%x\n", addr);
+ return;
+ }
+
size = *(unsigned *) addr;
printf ("Announced mbi size 0x%x\n", size);
- for (tag = (struct multiboot_tag *) (addr + 4);
+ for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
- tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + tag->size))
+ tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
+ + ((tag->size + 7) & ~7)))
{
printf ("Tag 0x%x, Size 0x%x\n", tag->type, tag->size);
switch (tag->type)
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;
(multiboot_uint8_t *) mmap
< (multiboot_uint8_t *) tag + tag->size;
- mmap = (multiboot_memory_map_t *) ((unsigned long) mmap
- + mmap->size
- + sizeof (mmap->size)))
- printf (" size = 0x%x, base_addr = 0x%x%x,"
+ mmap = (multiboot_memory_map_t *)
+ ((unsigned long) mmap
+ + ((struct multiboot_tag_mmap *) tag)->entry_size))
+ printf (" base_addr = 0x%x%x,"
" length = 0x%x%x, type = 0x%x\n",
- (unsigned) mmap->size,
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
}
}
- tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + tag->size);
+ tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
+ + ((tag->size + 7) & ~7));
printf ("Total mbi size 0x%x\n", (unsigned) tag - addr);
}
it is done using it.
@subsection Basic tags structure
-Boot information consists of fixed part and a series of tags. Fixed part is as following:
+Boot information consists of fixed part and a series of tags. Its start is 8-bytes aligned. Fixed part is as following:
@example
@group
+-------------------+
0-3 | total_size |
+4-7 | reserved |
+-------------------+
@end group
@end example
@samp{total_size} contains the total size of boot information including
this field and terminating tag in bytes
+@samp{reserved} is always set to zero and must be ignored by OS image
+
Every tag begins with following fields:
@example
@end example
@samp{type} contains an identifier of contents of the rest of the tag.
-@samp{size} contains the size of tag including header fields.
-Tags follow one another without any gaps. Tags are terminated by a tag of type @samp{0} and size @samp{8}.
+@samp{size} contains the size of tag including header fields but not including padding.
+Tags follow one another padded when necessary in order for each tag to start at 8-bytes aligned address. Tags are terminated by a tag of type @samp{0} and size @samp{8}.
@subsection Basic memory information
@example
@end group
@end example
-@samp{string} contains command line. The command line is a normal C-styl
-zero-terminated UTF-8 string padded to have length divisible by 4.
+@samp{string} contains command line. The command line is a normal C-style
+zero-terminated UTF-8 string.
@subsection Modules
@example
system treats boot modules as files in a file system), but its exact use
is specific to the operating system.
-Tag is padded in the way to have size divisible by 4.
-
One tag appears per module. This tag type may appear multiple times.
@subsection ELF-Symbols
details as to how to read the section header(s)).
@subsection Memory map
-If bit 6 in the @samp{flags} word is set, then the @samp{mmap_*} fields
-are valid, and indicate the address and length of a buffer containing a
-memory map of the machine provided by the @sc{bios}. @samp{mmap_addr} is
-the address, and @samp{mmap_length} is the total size of the buffer. The
-buffer consists of one or more of the following size/structure pairs
-(@samp{size} is really used for skipping to the next pair):
+
+This tag provides memory map.
@example
@group
+-------------------+
--4 | size |
+0 | type = 6 |
+4 | size |
+8 | entry_size |
+12 | entry_version |
+16-xx | entries |
+ +-------------------+
+@end group
+@end example
+
+@samp{entry_size} contains the size of one entry so that in future new fields may be added to it. It's guaranteed to be a multiple of 8. @samp{entry_version} is currently set at @samp{0}. Future versions will increment this field. Future version are guranteed to be backward compatible with older format. Each entry has the following structure:
+
+
+@example
+@group
+-------------------+
0 | base_addr |
8 | length |
16 | type |
+20 | reserved |
+-------------------+
@end group
@end example
-where @samp{size} is the size of the associated structure in bytes, which
-can be greater than the minimum of 20 bytes. @samp{base_addr} is the
-starting address. @samp{length} is the size of the memory region in bytes.
+@samp{size} contains the size of current entry including this field itself. It may be bigger than 24 bytes in future versions but is guaranteed to be
+@samp{base_addr} is the starting physical address. @samp{length} is the size of the memory region in bytes.
@samp{type} is the variety of address range represented, where a
value of 1 indicates available @sc{ram}, and all other values currently
indicated a reserved area.
+@samp{reserved} is set to @samp{0} by bootloader and must be ignored by the OS image.
The map provided is guaranteed to list all standard @sc{ram} that should
be available for normal use.
-The corresponding tag is
-@example
-@group
- +-------------------+
-0 | type = 6 |
-4 | size |
-8-xx | entries |
- +-------------------+
-@end group
-@end example
-
@subsection Boot loader name
-If bit 9 in the @samp{flags} is set, the @samp{boot_loader_name} field
-is valid, and contains the physical address of the name of a boot
-loader booting the kernel. The name is a normal C-style zero-terminated
-string.
-
-Corresponding tag is:
@example
@group
+-------------------+
@end group
@end example
-@samp{string} contains zero-terminated UTF-8 string padded to have length divisible by 4.
+@samp{string} contains the name of a boot
+loader booting the kernel. The name is a normal C-style UTF-8 zero-terminated
+string.
@subsection APM table
The tag type 10 contains @sc{apm} table
@group
+----------------------+
0 | type = 10 |
-4 | size |
+4 | size = 28 |
8 | version |
10 | cseg |
12 | offset |
24 | framebuffer_height |
28 | framebuffer_bpp |
29 | framebuffer_type |
-30 | color_info |
+30 | reserved |
+32 | color_info |
+--------------------+
@end group
@end example
-The field @samp{framebuffer_addr} contains framebuffer physical address. This field is 64-bit wide but bootloader @dfn{should} set it under 4GiB if possible for compatibility with payloads which aren't aware of PAE or amd64. The field @samp{framebuffer_pitch} contains pitch in bytes. The fields @samp{framebuffer_width}, @samp{framebuffer_height} contain framebuffer dimensions in pixels. The field @samp{framebuffer_bpp} contains number of bits per pixel. If @samp{framebuffer_type} is set to 0 it means indexed color. In this case color_info is defined as follows:
+The field @samp{framebuffer_addr} contains framebuffer physical address. This field is 64-bit wide but bootloader @dfn{should} set it under 4GiB if possible for compatibility with payloads which aren't aware of PAE or amd64. The field @samp{framebuffer_pitch} contains pitch in bytes. The fields @samp{framebuffer_width}, @samp{framebuffer_height} contain framebuffer dimensions in pixels. The field @samp{framebuffer_bpp} contains number of bits per pixel. @samp{reserved} always contains 0 in current version of specification and must be ignored by OS image. If @samp{framebuffer_type} is set to 0 it means indexed color. In this case color_info is defined as follows:
@example
@group
+----------------------------------+
-30 | framebuffer_palette_num_colors |
-34-xx | framebuffer_palette |
+32 | framebuffer_palette_num_colors |
+36-xx | framebuffer_palette |
+----------------------------------+
@end group
@end example
@example
@group
+----------------------------------+
-30 | framebuffer_red_field_position |
-31 | framebuffer_red_mask_size |
-32 | framebuffer_green_field_position |
-33 | framebuffer_green_mask_size |
-34 | framebuffer_blue_field_position |
-35-35 | framebuffer_blue_mask_size |
+32 | framebuffer_red_field_position |
+33 | framebuffer_red_mask_size |
+34 | framebuffer_green_field_position |
+35 | framebuffer_green_mask_size |
+36 | framebuffer_blue_field_position |
+37-37 | framebuffer_blue_mask_size |
+----------------------------------+
@end group
@end example
/* This flag indicates the use of the address fields in the header. */
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
+#define MULTIBOOT_TAG_ALIGN 8
#define MULTIBOOT_TAG_TYPE_END 0
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
#define MULTIBOOT_TAG_TYPE_MMAP 6
#define MULTIBOOT_TAG_TYPE_VBE 7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
-#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
-#define MULTIBOOT_TAG_TYPE_APM 10
#ifndef ASM_FILE
struct multiboot_mmap_entry
{
- multiboot_uint32_t size;
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
+#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
+#define MULTIBOOT_MEMORY_NVS 4
multiboot_uint32_t type;
+ multiboot_uint32_t zero;
} __attribute__((packed));
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
{
multiboot_uint32_t type;
multiboot_uint32_t size;
+ multiboot_uint32_t entry_size;
+ multiboot_uint32_t entry_version;
char string[0];
};
{
multiboot_uint32_t type;
multiboot_uint32_t size;
+ multiboot_uint32_t entry_size;
+ multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
};
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
multiboot_uint8_t framebuffer_type;
+ multiboot_uint16_t reserved;
};
struct multiboot_tag_framebuffer