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. My first mainline submitted patch so be gentle :). Scott diff -Naur 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,7 @@ { struct fb_fix_screeninfo fix; struct fb_var_screeninfo var; - static char *magic = "VESA VGA"; + /*static char *magic = "VESA VGA";*/ int fd; fd = open("/dev/fb0", O_RDONLY); @@ -115,11 +115,23 @@ goto out; if (-1 == ioctl(fd, FBIOGET_VSCREENINFO, &var)) goto out; + /* if (0 != strcmp(fix.id, magic)) goto out; + */ + 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->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;