[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