[PATCH] kexec: fix i386 EFI boot using efifb

Scott D. Davilla davilla at 4pi.com
Wed Mar 5 09:57:17 EST 2008


Problem:
	kexec fails under i386 EFI boot for hardware that does not 
have a VGA bios or PC bios present. The EFI bootloader properly set 
the initial screen_info boot params but kexec assumes an 
orig_video_isVGA type of 1. This causes the kexec'd kernel assume the 
presence of both VGA bios and normal PC BIOS and starts probing which 
then panics somewhere I can't see because I have no console output 
nor serial ports.

Solution:
	For EFI, efifb is a linear VGA framebuffer and can handle the 
kexec kernel switch, kexec just has to setup the kernel boot params 
properly. The below patch fixes this issue and allow a i386 EFI 
booted kernel with no VGA bios/PC bios to kexec to another kernel.

Questions:
	Why is kexec assuming i386 x86 == VGA bios in the first 
place. The existing kernel has a perfectly good screen_info stucture 
that is an exported symbol by the kernel and could be accessed by 
kexec. Since kexec is just pretending to be a boot loader, why does 
it ignore information that the real bootloader (which knows a lot 
more about the hardware) has passed? The below patch just hacks in a 
trap for efifb and will fail in the future as other x86 hardware 
without VGA bios/PC bios become available.

diff -rup 
kexec-tools-testing-20080227-org/kexec/arch/i386/x86-linux-setup.c 
kexec-tools-testing-20080227/kexec/arch/i386/x86-linux-setup.c
--- kexec-tools-testing-20080227-org/kexec/arch/i386/x86-linux-setup.c
+++ kexec-tools-testing-20080227/kexec/arch/i386/x86-linux-setup.c
@@ -104,7 +104,6 @@ int setup_linux_vesafb(struct x86_linux_
{
	struct fb_fix_screeninfo fix;
	struct fb_var_screeninfo var;
-	static char *magic = "VESA VGA";
	int fd;

	fd = open("/dev/fb0", O_RDONLY);
@@ -115,11 +114,18 @@ int setup_linux_vesafb(struct x86_linux_
		goto out;
	if (-1 == ioctl(fd, FBIOGET_VSCREENINFO, &var))
		goto out;
-	if (0 != strcmp(fix.id, magic))
+	if (0 == strcmp(fix.id, "VESA VGA")) {
+		/* VIDEO_TYPE_VLFB */
+		real_mode->orig_video_isVGA = 0x23;
+	} else if (0 == strcmp(fix.id, "EFI VGA")) {
+		/* VIDEO_TYPE_EFI */
+		real_mode->orig_video_isVGA = 0x70;
+	} else {
+		/* cannot handle and other types */
		goto out;
+	}
	close(fd);

-	real_mode->orig_video_isVGA = 0x23 /* VIDEO_TYPE_VLFB */;
	real_mode->lfb_width      = var.xres;
	real_mode->lfb_height     = var.yres;
	real_mode->lfb_depth      = var.bits_per_pixel;


Signed-off-by: Scott D Davilla <davilla at 4pi.com>



More information about the kexec mailing list