]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Example kernel for tagged mbi
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 2 Jan 2010 22:08:47 +0000 (23:08 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 2 Jan 2010 22:08:47 +0000 (23:08 +0100)
doc/boot.S
doc/kernel.c
doc/multiboot.h

index d7e128fc4720a7acbccb4b365005c8fcdd6f1549..cfa975c4a136fe0e594b6ce303f47345f77f23bc 100644 (file)
@@ -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
index 598046264b2cddf2daaa57620e6388a2227b7a3b..9a1329ea1295f07c59a83c1f8745a5871f8ef388 100644 (file)
@@ -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)
     {
index e48d45b84376b7898ecebf630f1cb4a444401474..e14977657313ab7c78d7d4c21e124a99adde2814 100644 (file)
 /* 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 */