diff options
author | Gerd Hoffmann <kraxel@suse.de> | 2006-03-10 14:47:52 +0100 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2006-07-27 12:08:42 -0600 |
commit | 529ad18980e297efc6ac2839c82afc24eccdcd1f (patch) | |
tree | 7011a3fc941576d1e36382754f06af0b224f75a8 /kexec/arch/i386/x86-linux-setup.c | |
parent | 6dcc69c0eb91b643f77c042db31ba23b4a67f1d6 (diff) |
kexec & vesafb
Hi,
Attached is a patch which fills real_mode info correctly in case of
vesafb being active, so the new kernel comes up with a working
framebuffer console.
cheers,
Gerd
Diffstat (limited to 'kexec/arch/i386/x86-linux-setup.c')
-rw-r--r-- | kexec/arch/i386/x86-linux-setup.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index 14acf8e..5701b27 100644 --- a/kexec/arch/i386/x86-linux-setup.c +++ b/kexec/arch/i386/x86-linux-setup.c @@ -24,6 +24,8 @@ #include <sys/stat.h> #include <sys/mman.h> #include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/fb.h> #include <unistd.h> #include <x86/x86-linux.h> #include "../../kexec.h" @@ -94,6 +96,57 @@ void setup_linux_bootloader_parameters( cmdline_ptr[cmdline_len - 1] = '\0'; } +int setup_linux_vesafb(struct x86_linux_param_header *real_mode) +{ + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + static char *magic = "VESA VGA"; + int fd; + + fd = open("/dev/fb0", O_RDONLY); + if (-1 == fd) + return -1; + + if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, &fix)) + goto out; + if (-1 == ioctl(fd, FBIOGET_VSCREENINFO, &var)) + goto out; + if (0 != strcmp(fix.id, magic)) + 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; + real_mode->lfb_base = fix.smem_start; + real_mode->lfb_linelength = fix.line_length; + real_mode->vesapm_seg = 0; + + /* FIXME: better get size from /proc/iomem */ + real_mode->lfb_size = (fix.smem_len + 65535) / 65536; + real_mode->pages = (fix.smem_len + 4095) / 4096; + + if (var.bits_per_pixel > 8) { + real_mode->red_pos = var.red.offset; + real_mode->red_size = var.red.length; + real_mode->green_pos = var.green.offset; + real_mode->green_size = var.green.length; + real_mode->blue_pos = var.blue.offset; + real_mode->blue_size = var.blue.length; + real_mode->rsvd_pos = var.transp.offset; + real_mode->rsvd_size = var.transp.length; + } + fprintf(stderr, "%s: %dx%dx%d @ %lx +%x\n", __FUNCTION__, + var.xres, var.yres, var.bits_per_pixel, + fix.smem_start, fix.smem_len); + return 0; + + out: + close(fd); + return -1; +} + void setup_linux_system_parameters(struct x86_linux_param_header *real_mode, unsigned long kexec_flags) { @@ -111,6 +164,7 @@ void setup_linux_system_parameters(struct x86_linux_param_header *real_mode, real_mode->orig_video_ega_bx = 0; real_mode->orig_video_isVGA = 1; real_mode->orig_video_points = 16; + setup_linux_vesafb(real_mode); /* Fill in the memsize later */ real_mode->ext_mem_k = 0; |