All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 1/3] Update the Linux boot protocol
@ 2012-02-08 16:55 Matthew Garrett
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Matthew Garrett @ 2012-02-08 16:55 UTC (permalink / raw)
  To: grub-devel; +Cc: Matthew Garrett

The Linux boot header includes information on the kernel's desired load
address and alignment. Add support for that.
---
 ChangeLog                 |    6 ++++++
 include/grub/i386/linux.h |   28 +++++++++++++++++++++++-----
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ede7f8e..2bdb3a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-02-08  Matthew Garrett  <mjg@redhat.com>
+
+	* include/grub/i386/linux.h (linux_kernel_header): Update to
+	boot protocol 2.10.
+	(linux_kernel_params): Likewise
+
 2012-02-07  Vladimir Serbinenko  <phcoder@gmail.com>
 
 	* grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index 6aa2391..8e27b93 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -86,7 +86,7 @@ enum
     GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70    /* Linear framebuffer without any additional functions.  */
   };
 
-/* For the Linux/i386 boot protocol version 2.03.  */
+/* For the Linux/i386 boot protocol version 2.10.  */
 struct linux_kernel_header
 {
   grub_uint8_t code1[0x0020];
@@ -131,8 +131,16 @@ struct linux_kernel_header
   grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
   grub_uint32_t kernel_alignment;
   grub_uint8_t relocatable;
-  grub_uint8_t pad[3];
+  grub_uint8_t min_alignment;
+  grub_uint8_t pad[2];
   grub_uint32_t cmdline_size;
+  grub_uint32_t hardware_subarch;
+  grub_uint64_t hardware_subarch_data;
+  grub_uint32_t payload_offset;
+  grub_uint32_t payload_length;
+  grub_uint64_t setup_data;
+  grub_uint64_t pref_address;
+  grub_uint64_t init_size;
 } __attribute__ ((packed));
 
 /* Boot parameters for Linux based on 2.6.12. This is used by the setup
@@ -276,10 +284,20 @@ struct linux_kernel_params
   grub_uint32_t ramdisk_size;		/* initrd size */
   grub_uint32_t bootsect_kludge;	/* obsolete */
   grub_uint16_t heap_end_ptr;		/* Free memory after setup end */
-  grub_uint16_t pad1;			/* Unused */
+  grub_uint8_t ext_loader_ver;		/* Extended loader version */
+  grub_uint8_t ext_loader_type;		/* Extended loader type */  
   grub_uint32_t cmd_line_ptr;		/* Points to the kernel command line */
-
-  grub_uint8_t pad2[164];		/* 22c */
+  grub_uint32_t initrd_addr_max;	/* Maximum initrd address */
+  grub_uint32_t kernel_alignment;	/* Alignment of the kernel */
+  grub_uint8_t relocatable_kernel;	/* Is the kernel relocatable */
+  grub_uint8_t pad1[3];
+  grub_uint32_t cmdline_size;		/* Size of the kernel command line */
+  grub_uint32_t hardware_subarch;
+  grub_uint64_t hardware_subarch_data;
+  grub_uint32_t payload_offset;
+  grub_uint32_t payload_length;
+  grub_uint64_t setup_data;
+  grub_uint8_t pad2[120];		/* 258 */
   struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY];	/* 2d0 */
 
 } __attribute__ ((packed));
-- 
1.7.7.6



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

* [PATCH V3 2/3] Add support for avoiding firmware in relocations
  2012-02-08 16:55 [PATCH V3 1/3] Update the Linux boot protocol Matthew Garrett
@ 2012-02-08 16:55 ` Matthew Garrett
  2012-02-08 19:41   ` Vladimir 'φ-coder/phcoder' Serbinenko
                     ` (2 more replies)
  2012-02-08 16:55 ` [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences Matthew Garrett
  2012-02-08 19:35 ` [PATCH V3 1/3] Update the Linux boot protocol Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 3 replies; 14+ messages in thread
From: Matthew Garrett @ 2012-02-08 16:55 UTC (permalink / raw)
  To: grub-devel; +Cc: Matthew Garrett

EFI and OF both support firmware regions which may be in use during loading.
Add support for avoiding these.
---
 ChangeLog                                    |   10 +++++
 grub-core/lib/efi/relocator.c                |   51 ++++++++++++++++++++++++++
 grub-core/lib/ieee1275/relocator.c           |   27 ++++++++++++++
 grub-core/lib/relocator.c                    |   12 ++++++-
 grub-core/loader/i386/bsd.c                  |   19 ++++++----
 grub-core/loader/i386/bsdXX.c                |    8 ++--
 grub-core/loader/i386/coreboot/chainloader.c |    2 +-
 grub-core/loader/i386/linux.c                |    4 +-
 grub-core/loader/i386/multiboot_mbi.c        |    2 +-
 grub-core/loader/i386/pc/chainloader.c       |    4 +-
 grub-core/loader/i386/pc/freedos.c           |    2 +-
 grub-core/loader/i386/pc/linux.c             |    4 +-
 grub-core/loader/i386/pc/ntldr.c             |    4 +-
 grub-core/loader/i386/pc/plan9.c             |    4 +-
 grub-core/loader/i386/pc/pxechainloader.c    |    2 +-
 grub-core/loader/mips/linux.c                |    6 ++--
 grub-core/loader/multiboot_elfxx.c           |    2 +-
 grub-core/loader/multiboot_mbi2.c            |    2 +-
 grub-core/loader/xnu.c                       |    2 +-
 grub-core/loader/xnu_resume.c                |    2 +-
 include/grub/relocator.h                     |    3 +-
 include/grub/relocator_private.h             |    2 +
 22 files changed, 139 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2bdb3a0..8bef256 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2012-02-08  Matthew Garrett  <mjg@redhat.com>
 
+	* grub-core/lib/efi/relocator.c (grub_relocator_alloc_chunk_addr):
+	Add argument to fail allocation when target address overlaps
+	firmware regions. All users updated.
+	* grub-core/lib/efi/relocator.c (grub_relocator_firmware_overlaps):
+	New function
+	* grub-core/lib/ieee1275/relocator.c (grub_relocator_firmware_overlaps):
+	Likewise
+
+2012-02-08  Matthew Garrett  <mjg@redhat.com>
+
 	* include/grub/i386/linux.h (linux_kernel_header): Update to
 	boot protocol 2.10.
 	(linux_kernel_params): Likewise
diff --git a/grub-core/lib/efi/relocator.c b/grub-core/lib/efi/relocator.c
index 0d346be..9d51a27 100644
--- a/grub-core/lib/efi/relocator.c
+++ b/grub-core/lib/efi/relocator.c
@@ -39,6 +39,57 @@ grub_relocator_firmware_get_max_events (void)
   return 2 * (mmapsize / descriptor_size + 10);
 }
 
+unsigned
+grub_relocator_firmware_overlaps (grub_phys_addr_t target, grub_size_t size)
+{
+  grub_efi_uintn_t mmapsize = 0, desc_size = 0;
+  grub_efi_uint32_t descriptor_version = 0;
+  grub_efi_memory_descriptor_t *descs = NULL;
+  grub_efi_uintn_t key;
+  int overlap = 0;
+  grub_efi_memory_descriptor_t *desc;
+
+  grub_efi_get_memory_map (&mmapsize, NULL, &key, &desc_size,
+			   &descriptor_version);
+  descs = grub_malloc (mmapsize);
+  if (!descs)
+    return 0;
+
+  grub_efi_get_memory_map (&mmapsize, descs, &key, &desc_size,
+			   &descriptor_version);
+
+  for (desc = descs;
+       (char *) desc < ((char *) descs + mmapsize);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_uint64_t start = desc->physical_start;
+      grub_uint64_t end = desc->physical_start + (desc->num_pages << 12);
+
+      switch (desc->type) {
+      case GRUB_EFI_CONVENTIONAL_MEMORY:
+      case GRUB_EFI_LOADER_CODE:
+      case GRUB_EFI_LOADER_DATA:
+	continue;
+      }
+
+      if (target >= start && target <= end)
+	{
+	  overlap = 1;
+	  break;
+	}
+
+      if (target + size >= start && target + size <= end)
+	{
+	  overlap = 1;
+	  break;
+	}
+    }
+
+  grub_free(descs);
+
+  return overlap;
+}
+
 unsigned 
 grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
 {
diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c
index 021f0ce..28258d7 100644
--- a/grub-core/lib/ieee1275/relocator.c
+++ b/grub-core/lib/ieee1275/relocator.c
@@ -42,6 +42,33 @@ grub_relocator_firmware_get_max_events (void)
   return 2 * counter;
 }
 
+unsigned
+grub_relocator_firmware_overlaps (grub_phys_addr_t target, grub_size_t size)
+{
+  int overlap = 0;
+  auto int NESTED_FUNC_ATTR check (grub_uint64_t addr, grub_uint64_t len,
+				  grub_memory_type_t type);
+  int NESTED_FUNC_ATTR check (grub_uint64_t addr, grub_uint64_t len,
+			     grub_memory_type_t type)
+  {
+    grub_uint64_t end = addr + len;
+
+    if (type == GRUB_MEMORY_AVAILABLE)
+      return 0;
+
+    if (target >= addr && target <= end)
+      overlap = 1;
+
+    if (target + size >= addr && target + size <= end)
+      overlap = 1;
+
+    return 0;
+  }
+
+  grub_machine_mmap_iterate (check);
+  return overlap;
+}
+
 unsigned 
 grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
 {
diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
index 6630646..7e202a5 100644
--- a/grub-core/lib/relocator.c
+++ b/grub-core/lib/relocator.c
@@ -1203,7 +1203,8 @@ adjust_limits (struct grub_relocator *rel,
 grub_err_t
 grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
 				 grub_relocator_chunk_t *out,
-				 grub_phys_addr_t target, grub_size_t size)
+				 grub_phys_addr_t target, grub_size_t size,
+				 int avoid_firmware)
 {
   struct grub_relocator_chunk *chunk;
   grub_phys_addr_t min_addr = 0, max_addr;
@@ -1213,6 +1214,15 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
 
   adjust_limits (rel, &min_addr, &max_addr, target, target);
 
+  if (avoid_firmware)
+    {
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+      if (grub_relocator_firmware_overlaps(target, size))
+
+      return grub_error(GRUB_ERR_BAD_ARGUMENT, "target overlaps with firmware");
+#endif
+    }
+
   for (chunk = rel->chunks; chunk; chunk = chunk->next)
     if ((chunk->target <= target && target < chunk->target + chunk->size)
 	|| (target <= chunk->target && chunk->target < target + size))
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index 835f146..f7b89a6 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -606,7 +606,7 @@ grub_freebsd_boot (void)
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   kern_end, p_size);
+					   kern_end, p_size, 0);
     if (err)
       return err;
     p = get_virtual_current_address (ch);
@@ -788,7 +788,7 @@ grub_openbsd_boot (void)
     err = grub_relocator_alloc_chunk_addr (relocator, &ch, buf_target,
 					   tag_buf_len
 					   + sizeof (struct grub_openbsd_bootargs)
-					   + 9 * sizeof (grub_uint32_t));
+					   + 9 * sizeof (grub_uint32_t), 0);
     if (err)
       return err;
     buf0 = get_virtual_current_address (ch);
@@ -1079,7 +1079,8 @@ grub_netbsd_boot (void)
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   arg_target, tag_buf_len
 					   + sizeof (struct grub_netbsd_bootinfo)
-					   + tag_count * sizeof (grub_uint32_t));
+					   + tag_count * sizeof (grub_uint32_t),
+					   0);
     if (err)
       return err;
     curarg = get_virtual_current_address (ch);
@@ -1219,7 +1220,8 @@ grub_bsd_load_aout (grub_file_t file, const char *filename)
     grub_relocator_chunk_t ch;
 
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   kern_start, kern_end - kern_start);
+					   kern_start, kern_end - kern_start,
+					   0);
     if (err)
       return err;
     kern_chunk_src = get_virtual_current_address (ch);
@@ -1330,7 +1332,8 @@ grub_bsd_load_elf (grub_elf_t elf)
       if (err)
 	return err;
       err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					     kern_start, kern_end - kern_start);
+					     kern_start, kern_end - kern_start,
+					     0);
       if (err)
 	return err;
 
@@ -1373,7 +1376,7 @@ grub_bsd_load_elf (grub_elf_t elf)
 	grub_relocator_chunk_t ch;
 
 	err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start,
-					       kern_end - kern_start);
+					       kern_end - kern_start, 0);
 	if (err)
 	  return err;
 	kern_chunk_src = get_virtual_current_address (ch);
@@ -1837,7 +1840,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, 
-					   file->size);
+					   file->size, 0);
     if (err)
       goto fail;
     src = get_virtual_current_address (ch);
@@ -1888,7 +1891,7 @@ grub_netbsd_module_load (char *filename, grub_uint32_t type)
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, 
-					   file->size);
+					   file->size, 0);
     if (err)
       goto fail;
 
diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
index 7cec7a8..239c633 100644
--- a/grub-core/loader/i386/bsdXX.c
+++ b/grub-core/loader/i386/bsdXX.c
@@ -106,7 +106,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   module, chunk_size);
+					   module, chunk_size, 0);
     if (err)
       return err;
     chunk_src = get_virtual_current_address (ch);
@@ -204,7 +204,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
     grub_relocator_chunk_t ch;
 
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   module, chunk_size);
+					   module, chunk_size, 0);
     if (err)
       return err;
 
@@ -319,7 +319,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   symtarget, chunk_size);
+					   symtarget, chunk_size, 0);
     if (err)
       return err;
     sym_chunk = get_virtual_current_address (ch);
@@ -434,7 +434,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   symtarget, chunk_size);
+					   symtarget, chunk_size, 0);
     if (err)
       return err;
     sym_chunk = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c
index 3f85aa3..2bf0c6a 100644
--- a/grub-core/loader/i386/coreboot/chainloader.c
+++ b/grub-core/loader/i386/coreboot/chainloader.c
@@ -69,7 +69,7 @@ grub_chain_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
 
   *do_load = 1;
   err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					 phdr->p_paddr, phdr->p_memsz);
+					 phdr->p_paddr, phdr->p_memsz, 0);
   if (err)
     return err;
 
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index a5bcb24..67a4533 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -266,7 +266,7 @@ allocate_pages (grub_size_t prot_size)
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   real_mode_target,
 					   (real_size + mmap_size 
-					    + efi_mmap_size));
+					    + efi_mmap_size), 0);
     if (err)
       goto fail;
     real_mode_mem = get_virtual_current_address (ch);
@@ -278,7 +278,7 @@ allocate_pages (grub_size_t prot_size)
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   prot_mode_target, prot_size);
+					   prot_mode_target, prot_size, 0);
     if (err)
       goto fail;
     prot_mode_mem = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index abd4ae9..a95abc9 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -119,7 +119,7 @@ grub_multiboot_load (grub_file_t file)
 
       err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
 					     &ch, header->load_addr,
-					     code_size);
+					     code_size, 0);
       if (err)
 	{
 	  grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c
index 30b1e8b..9da0128 100644
--- a/grub-core/loader/i386/pc/chainloader.c
+++ b/grub-core/loader/i386/pc/chainloader.c
@@ -166,13 +166,13 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
     grub_err_t err;
 
     err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
-					   GRUB_DISK_SECTOR_SIZE);
+					   GRUB_DISK_SECTOR_SIZE, 0);
     if (err)
       goto fail;
     bs = get_virtual_current_address (ch);
     err = grub_relocator_alloc_chunk_addr (rel, &ch,
 					   GRUB_MEMORY_MACHINE_PART_TABLE_ADDR,
-					   64);
+					   64, 0);
     if (err)
       goto fail;
     ptable = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c
index 1f088e2..24b6dce 100644
--- a/grub-core/loader/i386/pc/freedos.c
+++ b/grub-core/loader/i386/pc/freedos.c
@@ -101,7 +101,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4,
-					   kernelsyssize);
+					   kernelsyssize, 0);
     if (err)
       goto fail;
     kernelsys = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 7c4a4be..dee4126 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -273,7 +273,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   grub_linux_real_target,
 					   GRUB_LINUX_CL_OFFSET
-					   + maximal_cmdline_size);
+					   + maximal_cmdline_size, 0);
     if (err)
       return err;
     grub_linux_real_chunk = get_virtual_current_address (ch);
@@ -317,7 +317,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   grub_linux_prot_target,
-					   grub_linux16_prot_size);
+					   grub_linux16_prot_size, 0);
     if (err)
       return err;
     grub_linux_prot_chunk = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c
index 153b605..f613887 100644
--- a/grub-core/loader/i386/pc/ntldr.c
+++ b/grub-core/loader/i386/pc/ntldr.c
@@ -97,7 +97,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
-					   GRUB_DISK_SECTOR_SIZE);
+					   GRUB_DISK_SECTOR_SIZE, 0);
     if (err)
       goto fail;
     bs = get_virtual_current_address (ch);
@@ -124,7 +124,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
-					   ntldrsize);
+					   ntldrsize, 0);
     if (err)
       goto fail;
     ntldr = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c
index 169f83a..7de8c54 100644
--- a/grub-core/loader/i386/pc/plan9.c
+++ b/grub-core/loader/i386/pc/plan9.c
@@ -417,7 +417,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
     grub_relocator_chunk_t ch;
     grub_err_t err;
     err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR,
-					   configsize);
+					   configsize, 0);
     if (err)
       goto fail;
     config = get_virtual_current_address (ch);
@@ -448,7 +448,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
     grub_err_t err;
 
     err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET,
-					   memsize);
+					   memsize, 0);
     if (err)
       goto fail;
     mem = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/pxechainloader.c b/grub-core/loader/i386/pc/pxechainloader.c
index 30a4c24..e0d8e7c 100644
--- a/grub-core/loader/i386/pc/pxechainloader.c
+++ b/grub-core/loader/i386/pc/pxechainloader.c
@@ -130,7 +130,7 @@ grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)),
   imagesize = grub_file_size (file);
   {
     grub_relocator_chunk_t ch;
-    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize);
+    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize, 0);
     if (err)
       goto fail;
     image = get_virtual_current_address (ch);
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
index 7fda817..8fba174 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -87,7 +87,7 @@ grub_linux_boot (void)
 
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   ((16 << 20) - 264),
-					   grub_strlen (params) + 1 + 8);
+					   grub_strlen (params) + 1 + 8, 0);
     if (err)
       return err;
     memsize = get_virtual_current_address (ch);
@@ -159,7 +159,7 @@ grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   target_addr & 0x1fffffff,
-					   linux_size);
+					   linux_size, 0);
     if (err)
       return err;
     playground = get_virtual_current_address (ch);
@@ -214,7 +214,7 @@ grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 					   target_addr & 0x1fffffff,
-					   linux_size);
+					   linux_size, 0);
     if (err)
       return err;
     playground = get_virtual_current_address (ch);
diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
index c6c88f1..9bbc10b 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -102,7 +102,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
 	    grub_relocator_chunk_t ch;
 	    err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
 						   &ch, phdr(i)->p_paddr,
-						   phdr(i)->p_memsz);
+						   phdr(i)->p_memsz, 0);
 	    if (err)
 	      {
 		grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 9a81afe..15760d0 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -227,7 +227,7 @@ grub_multiboot_load (grub_file_t file)
 
       err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
 					     &ch, addr_tag->load_addr,
-					     code_size);
+					     code_size, 0);
       if (err)
 	{
 	  grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index ec7c342..5d70145 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -60,7 +60,7 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
   
   err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
 					 grub_xnu_heap_target_start
-					 + grub_xnu_heap_size, size);
+					 + grub_xnu_heap_size, size, 0);
   if (err)
     return err;
 
diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
index d7f9ada..e4fdb95 100644
--- a/grub-core/loader/xnu_resume.c
+++ b/grub-core/loader/xnu_resume.c
@@ -110,7 +110,7 @@ grub_xnu_resume (char *imagename)
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, codedest,
-					   codesize + GRUB_XNU_PAGESIZE);
+					   codesize + GRUB_XNU_PAGESIZE, 0);
     if (err)
       {
 	grub_file_close (file);
diff --git a/include/grub/relocator.h b/include/grub/relocator.h
index 653a00e..b250512 100644
--- a/include/grub/relocator.h
+++ b/include/grub/relocator.h
@@ -33,7 +33,8 @@ struct grub_relocator *grub_relocator_new (void);
 grub_err_t
 grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
 				 grub_relocator_chunk_t *out,
-				 grub_phys_addr_t target, grub_size_t size);
+				 grub_phys_addr_t target, grub_size_t size,
+				 int avoid_firmware);
 
 void *
 get_virtual_current_address (grub_relocator_chunk_t in);
diff --git a/include/grub/relocator_private.h b/include/grub/relocator_private.h
index 1c563cb..1948af4 100644
--- a/include/grub/relocator_private.h
+++ b/include/grub/relocator_private.h
@@ -104,6 +104,8 @@ struct grub_relocator_mmap_event
 #if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
 int grub_relocator_firmware_alloc_region (grub_phys_addr_t start,
 					  grub_size_t size);
+unsigned grub_relocator_firmware_overlaps (grub_phys_addr_t start,
+					   grub_size_t size);
 unsigned grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events);
 unsigned grub_relocator_firmware_get_max_events (void);
 void grub_relocator_firmware_free_region (grub_phys_addr_t start,
-- 
1.7.7.6



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

* [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences
  2012-02-08 16:55 [PATCH V3 1/3] Update the Linux boot protocol Matthew Garrett
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
@ 2012-02-08 16:55 ` Matthew Garrett
  2012-02-08 19:49   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-08 19:35 ` [PATCH V3 1/3] Update the Linux boot protocol Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 1 reply; 14+ messages in thread
From: Matthew Garrett @ 2012-02-08 16:55 UTC (permalink / raw)
  To: grub-devel; +Cc: Matthew Garrett

We should attempt to load the kernel at its preferred address, and if we
can't do that then we should at lesat align it correctly. When doing so
we should also make sure to avoid putting the kernel on top of any regions
being used by the firmware.
---
 ChangeLog                     |    8 +++++
 grub-core/loader/i386/linux.c |   67 ++++++++++++++++++++++++++++++++++------
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8bef256..162f82b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2012-02-08  Matthew Garrett  <mjg@redhat.com>
 
+	* grub-core/loader/i386/linux.c (allocate_pages): Attempt to obtain
+	appropriately aligned memory if the desired target is unavailable
+	(grub_cmd_linux): Update to match newer Linux boot protocols, and
+	attempt to load the kernel at its preferred address rather than
+	hardcoding.
+
+2012-02-08  Matthew Garrett  <mjg@redhat.com>
+
 	* grub-core/lib/efi/relocator.c (grub_relocator_alloc_chunk_addr):
 	Add argument to fail allocation when target address overlaps
 	firmware regions. All users updated.
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 67a4533..3eb8fa0 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -183,13 +183,14 @@ free_pages (void)
   grub_relocator_unload (relocator);
   relocator = NULL;
   real_mode_mem = prot_mode_mem = initrd_mem = 0;
-  real_mode_target = prot_mode_target = initrd_mem_target = 0;
+  real_mode_target = initrd_mem_target = 0;
 }
 
 /* Allocate pages for the real mode code and the protected mode code
    for linux as well as a memory map buffer.  */
 static grub_err_t
-allocate_pages (grub_size_t prot_size)
+allocate_pages (grub_size_t prot_size, grub_size_t *align,
+		grub_size_t min_align, int relocatable)
 {
   grub_size_t real_size, mmap_size;
   grub_err_t err;
@@ -269,18 +270,38 @@ allocate_pages (grub_size_t prot_size)
 					    + efi_mmap_size), 0);
     if (err)
       goto fail;
+
+    grub_errno = GRUB_ERR_NONE;
     real_mode_mem = get_virtual_current_address (ch);
   }
   efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
 
-  prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
-
   {
     grub_relocator_chunk_t ch;
     err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   prot_mode_target, prot_size, 0);
+					   prot_mode_target, prot_size,
+					   relocatable);
+    if (err)
+      {
+	unsigned int i;
+	for (i = *align; i >= min_align; i--)
+	  {
+	    err = grub_relocator_alloc_chunk_align (relocator, &ch,
+						    0x1000000, 0xffffffff,
+						    prot_size, 1 << i,
+						    GRUB_RELOCATOR_PREFERENCE_LOW);
+	    if (!err)
+	      {
+		*align = i;
+		prot_mode_target = get_physical_target_address (ch);
+		break;
+	      }
+	  }
+      }
+
     if (err)
       goto fail;
+
     prot_mode_mem = get_virtual_current_address (ch);
   }
 
@@ -631,8 +652,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   struct linux_kernel_header lh;
   struct linux_kernel_params *params;
   grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
+  grub_size_t real_size, prot_size, prot_file_size, align = 0, min_align = 0;
   grub_ssize_t len;
+  int relocatable = 0;
   int i;
 
   grub_dl_ref (my_mod);
@@ -705,9 +727,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
     setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
 
   real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
 
-  if (allocate_pages (prot_size))
+  if (grub_le_to_cpu16 (lh.version) >= 0x205)
+    {
+      for (align = 0; align < 32; align++)
+	{
+	  if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align))
+	    break;
+	}
+      relocatable = grub_le_to_cpu32 (lh.relocatable);
+    }
+
+  if (grub_le_to_cpu16 (lh.version) >= 0x020a)
+    {
+      min_align = lh.min_alignment;
+      prot_size = grub_le_to_cpu32 (lh.init_size);
+      prot_mode_target = grub_le_to_cpu64 (lh.pref_address);
+    }
+  else
+    {
+      min_align = 0;
+      prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+      prot_mode_target = grub_le_to_cpu32 (lh.code32_start);
+    }
+
+  prot_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+  if (allocate_pages (prot_size, &align, min_align, relocatable))
     goto fail;
 
   params = (struct linux_kernel_params *) real_mode_mem;
@@ -715,6 +760,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
 
   params->ps_mouse = params->padding10 =  0;
+  params->code32_start = prot_mode_target;
+  params->kernel_alignment = (1 << align);
 
   len = 0x400 - sizeof (lh);
   if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
@@ -774,7 +821,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
 
   grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
-		(unsigned) real_size, (unsigned) prot_size);
+		(unsigned) real_size, (unsigned) prot_file_size);
 
   /* Look for memory size and video mode specified on the command line.  */
   linux_mem_size = 0;
@@ -911,7 +958,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 			      maximal_cmdline_size
 			      - (sizeof (LINUX_IMAGE) - 1));
 
-  len = prot_size;
+  len = prot_file_size;
   if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
     grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
 		argv[0]);
-- 
1.7.7.6



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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-08 16:55 [PATCH V3 1/3] Update the Linux boot protocol Matthew Garrett
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
  2012-02-08 16:55 ` [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences Matthew Garrett
@ 2012-02-08 19:35 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-26 21:01   ` Keshav P R
  2 siblings, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-08 19:35 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

Go ahead.
On 08.02.2012 17:55, Matthew Garrett wrote:
> The Linux boot header includes information on the kernel's desired load
> address and alignment. Add support for that.
> ---
>   ChangeLog                 |    6 ++++++
>   include/grub/i386/linux.h |   28 +++++++++++++++++++++++-----
>   2 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/ChangeLog b/ChangeLog
> index ede7f8e..2bdb3a0 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,9 @@
> +2012-02-08  Matthew Garrett<mjg@redhat.com>
> +
> +	* include/grub/i386/linux.h (linux_kernel_header): Update to
> +	boot protocol 2.10.
> +	(linux_kernel_params): Likewise
> +
>   2012-02-07  Vladimir Serbinenko<phcoder@gmail.com>
>
>   	* grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM
> diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
> index 6aa2391..8e27b93 100644
> --- a/include/grub/i386/linux.h
> +++ b/include/grub/i386/linux.h
> @@ -86,7 +86,7 @@ enum
>       GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70    /* Linear framebuffer without any additional functions.  */
>     };
>
> -/* For the Linux/i386 boot protocol version 2.03.  */
> +/* For the Linux/i386 boot protocol version 2.10.  */
>   struct linux_kernel_header
>   {
>     grub_uint8_t code1[0x0020];
> @@ -131,8 +131,16 @@ struct linux_kernel_header
>     grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
>     grub_uint32_t kernel_alignment;
>     grub_uint8_t relocatable;
> -  grub_uint8_t pad[3];
> +  grub_uint8_t min_alignment;
> +  grub_uint8_t pad[2];
>     grub_uint32_t cmdline_size;
> +  grub_uint32_t hardware_subarch;
> +  grub_uint64_t hardware_subarch_data;
> +  grub_uint32_t payload_offset;
> +  grub_uint32_t payload_length;
> +  grub_uint64_t setup_data;
> +  grub_uint64_t pref_address;
> +  grub_uint64_t init_size;
>   } __attribute__ ((packed));
>
>   /* Boot parameters for Linux based on 2.6.12. This is used by the setup
> @@ -276,10 +284,20 @@ struct linux_kernel_params
>     grub_uint32_t ramdisk_size;		/* initrd size */
>     grub_uint32_t bootsect_kludge;	/* obsolete */
>     grub_uint16_t heap_end_ptr;		/* Free memory after setup end */
> -  grub_uint16_t pad1;			/* Unused */
> +  grub_uint8_t ext_loader_ver;		/* Extended loader version */
> +  grub_uint8_t ext_loader_type;		/* Extended loader type */
>     grub_uint32_t cmd_line_ptr;		/* Points to the kernel command line */
> -
> -  grub_uint8_t pad2[164];		/* 22c */
> +  grub_uint32_t initrd_addr_max;	/* Maximum initrd address */
> +  grub_uint32_t kernel_alignment;	/* Alignment of the kernel */
> +  grub_uint8_t relocatable_kernel;	/* Is the kernel relocatable */
> +  grub_uint8_t pad1[3];
> +  grub_uint32_t cmdline_size;		/* Size of the kernel command line */
> +  grub_uint32_t hardware_subarch;
> +  grub_uint64_t hardware_subarch_data;
> +  grub_uint32_t payload_offset;
> +  grub_uint32_t payload_length;
> +  grub_uint64_t setup_data;
> +  grub_uint8_t pad2[120];		/* 258 */
>     struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY];	/* 2d0 */
>
>   } __attribute__ ((packed));


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 2/3] Add support for avoiding firmware in relocations
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
@ 2012-02-08 19:41   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-08 22:22   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-08 22:25   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-08 19:41 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

On 08.02.2012 17:55, Matthew Garrett wrote:
> EFI and OF both support firmware regions which may be in use during loading.
>
> +unsigned
> +grub_relocator_firmware_overlaps (grub_phys_addr_t target, grub_size_t size)
> +{
> +  grub_efi_uintn_t mmapsize = 0, desc_size = 0;
> +  grub_efi_uint32_t descriptor_version = 0;
> +  grub_efi_memory_descriptor_t *descs = NULL;
> +  grub_efi_uintn_t key;
> +  int overlap = 0;
> +  grub_efi_memory_descriptor_t *desc;
> +
> +  grub_efi_get_memory_map (&mmapsize, NULL,&key,&desc_size,
> +			&descriptor_version);
You need to check return value.
You don't use key. You can just make it NULL (grub_efi_get_memory_map 
handles it).
> +  descs = grub_malloc (mmapsize);
> +  if (!descs)
> +    return 0;
> +
You seem to lack error handling as whole. I'd suggest make this function 
return grub_err_t and generate a grub_error itself if overlap is detected.
You current code would happily allocate anywhere if grub_malloc fails.
> +  grub_efi_get_memory_map (&mmapsize, descs,&key,&desc_size,
> +			&descriptor_version);
> +
> +
>     adjust_limits (rel,&min_addr,&max_addr, target, target);
>
> +  if (avoid_firmware)
> +    {
> +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
> +      if (grub_relocator_firmware_overlaps(target, size))
> +
> +      return grub_error(GRUB_ERR_BAD_ARGUMENT, "target overlaps with firmware");
> +#endif
> +    }
> +
Ditto. Also here you have indentation problem

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences
  2012-02-08 16:55 ` [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences Matthew Garrett
@ 2012-02-08 19:49   ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-08 19:49 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

On 08.02.2012 17:55, Matthew Garrett wrote:
> We should attempt to load the kernel at its preferred address, and if we
> can't do that then we should at lesat align it correctly. When doing so
> we should also make sure to avoid putting the kernel on top of any regions
> being used by the firmware.
> ---
>   ChangeLog                     |    8 +++++
>   grub-core/loader/i386/linux.c |   67 ++++++++++++++++++++++++++++++++++------
>   2 files changed, 65 insertions(+), 10 deletions(-)
>
> diff --git a/ChangeLog b/ChangeLog
> index 8bef256..162f82b 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,13 @@
>   2012-02-08  Matthew Garrett<mjg@redhat.com>
>
> +	* grub-core/loader/i386/linux.c (allocate_pages): Attempt to obtain
> +	appropriately aligned memory if the desired target is unavailable
> +	(grub_cmd_linux): Update to match newer Linux boot protocols, and
> +	attempt to load the kernel at its preferred address rather than
> +	hardcoding.
> +
> +2012-02-08  Matthew Garrett<mjg@redhat.com>
> +
>   	* grub-core/lib/efi/relocator.c (grub_relocator_alloc_chunk_addr):
>   	Add argument to fail allocation when target address overlaps
>   	firmware regions. All users updated.
> diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
> index 67a4533..3eb8fa0 100644
> --- a/grub-core/loader/i386/linux.c
> +++ b/grub-core/loader/i386/linux.c
> @@ -183,13 +183,14 @@ free_pages (void)
>     grub_relocator_unload (relocator);
>     relocator = NULL;
>     real_mode_mem = prot_mode_mem = initrd_mem = 0;
> -  real_mode_target = prot_mode_target = initrd_mem_target = 0;
> +  real_mode_target = initrd_mem_target = 0;
Any reason not to clean prot_mode_target? Looks like you wanted to 
remove its use. If so, can you remove declaration as well?
> @@ -269,18 +270,38 @@ allocate_pages (grub_size_t prot_size)
>   					    + efi_mmap_size), 0);
>       if (err)
>         goto fail;
> +
> +    grub_errno = GRUB_ERR_NONE;
Why do you reset error here?
>       real_mode_mem = get_virtual_current_address (ch);
>     }
>     efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
>
> -  prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
> -
>     {
>       grub_relocator_chunk_t ch;
>       err = grub_relocator_alloc_chunk_addr (relocator,&ch,
> -					   prot_mode_target, prot_size, 0);
> +					   prot_mode_target, prot_size,
> +					   relocatable);
> +    if (err)
> +      {
> +	unsigned int i;
> +	for (i = *align; i>= min_align; i--)
> +	  {
I see here no check that kernel is relocatable.
> +	    err = grub_relocator_alloc_chunk_align (relocator,&ch,
> +						    0x1000000, 0xffffffff,
> +						    prot_size, 1<<  i,
> +						    GRUB_RELOCATOR_PREFERENCE_LOW);
> +	    if (!err)
> +	      {
> +		*align = i;
> +		prot_mode_target = get_physical_target_address (ch);
> +		break;
> +	      }
Here you need to clean grub_errno since you ignore error
> +	  }
> +      }
> +
You need to restore grub_errno here (you can use grub_error_save and 
grub_error_load).
>       if (err)
>         goto fail;
> +
>       prot_mode_mem = get_virtual_current_address (ch);
>     }
>
> @@ -631,8 +652,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
>     struct linux_kernel_header lh;
>     struct linux_kernel_params *params;
>     grub_uint8_t setup_sects;
> -  grub_size_t real_size, prot_size;
> +  grub_size_t real_size, prot_size, prot_file_size, align = 0, min_align = 0;
>     grub_ssize_t len;
> +  int relocatable = 0;
>     int i;
>
>     grub_dl_ref (my_mod);
> @@ -705,9 +727,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
>       setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
>
>     real_size = setup_sects<<  GRUB_DISK_SECTOR_BITS;
> -  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
>
> -  if (allocate_pages (prot_size))
> +  if (grub_le_to_cpu16 (lh.version)>= 0x205)
> +    {
> +      for (align = 0; align<  32; align++)
> +	{
> +	  if (grub_le_to_cpu32 (lh.kernel_alignment)&  (1<<  align))
> +	    break;
> +	}
> +      relocatable = grub_le_to_cpu32 (lh.relocatable);
> +    }
> +
> +  if (grub_le_to_cpu16 (lh.version)>= 0x020a)
> +    {
> +      min_align = lh.min_alignment;
> +      prot_size = grub_le_to_cpu32 (lh.init_size);
> +      prot_mode_target = grub_le_to_cpu64 (lh.pref_address);
> +    }
> +  else
> +    {
> +      min_align = 0;
> +      prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
> +      prot_mode_target = grub_le_to_cpu32 (lh.code32_start);
> +    }
> +
> +  prot_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
> +  if (allocate_pages (prot_size,&align, min_align, relocatable))
>       goto fail;
>
>     params = (struct linux_kernel_params *) real_mode_mem;
> @@ -715,6 +760,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
>     grub_memcpy (&params->setup_sects,&lh.setup_sects, sizeof (lh) - 0x1F1);
>
>     params->ps_mouse = params->padding10 =  0;
> +  params->code32_start = prot_mode_target;
> +  params->kernel_alignment = (1<<  align);
>
>     len = 0x400 - sizeof (lh);
>     if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
> @@ -774,7 +821,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
>     grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
>
>     grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
> -		(unsigned) real_size, (unsigned) prot_size);
> +		(unsigned) real_size, (unsigned) prot_file_size);
>
>     /* Look for memory size and video mode specified on the command line.  */
>     linux_mem_size = 0;
> @@ -911,7 +958,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
>   			      maximal_cmdline_size
>   			      - (sizeof (LINUX_IMAGE) - 1));
>
> -  len = prot_size;
> +  len = prot_file_size;
Any reason for rename?
>     if (grub_file_read (file, prot_mode_mem, len) != len&&  !grub_errno)
>       grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
>   		argv[0]);
> -- 1.7.7.6 _______________________________________________ Grub-devel 
> mailing list Grub-devel@gnu.org 
> https://lists.gnu.org/mailman/listinfo/grub-devel


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 2/3] Add support for avoiding firmware in relocations
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
  2012-02-08 19:41   ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2012-02-08 22:22   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-08 22:25   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-08 22:22 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

On 08.02.2012 17:55, Matthew Garrett wrote:
> +    if (type == GRUB_MEMORY_AVAILABLE)
> +      return 0;
> +
> +    if (target>= addr&&  target<= end)
> +      overlap = 1;
> +
> +    if (target + size>= addr&&  target + size<= end)
> +      overlap = 1;
This won't work. IEEE1275 declares only one type of memory range: 
available. Other ranges aren't declared at all.
Also it would make sense to expand this implementation to other non-efi 
platforms (pc, coreboot, ...).

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 2/3] Add support for avoiding firmware in relocations
  2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
  2012-02-08 19:41   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-08 22:22   ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2012-02-08 22:25   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-08 22:25 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

On 08.02.2012 17:55, Matthew Garrett wrote:
> EFI and OF both support firmware regions which may be in use during loading.
> Add support for avoiding these.
Also Seth Goldberg noticed that using chunk_align with start=end=target 
does exactly what we want (as if avoid=1). You may need to modify 
efi/relocator.c though as to which regions it considers available.

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-08 19:35 ` [PATCH V3 1/3] Update the Linux boot protocol Vladimir 'φ-coder/phcoder' Serbinenko
@ 2012-02-26 21:01   ` Keshav P R
  2012-02-26 21:12     ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 14+ messages in thread
From: Keshav P R @ 2012-02-26 21:01 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Matthew Garrett

Status of this patch in grub2 v2.00 code freeze?

- Keshav

On 09/02/2012, Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com> wrote:
> Go ahead.
> On 08.02.2012 17:55, Matthew Garrett wrote:
>> The Linux boot header includes information on the kernel's desired load
>> address and alignment. Add support for that.
>> ---
>>   ChangeLog                 |    6 ++++++
>>   include/grub/i386/linux.h |   28 +++++++++++++++++++++++-----
>>   2 files changed, 29 insertions(+), 5 deletions(-)
>>
>> diff --git a/ChangeLog b/ChangeLog
>> index ede7f8e..2bdb3a0 100644
>> --- a/ChangeLog
>> +++ b/ChangeLog
>> @@ -1,3 +1,9 @@
>> +2012-02-08  Matthew Garrett<mjg@redhat.com>
>> +
>> +	* include/grub/i386/linux.h (linux_kernel_header): Update to
>> +	boot protocol 2.10.
>> +	(linux_kernel_params): Likewise
>> +
>>   2012-02-07  Vladimir Serbinenko<phcoder@gmail.com>
>>
>>   	* grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM
>> diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
>> index 6aa2391..8e27b93 100644
>> --- a/include/grub/i386/linux.h
>> +++ b/include/grub/i386/linux.h
>> @@ -86,7 +86,7 @@ enum
>>       GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70    /* Linear framebuffer without
>> any additional functions.  */
>>     };
>>
>> -/* For the Linux/i386 boot protocol version 2.03.  */
>> +/* For the Linux/i386 boot protocol version 2.10.  */
>>   struct linux_kernel_header
>>   {
>>     grub_uint8_t code1[0x0020];
>> @@ -131,8 +131,16 @@ struct linux_kernel_header
>>     grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
>>     grub_uint32_t kernel_alignment;
>>     grub_uint8_t relocatable;
>> -  grub_uint8_t pad[3];
>> +  grub_uint8_t min_alignment;
>> +  grub_uint8_t pad[2];
>>     grub_uint32_t cmdline_size;
>> +  grub_uint32_t hardware_subarch;
>> +  grub_uint64_t hardware_subarch_data;
>> +  grub_uint32_t payload_offset;
>> +  grub_uint32_t payload_length;
>> +  grub_uint64_t setup_data;
>> +  grub_uint64_t pref_address;
>> +  grub_uint64_t init_size;
>>   } __attribute__ ((packed));
>>
>>   /* Boot parameters for Linux based on 2.6.12. This is used by the setup
>> @@ -276,10 +284,20 @@ struct linux_kernel_params
>>     grub_uint32_t ramdisk_size;		/* initrd size */
>>     grub_uint32_t bootsect_kludge;	/* obsolete */
>>     grub_uint16_t heap_end_ptr;		/* Free memory after setup end */
>> -  grub_uint16_t pad1;			/* Unused */
>> +  grub_uint8_t ext_loader_ver;		/* Extended loader version */
>> +  grub_uint8_t ext_loader_type;		/* Extended loader type */
>>     grub_uint32_t cmd_line_ptr;		/* Points to the kernel command line */
>> -
>> -  grub_uint8_t pad2[164];		/* 22c */
>> +  grub_uint32_t initrd_addr_max;	/* Maximum initrd address */
>> +  grub_uint32_t kernel_alignment;	/* Alignment of the kernel */
>> +  grub_uint8_t relocatable_kernel;	/* Is the kernel relocatable */
>> +  grub_uint8_t pad1[3];
>> +  grub_uint32_t cmdline_size;		/* Size of the kernel command line */
>> +  grub_uint32_t hardware_subarch;
>> +  grub_uint64_t hardware_subarch_data;
>> +  grub_uint32_t payload_offset;
>> +  grub_uint32_t payload_length;
>> +  grub_uint64_t setup_data;
>> +  grub_uint8_t pad2[120];		/* 258 */
>>     struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY];	/* 2d0 */
>>
>>   } __attribute__ ((packed));
>
>
> --
> Regards
> Vladimir 'φ-coder/phcoder' Serbinenko
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>


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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-26 21:01   ` Keshav P R
@ 2012-02-26 21:12     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-26 21:18       ` Keshav P R
  0 siblings, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-26 21:12 UTC (permalink / raw)
  To: The development of GNU GRUB

On 26.02.2012 22:01, Keshav P R wrote:
> Status of this patch in grub2 v2.00 code freeze?
I have written what have to be fixed first.
And one thing: your idea to put into distro a patch which has known 
serious issues that have to be resolved was a very bad one.

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-26 21:12     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2012-02-26 21:18       ` Keshav P R
  2012-02-26 21:22         ` Keshav P R
  2012-02-26 21:34         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 14+ messages in thread
From: Keshav P R @ 2012-02-26 21:18 UTC (permalink / raw)
  To: The development of GNU GRUB

I am asking about 'this' patch (patch 1/3) alone. Not the other two
ones. And the distro package was never updated, it was just a test
build with a bzr snapshot and these patches, given to users willing to
test the code.

- Keshav

On 27/02/2012, Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com> wrote:
> On 26.02.2012 22:01, Keshav P R wrote:
>> Status of this patch in grub2 v2.00 code freeze?
> I have written what have to be fixed first.
> And one thing: your idea to put into distro a patch which has known
> serious issues that have to be resolved was a very bad one.
>
> --
> Regards
> Vladimir 'φ-coder/phcoder' Serbinenko
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>


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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-26 21:18       ` Keshav P R
@ 2012-02-26 21:22         ` Keshav P R
  2012-02-26 21:29           ` Vladimir 'φ-coder/phcoder' Serbinenko
  2012-02-26 21:34         ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 14+ messages in thread
From: Keshav P R @ 2012-02-26 21:22 UTC (permalink / raw)
  To: The development of GNU GRUB

Coming to the issue of distro package, has the uefi relocator hang
(seen in many asus laptops) been fixed in bzr mainline?

On 27/02/2012, Keshav P R <the.ridikulus.rat@gmail.com> wrote:
> I am asking about 'this' patch (patch 1/3) alone. Not the other two
> ones. And the distro package was never updated, it was just a test
> build with a bzr snapshot and these patches, given to users willing to
> test the code.
>
> - Keshav
>
> On 27/02/2012, Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com>
> wrote:
>> On 26.02.2012 22:01, Keshav P R wrote:
>>> Status of this patch in grub2 v2.00 code freeze?
>> I have written what have to be fixed first.
>> And one thing: your idea to put into distro a patch which has known
>> serious issues that have to be resolved was a very bad one.
>>
>> --
>> Regards
>> Vladimir 'φ-coder/phcoder' Serbinenko
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> https://lists.gnu.org/mailman/listinfo/grub-devel
>>
>


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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-26 21:22         ` Keshav P R
@ 2012-02-26 21:29           ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-26 21:29 UTC (permalink / raw)
  To: The development of GNU GRUB

On 26.02.2012 22:22, Keshav P R wrote:
> Coming to the issue of distro package, has the uefi relocator hang
> (seen in many asus laptops) been fixed in bzr mainline?
The reports feature one bug that debug=all caused relocator to hang. I 
don't know what happens in case when no "debug" is set and whether it's 
relocator's (or GRUB's at all for that matter) fault.
> On 27/02/2012, Keshav P R<the.ridikulus.rat@gmail.com>  wrote:
>> I am asking about 'this' patch (patch 1/3) alone. Not the other two
>> ones. And the distro package was never updated, it was just a test
>> build with a bzr snapshot and these patches, given to users willing to
>> test the code.
>>
>> - Keshav
>>
>> On 27/02/2012, Vladimir 'φ-coder/phcoder' Serbinenko<phcoder@gmail.com>
>> wrote:
>>> On 26.02.2012 22:01, Keshav P R wrote:
>>>> Status of this patch in grub2 v2.00 code freeze?
>>> I have written what have to be fixed first.
>>> And one thing: your idea to put into distro a patch which has known
>>> serious issues that have to be resolved was a very bad one.
>>>
>>> --
>>> Regards
>>> Vladimir 'φ-coder/phcoder' Serbinenko
>>>
>>>
>>> _______________________________________________
>>> Grub-devel mailing list
>>> Grub-devel@gnu.org
>>> https://lists.gnu.org/mailman/listinfo/grub-devel
>>>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

* Re: [PATCH V3 1/3] Update the Linux boot protocol
  2012-02-26 21:18       ` Keshav P R
  2012-02-26 21:22         ` Keshav P R
@ 2012-02-26 21:34         ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2012-02-26 21:34 UTC (permalink / raw)
  To: The development of GNU GRUB

On 26.02.2012 22:18, Keshav P R wrote:
> I am asking about 'this' patch (patch 1/3) alone.
'This' patch by itself has no effect.

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



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

end of thread, other threads:[~2012-02-26 21:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-08 16:55 [PATCH V3 1/3] Update the Linux boot protocol Matthew Garrett
2012-02-08 16:55 ` [PATCH V3 2/3] Add support for avoiding firmware in relocations Matthew Garrett
2012-02-08 19:41   ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-08 22:22   ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-08 22:25   ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-08 16:55 ` [PATCH V3 3/3] Update Linux loader to follow the kernel's preferences Matthew Garrett
2012-02-08 19:49   ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-08 19:35 ` [PATCH V3 1/3] Update the Linux boot protocol Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-26 21:01   ` Keshav P R
2012-02-26 21:12     ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-26 21:18       ` Keshav P R
2012-02-26 21:22         ` Keshav P R
2012-02-26 21:29           ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-02-26 21:34         ` Vladimir 'φ-coder/phcoder' Serbinenko

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.