Update with newest mbtag spec

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-03-07 14:59:15 +01:00
parent 3f5a90c616
commit 8eb567e662
5 changed files with 81 additions and 42 deletions

View file

@ -44,7 +44,7 @@ grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
int argc, char *argv[]);
void grub_multiboot_set_bootdev (void);
grub_uint32_t grub_get_multiboot_mmap_len (void);
grub_uint32_t grub_get_multiboot_mmap_count (void);
grub_err_t grub_multiboot_set_video_mode (void);
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)

View file

@ -51,6 +51,7 @@
/* 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
@ -102,7 +103,6 @@ struct multiboot_color
struct multiboot_mmap_entry
{
multiboot_uint32_t size;
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
@ -110,6 +110,7 @@ struct multiboot_mmap_entry
#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;
@ -123,6 +124,8 @@ struct multiboot_tag_string
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
char string[0];
};
@ -156,6 +159,8 @@ struct multiboot_tag_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
};
@ -197,6 +202,7 @@ struct multiboot_tag_framebuffer_common
#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
@ -222,6 +228,31 @@ struct multiboot_tag_framebuffer
};
};
struct multiboot_tag_elf_sections
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t num;
multiboot_uint32_t entsize;
multiboot_uint32_t shndx;
char sections[0];
};
struct multiboot_tag_apm
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t version;
multiboot_uint16_t cseg;
multiboot_uint32_t offset;
multiboot_uint16_t cseg_16;
multiboot_uint16_t dseg;
multiboot_uint16_t flags;
multiboot_uint16_t cseg_len;
multiboot_uint16_t cseg_16_len;
multiboot_uint16_t dseg_len;
};
#endif /* ! ASM_FILE */
#endif /* ! MULTIBOOT_HEADER */

View file

@ -68,7 +68,7 @@ static int accepts_video;
/* Return the length of the Multiboot mmap that will be needed to allocate
our platform's map. */
grub_uint32_t
grub_get_multiboot_mmap_len (void)
grub_get_multiboot_mmap_count (void)
{
grub_size_t count = 0;
@ -83,7 +83,7 @@ grub_get_multiboot_mmap_len (void)
grub_mmap_iterate (hook);
return count * sizeof (struct multiboot_mmap_entry);
return count;
}
grub_err_t

View file

@ -53,7 +53,8 @@ grub_multiboot_get_mbi_size (void)
{
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len ()
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4)
+ grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
#if GRUB_MACHINE_HAS_VBE
+ sizeof (struct grub_vbe_info_block)
+ sizeof (struct grub_vbe_mode_info_block)
@ -233,7 +234,8 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
mbi->mods_count = 0;
}
mmap_size = grub_get_multiboot_mmap_len ();
mmap_size = grub_get_multiboot_mmap_count ()
* sizeof (struct multiboot_mmap_entry);
grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
mbi->mmap_length = mmap_size;
mbi->mmap_addr = ptrdest;

View file

@ -62,15 +62,17 @@ static grub_uint32_t biosdev, slice, part;
grub_size_t
grub_multiboot_get_mbi_size (void)
{
return sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+ (sizeof (struct multiboot_tag_string) + ALIGN_UP (cmdline_size, 4))
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+ (sizeof (struct multiboot_tag_string)
+ ALIGN_UP (sizeof (PACKAGE_STRING), 4))
+ ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
+ (sizeof (struct multiboot_tag_string)
+ ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN))
+ (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
+ sizeof (struct multiboot_tag_basic_meminfo)
+ sizeof (struct multiboot_tag_bootdev)
+ (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_len ())
+ sizeof (struct multiboot_tag_vbe);
+ ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
+ (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
* sizeof (struct multiboot_mmap_entry))
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
}
#ifdef GRUB_MACHINE_HAS_VBE
@ -98,7 +100,7 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out,
*vbe_mode_info_out = (struct grub_vbe_mode_info_block *)
&(tag->vbe_mode_info);
tag->size = sizeof (struct multiboot_tag_vbe);
*ptrorig += tag->size;
*ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
return GRUB_ERR_NONE;
}
@ -106,9 +108,9 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out,
/* Fill previously allocated Multiboot mmap. */
static void
grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
{
struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
struct multiboot_mmap_entry *mmap_entry = tag->entries;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
@ -137,12 +139,17 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
break;
}
mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
mmap_entry++;
return 0;
}
tag->type = MULTIBOOT_TAG_TYPE_MMAP;
tag->size = sizeof (struct multiboot_tag_mmap)
+ sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count ();
tag->entry_size = sizeof (struct multiboot_mmap_entry);
tag->entry_version = 0;
grub_mmap_iterate (hook);
}
@ -190,7 +197,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
tag->common.size = sizeof (tag->common);
*ptrorig += tag->common.size;
tag->common.reserved = 0;
*ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
}
return GRUB_ERR_NONE;
}
@ -214,6 +222,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
tag->common.framebuffer_height = mode_info.height;
tag->common.framebuffer_bpp = mode_info.bpp;
tag->common.reserved = 0;
if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
{
@ -231,7 +241,6 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
tag->framebuffer_palette[i].green = palette[i].g;
tag->framebuffer_palette[i].blue = palette[i].b;
}
*ptrorig += tag->common.size;
}
else
{
@ -246,6 +255,7 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
}
*ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
#if HAS_VBE
if (driv_id == GRUB_VIDEO_DRIVER_VBE)
@ -264,30 +274,29 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
grub_size_t bufsize)
{
grub_uint8_t *ptrorig;
grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off;
grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off
+ (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
grub_err_t err;
if (bufsize < grub_multiboot_get_mbi_size ())
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
ptrorig = (grub_uint8_t *) orig + buf_off + sizeof (grub_uint32_t);
ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
{
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
tag->size = sizeof (struct multiboot_tag_string)
+ ALIGN_UP (cmdline_size, 4);
tag->size = sizeof (struct multiboot_tag_string) + cmdline_size;
grub_memcpy (tag->string, cmdline, cmdline_size);
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
{
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
tag->size = sizeof (struct multiboot_tag_string)
+ ALIGN_UP (sizeof (PACKAGE_STRING), 4);
tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING);
grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
{
@ -299,23 +308,18 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
struct multiboot_tag_module *tag
= (struct multiboot_tag_module *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_MODULE;
tag->size = sizeof (struct multiboot_tag_module)
+ ALIGN_UP (sizeof (cur->cmdline_size), 4);
tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
tag->mod_start = dest + cur->start;
tag->mod_end = tag->mod_start + cur->size;
grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
}
{
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_MMAP;
tag->size = sizeof (struct multiboot_tag_mmap)
+ grub_get_multiboot_mmap_len ();
grub_fill_multiboot_mmap (tag->entries);
ptrorig += tag->size;
grub_fill_multiboot_mmap (tag);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
{
@ -327,7 +331,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
/* Convert from bytes to kilobytes. */
tag->mem_lower = grub_mmap_get_lower () / 1024;
tag->mem_upper = grub_mmap_get_upper () / 1024;
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
if (bootdev_set)
@ -340,7 +344,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
tag->biosdev = biosdev;
tag->slice = slice;
tag->part = part;
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
{
@ -356,10 +360,11 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_END;
tag->size = sizeof (struct multiboot_tag);
ptrorig += tag->size;
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
}
*(grub_uint32_t *) mbistart = ptrorig - mbistart;
((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart;
((grub_uint32_t *) mbistart)[1] = 0;
return GRUB_ERR_NONE;
}
@ -447,7 +452,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
return grub_errno;
}
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, 4);
total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
for (i = 0; i < argc; i++)
{
@ -495,8 +500,8 @@ grub_multiboot_set_bootdev (void)
dev = grub_device_open (0);
if (dev && dev->disk && dev->disk->partition)
{
p = dev->disk->partition->partmap->get_name (dev->disk->partition);
char *p0;
p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition);
if (p)
{
if ((p[0] >= '0') && (p[0] <= '9'))
@ -510,6 +515,7 @@ grub_multiboot_set_bootdev (void)
if ((p[0] >= 'a') && (p[0] <= 'z'))
part = p[0] - 'a';
}
grub_free (p0);
}
if (dev)
grub_device_close (dev);