rpms/grub/devel grub-0.97-efi-graphics-mode-selection.patch, NONE, 1.1 grub-0.97-relocatable-kernel-on-x86_64-uefi.patch, 1.1, 1.2 grub.spec, 1.109, 1.110

Peter Jones pjones at fedoraproject.org
Fri Nov 13 18:58:29 UTC 2009


Author: pjones

Update of /cvs/extras/rpms/grub/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv14403

Modified Files:
	grub-0.97-relocatable-kernel-on-x86_64-uefi.patch grub.spec 
Added Files:
	grub-0.97-efi-graphics-mode-selection.patch 
Log Message:
* Fri Nov 13 2009 Peter Jones <pjones at redhat.com> - 0.97-61
- Update relocatable kernel support for UEFI/x86_64 .
  Related: rhbz #476230
- grub-0.97-gate-a20.patch: Patch from Suse. Make really, really sure that
  A20 is behaving itself. (mjg)
- add "silent" option (mjg)
- Rework EFI Graphics Output Protocol mode selection.


grub-0.97-efi-graphics-mode-selection.patch:
 efigraph.c |  343 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 300 insertions(+), 43 deletions(-)

--- NEW FILE grub-0.97-efi-graphics-mode-selection.patch ---
diff -urpN grub-0.97/efi/efigraph.c.badmodes grub-0.97/efi/efigraph.c
--- grub-0.97/efi/efigraph.c.badmodes	2009-11-13 13:48:40.000000000 -0500
+++ grub-0.97/efi/efigraph.c	2009-11-13 13:50:06.000000000 -0500
@@ -37,6 +37,23 @@
 #include "graphics.h"
 #include "xpm.h"
 
+#define dbgdelay(_f, _l) ({\
+	if (debug_graphics) {				\
+  		do {					\
+			grub_efi_stall(1000);		\
+		} while (console_getkey() < 0);		\
+	}						\
+	})
+
+#define dprintf(format, args...) ({			\
+	if (debug_graphics) {				\
+		struct term_entry *_tt = current_term;	\
+		current_term = term_table;		\
+		grub_printf(format, ##args);		\
+		current_term = _tt;			\
+	}						\
+	})
+
 struct grub_pixel_info
 {
   char depth_bits;
@@ -139,6 +156,59 @@ find_bits (unsigned long mask, unsigned 
   *len = bit_len;
 }
 
+static grub_efi_graphics_output_mode_information_t *
+get_graphics_mode_info_for_mode(struct eg *eg, int mode)
+{
+	int i;
+	
+	for (i = 0; i < eg->max_mode; i++) {
+		if (eg->modes[i] == NULL)
+			continue;
+		if (eg->modes[i]->number == mode)
+			return eg->modes[i]->info;
+	}
+	return NULL;
+}
+
+static grub_efi_graphics_output_mode_information_t *
+get_graphics_mode_info(struct eg *eg)
+{
+	return get_graphics_mode_info_for_mode(eg, eg->graphics_mode);
+}
+
+static void
+print_mode_info(struct video_mode *mode)
+{
+	grub_efi_graphics_output_mode_information_t *info = mode->info;
+	dprintf("mode %d (%dx%d, pitch %d, ",
+		mode->number,
+		info->horizontal_resolution,
+		info->vertical_resolution,
+		info->pixels_per_scan_line);
+	switch(info->pixel_format) {
+		case GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR:
+			dprintf("rgbr 8bpc");
+			break;
+		case GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR:
+			dprintf("bgrr 8bpc");
+			break;
+		case GRUB_EFI_PIXEL_BIT_MASK:
+			dprintf("bitmask color");
+			break;
+		case GRUB_EFI_PIXEL_BLT_ONLY:
+			dprintf("blt only");
+			break;
+	}
+	dprintf(")\n");
+	if (info->pixel_format == GRUB_EFI_PIXEL_BIT_MASK) {
+		dprintf("red: %08x green: %08x blue: %08x res: %08x\n",
+		info->pixel_information.red_mask,
+		info->pixel_information.green_mask,
+		info->pixel_information.blue_mask,
+		info->pixel_information.reserved_mask);
+	}
+}
+
 static void
 set_kernel_params(struct graphics_backend *backend,
             struct linux_kernel_params *params)
@@ -197,7 +267,7 @@ set_kernel_params(struct graphics_backen
             params->blue_field_pos = 0;
             params->reserved_mask_size = 8;
             params->reserved_field_pos = 24;
-            params->lfb_line_len = gop_info->pixels_per_scan_line * 4;
+	    params->lfb_line_len = gop_info->pixels_per_scan_line * 4;
         } else if (gop_info->pixel_format == GRUB_EFI_PIXEL_BIT_MASK) {
             find_bits (gop_info->pixel_information.red_mask,
       		 &params->red_field_pos, &params->red_mask_size);
@@ -306,9 +376,8 @@ static struct bltbuf *alloc_bltbuf(grub_
 }
 
 
-#if 1
 static void
-blt_pos_to_screen_pos(struct eg *eg, struct bltbuf *bltbuf,
+hw_blt_pos_to_screen_pos(struct eg *eg, struct bltbuf *bltbuf,
                       position_t *bltpos, position_t *bltsz, position_t *pos)
 {
     position_t phys;
@@ -322,12 +391,12 @@ blt_pos_to_screen_pos(struct eg *eg, str
                     bltsz->x, bltsz->y,
                     0);
 }
-#else
+
 static void
 blt_pos_to_screen_pos(struct eg *eg, struct bltbuf *bltbuf,
         position_t *bltpos, position_t *bltsz, position_t *pos)
 {
-    grub_efi_graphics_output_mode_information_t *info = eg->modes[eg->graphics_mode]->info;
+    grub_efi_graphics_output_mode_information_t *info = get_graphics_mode_info(eg);
     grub_efi_graphics_output_pixel_t *pixel;
     position_t phys;
     const int pxlstride = info->pixels_per_scan_line;
@@ -335,8 +404,9 @@ blt_pos_to_screen_pos(struct eg *eg, str
 
     position_to_phys(eg, pos, &phys);
 
-    if (info->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY) {
-        ;
+    if (info->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY || 1) {
+        hw_blt_pos_to_screen_pos(eg, bltbuf, bltpos, bltsz, pos);
+#if 0
     } else if (info->pixel_format == GRUB_EFI_PIXEL_BIT_MASK) {
         int y;
         grub_pixel_info_t *pinfo = &eg->pixel_info;
@@ -384,19 +454,24 @@ blt_pos_to_screen_pos(struct eg *eg, str
             }
             memmove(fb, raw_pixels, maxpixels * pinfo->depth_bytes);
         }
+#endif
     } else {
         int y;
+        grub_pixel_info_t *pinfo = &eg->pixel_info;
+        const int maxpixels =
+            MIN(info->horizontal_resolution - pos->x, bltsz->x);
+
+	//char *line = &fb[phys.y * bytestride + phys.x * sizeof(*pixel)];
         for (y = bltpos->y; y < bltpos->y + bltsz->y; y++, phys.y++) {
+	    char raw_pixels[maxpixels * sizeof(*pixel)];
             char *fb = (char *)(unsigned long)eg->output_intf->mode->frame_buffer_base;
-            char *line = &fb[phys.y * bytestride + phys.x * sizeof(*pixel)];
-            const int maxpixels =
-                MIN(info->horizontal_resolution - pos->x, bltsz->x);
             int x;
 
-            pixel = &bltbuf->pixbuf[y * bltbuf->width + bltpos->x];
+            pixel = (void *)&bltbuf->pixbuf[y * bltbuf->width + bltpos->x];
+            fb += phys.y * pinfo->line_length + phys.x * pinfo->depth_bytes;
 
             if (info->pixel_format == GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR) {
-                memmove(line, pixel, maxpixels * sizeof (*pixel));
+                memmove(raw_pixels, pixel, maxpixels * sizeof (*pixel));
                 continue;
             } else if (info->pixel_format==GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR) {
                 grub_efi_graphics_output_pixel_t shadow[maxpixels];
@@ -405,12 +480,45 @@ blt_pos_to_screen_pos(struct eg *eg, str
                     shadow[x].rgbr.green = pixel[x].bgrr.green;
                     shadow[x].rgbr.blue = pixel[x].bgrr.blue;
                 }
-                memmove(line, shadow, maxpixels * sizeof (*pixel));
-            }
+            
+                memmove(raw_pixels, shadow, maxpixels * sizeof (*pixel));
+            } else if (info->pixel_format == GRUB_EFI_PIXEL_BIT_MASK) {
+                for (x = 0; x < maxpixels; x++) {
+                    char depth_bytes = pinfo->depth_bytes;
+                    char *raw_pixel = raw_pixels + x * depth_bytes;
+
+                    int red, green, blue, color;
+                    char *colorp;
+
+#if 0
+                    red = pixel[x].bgrr.red & 0x3f;
+                    green = pixel[x].bgrr.green & 0x3f;
+                    blue = pixel[x].bgrr.blue & 0x3f;
+                    red = red * ((1 << pinfo->red_size) - 1) / 0x3f;
+                    green = green * ((1 << pinfo->green_size) - 1) / 0x3f;
+                    blue = blue * ((1 << pinfo->blue_size) - 1) / 0x3f;
+#else
+                    red = pixel[x].bgrr.red;
+                    green = pixel[x].bgrr.green;
+                    blue = pixel[x].bgrr.blue;
+
+                    red >>= 8 - pinfo->red_size;
+                    green >>= 8 - pinfo->green_size;
+                    blue >>= 8 - pinfo->blue_size;
+#endif
+
+                    color = (red << pinfo->red_pos) | 
+                            (green << pinfo->green_pos) |
+                            (blue << pinfo->blue_pos);
+                    colorp = (void *)&color;
+                    while (depth_bytes--)
+                        *raw_pixel++ = *colorp++;
+                }
+	    }
+	    memmove(fb, raw_pixels, maxpixels * pinfo->depth_bytes);
         }
     }
 }
-#endif
 
 static void
 blt_to_screen(struct eg *eg, struct bltbuf *bltbuf)
@@ -462,7 +570,7 @@ get_screen_size(struct graphics_backend 
     struct eg *eg = backend->priv;
     grub_efi_graphics_output_mode_information_t *info;
 
-    info = eg->modes[eg->graphics_mode]->info;
+    info = get_graphics_mode_info(eg);
 
     size->x = info->horizontal_resolution;
     size->y = info->vertical_resolution;
@@ -586,7 +694,7 @@ reset_screen_geometry(struct graphics_ba
     grub_efi_graphics_output_mode_information_t *info;
     position_t screensz;
 
-    info = eg->modes[eg->graphics_mode]->info;
+    info = get_graphics_mode_info(eg);
 
     if (xpm) {
         eg->screen_pos.x =
@@ -681,7 +789,7 @@ blank(struct graphics_backend *backend)
     grub_efi_uintn_t x, y, i, j;
     unsigned char r = 0 ,g = 0;
 
-    info = eg->modes[eg->graphics_mode]->info;
+    info = get_graphics_mode_info(eg);
     x = info->horizontal_resolution;
     y = info->vertical_resolution;
 
@@ -965,6 +1073,14 @@ setup_cga_palette(struct eg *eg)
     rgb_to_pixel(0xff,0xff,0xff, &eg->palette[16]); // 16 Also white ;)
 }
 
+static grub_efi_status_t
+set_video_mode(struct eg *eg, int mode)
+{
+	grub_efi_status_t efi_status;
+	efi_status = Call_Service_2(eg->output_intf->set_mode, eg->output_intf, mode);
+	return efi_status;
+}
+
 static void disable(struct graphics_backend *backend)
 {
     struct eg *eg;
@@ -979,7 +1095,7 @@ static void disable(struct graphics_back
 #if 0
     blank(backend);
 
-    set_video_mode(eg, &eg->text_mode);
+    set_video_mode(eg, eg->text_mode);
     grub_efi_set_text_mode(1);
 #endif
     eg->current_mode = TEXT;
@@ -1038,13 +1154,130 @@ fill_pixel_info (grub_pixel_info_t *pixe
   return 1;
 }
 
+/* 1 = prefer a
+ * 0 = prefer neither
+ * -1 = prefer b
+ */
+static int
+modecmp_helper(struct eg *eg, struct video_mode *amode, struct video_mode *bmode)
+{
+        grub_efi_graphics_output_mode_information_t *a = amode->info;
+        grub_efi_graphics_output_mode_information_t *b = bmode->info;
+
+        if (a != NULL && b == NULL)
+                return 1;
+        if (a == NULL && b == NULL)
+                return 0;
+        if (a == NULL && b != NULL)
+                return -1;
+
+#if 0
+	if (amode->number == eg->graphics_mode && bmode->number != eg->graphics_mode)
+		return 1;
+	if (amode->number == eg->graphics_mode && bmode->number == eg->graphics_mode)
+		return 0;
+	if (amode->number != eg->graphics_mode && bmode->number == eg->graphics_mode)
+		return -1;
+#endif
+
+
+	/* kernel doesn't deal with blt only modes, so prefer against them. */
+        if (a->pixel_format != GRUB_EFI_PIXEL_BLT_ONLY &&
+                        b->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY)
+                return 1;
+        if (b->pixel_format != GRUB_EFI_PIXEL_BLT_ONLY &&
+                        a->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY)
+                return -1;
+
+	/* XXX PJFIX there's something wrong with what we're passing to the
+	 * kernel for stride in the bgrr/rgbr modes, and I haven't figured out
+	 * just what yet, so for now, prefer bitmask modes.
+	 */
+	if (a->pixel_format == GRUB_EFI_PIXEL_BIT_MASK &&
+			b->pixel_format != GRUB_EFI_PIXEL_BIT_MASK)
+		return 1;
+	if (a->pixel_format != GRUB_EFI_PIXEL_BIT_MASK &&
+			b->pixel_format == GRUB_EFI_PIXEL_BIT_MASK)
+		return -1;
+
+        if (a->pixel_format == GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
+			b->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR)
+		return 1;
+        if (a->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
+			b->pixel_format == GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR)
+		return -1;
+
+        if (a->pixel_format == GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+			b->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR)
+		return 1;
+        if (a->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+			b->pixel_format == GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR)
+		return -1;
+
+        if (a->horizontal_resolution > b->horizontal_resolution &&
+                        a->vertical_resolution > b->vertical_resolution)
+                return 1;
+        if (a->horizontal_resolution < b->horizontal_resolution &&
+                        a->vertical_resolution < b->vertical_resolution)
+                return -1;
+        return 0;
+}
+
+static int
+modecmp(struct eg *eg, struct video_mode *amode, struct video_mode *bmode)
+{
+        int rc;
+#if 0
+        grub_efi_graphics_output_mode_information_t *a = amode->info;
+        grub_efi_graphics_output_mode_information_t *b = bmode->info;
+#endif
+        rc = modecmp_helper(eg, amode, bmode);
+#if 0
+        grub_printf("comparing nodes:\n");
+        print_mode_info(amode);
+        print_mode_info(bmode);
+        if (rc > 0)
+                grub_printf("result: a > b\n");
+        else if (rc < 0)
+                grub_printf("result: a < b\n");
+        else
+                grub_printf("result: a == b\n");
+
+        //dbgdelay(__FILE__, __LINE__);
+#endif
+        return rc;
+}
+
+static void
+modeswap(struct video_mode *amode, struct video_mode *bmode)
+{
+        struct video_mode tmp;
+
+        memcpy(&tmp, amode, sizeof (tmp));
+        memcpy(amode, bmode, sizeof (tmp));
+        memcpy(bmode, &tmp, sizeof(tmp));
+}
+
+static void
+sort_modes(struct eg *eg, int p, int r)
+{
+	struct video_mode **modes = eg->modes;
+        
+        int i, j;
+	for (i = 0; i < eg->max_mode; i++) {
+		for (j = i + 1; j < eg->max_mode; j++) {
+			if (modecmp(eg, modes[j], modes[i]) < 0)
+				modeswap(modes[j], modes[i]);
+		}
+	}
+}
+
 static int
 try_enable(struct graphics_backend *backend)
 {
     struct eg *eg = backend->priv;
     grub_efi_status_t efi_status;
     int i;
-    void *tmp_term = current_term;
 
     if (eg->text_mode == 0xffffffff) {
         grub_efi_set_text_mode(1);
@@ -1053,50 +1286,74 @@ try_enable(struct graphics_backend *back
 
     if (eg->graphics_mode == 0xffffffff) {
         grub_efi_graphics_output_mode_information_t *info;
-        grub_efi_graphics_output_mode_information_t *bestinfo;
-        int largest_mode = 0;
 
         if (!graphics_alloc_text_buf())
             return 0;
 
-	bestinfo = eg->modes[0]->info;
-        
+        grub_efi_set_text_mode(0);
         eg->graphics_mode = eg->output_intf->mode->mode;
+        grub_efi_set_text_mode(1);
+#if 0
+	dprintf("graphics mode is %d\n", eg->graphics_mode);
+	/* this is okay here because we haven't sorted yet.*/
+	print_mode_info(eg->modes[eg->graphics_mode]);
+	dprintf("text mode is %d\n", eg->text_mode);
+	print_mode_info(eg->modes[eg->text_mode]);
+#endif
 
-        for (i = 0; i < eg->max_mode; i++) {
+        sort_modes(eg, 0, eg->max_mode-1);
+
+#if 0
+        for (i = eg->max_mode - 1; i >= 0; i--)
+            print_mode_info(eg->modes[i]);
+	dbgdelay(__FILE__, __LINE__);
+#endif
+
+        for (i = eg->max_mode - 1; i >= 0; i--) {
             if (!eg->modes[i])
                 continue;
+
             info = eg->modes[i]->info;
 
-	    if (info->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+#if 0
+            if (info->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
                  info->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
                  info->pixel_format != GRUB_EFI_PIXEL_BIT_MASK) {
-                info = NULL;
                 continue;
             }
+#endif
 
-            if (info->horizontal_resolution > bestinfo->horizontal_resolution &&
-                    info->vertical_resolution > bestinfo->vertical_resolution) {
-                bestinfo = info;
-                largest_mode = i;
-                continue;
+            grub_efi_set_text_mode(0);
+            efi_status = set_video_mode(eg, eg->modes[i]->number);	    
+            if (efi_status == GRUB_EFI_SUCCESS) {
+#if 0
+                grub_efi_set_text_mode(1);
+	        dprintf("switched to mode %d successfully\n",
+		        eg->modes[i]->number);
+	        dbgdelay(__FILE__,__LINE__);
+                grub_efi_set_text_mode(0);
+#endif
+                eg->graphics_mode = eg->modes[i]->number;
+	        fill_pixel_info(&eg->pixel_info, info);
+                break;
+            } else {
+#if 0
+                set_video_mode(eg, eg->text_mode);
+                grub_efi_set_text_mode(1);
+		dprintf("return code was %d\n", efi_status);
+#endif
             }
         }
-        eg->graphics_mode = largest_mode;
-
-        info = eg->modes[eg->graphics_mode]->info;
-
-        grub_efi_set_text_mode(0);
-        efi_status = Call_Service_2(eg->output_intf->set_mode, eg->output_intf,
-                           eg->graphics_mode);
         if (efi_status != GRUB_EFI_SUCCESS) {
+#if 1
             grub_efi_set_text_mode(1);
+            set_video_mode(eg, eg->text_mode);
+#endif
             return 0;
         }
 
-        fill_pixel_info(&eg->pixel_info, eg->modes[eg->graphics_mode]->info);
     }
-    
+
     eg->current_mode = GRAPHICS;
     return 1;
 }
@@ -1137,7 +1394,7 @@ enable(struct graphics_backend *backend)
             eg->modes[i] = grub_malloc(sizeof eg->modes[0]);
             if (!eg->modes[i])
                 goto fail;
-            memset(eg->modes, '\0', sizeof (eg->modes[0]));
+            memset(eg->modes[i], '\0', sizeof (eg->modes[0]));
             eg->modes[i]->number = i;
 
             efi_status = Call_Service_4(eg->output_intf->query_mode,
@@ -1146,7 +1403,7 @@ enable(struct graphics_backend *backend)
             if (efi_status != GRUB_EFI_SUCCESS) {
                 grub_free(eg->modes[i]);
                 eg->modes[i] = NULL;
-                eg->max_mode = i;
+                //eg->max_mode = i;
                 break;
             }
         }

grub-0.97-relocatable-kernel-on-x86_64-uefi.patch:
 efimm.c               |   39 +++++++++++++++++++++++++++++++++++++++
 grub/efi/efi.h        |    1 +
 x86_64/loader/linux.c |   18 +++++++++++++++++-
 3 files changed, 57 insertions(+), 1 deletion(-)

Index: grub-0.97-relocatable-kernel-on-x86_64-uefi.patch
===================================================================
RCS file: /cvs/extras/rpms/grub/devel/grub-0.97-relocatable-kernel-on-x86_64-uefi.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- grub-0.97-relocatable-kernel-on-x86_64-uefi.patch	11 Aug 2009 15:29:50 -0000	1.1
+++ grub-0.97-relocatable-kernel-on-x86_64-uefi.patch	13 Nov 2009 18:58:29 -0000	1.2
@@ -1,22 +1,19 @@
-From 1ccd96dbe74f7dad8d57080c83b68de85f1fe466 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones at redhat.com>
-Date: Tue, 11 Aug 2009 11:26:17 -0400
-Subject: [PATCH] Dynamically choose load address for bzimage on 64-bit UEFI.
 
-Instead of loading the kernel at one meg, dynamically load it at an
-address that UEFI tells us is actually available.  Based on a patch from
-Masahiro Matsuya <mmatsuya at redhat.com>.
----
- efi/efimm.c               |   39 +++++++++++++++++++++++++++++++++++++++
- efi/grub/efi/efi.h        |    1 +
- efi/grub/x86_64/linux.h   |    1 -
- efi/x86_64/loader/linux.c |   13 ++++++++++++-
- 4 files changed, 52 insertions(+), 2 deletions(-)
+This patch fixes the problem that UEFI boot fains on systems that
+have the memory region starting at 1MB in use. 
+The strategy is as follows:
+
+ - Loading temporarily vmlinuz image to the address which AllocatePages()
+   function returned.
+ - After calling ExitBootServices() function, copy its reagion to the
+   address which params->hdr.code32_start points to.
 
-diff --git a/efi/efimm.c b/efi/efimm.c
-index d14b630..3b790d5 100644
---- a/efi/efimm.c
-+++ b/efi/efimm.c
+Signed-off-by: Taku Izumi <izumi.taku at jp.fujitsu.com>
+---
+Index: grub-0.97/efi/efimm.c
+===================================================================
+--- grub-0.97.orig/efi/efimm.c
++++ grub-0.97/efi/efimm.c
 @@ -78,6 +78,45 @@ grub_efi_free_pool (void *buffer)
    Call_Service_1(b->free_pool, buffer);
  }
@@ -63,11 +60,11 @@ index d14b630..3b790d5 100644
  /* Allocate pages. Return the pointer to the first of allocated pages.  */
  void *
  grub_efi_allocate_pages (grub_efi_physical_address_t address,
-diff --git a/efi/grub/efi/efi.h b/efi/grub/efi/efi.h
-index 5409911..59314bd 100644
---- a/efi/grub/efi/efi.h
-+++ b/efi/grub/efi/efi.h
-@@ -46,6 +46,7 @@ int grub_efi_get_text_mode(void);
+Index: grub-0.97/efi/grub/efi/efi.h
+===================================================================
+--- grub-0.97.orig/efi/grub/efi/efi.h
++++ grub-0.97/efi/grub/efi/efi.h
+@@ -45,6 +45,7 @@ int grub_efi_set_text_mode (int on);
  void grub_efi_stall (grub_efi_uintn_t microseconds);
  void *grub_efi_allocate_pool (grub_efi_uintn_t size);
  void grub_efi_free_pool (void *buffer);
@@ -75,31 +72,20 @@ index 5409911..59314bd 100644
  void *grub_efi_allocate_pages (grub_efi_physical_address_t address,
  			       grub_efi_uintn_t pages);
  void
-diff --git a/efi/grub/x86_64/linux.h b/efi/grub/x86_64/linux.h
-index 65af9ee..06e83d0 100644
---- a/efi/grub/x86_64/linux.h
-+++ b/efi/grub/x86_64/linux.h
-@@ -28,7 +28,6 @@
- #define GRUB_LINUX_BOOT_LOADER_TYPE	0x72
- #define GRUB_LINUX_HEAP_END_OFFSET	(0x9000 - 0x200)
- 
--#define GRUB_LINUX_BZIMAGE_ADDR		0x100000
- #define GRUB_LINUX_ZIMAGE_ADDR		0x10000
- #define GRUB_LINUX_OLD_REAL_MODE_ADDR	0x90000
- #define GRUB_LINUX_SETUP_STACK		0x9000
-diff --git a/efi/x86_64/loader/linux.c b/efi/x86_64/loader/linux.c
-index 542b0b0..cfa66b2 100644
---- a/efi/x86_64/loader/linux.c
-+++ b/efi/x86_64/loader/linux.c
-@@ -40,6 +40,7 @@
+Index: grub-0.97/efi/x86_64/loader/linux.c
+===================================================================
+--- grub-0.97.orig/efi/x86_64/loader/linux.c
++++ grub-0.97/efi/x86_64/loader/linux.c
+@@ -40,6 +40,8 @@
  static unsigned long linux_mem_size;
  static int loaded;
  static void *real_mode_mem;
 +static void *prot_mode_mem;
++static grub_size_t prot_kernel_size;
  static void *initrd_mem;
  static void *mmap_buf;
  static grub_efi_uintn_t real_mode_pages;
-@@ -143,6 +144,7 @@ allocate_pages (grub_size_t real_size, grub_size_t prot_size)
+@@ -143,6 +145,7 @@ allocate_pages (grub_size_t real_size, g
  
    /* Initialize the memory pointers with NULL for convenience.  */
    real_mode_mem = 0;
@@ -107,21 +93,41 @@ index 542b0b0..cfa66b2 100644
    mmap_buf = 0;
  
    /* Read the memory map temporarily, to find free space.  */
-@@ -205,6 +207,13 @@ allocate_pages (grub_size_t real_size, grub_size_t prot_size)
+@@ -205,6 +208,13 @@ allocate_pages (grub_size_t real_size, g
        goto fail;
      }
  
 +  grub_printf("Trying to allocate %u pages for VMLINUZ\n",
 +		(unsigned) prot_mode_pages);
 +  prot_mode_mem = grub_efi_allocate_anypages(prot_mode_pages);
++
 +  if (!prot_mode_mem)
 +	grub_fatal("Cannot allocate pages for VMLINUZ");
-+  
-+  
++    
    mmap_buf = grub_efi_allocate_pages (0, mmap_pages);
    if (! mmap_buf)
      {
-@@ -501,9 +510,11 @@ grub_load_linux (char *kernel, char *arg)
+@@ -259,6 +269,11 @@ big_linux_boot (void)
+     grub_fatal ("cannot exit boot services");
+ 
+   /* Note that no boot services are available from here.  */
++
++  /* copy vmlinuz image to hdr.code32_start */
++  memcpy ((char *)(unsigned long)(params->hdr.code32_start), (char *)prot_mode_mem,
++	  prot_kernel_size);
++  /* copy switch image */
+   memcpy ((void *) 0x700, switch_image, switch_size);
+ 
+   lh = &params->hdr;
+@@ -370,6 +385,7 @@ grub_load_linux (char *kernel, char *arg
+ 
+   real_size = 0x1000 + grub_strlen(arg);
+   prot_size = grub_file_size () - (setup_sects << SECTOR_BITS) - SECTOR_SIZE;
++  prot_kernel_size = prot_size;
+ 
+   if (! allocate_pages (real_size, prot_size))
+     goto fail;
+@@ -501,7 +517,7 @@ grub_load_linux (char *kernel, char *arg
  
    grub_seek ((setup_sects << SECTOR_BITS) + SECTOR_SIZE);
    len = prot_size;
@@ -129,11 +135,4 @@ index 542b0b0..cfa66b2 100644
 +  if (grub_read ((char *)prot_mode_mem, len) != len)
      grub_printf ("Couldn't read file");
  
-+  params->hdr.code32_start = (long)prot_mode_mem;
-+
    if (errnum == ERR_NONE)
-     {
-       loaded = 1;
--- 
-1.6.4
-


Index: grub.spec
===================================================================
RCS file: /cvs/extras/rpms/grub/devel/grub.spec,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -p -r1.109 -r1.110
--- grub.spec	13 Nov 2009 15:28:56 -0000	1.109
+++ grub.spec	13 Nov 2009 18:58:29 -0000	1.110
@@ -1,6 +1,6 @@
 Name: grub
 Version: 0.97
-Release: 60%{?dist}
+Release: 61%{?dist}
 Summary: Grand Unified Boot Loader.
 Group: System Environment/Base
 License: GPLv2+
@@ -49,6 +49,8 @@ Patch20: grub-0.97-partitionable-md.patc
 Patch21: grub-0.97-relocatable-kernel-on-x86_64-uefi.patch
 Patch22: grub-0.97-use-gnuefi.patch
 Patch23: grub-0.97-gate-a20.patch
+Patch24: grub-0.97-efi-graphics-mode-selection.patch
+Patch25: grub-silent.patch
 
 %description
 GRUB (Grand Unified Boot Loader) is an experimental boot loader
@@ -82,6 +84,8 @@ systems.
 %patch21 -p1
 %patch22 -p1
 %patch23 -p1
+%patch24 -p1
+%patch25 -p1
 
 %build
 autoreconf
@@ -143,9 +147,13 @@ fi
 %{_datadir}/grub
 
 %changelog
-* Fri Nov 13 2009 Matthew Garrett <mjg at redhat.com> - 0.97-61
+* Fri Nov 13 2009 Peter Jones <pjones at redhat.com> - 0.97-61
+- Update relocatable kernel support for UEFI/x86_64 .
+  Related: rhbz #476230
 - grub-0.97-gate-a20.patch: Patch from Suse. Make really, really sure that
-  A20 is behaving itself.
+  A20 is behaving itself. (mjg)
+- add "silent" option (mjg)
+- Rework EFI Graphics Output Protocol mode selection.
 
 * Wed Sep 16 2009 Peter Jones <pjones at redhat.com> - 0.97-60
 - Fix a typo introduced in grub-fedora-9.patch that may effect UEFI




More information about the scm-commits mailing list