From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jan 2010 22:08:47 +0000 (+0100) Subject: Example kernel for tagged mbi X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1d6d3a00fd735cb1cde2113155859d2db220647;p=thirdparty%2Fgrub.git Example kernel for tagged mbi --- diff --git a/doc/boot.S b/doc/boot.S index d7e128fc4..cfa975c4a 100644 --- a/doc/boot.S +++ b/doc/boot.S @@ -30,9 +30,9 @@ /* The flags for the Multiboot header. */ #ifdef __ELF__ -# define MULTIBOOT_HEADER_FLAGS 0x00000007 +# define MULTIBOOT_HEADER_FLAGS 0x0000000f #else -# define MULTIBOOT_HEADER_FLAGS 0x00010007 +# define MULTIBOOT_HEADER_FLAGS 0x0001000f #endif .text diff --git a/doc/kernel.c b/doc/kernel.c index 598046264..9a1329ea1 100644 --- a/doc/kernel.c +++ b/doc/kernel.c @@ -47,6 +47,153 @@ static void itoa (char *buf, int base, int d); 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 @@ -57,6 +204,12 @@ cmain (unsigned long magic, unsigned long addr) /* 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) { diff --git a/doc/multiboot.h b/doc/multiboot.h index e48d45b84..e14977657 100644 --- a/doc/multiboot.h +++ b/doc/multiboot.h @@ -31,8 +31,11 @@ /* 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 @@ -51,6 +54,9 @@ /* 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 @@ -254,6 +260,122 @@ struct multiboot_mod_list }; 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 */