📄 vesafb.c
字号:
palette[regno].red = red; palette[regno].green = green; palette[regno].blue = blue; switch (video_bpp) {#ifdef FBCON_HAS_CFB8 case 8: vesa_setpalette(regno,red,green,blue); break;#endif#ifdef FBCON_HAS_CFB16 case 15: case 16: if (vesafb_defined.red.offset == 10) { /* 1:5:5:5 */ fbcon_cmap.cfb16[regno] = ((red & 0xf800) >> 1) | ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); } else { /* 0:5:6:5 */ fbcon_cmap.cfb16[regno] = ((red & 0xf800) ) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); } break;#endif#ifdef FBCON_HAS_CFB24 case 24: red >>= 8; green >>= 8; blue >>= 8; fbcon_cmap.cfb24[regno] = (red << vesafb_defined.red.offset) | (green << vesafb_defined.green.offset) | (blue << vesafb_defined.blue.offset); break;#endif#ifdef FBCON_HAS_CFB32 case 32: red >>= 8; green >>= 8; blue >>= 8; fbcon_cmap.cfb32[regno] = (red << vesafb_defined.red.offset) | (green << vesafb_defined.green.offset) | (blue << vesafb_defined.blue.offset); break;#endif } return 0;}static void do_install_cmap(int con, struct fb_info *info){ if (con != currcon) return; if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, 1, vesa_setcolreg, info); else fb_set_cmap(fb_default_cmap(video_cmap_len), 1, vesa_setcolreg, info);}static int vesafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ if (con == currcon) /* current console? */ return fb_get_cmap(cmap, kspc, vesa_getcolreg, info); else if (fb_display[con].cmap.len) /* non default colormap? */ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); else fb_copy_cmap(fb_default_cmap(video_cmap_len), cmap, kspc ? 0 : 2); return 0;}static int vesafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ int err; if (!fb_display[con].cmap.len) { /* no colormap allocated? */ err = fb_alloc_cmap(&fb_display[con].cmap,video_cmap_len,0); if (err) return err; } if (con == currcon) /* current console? */ return fb_set_cmap(cmap, kspc, vesa_setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0;}static struct fb_ops vesafb_ops = { owner: THIS_MODULE, fb_get_fix: vesafb_get_fix, fb_get_var: vesafb_get_var, fb_set_var: vesafb_set_var, fb_get_cmap: vesafb_get_cmap, fb_set_cmap: vesafb_set_cmap, fb_pan_display: vesafb_pan_display,};int __init vesafb_setup(char *options){ char *this_opt; fb_info.fontname[0] = '\0'; if (!options || !*options) return 0; while ((this_opt = strsep(&options, ",")) != NULL) { if (!*this_opt) continue; if (! strcmp(this_opt, "inverse")) inverse=1; else if (! strcmp(this_opt, "redraw")) ypan=0; else if (! strcmp(this_opt, "ypan")) ypan=1; else if (! strcmp(this_opt, "ywrap")) ypan=2; else if (! strcmp(this_opt, "vgapal")) pmi_setpal=0; else if (! strcmp(this_opt, "pmipal")) pmi_setpal=1; else if (! strcmp(this_opt, "mtrr")) mtrr=1; /* checks for vram boot option */ else if (! strncmp(this_opt, "vram:", 5)) vram = simple_strtoul(this_opt+5, NULL, 0); else if (!strncmp(this_opt, "font:", 5)) strcpy(fb_info.fontname, this_opt+5); } return 0;}static int vesafb_switch(int con, struct fb_info *info){ /* Do we have to save the colormap? */ if (fb_display[currcon].cmap.len) fb_get_cmap(&fb_display[currcon].cmap, 1, vesa_getcolreg, info); currcon = con; /* Install new colormap */ do_install_cmap(con, info); vesafb_update_var(con,info); return 1;}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static void vesafb_blank(int blank, struct fb_info *info){ /* Not supported */}int __init vesafb_init(void){ int i,j; if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return -ENXIO; video_base = screen_info.lfb_base; video_bpp = screen_info.lfb_depth; if (15 == video_bpp) video_bpp = 16; video_width = screen_info.lfb_width; video_height = screen_info.lfb_height; video_linelength = screen_info.lfb_linelength; /* remap memory according to videomode, multiply by 2 to get space for doublebuffering */ video_size = screen_info.lfb_width * screen_info.lfb_height * video_bpp / 8 * 2; /* check that we don't remap more memory than old cards have */ if (video_size > screen_info.lfb_size * 65536) video_size = screen_info.lfb_size * 65536; /* FIXME: Should we clip against declared size for banked devices ? */ /* sets video_size according to vram boot option */ if (vram && vram * 1024 * 1024 != video_size) video_size = vram * 1024 * 1024; video_visual = (video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;#ifndef __i386__ screen_info.vesapm_seg = 0;#endif if (!request_mem_region(video_base, video_size, "vesafb")) { printk(KERN_WARNING "vesafb: abort, cannot reserve video memory at 0x%lx\n", video_base); /* We cannot make this fatal. Sometimes this comes from magic spaces our resource handlers simply don't know about */ } video_vbase = ioremap(video_base, video_size); if (!video_vbase) { release_mem_region(video_base, video_size); printk(KERN_ERR "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", video_size, video_base); return -EIO; } printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", video_base, video_vbase, video_size/1024); printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", video_width, video_height, video_bpp, video_linelength, screen_info.pages); if (screen_info.vesapm_seg) { printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", screen_info.vesapm_seg,screen_info.vesapm_off); } if (screen_info.vesapm_seg < 0xc000) ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */ if (ypan || pmi_setpal) { pmi_base = (unsigned short*)bus_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); pmi_start = (void*)((char*)pmi_base + pmi_base[1]); pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); if (pmi_base[3]) { printk(KERN_INFO "vesafb: pmi: ports = "); for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) printk("%x ",pmi_base[i]); printk("\n"); if (pmi_base[i] != 0xffff) { /* * memory areas not supported (yet?) * * Rules are: we have to set up a descriptor for the requested * memory area and pass it in the ES register to the BIOS function. */ printk(KERN_INFO "vesafb: can't handle memory requests, pmi disabled\n"); ypan = pmi_setpal = 0; } } } vesafb_defined.xres=video_width; vesafb_defined.yres=video_height; vesafb_defined.xres_virtual=video_width; vesafb_defined.yres_virtual=video_size / video_linelength; vesafb_defined.bits_per_pixel=video_bpp; if (ypan && vesafb_defined.yres_virtual > video_height) { printk(KERN_INFO "vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n", (ypan > 1) ? "ywrap" : "ypan",vesafb_defined.yres_virtual); } else { printk(KERN_INFO "vesafb: scrolling: redraw\n"); vesafb_defined.yres_virtual = video_height; ypan = 0; } video_height_virtual = vesafb_defined.yres_virtual; /* some dummy values for timing to make fbset happy */ vesafb_defined.pixclock = 10000000 / video_width * 1000 / video_height; vesafb_defined.left_margin = (video_width / 8) & 0xf8; vesafb_defined.right_margin = 32; vesafb_defined.upper_margin = 16; vesafb_defined.lower_margin = 4; vesafb_defined.hsync_len = (video_width / 8) & 0xf8; vesafb_defined.vsync_len = 4; if (video_bpp > 8) { vesafb_defined.red.offset = screen_info.red_pos; vesafb_defined.red.length = screen_info.red_size; vesafb_defined.green.offset = screen_info.green_pos; vesafb_defined.green.length = screen_info.green_size; vesafb_defined.blue.offset = screen_info.blue_pos; vesafb_defined.blue.length = screen_info.blue_size; vesafb_defined.transp.offset = screen_info.rsvd_pos; vesafb_defined.transp.length = screen_info.rsvd_size; printk(KERN_INFO "vesafb: directcolor: " "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", screen_info.rsvd_size, screen_info.red_size, screen_info.green_size, screen_info.blue_size, screen_info.rsvd_pos, screen_info.red_pos, screen_info.green_pos, screen_info.blue_pos); video_cmap_len = 16; } else { vesafb_defined.red.length = 6; vesafb_defined.green.length = 6; vesafb_defined.blue.length = 6; for(i = 0; i < 16; i++) { j = color_table[i]; palette[i].red = default_red[j]; palette[i].green = default_grn[j]; palette[i].blue = default_blu[j]; } video_cmap_len = 256; } /* request failure does not faze us, as vgacon probably has this * region already (FIXME) */ request_region(0x3c0, 32, "vesafb"); if (mtrr) { int temp_size = video_size; /* Find the largest power-of-two */ while (temp_size & (temp_size - 1)) temp_size &= (temp_size - 1); /* Try and find a power of two to add */ while (temp_size && mtrr_add(video_base, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { temp_size >>= 1; } } strcpy(fb_info.modename, "VESA VGA"); fb_info.changevar = NULL; fb_info.node = -1; fb_info.fbops = &vesafb_ops; fb_info.disp=&disp; fb_info.switch_con=&vesafb_switch; fb_info.updatevar=&vesafb_update_var; fb_info.blank=&vesafb_blank; fb_info.flags=FBINFO_FLAG_DEFAULT; vesafb_set_disp(-1); if (register_framebuffer(&fb_info)<0) return -EINVAL; printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), fb_info.modename); return 0;}/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -