static void putchar (int c);
void printf (const char *format, ...);
+static void
+tagged (unsigned long addr)
+{
+ struct multiboot_tag *tag;
+
+ for (tag = (struct multiboot_tag *) addr; tag->type != MULTIBOOT_TAG_TYPE_END;
+ tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + tag->size))
+ {
+ printf ("Tag 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 ("mem_lower = %uKB, mem_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,%u,%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_MMAP:
+ {
+ multiboot_memory_map_t *mmap;
+
+ printf ("mmap\n");
+
+ 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,"
+ " length = 0x%x%x, type = 0x%x\n",
+ (unsigned) mmap->size,
+ (unsigned) (mmap->addr >> 32),
+ (unsigned) (mmap->addr & 0xffffffff),
+ (unsigned) (mmap->len >> 32),
+ (unsigned) (mmap->len & 0xffffffff),
+ (unsigned) mmap->type);
+ }
+ break;
+ case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
+ {
+ multiboot_uint32_t color;
+ unsigned i;
+ struct multiboot_tag_framebuffer *tagfb
+ = (struct multiboot_tag_framebuffer *) tag;
+ void *fb = (void *) (unsigned long) tagfb->common.framebuffer_addr;
+
+ switch (tagfb->common.framebuffer_type)
+ {
+ case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
+ {
+ unsigned best_distance, distance;
+ struct multiboot_color *palette;
+
+ palette = tagfb->framebuffer_palette;
+
+ color = 0;
+ best_distance = 4*256*256;
+
+ for (i = 0; i < tagfb->framebuffer_palette_num_colors; i++)
+ {
+ distance = (0xff - palette[i].blue)
+ * (0xff - palette[i].blue)
+ + palette[i].red * palette[i].red
+ + palette[i].green * palette[i].green;
+ if (distance < best_distance)
+ {
+ color = i;
+ best_distance = distance;
+ }
+ }
+ }
+ break;
+
+ case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
+ color = ((1 << tagfb->framebuffer_blue_mask_size) - 1)
+ << tagfb->framebuffer_blue_field_position;
+ break;
+
+ default:
+ color = 0xffffffff;
+ break;
+ }
+
+ for (i = 0; i < tagfb->common.framebuffer_width
+ && i < tagfb->common.framebuffer_height; i++)
+ {
+ switch (tagfb->common.framebuffer_bpp)
+ {
+ case 8:
+ {
+ multiboot_uint8_t *pixel = fb
+ + tagfb->common.framebuffer_pitch * i + i;
+ *pixel = color;
+ }
+ break;
+ case 15:
+ case 16:
+ {
+ multiboot_uint16_t *pixel
+ = fb + tagfb->common.framebuffer_pitch * i + 2 * i;
+ *pixel = color;
+ }
+ break;
+ case 24:
+ {
+ multiboot_uint32_t *pixel
+ = fb + tagfb->common.framebuffer_pitch * i + 3 * i;
+ *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+ }
+ break;
+
+ case 32:
+ {
+ multiboot_uint32_t *pixel
+ = fb + tagfb->common.framebuffer_pitch * i + 4 * i;
+ *pixel = color;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+
/* Check if MAGIC is valid and print the Multiboot information structure
pointed by ADDR. */
void
/* Clear the screen. */
cls ();
+ if (magic == MULTIBOOT_BOOTLOADER_MAGIC_TAGGED)
+ {
+ tagged (addr);
+ return;
+ }
+
/* Am I booted by a Multiboot-compliant boot loader? */
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
/* This should be in %eax. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+/* This should be in %eax. */
+#define MULTIBOOT_BOOTLOADER_MAGIC_TAGGED 0x3BADB002
+
/* The bits in the required part of flags field we don't support. */
-#define MULTIBOOT_UNSUPPORTED 0x0000fff8
+#define MULTIBOOT_UNSUPPORTED 0x0000fff0
/* Alignment of multiboot modules. */
#define MULTIBOOT_MOD_ALIGN 0x00001000
/* Must pass video information to OS. */
#define MULTIBOOT_VIDEO_MODE 0x00000004
+/* Must pass tagged mbi to OS. */
+#define MULTIBOOT_TAGGED_MBI 0x00000008
+
/* This flag indicates the use of the address fields in the header. */
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
};
typedef struct multiboot_mod_list multiboot_module_t;
+struct multiboot_tag
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+};
+
+struct multiboot_tag_string
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+ char string[0];
+};
+
+struct multiboot_tag_module
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+ multiboot_uint32_t mod_start;
+ multiboot_uint32_t mod_end;
+ char cmdline[0];
+};
+
+struct multiboot_tag_basic_meminfo
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+ multiboot_uint32_t mem_lower;
+ multiboot_uint32_t mem_upper;
+};
+
+struct multiboot_tag_bootdev
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+ multiboot_uint32_t biosdev;
+ multiboot_uint32_t slice;
+ multiboot_uint32_t part;
+};
+
+struct multiboot_tag_mmap
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+ struct multiboot_mmap_entry entries[0];
+};
+
+struct multiboot_vbe_info_block
+{
+ multiboot_uint8_t external_specification[512];
+};
+
+struct multiboot_vbe_mode_info_block
+{
+ multiboot_uint8_t external_specification[256];
+};
+
+struct multiboot_tag_vbe
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+
+ multiboot_uint16_t vbe_mode;
+ multiboot_uint16_t vbe_interface_seg;
+ multiboot_uint16_t vbe_interface_off;
+ multiboot_uint16_t vbe_interface_len;
+
+ struct multiboot_vbe_info_block vbe_control_info;
+ struct multiboot_vbe_mode_info_block vbe_mode_info;
+};
+
+struct multiboot_tag_framebuffer_common
+{
+ multiboot_uint32_t type;
+ multiboot_uint32_t size;
+
+ multiboot_uint64_t framebuffer_addr;
+ multiboot_uint32_t framebuffer_pitch;
+ multiboot_uint32_t framebuffer_width;
+ multiboot_uint32_t framebuffer_height;
+ multiboot_uint8_t framebuffer_bpp;
+ multiboot_uint8_t framebuffer_type;
+};
+
+struct multiboot_tag_framebuffer
+{
+ struct multiboot_tag_framebuffer_common common;
+
+ union
+ {
+ struct
+ {
+ multiboot_uint16_t framebuffer_palette_num_colors;
+ struct multiboot_color framebuffer_palette[0];
+ };
+ struct
+ {
+ multiboot_uint8_t framebuffer_red_field_position;
+ multiboot_uint8_t framebuffer_red_mask_size;
+ multiboot_uint8_t framebuffer_green_field_position;
+ multiboot_uint8_t framebuffer_green_mask_size;
+ multiboot_uint8_t framebuffer_blue_field_position;
+ multiboot_uint8_t framebuffer_blue_mask_size;
+ };
+ };
+};
+
+#define MULTIBOOT_TAG_TYPE_END 0
+#define MULTIBOOT_TAG_TYPE_CMDLINE 1
+#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
+#define MULTIBOOT_TAG_TYPE_MODULE 3
+#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
+#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
+#define MULTIBOOT_TAG_TYPE_MMAP 6
+#define MULTIBOOT_TAG_TYPE_VBE 7
+#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
+
#endif /* ! ASM_FILE */
#endif /* ! MULTIBOOT_HEADER */