All of lore.kernel.org
 help / color / mirror / Atom feed
* question about adding a field into linux boot header
@ 2011-03-24  8:12 GuoMinskey
  2011-03-24  8:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 3+ messages in thread
From: GuoMinskey @ 2011-03-24  8:12 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1317 bytes --]




I want to use setup_data fields of linux boot header,  but grub doesn'tsupport it. So,  I cone latest grub repo (1.99) and modify grub code asfollows:

1.  in include/grub/i386/linux.h,  
 struct linux_kernel_header {@@ -130,6 +144,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 new_field;    <--------------  aligned to the offset : 0x250 as linux } __attribute__ ((packed));

2.  grub-core/loader/i386/linux.c
     I add a command by following "initrd", but simply as follows:
       static grub_err_t           grub_cmd_test(cmd, argc, argv[])      {                 grub_printf("entering my test command\n");
                 ...   //ensure kernel is loaded                  struct linux_kernel_header *lh = (struct linux_kernel_header *) real_mode_mem;                   lh->new_field  = 0x34FFFFFF;      }      when I boot GRUB with my command,  GRUB panic in relocator. I print the kernelheader, seems the header is there ( I mean real_mode_mem).   If I removed the line"lh->new_field = 0x34FFFFFF",  GRUB can work.  
Did I miss something if I want pass this field into linux kernel ?

thanks,-minskey 
     		 	   		  

[-- Attachment #2: Type: text/html, Size: 6177 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread
* Re: question about adding a field into linux boot header
@ 2011-03-29  3:29 GuoMinskey
  0 siblings, 0 replies; 3+ messages in thread
From: GuoMinskey @ 2011-03-29  3:29 UTC (permalink / raw)
  To: phcoder, grub-devel


[-- Attachment #1.1: Type: text/plain, Size: 3618 bytes --]


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

 		 	   		  

[-- Attachment #1.2: Type: text/html, Size: 24212 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub.diff --]
[-- Type: text/x-patch, Size: 4235 bytes --]

=== 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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-03-29  3:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-24  8:12 question about adding a field into linux boot header GuoMinskey
2011-03-24  8:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
  -- strict thread matches above, loose matches on Subject: below --
2011-03-29  3:29 GuoMinskey

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.