thank you for response.
Sorry for the confusion.  It was my fault. I just use qemu to debug my 
change.It is a kernel panic.  It panic so early, so that I made a mistake and 
consideredit as a panic in grub. 

I am using grub repo (revno: 3116). Now, I can see the kernel panic message: 
"PANIC: early exception 08 rip 246:10 error ffffff8102b785 cr2 
ffffffffff47900b"The panic message comes from linux kernel: early_idt_handlers 
in the filearch/x86/kernel/head_64.S.
So, it doesn't matter with grub.

 /* For the Linux/i386 boot protocol version 2.03.  */ struct 
linux_kernel_header {@@ -130,6 +146,8 @@   grub_uint16_t pad1;                  
/* Unused */   grub_uint32_t cmd_line_ptr;          /* Points to the kernel 
command line */   grub_uint32_t initrd_addr_max;        /* Highest address for 
initrd */+  grub_uint32_t pad2[8];+  grub_uint64_t setup_data; } __attribute__ 
((packed));And then,  I tried to use setup_data field to pass an pointer (which 
points to a binaryblob) to Linux kernel, === modified file 
'grub-core/loader/i386/linux.c'--- grub-core/loader/i386/linux.c       
2011-03-09 17:38:31 +0000+++ grub-core/loader/i386/linux.c       2011-03-28 
15:44:34 +0000@@ -994,7 +994,89 @@   return grub_errno; }
-static grub_command_t cmd_linux, cmd_initrd;+static grub_err_t+grub_cmd_ucode 
(grub_command_t cmd __attribute__ ((unused)),+                int argc, char 
*argv[])+{+  grub_file_t file = 0;+  grub_ssize_t size;+  grub_addr_t addr_min, 
addr_max;+  grub_err_t err;+  struct linux_kernel_header *lh;+  
grub_relocator_chunk_t ch;+  void *ucode_mem;+  grub_addr_t ucode_mem_target;+  
struct setup_data *hdr;++  if (argc == 0)+    {+      grub_error 
(GRUB_ERR_BAD_ARGUMENT, "no module specified");+      goto fail;+    }++  if (! 
loaded)+    {+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the 
kernel first");+      goto fail;+    }++  grub_file_filter_disable_compression 
();+  file = grub_file_open (argv[0]);+  size = grub_file_size(file);++  lh = 
(struct linux_kernel_header *) real_mode_mem;+  if 
(grub_le_to_cpu16(lh->version) < 0x0209)+    {+      grub_printf("%s:%d: header 
version=0x%x(<0x0209)\n",+           __FUNCTION__, __LINE__, lh->version);+     
 goto fail;+    }++  addr_max = grub_cpu_to_le32(lh->initrd_addr_max);+  if 
(addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)+      addr_max = 
GRUB_LINUX_INITRD_MAX_ADDRESS;+  addr_max -= 0x10000;++  if ((linux_mem_size != 
0) && (linux_mem_size < addr_max))+       addr_max = linux_mem_size;+  addr_max 
= (addr_max - size - sizeof(*hdr)) & ~0xFFF;+  addr_min = prot_mode_target;++  
grub_printf("microcode addr_min=%p, add_max=%p\n", +       (void*)addr_min, 
(void *)addr_max);++  err = grub_relocator_alloc_chunk_align(relocator, &ch, 
addr_min,+                                       addr_max, size + 
sizeof(*hdr),+                                       0x1000, 
GRUB_RELOCATOR_PREFERENCE_HIGH);+  if (err) return err;+  ucode_mem = 
get_virtual_current_address(ch);+  ucode_mem_target = 
get_physical_target_address(ch);++  if (grub_file_read(file, (unsigned 
char*)ucode_mem + sizeof(*hdr), size) != size)+     {+       grub_error 
(GRUB_ERR_FILE_READ_ERROR, "couldn't read file");+       goto fail;+     }++  
hdr = (struct setup_data *)ucode_mem;+  hdr->type = SETUP_MICROCODE;+  hdr->len 
= size;+  hdr->next = 0;++  lh->setup_data = ucode_mem_target;++  
grub_printf("%s: header_version=0x%x, ucode_size=%d\n", __FUNCTION__,+      
grub_le_to_cpu16 (lh->version), size);+      ++ fail:+  if (file)+    
grub_file_close (file);++  return grub_errno;+}++static grub_command_t 
cmd_linux, cmd_initrd, cmd_ucode;


thanks,-minskey

                                          
=== modified file 'grub-core/loader/i386/linux.c'
--- grub-core/loader/i386/linux.c	2011-03-09 17:38:31 +0000
+++ grub-core/loader/i386/linux.c	2011-03-28 15:44:34 +0000
@@ -994,7 +994,89 @@
   return grub_errno;
 }
 
-static grub_command_t cmd_linux, cmd_initrd;
+static grub_err_t
+grub_cmd_ucode (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_min, addr_max;
+  grub_err_t err;
+  struct linux_kernel_header *lh;
+  grub_relocator_chunk_t ch;
+  void *ucode_mem;
+  grub_addr_t ucode_mem_target;
+  struct setup_data *hdr;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+      goto fail;
+    }
+
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  grub_file_filter_disable_compression ();
+  file = grub_file_open (argv[0]);
+  size = grub_file_size(file);
+
+  lh = (struct linux_kernel_header *) real_mode_mem;
+  if (grub_le_to_cpu16(lh->version) < 0x0209)
+    {
+      grub_printf("%s:%d: header version=0x%x(<0x0209)\n",
+           __FUNCTION__, __LINE__, lh->version);
+      goto fail;
+    }
+
+  addr_max = grub_cpu_to_le32(lh->initrd_addr_max);
+  if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+      addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+  addr_max -= 0x10000;
+
+  if ((linux_mem_size != 0) && (linux_mem_size < addr_max))
+       addr_max = linux_mem_size;
+  addr_max = (addr_max - size - sizeof(*hdr)) & ~0xFFF;
+  addr_min = prot_mode_target;
+
+  grub_printf("microcode addr_min=%p, add_max=%p\n", 
+	(void*)addr_min, (void *)addr_max);
+
+  err = grub_relocator_alloc_chunk_align(relocator, &ch, addr_min,
+                                       addr_max, size + sizeof(*hdr),
+                                       0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH);
+  if (err) return err;
+  ucode_mem = get_virtual_current_address(ch);
+  ucode_mem_target = get_physical_target_address(ch);
+
+  if (grub_file_read(file, (unsigned char*)ucode_mem + sizeof(*hdr), size) != size)
+     {
+       grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+       goto fail;
+     }
+
+  hdr = (struct setup_data *)ucode_mem;
+  hdr->type = SETUP_MICROCODE;
+  hdr->len = size;
+  hdr->next = 0;
+
+  lh->setup_data = ucode_mem_target;
+
+  grub_printf("%s: header_version=0x%x, ucode_size=%d\n", __FUNCTION__,
+      grub_le_to_cpu16 (lh->version), size);
+      
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd, cmd_ucode;
 
 GRUB_MOD_INIT(linux)
 {
@@ -1002,6 +1084,8 @@
 				     0, N_("Load Linux."));
   cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
 				      0, N_("Load initrd."));
+  cmd_ucode = grub_register_command ("microcode", grub_cmd_ucode,
+				      0, N_("Load microcode."));
   my_mod = mod;
 }
 
@@ -1009,4 +1093,5 @@
 {
   grub_unregister_command (cmd_linux);
   grub_unregister_command (cmd_initrd);
+  grub_unregister_command (cmd_ucode);
 }

=== modified file 'include/grub/i386/linux.h'
--- include/grub/i386/linux.h	2011-01-10 23:02:01 +0000
+++ include/grub/i386/linux.h	2011-03-28 09:41:12 +0000
@@ -87,6 +87,22 @@
     GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70    /* Linear framebuffer without any additional functions.  */
   };
 
+/* setup data types */
+#define SETUP_NONE                      0
+#define SETUP_E820_EXT                  1
+#define SETUP_DTB                       2
+#define SETUP_MICROCODE                 3
+
+/* extensible setup data list node */
+struct setup_data {
+  grub_uint64_t next;
+  grub_uint32_t type;
+  grub_uint32_t len;
+  grub_uint8_t  data[0];
+} __attribute__ ((packed));
+
+
+
 /* For the Linux/i386 boot protocol version 2.03.  */
 struct linux_kernel_header
 {
@@ -130,6 +146,8 @@
   grub_uint16_t pad1;			/* Unused */
   grub_uint32_t cmd_line_ptr;		/* Points to the kernel command line */
   grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
+  grub_uint32_t pad2[8];
+  grub_uint64_t setup_data;
 } __attribute__ ((packed));
 
 /* Boot parameters for Linux based on 2.6.12. This is used by the setup

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to