From 060eee589dd1499465ec8dae099824e81331b51a Mon Sep 17 00:00:00 2001 From: Dave Young Date: Sun, 28 Jan 2018 13:52:31 +0800 Subject: x86: use old screen_info if needed With modern drm/kms graphic driver kexec-tools does not setup screen_info correctly so one will only see screen output after those drm drivers reinitializing after rebooting. Copying the old screen info from original boot_params will help during my test, although it could not work for some potential cases, but it is not worse than before. This has been used in the kernel kexec_file_load. Signed-off-by: Dave Young Signed-off-by: Simon Horman --- kexec/arch/i386/x86-linux-setup.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index c75adaa..6c7d260 100644 --- a/kexec/arch/i386/x86-linux-setup.c +++ b/kexec/arch/i386/x86-linux-setup.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -122,7 +123,8 @@ void setup_linux_bootloader_parameters_high( cmdline_ptr[cmdline_len - 1] = '\0'; } -int setup_linux_vesafb(struct x86_linux_param_header *real_mode) +static int get_bootparam(void *buf, off_t offset, size_t size); +static int setup_linux_vesafb(struct x86_linux_param_header *real_mode) { struct fb_fix_screeninfo fix; struct fb_var_screeninfo var; @@ -143,8 +145,13 @@ int setup_linux_vesafb(struct x86_linux_param_header *real_mode) /* VIDEO_TYPE_EFI */ real_mode->orig_video_isVGA = 0x70; } else { - /* cannot handle and other types */ - goto out; + int err; + off_t offset = offsetof(typeof(*real_mode), orig_video_isVGA); + + /* blindly try old boot time video type */ + err = get_bootparam(&real_mode->orig_video_isVGA, offset, 1); + if (err) + goto out; } close(fd); @@ -826,6 +833,8 @@ out: void setup_linux_system_parameters(struct kexec_info *info, struct x86_linux_param_header *real_mode) { + int err; + /* get subarch from running kernel */ setup_subarch(real_mode); if (bzImage_support_efi_boot && !arch_options.noefi) @@ -841,8 +850,22 @@ void setup_linux_system_parameters(struct kexec_info *info, real_mode->orig_video_ega_bx = 0; real_mode->orig_video_isVGA = 1; real_mode->orig_video_points = 16; - setup_linux_vesafb(real_mode); + /* setup vesa fb if possible, or just use original screen_info */ + err = setup_linux_vesafb(real_mode); + if (err) { + uint16_t cl_magic, cl_offset; + + /* save and restore the old cmdline param if needed */ + cl_magic = real_mode->cl_magic; + cl_offset = real_mode->cl_offset; + + err = get_bootparam(real_mode, 0, sizeof(struct screen_info)); + if (!err) { + real_mode->cl_magic = cl_magic; + real_mode->cl_offset = cl_offset; + } + } /* Fill in the memsize later */ real_mode->ext_mem_k = 0; real_mode->alt_mem_k = 0; -- cgit