Messages in this thread Patch in this message |  | | Subject | [PATCH v2.4.x] Yet Another Boot Logo | Date | Tue, 3 Oct 2000 21:49:50 -0400 (EDT) | From | Jason McMullan <> |
| |
This kernel patch will allow you to have a full-screen boot logo in any FBcon supported video mode, except for VGA text mode. After applying the patch, you simply need to answer `Y' to `Custom boot logo' under the Framebuffer Support options. Then, place your custom boot_logo.ppm into linux/Documentation/boot_logo.ppm
When you recompile your kernel, the boot_logo.ppm file will be reconstructed into a 214 color, 16 color, and 2 color B&W include file in linux/drivers/video/boot_logo.h
When you boot into the logo-enabled kernel, the logo will be automatically centered on your framebuffer, and you will have 2 lines of kernel/init status at the bottom of your screen. Like the std. ``penguin'' logo, your custom logo will be repeated horizontally for however many processors your have on your system, or however many logos will fit - whichever is smaller.
To remove the logo from the screen, simply switch away from, them back to, the original boot-up VT.
16 bit color seems buggy color-wise (pallette issue?) at this time.
Comments, suggestions, patches, etc. are welcome.
diff --new-file -u -r linux-2.4.x/Documentation/Configure.help linux-2.4.x-logo/Documentation/Configure.help --- linux-2.4.x/Documentation/Configure.help Wed Aug 30 12:57:37 2000 +++ linux-2.4.x-logo/Documentation/Configure.help Sat Sep 23 20:12:50 2000 @@ -3052,6 +3052,21 @@ running kernel whenever you want), say M here and read Documentation/modules.txt. The module will be called vga16fb.o. +Customizable Boot Logo for graphics modes +CONFIG_FBCON_LOGO_BOOT + This allows you to change the boot logo from the default + `penguin' bootup. If you enable this option, make sure that + the PNM utilities and development headers/libraries are installed. + (aka libgr and libgr-devel). + + Place your custom logo as a PPM file in the Documentation directory: + + /usr/src/linux/Documentation/boot_logo.ppm + + When you recompile your kernel and fbcon is enabled in a graphics + mode (ie anything but VGA text), your logo will be centered and + there will be 2 lines for boot messages. + Select other compiled-in fonts CONFIG_FBCON_FONTS Say Y here if you would like to use fonts other than the default diff --new-file -u -r linux-2.4.x/drivers/video/Config.in linux-2.4.x-logo/drivers/video/Config.in --- linux-2.4.x/drivers/video/Config.in Mon Aug 14 09:04:25 2000 +++ linux-2.4.x-logo/drivers/video/Config.in Sat Sep 23 19:44:52 2000 @@ -159,6 +159,7 @@ tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL fi + bool ' Custom boot splash screen (graphics mode only)?' CONFIG_FBCON_LOGO_BOOT bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then tristate ' Monochrome support' CONFIG_FBCON_MFB diff --new-file -u -r linux-2.4.x/drivers/video/Makefile linux-2.4.x-logo/drivers/video/Makefile --- linux-2.4.x/drivers/video/Makefile Mon Aug 14 09:04:25 2000 +++ linux-2.4.x-logo/drivers/video/Makefile Sat Sep 23 20:14:48 2000 @@ -160,7 +160,7 @@ include $(TOPDIR)/Rules.make clean: - rm -f core *.o *.a *.s + rm -f core *.o *.a *.s boot_logo.h ../conmakehash: ../conmakehash.c $(HOSTCC) $(HOSTCFLAGS) -o ../conmakehash ../conmakehash.c @@ -171,3 +171,14 @@ -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > promcon_tbl.c promcon_tbl.o: promcon_tbl.c $(TOPDIR)/include/linux/types.h + +ifeq ($(CONFIG_FBCON_LOGO_BOOT),y) +fbcon.o: boot_logo.h + +boot_logo.h: $(TOPDIR)/Documentation/boot_logo.ppm + $(MAKE) -C $(TOPDIR)/scripts ppmtolinuxlogo + ppmquant 214 $(TOPDIR)/Documentation/boot_logo.ppm | $(TOPDIR)/scripts/ppmtolinuxlogo >boot_logo.h + ppmquant 16 $(TOPDIR)/Documentation/boot_logo.ppm | $(TOPDIR)/scripts/ppmtolinuxlogo -16 >>boot_logo.h + ppmquant 2 $(TOPDIR)/Documentation/boot_logo.ppm | $(TOPDIR)/scripts/ppmtolinuxlogo -bw >>boot_logo.h +endif + diff --new-file -u -r linux-2.4.x/drivers/video/fbcon.c linux-2.4.x-logo/drivers/video/fbcon.c --- linux-2.4.x/drivers/video/fbcon.c Mon Jul 24 21:24:26 2000 +++ linux-2.4.x-logo/drivers/video/fbcon.c Sat Sep 23 20:03:04 2000 @@ -94,9 +94,12 @@ #ifdef CONFIG_FBCON_VGA_PLANES #include <asm/io.h> #endif +#ifndef CONFIG_FBCON_LOGO_BOOT #define INCLUDE_LINUX_LOGO_DATA +#endif #include <asm/linux_logo.h> + #include <video/fbcon.h> #include <video/fbcon-mac.h> /* for 6x11 font on mac */ #include <video/font.h> @@ -107,8 +110,14 @@ # define DPRINTK(fmt, args...) #endif -#define LOGO_H 80 -#define LOGO_W 80 +#ifndef CONFIG_FBCON_LOGO_BOOT +#define LOGO_W 80 +#define LOGO_H 80 +#else +#define INCLUDE_LINUX_LOGO16 +#define INCLUDE_LINUX_LOGOBW +#include "boot_logo.h" +#endif #define LOGO_LINE (LOGO_W/8) struct display fb_display[MAX_NR_CONSOLES]; @@ -608,8 +617,12 @@ /* Need to make room for the logo */ int cnt; int step; - + +#ifdef CONFIG_FBCON_LOGO_BOOT + logo_lines = nr_rows - 2; +#else logo_lines = (LOGO_H + fontheight(p) - 1) / fontheight(p); +#endif q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows); step = logo_lines * old_cols; for (r = q - logo_lines * old_cols; r < q; r++) @@ -638,10 +651,15 @@ conp->vc_pos += logo_lines * conp->vc_size_row; } } + if (conp->vc_y < logo_lines) { + conp->vc_y=logo_lines; + conp->vc_pos=logo_lines*conp->vc_size_row; + } scr_memsetw((unsigned short *)conp->vc_origin, conp->vc_video_erase_char, conp->vc_size_row * logo_lines); } + /* * ++guenther: console.c:vc_allocate() relies on initializing @@ -2054,6 +2072,7 @@ unsigned char *dst, *src; int i, j, n, x1, y1, x; int logo_depth, done = 0; + int num_logos,x_offset,y_offset; /* Return if the frame buffer is not mapped */ if (!fb) @@ -2114,8 +2133,17 @@ if (p->fb_info->fbops->fb_rasterimg) p->fb_info->fbops->fb_rasterimg(p->fb_info, 1); - for (x = 0; x < smp_num_cpus * (LOGO_W + 8) && - x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) { + num_logos=(p->var.xres/(LOGO_W+8)); + num_logos=(num_logos < smp_num_cpus) ? num_logos : smp_num_cpus; +#ifdef CONFIG_FBCON_LOGO_BOOT + y_offset=(p->var.yres-LOGO_H)/2; + x_offset=(p->var.xres-(LOGO_W+8)*num_logos)/2; +#else + y_offset=0; + x_offset=0; +#endif + + for (x = x_offset; num_logos > 0; x += (LOGO_W + 8), num_logos--) { #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \ defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS) @@ -2134,7 +2162,7 @@ src = logo; bdepth = depth/8; for( y1 = 0; y1 < LOGO_H; y1++ ) { - dst = fb + y1*line + x*bdepth; + dst = fb + (y1+y_offset)*line + x*bdepth; for( x1 = 0; x1 < LOGO_W; x1++, src++ ) { val = (*src << redshift) | (*src << greenshift) | @@ -2160,7 +2188,7 @@ src = linux_logo16; bdepth = (depth+7)/8; for( y1 = 0; y1 < LOGO_H; y1++ ) { - dst = fb + y1*line + x*bdepth; + dst = fb + (y1+y_offset)*line + x*bdepth; for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) { pix = (*src >> 4) | 0x10; /* upper nibble */ val = (pix << redshift) | @@ -2208,7 +2236,7 @@ src = logo; for( y1 = 0; y1 < LOGO_H; y1++ ) { - dst = fb + y1*line + x*bdepth; + dst = fb + (y1+y_offset)*line + x*bdepth; for( x1 = 0; x1 < LOGO_W; x1++, src++ ) { val = safe_shift((linux_logo_red[*src-32] & redmask), redshift) | safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) | @@ -2234,7 +2262,7 @@ if (depth == 4 && p->type == FB_TYPE_PACKED_PIXELS) { src = logo; for( y1 = 0; y1 < LOGO_H; y1++) { - dst = fb + y1*line + x/2; + dst = fb + (y1+y_offset)*line + x/2; for( x1 = 0; x1 < LOGO_W/2; x1++) { u8 q = *src++; q = (q << 4) | (q >> 4); @@ -2250,7 +2278,7 @@ src = logo; for( y1 = 0; y1 < LOGO_H; y1++ ) { - dst = fb + y1*line + x; + dst = fb + (y1+y_offset)*line + x; for( x1 = 0; x1 < LOGO_W; x1++ ) fb_writeb (*src++, dst++); } @@ -2283,7 +2311,7 @@ src = logo; for( y1 = 0; y1 < LOGO_H; y1++ ) { for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) { - dst = fb + y1*line + MAP_X(x/8+x1); + dst = fb + (y1+y_offset)*line + MAP_X(x/8+x1); for( bit = 0; bit < logo_depth; bit++ ) { val = 0; for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) { @@ -2302,7 +2330,7 @@ if (depth > logo_depth) { for( y1 = 0; y1 < LOGO_H; y1++ ) { for( x1 = 0; x1 < LOGO_LINE; x1++ ) { - dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane; + dst = fb + (y1+y_offset)*line + MAP_X(x/8+x1) + logo_depth*plane; for( i = logo_depth; i < depth; i++, dst += plane ) *dst = (i == logo_depth && logo_depth == 4) ? 0xff : 0x00; @@ -2329,9 +2357,9 @@ for( y1 = 0; y1 < LOGO_H; y1++ ) { src = logo + y1*LOGO_LINE; if (is_hga) - dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8; + dst = fb + ((y1+y_offset)%4)*8192 + ((y1+y_offset)>>2)*line + x/8; else - dst = fb + y1*line + x/8; + dst = fb + (y1+y_offset)*line + x/8; for( x1 = 0; x1 < LOGO_LINE; ++x1 ) fb_writeb(fb_readb(src++) ^ inverse, dst++); } @@ -2347,7 +2375,7 @@ src = logo; for (y1 = 0; y1 < LOGO_H; y1++) { for (x1 = 0; x1 < LOGO_W / 2; x1++) { - dst = fb + y1*line + x1/4 + x/8; + dst = fb + (y1+y_offset)*line + x1/4 + x/8; outb_p(0,0x3ce); outb_p(*src >> 4,0x3cf); diff --new-file -u -r linux-2.4.x/scripts/Makefile linux-2.4.x-logo/scripts/Makefile --- linux-2.4.x/scripts/Makefile Thu Mar 16 14:27:17 2000 +++ linux-2.4.x-logo/scripts/Makefile Sat Sep 23 20:13:23 2000 @@ -39,7 +39,10 @@ docproc: docproc.o ${HOSTCC} -o docproc docproc.o +ppmtolinuxlogo: ppmtolinuxlogo.o + ${HOSTCC} -o ppmtolinuxlogo ppmtolinuxlogo.o -lpnm -lppm -lpgm -lpbm + clean: - rm -f *~ kconfig.tk *.o tkparse mkdep split-include docproc + rm -f *~ kconfig.tk *.o tkparse mkdep split-include docproc ppmtolinuxlogo include $(TOPDIR)/Rules.make diff --new-file -u -r linux-2.4.x/scripts/ppmtolinuxlogo.c linux-2.4.x-logo/scripts/ppmtolinuxlogo.c --- linux-2.4.x/scripts/ppmtolinuxlogo.c Wed Dec 31 19:00:00 1969 +++ linux-2.4.x-logo/scripts/ppmtolinuxlogo.c Sat Sep 23 19:58:20 2000 @@ -0,0 +1,205 @@ +#include <stdio.h> + +#include <pnm.h> + +#define MAX_COLORS 214 +#define MAX_COLORS_16 16 +#define MAX_COLORS_BW 2 + +int color_lookup(xel color,xel *colormap,int *used,int maxcolor) +{ + int i; + + for (i=0;i<*used;i++) { + if (PPM_EQUAL(colormap[i],color)) + return i; + } + + if (i >= maxcolor) { + fprintf(stderr,"Too many colors: %d\n",maxcolor); + exit(1); + } + + (*used)++; + colormap[i]=color; + return i; +} + +void print_data(int *data,int len,const char *prefix,const char *name) +{ + int i; + + printf("unsigned char linux_logo%s%s[] __initdata = {",prefix,name); + + for (i=0;i<len;i++) { + if ( (i%8) == 0) printf("\n "); + printf(" 0x%.2X,",data[i]); + } + + printf("\n};\n\n"); +} + +void linux_encode_bw(xel **ppm,int rows,int cols,int colormax,const char *prefix) +{ + int *m; + int row,col,i,used=0,bytes; + xel black; + + PPM_PUTR(black,0); + PPM_PUTG(black,0); + PPM_PUTB(black,0); + + bytes=(cols+7)>>3; + m=malloc(sizeof(int)*rows*bytes); + for (row=i=0;row<rows;row++) { + for (col=0;col<cols;col++) { + if ((col&7)==0) { + m[++i] = 0; + } else { + m[i] <<= 1; + } + if (!PPM_EQUAL(ppm[row][col],black)) + m[i] |= 1; + } + /* End of row... */ + for (;(col&7) != 0;col++) { + m[i] <<= 1; + } + } + + printf("#ifdef INCLUDE_LINUX_LOGOBW\n\n"); + + print_data(m,rows*bytes,prefix,""); + + printf("\n#endif /* INCLUDE_LINUX_LOGOBW */\n\n"); + + free(m); +} + +void linux_encode_16(xel **ppm,int rows,int cols,int colormax,const char *prefix) +{ + int *r,*g,*b,*m; + xel colormap[MAX_COLORS]; + int row,col,i,used=0; + + m=malloc(sizeof(int)*rows*((cols+1)>>1)); + for (row=i=0;row<rows;row++) { + for (col=0;col<cols;col++) { + if ((col&1)==0) { + m[++i]=0; + } else { + m[i] <<= 4; + } + m[i] |= color_lookup(ppm[row][col],colormap,&used,colormax); + } + } + + r=malloc(sizeof(int)*used); + g=malloc(sizeof(int)*used); + b=malloc(sizeof(int)*used); + + for (i=0;i<used;i++) { + r[i]=PPM_GETR(colormap[i]); + g[i]=PPM_GETG(colormap[i]); + b[i]=PPM_GETB(colormap[i]); + } + + printf("#ifdef INCLUDE_LINUX_LOGO%s\n\n",prefix); + + print_data(r,used,prefix,"_red"); + print_data(g,used,prefix,"_green"); + print_data(b,used,prefix,"_blue"); + print_data(m,rows*((cols+1)>>1),prefix,""); + + printf("\n#endif /* INCLUDE_LINUX_LOGO%s */\n\n",prefix); + + free(r); + free(g); + free(b); + free(m); +} + +void linux_encode(xel **ppm,int rows,int cols,int colormax,const char *prefix) +{ + int *r,*g,*b,*m; + xel colormap[MAX_COLORS]; + int row,col,i,used=0; + + m=malloc(sizeof(int)*rows*cols); + for (row=i=0;row<rows;row++) { + for (col=0;col<cols;col++,i++) { + m[i]=color_lookup(ppm[row][col],colormap,&used,colormax)+32; + } + } + + r=malloc(sizeof(int)*used); + g=malloc(sizeof(int)*used); + b=malloc(sizeof(int)*used); + + for (i=0;i<used;i++) { + r[i]=PPM_GETR(colormap[i]); + g[i]=PPM_GETG(colormap[i]); + b[i]=PPM_GETB(colormap[i]); + } + + printf("#define LOGO_W %d\n",cols); + printf("#define LOGO_H %d\n\n",rows); + + print_data(r,used,prefix,"_red"); + print_data(g,used,prefix,"_green"); + print_data(b,used,prefix,"_blue"); + print_data(m,rows*cols,prefix,""); + + free(r); + free(g); + free(b); + free(m); +} + +int main(int argc,char **argv) +{ + xelval maxval; + xel **ppm; + FILE *inf; + int rows,cols,format,colors,colormax; + xel colormap[MAX_COLORS]; + const char *prefix; + void (*encode)(xel **ppm,int rows,int cols,int colormax,const char *prefix); + + if (argc>1 && strcmp(argv[1],"-16")==0) { + argc--; + memcpy(argv+1,argv+2,(argc-1)*sizeof(argv[0])); + prefix="16"; + colormax=MAX_COLORS_16; + encode=linux_encode_16; + } else if (argc>1 && strcmp(argv[1],"-bw")==0) { + argc--; + memcpy(argv+1,argv+2,(argc-1)*sizeof(argv[0])); + prefix="_bw"; + colormax=MAX_COLORS_BW; + encode=linux_encode_bw; + } else { + prefix=""; + colormax=MAX_COLORS; + encode=linux_encode; + } + + if (argc==1) { + inf=stdin; + } else { + inf=fopen(argv[1],"r"); + if (inf==NULL) + exit(1); + } + + ppm=pnm_readpnm(inf,&cols,&rows,&maxval,&format); + if (format != RPPM_FORMAT && + format != PPM_FORMAT) { + fprintf(stderr,"%s: Not a ppm file!\n",argv[1]); + exit(1); + } + + encode(ppm,rows,cols,colormax,prefix); + + return 0; +} -- Jason McMullan, Senior Linux Consultant, Linuxcare, Inc. 412.422.8077 tel, 412.656.3519 cell, 415.701.0792 fax jmcmullan@linuxcare.com, http://www.linuxcare.com/ Linuxcare. Support for the revolution. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |