diff -Nurp linux-2.4.20/drivers/block/genhd.c linux-2.4.20/drivers/block/genhd.c
--- linux-2.4.20/drivers/block/genhd.c	2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20/drivers/block/genhd.c	2003-01-23 10:44:50.000000000 +0100
@@ -222,6 +222,13 @@ static int part_show(struct seq_file *s,
 	return 0;
 }
 
+#if defined(CONFIG_LPP)
+extern void fbcon_progress( unsigned int progress, char *text);
+#define PROGRESS(value, text) fbcon_progress(value,text)
+#else
+#define PROGRESS(value,text)
+#endif
+
 struct seq_operations partitions_op = {
 	.start		= part_start,
 	.next		= part_next,
@@ -237,15 +244,19 @@ extern int atmdev_init(void);
 
 int __init device_init(void)
 {
+	PROGRESS(9,"setting up block devices");
 	blk_dev_init();
 	sti();
 #ifdef CONFIG_NET
+	PROGRESS(26, "setting up network devices");
 	net_dev_init();
 #endif
 #ifdef CONFIG_ATM
+	PROGRESS(28, "setting up ATM");
 	(void) atmdev_init();
 #endif
 #ifdef CONFIG_VT
+	PROGRESS(29, "setting up console");
 	console_map_init();
 #endif
 	return 0;
diff -Nurp linux-2.4.20/drivers/char/mem.c linux-2.4.20/drivers/char/mem.c
--- linux-2.4.20/drivers/char/mem.c	2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20/drivers/char/mem.c	2003-01-23 10:44:51.000000000 +0100
@@ -41,7 +41,14 @@ extern void mda_console_init(void);
 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
 extern void tapechar_init(void);
 #endif
-     
+
+#if defined(CONFIG_LPP)
+extern void fbcon_progress( unsigned int progress, char *text);
+#define PROGRESS(value, text) fbcon_progress(value,text)
+#else
+#define PROGRESS(value,text)
+#endif
+
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
 			    const char * buf, size_t count, loff_t *ppos)
 {
@@ -644,6 +651,7 @@ static struct file_operations memory_fop
 
 int __init chr_dev_init(void)
 {
+	PROGRESS(6,"setting up character devices");
 	if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 	memory_devfs_register();
diff -Nurp linux-2.4.20/drivers/parport/init.c linux-2.4.20/drivers/parport/init.c
--- linux-2.4.20/drivers/parport/init.c	2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20/drivers/parport/init.c	2003-01-23 10:45:02.000000000 +0100
@@ -18,6 +18,14 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 
+#if defined(CONFIG_LPP)
+extern void fbcon_progress( unsigned int progress, char *text);
+#define PROGRESS(value, text) fbcon_progress(value,text)
+#else
+#define PROGRESS(value,text)
+#endif
+	
+
 #ifndef MODULE
 static int io[PARPORT_MAX+1] __initdata = { [0 ... PARPORT_MAX] = 0 };
 #ifdef CONFIG_PARPORT_PC
@@ -142,6 +150,7 @@ int __init parport_init (void)
 	if (io[0] == PARPORT_DISABLE) 
 		return 1;
 
+	PROGRESS(4,"setting up parport");
 #ifdef CONFIG_SYSCTL
 	parport_default_proc_register ();
 #endif
diff -Nurp linux-2.4.20/drivers/video/Config.in linux-2.4.20/drivers/video/Config.in
--- linux-2.4.20/drivers/video/Config.in	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.20/drivers/video/Config.in	2003-01-23 10:44:58.000000000 +0100
@@ -92,6 +92,9 @@ if [ "$CONFIG_FB" = "y" ]; then
    fi
    if [ "$CONFIG_X86" = "y" ]; then
       bool '  VESA VGA graphics console' CONFIG_FB_VESA
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+         bool '  Enable Linux Progress Patch (EXPERIMENTAL)' CONFIG_LPP
+      fi
       tristate '  VGA 16-color graphics console' CONFIG_FB_VGA16
       tristate '  Hercules mono graphics console (EXPERIMENTAL)' CONFIG_FB_HGA
       define_bool CONFIG_VIDEO_SELECT y
diff -Nurp linux-2.4.20/drivers/video/Makefile linux-2.4.20/drivers/video/Makefile
--- linux-2.4.20/drivers/video/Makefile	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.20/drivers/video/Makefile	2003-01-23 10:44:58.000000000 +0100
@@ -34,10 +34,11 @@ obj-$(CONFIG_FONT_PEARL_8x8)      += fon
 obj-$(CONFIG_FONT_ACORN_8x8)      += font_acorn_8x8.o
 
 # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
-obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o
+obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o fbprogress.o
 # Only include macmodes.o if we have FB support and are PPC
 ifeq ($(CONFIG_FB),y)
 obj-$(CONFIG_PPC)                 += macmodes.o
+obj-$(CONFIG_LPP)                 += fbprogress.o
 endif
 
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
diff -Nurp linux-2.4.20/drivers/video/fbcon.c linux-2.4.20/drivers/video/fbcon.c
--- linux-2.4.20/drivers/video/fbcon.c	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.20/drivers/video/fbcon.c	2003-01-27 20:43:19.000000000 +0100
@@ -75,6 +75,7 @@
 #include <linux/selection.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/proc_fs.h>
 #include <linux/pm.h>
 
 #include <asm/irq.h>
@@ -98,6 +99,9 @@
 #include <asm/io.h>
 #endif
 #define INCLUDE_LINUX_LOGO_DATA
+#define LINUX_LOGO_COLORS 214
+#define INCLUDE_LINUX_LOGO16 1
+#define INCLUDE_LINUX_LOGOBW 1
 #include <asm/linux_logo.h>
 
 #include <video/fbcon.h>
@@ -110,8 +114,8 @@
 #  define DPRINTK(fmt, args...)
 #endif
 
-#define LOGO_H			80
-#define LOGO_W			80
+#define LOGO_H              480
+#define LOGO_W              640
 #define LOGO_LINE	(LOGO_W/8)
 
 struct display fb_display[MAX_NR_CONSOLES];
@@ -125,6 +129,11 @@ static unsigned long softback_in;
 static unsigned long softback_top, softback_end;
 static int softback_lines;
 
+#ifdef CONFIG_LPP
+extern void fbcon_progress(unsigned int progress,char *text);
+extern void fbcon_progress_setup( unsigned char *fb, unsigned int line);
+#endif
+
 #define REFCOUNT(fd)	(((int *)(fd))[-1])
 #define FNTSIZE(fd)	(((int *)(fd))[-2])
 #define FNTCHARCNT(fd)	(((int *)(fd))[-3])
@@ -201,6 +210,9 @@ static int fbcon_font_op(struct vc_data 
 static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
 static int fbcon_scrolldelta(struct vc_data *conp, int lines);
 
+#define LOGO_H              480
+#define LOGO_W              640
+#define LOGO_LINE  (LOGO_W/8)
 
 /*
  *  Internal routines
@@ -1509,6 +1521,10 @@ static int fbcon_switch(struct vc_data *
     struct display *p = &fb_display[unit];
     struct fb_info *info = p->fb_info;
 
+    int depth = p->var.bits_per_pixel;
+    int line = p->next_line;
+    unsigned char *fb = p->screen_base;
+
     if (softback_top) {
     	int l = fbcon_softback_size / conp->vc_size_row;
 	if (softback_lines)
@@ -1558,6 +1574,14 @@ static int fbcon_switch(struct vc_data *
 	update_region(fg_console,
 		      conp->vc_origin + conp->vc_size_row * conp->vc_top,
 		      conp->vc_size_row * (conp->vc_bottom - conp->vc_top) / 2);
+
+#ifdef CONFIG_LPP
+	/* initialize progress bar part */
+	if(depth==8||depth==15||depth==16||depth==24||depth==32){
+		fbcon_progress_setup( fb, line );
+		vbl_cursor_cnt= 0;
+	}
+#endif 
 	return 0;
     }
     return 1;
@@ -2189,7 +2213,11 @@ static int __init fbcon_show_logo( void 
     if (p->fb_info->fbops->fb_rasterimg)
     	p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
 
+#ifdef CONFIG_LPP
+	for (x = 0; x < (LOGO_W + 8) &&
+#else
     for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
+#endif
     	 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
     	 
 #if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
diff -Nurp linux-2.4.20/drivers/video/fbprogress.c linux-2.4.20/drivers/video/fbprogress.c
--- linux-2.4.20/drivers/video/fbprogress.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20/drivers/video/fbprogress.c	2003-01-23 10:44:59.000000000 +0100
@@ -0,0 +1,536 @@
+/*
+ *  Copyright (C) 2000 Cajus Pollmeier
+ *
+ *  Support for higher color depths added by
+ *  Jeroen Asselman <jeroen@asselman.com>
+ *
+ *
+ *  Support for displaying a progress bar and
+ *  status message while booting using 8/16/24/32 bits/pixel.
+ *
+ *  It is accessible via /proc/progress like this:
+ *
+ *  echo "45 starting init" > /proc/progress
+ *
+ *  This sets the progress bar to 45% and shows the message
+ *  "starting init".
+ *
+ *  Position definitions:
+ *  PROGRESS_BAR_X      306  (upper left
+ *  PROGRESS_BAR_Y      310   corner pixel)
+ *  PROGRESS_CORNER_X   513  (lower right    (or use PROGRESS_BAR_WIDTH  207)
+ *  PROGRESS_CORNER_Y   324   corner pixel)  (or use PROGRESS_BAR_HEIGHT 14)
+ *  STRIPE_BAR          1    (optional, defaults to 0) (0 = bar is solid
+ *                            color, 1= bar is repeated stripes of color)
+ *  PROGRESS_VERTICALLY 0    (optional, defaults to false)
+ *  REVERSE_DIRECTION   0    (optional, defaults to false)
+ *  TEXT_X              305
+ *  TEXT_Y              294
+ *  ICON_X              290
+ *  ICON_Y              311
+ *
+ *  Text definitions:
+ *  MAX_TEXT_LEN        25
+ *  MESSAGE_LENGTH      80
+ *  LPP_TEXT_BLOCK_HEIGHT 4 
+ *
+ *  See the README for more informations.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <linux/boot_font.h>
+
+#include "fbprogress.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  #define LINUX22
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+  #undef LINUX22
+#endif
+
+#define LPP_BPP ((p->var.bits_per_pixel+7)/8)
+#define LPP_CHAR_HEIGHT 11
+#define LPP_CHAR_WIDTH 8
+
+/*
+ * Compile time computations based on theme.
+ */
+
+/* Establish default choices. */
+#ifndef PROGRESS_VERTICALLY
+#   define PROGRESS_VERTICALLY 0
+#endif
+
+#ifndef REVERSE_DIRECTION
+#   define REVERSE_DIRECTION 0
+#endif
+
+#ifndef STRIPE_BAR
+#   define STRIPE_BAR 0
+#endif
+
+/* Support human-friendly "diagonal corner" defines in definitions file.
+ * (Exploit compiler's constant folding.) */
+#ifndef PROGRESS_BAR_WIDTH
+#   define PROGRESS_BAR_WIDTH (PROGRESS_CORNER_X - PROGRESS_BAR_X + 1)
+#endif
+
+#ifndef PROGRESS_BAR_HEIGHT
+#   define PROGRESS_BAR_HEIGHT (PROGRESS_CORNER_Y - PROGRESS_BAR_Y + 1)
+#endif
+
+/* The size of the icons are limited by the minimum dimention of the
+ * progress bar. */
+#if PROGRESS_BAR_HEIGHT < PROGRESS_BAR_WIDTH
+#   define ICON_EDGE_LENGTH PROGRESS_BAR_HEIGHT
+#else
+#   define ICON_EDGE_LENGTH PROGRESS_BAR_WIDTH
+#endif
+
+#if PROGRESS_VERTICALLY
+    /* Progress bar is oriented vertically. */
+    /* (HEIGHT and WIDTH are vertical and horzontal, LENGTH and THICKNESS
+     *  give longways and shortways dimensions. */
+#   define PB_LENGTH PROGRESS_BAR_HEIGHT
+#   define PB_THICKNESS PROGRESS_BAR_WIDTH
+    /* The Y dimention represents progess */
+#   define SIG_DIM(X, Y) Y
+    /* Don't apply a progress offset to the X dimention */
+#   define APPLY_X_OFFSET(OFFSET) 0
+    /* Apply progress offset to Y dimension */
+#   define APPLY_Y_OFFSET(OFFSET) OFFSET
+#else
+    /* Progress bar is oriented horizontally. */
+#   define PB_LENGTH PROGRESS_BAR_WIDTH
+#   define PB_THICKNESS PROGRESS_BAR_HEIGHT
+    /* The X dimention represents progess */
+#   define SIG_DIM(X, Y) X
+    /* Apply progress offset to X dimension */
+#   define APPLY_X_OFFSET(OFFSET) OFFSET
+    /* Don't apply a progress offset to the Y dimention */
+#   define APPLY_Y_OFFSET(OFFSET) 0
+#endif
+
+/* Is the pixel in the forground of the progress bar? */
+#if REVERSE_DIRECTION
+    /* Exchange forgound for background in bar.  (Elsewhere the bar
+     * is flipped about the 50% line.) */
+#   define PIXEL_FG(X, Y, EDGE_COORD) (SIG_DIM(X, Y) > EDGE_COORD)
+#else
+#   define PIXEL_FG(X, Y, EDGE_COORD) (SIG_DIM(X,Y) < EDGE_COORD)
+#endif
+
+int fbcon_set_progress(struct file *file, const char *buffer,
+		       unsigned long count, void *data);
+
+void fbcon_progress(unsigned int progress, char *text);
+
+static int module_permission(struct inode *inode, int op);
+
+static ssize_t module_input(struct file *file, const char *buf,
+		            size_t length, loff_t *offset);
+
+static ssize_t module_output(struct file *file, char *buf, size_t len,
+		             loff_t *offset);
+
+/* globals */
+/* we don't know how many bpp before hand, it shouldn't be biger than 4 */
+#define LPP_MAX_BPP 4
+#if STRIPE_BAR
+    unsigned char bg_color[LPP_MAX_BPP*PB_THICKNESS] = {0};
+    unsigned char fg_color[LPP_MAX_BPP*PB_THICKNESS] = {0};
+#else
+    unsigned char bg_color[LPP_MAX_BPP] = {0};
+    unsigned char fg_color[LPP_MAX_BPP] = {0};
+#endif
+unsigned char bg_text[LPP_MAX_BPP] = {0};
+unsigned char fg_text[LPP_MAX_BPP] = {0};
+unsigned char warning[ICON_EDGE_LENGTH*ICON_EDGE_LENGTH*LPP_MAX_BPP];
+unsigned char failure[ICON_EDGE_LENGTH*ICON_EDGE_LENGTH*LPP_MAX_BPP];
+int last_progress;
+int ignore_proc;
+
+static struct file_operations file_fbcon_progress_proc_entry =
+{
+    NULL,
+    module_output,  /* "read" from the file */
+    module_input,   /* "write" to the file */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL, /* module_open, */
+    NULL,
+    NULL, /*module_close, */
+};
+
+static struct inode_operations  inode_fbcon_progress_proc_entry =
+{
+    &file_fbcon_progress_proc_entry,
+    NULL, /* create */
+    NULL, /* lookup */
+    NULL, /* link */
+    NULL, /* unlink */
+    NULL, /* symlink */
+    NULL, /* mkdir */
+    NULL, /* rmdir */
+    NULL, /* mknod */
+    NULL, /* rename */
+    NULL, /* readlink */
+    NULL, /* follow_link */
+    NULL, /* readpage */
+    NULL, /* writepage */
+    NULL, /* bmap */
+    NULL, /* truncate */
+    module_permission /* check for permissions */
+};
+
+#ifdef LINUX22
+/* Directory entry */
+static struct proc_dir_entry fbcon_progress_proc_entry =
+{
+    0,
+    8, "progress",
+    S_IFREG | S_IRUGO | S_IWUSR,
+    1,
+    0, 0,
+    80,
+    &inode_fbcon_progress_proc_entry,
+    NULL
+};
+#else
+static struct proc_dir_entry *fbprogress_proc_entry;
+#endif
+
+static unsigned int fbcon_atoi(char *str)
+{
+        unsigned int    val;
+        int             c;
+        char            *sp;
+
+        val = 0;
+        sp = str;
+
+        for (; (*sp != 0); sp++) {
+                c = *sp - '0';
+                if ((c < 0) || (c >= 10)) {
+                        break;
+                }
+                val = (val * 10) + c;
+        }
+	return(val);
+}
+
+static int module_permission(struct inode *inode, int op)
+{
+  /* We allow everybody to read from our module, but
+   * only root (uid 0) may write to it */
+  if (op == 4 || (op == 2 && current->euid == 0))
+    return 0;
+
+  /* If it's anything else, access is denied */
+  return -EACCES;
+}
+
+
+void fbcon_draw( unsigned char *pic)
+{
+   int y;
+   struct display *p = &fb_display[fg_console];
+   int line = p->next_line;
+   unsigned char *fb = p->screen_base + ICON_X*LPP_BPP + ICON_Y * line;
+
+   for( y= 0; y<ICON_EDGE_LENGTH; y++ )
+     memcpy((fb+y*line),
+	    &pic[y*ICON_EDGE_LENGTH], 
+	    ICON_EDGE_LENGTH*LPP_BPP);
+}
+
+
+static ssize_t module_input( struct file *file, const char *buf, size_t length, loff_t *offset)
+{
+  int i, j= 0;
+  int space_found= 0;
+  int no_message= 0;
+  int get_rest= 0;
+  static char buffer[MAX_TEXT_LEN];
+  static char Message[MESSAGE_LENGTH];
+  unsigned int value;
+
+  for(i=0; i<MESSAGE_LENGTH-1 && i<length; i++){
+    if(!space_found || get_rest){
+      get_user(Message[i], buf+i);
+      if( i==0 && Message[0] == 'w' ){
+        fbcon_draw(warning);
+        get_rest= 1;
+	no_message= 1;
+      }
+      if( i==0 && Message[0] == 'f' ){
+        fbcon_draw(failure);
+        get_rest= 1;
+	no_message= 1;
+      }
+    }
+    else{
+      get_user(buffer[j++], buf+i);
+      if( j > MAX_TEXT_LEN ) get_rest= 1;
+    }
+    if( Message[i] == ' ' ){
+      space_found= 1;
+      Message[i]= '\0';
+    }
+  }
+ 
+  if( no_message ) return i;
+  
+  buffer[j]=   0;
+  Message[i]=  0;
+  
+  value= fbcon_atoi(Message);
+
+  if(value > 100 )
+    ignore_proc= 1;
+  if( !ignore_proc ) fbcon_progress(value, buffer);
+  
+  return i;
+}
+
+
+static ssize_t module_output( struct file *file, char *buf, size_t len, loff_t *offset)
+{
+  static int finished = 0;
+  int i;
+  char message[MESSAGE_LENGTH+30];
+
+  if (finished) {
+    finished = 0;
+    return 0;
+  }
+
+  sprintf(message, "%d", last_progress);
+
+  for(i=0; i<len && message[i]; i++)
+    put_user(message[i], buf+i);
+
+  finished = 1;
+
+  return i;
+}
+
+
+void fbcon_render_char( int offset, int x, int y, unsigned char fgcol[], unsigned char bgcol[] )
+{
+    struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+    int line = p->next_line;
+    int depth=LPP_BPP;
+    unsigned char *fb = p->screen_base + x + y * line;
+    int i, j;
+    unsigned char bits;
+
+    for( i= 0; i<11; i++ ){
+      bits= (offset < 69) ? font[offset*11+i] : 0;
+      for( j= 0; j<LPP_CHAR_WIDTH; j++ ){
+	if( bits & (1 << j) ){
+          memcpy((fb+j*depth), fgcol, depth);
+	} else {
+	  memcpy((fb+j*depth), bgcol, depth);
+	}
+      }
+      fb+= line;
+    }
+}
+
+
+void fbcon_write( char *str, int x, int y, int len, unsigned char fgcol[], unsigned char bgcol[])
+{
+  char *idx= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789():;-+. ";
+  char z;
+  int offset, k, x_pos= x, sw;
+
+#ifdef LPP_TEXT_BLOCK_HEIGHT
+  struct display *p = &fb_display[fg_console];
+  int line = p->next_line;
+  char *tmp = (p->screen_base+x*LPP_BPP + y * line);
+
+  for ( k = 0; k < (LPP_CHAR_HEIGHT * (LPP_TEXT_BLOCK_HEIGHT-1));k++) {
+    memcpy(tmp, (tmp+LPP_CHAR_HEIGHT*line),MAX_TEXT_LEN*LPP_CHAR_WIDTH*LPP_BPP);
+    tmp+=line;
+  }
+
+  y+=11*(LPP_TEXT_BLOCK_HEIGHT-1);
+#endif
+
+  sw= 0;
+
+  for( k= 0; k<len; k++ ){
+    if( !str[k] ) sw= 1;
+    z= sw?' ':str[k];
+
+    for( offset= 0; offset < 70; offset++){
+      if( idx[offset] == z ) break;
+    }
+
+    fbcon_render_char( offset, x_pos, y, fgcol, bgcol );
+    x_pos+= LPP_CHAR_WIDTH;
+  }
+}
+
+
+void fbcon_register_progress(void)
+{
+#ifdef LINUX22
+    proc_register(&proc_root, &fbcon_progress_proc_entry);
+    printk("FBCON: Trying LINUX22\n");
+#else
+    fbprogress_proc_entry = create_proc_entry("progress", 
+                            S_IFREG | S_IRUGO | S_IWUSR,&proc_root);
+    if(fbprogress_proc_entry == NULL)
+    {
+          printk("FBCON: unable to create proc entry\n");
+          return;
+    }
+    printk("FBCON: created proc entry\n");
+ 
+    fbprogress_proc_entry->proc_iops = &inode_fbcon_progress_proc_entry;
+    fbprogress_proc_entry->write_proc = &module_input;
+    fbprogress_proc_entry->read_proc = &module_output;
+#endif
+}
+
+
+void fbcon_progress( unsigned int progress, char *text )
+{
+    /* Redraw entire progress bar. */
+
+    struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+    int depth = p->var.bits_per_pixel;
+    int line = p->next_line;                     /* _bytes_/screen line */
+    unsigned char *fb = p->screen_base;
+    unsigned int i, w, l;
+
+    last_progress= progress;
+
+    printk("FBCON: fbcon_progress called\n");
+    if( (depth != 8) && (depth != 15) && (depth != 16) && (depth != 24) && (depth != 32) )
+         return;
+    
+    w= (progress>100?100:progress);   /* force to percentage boundries */
+#   if REVERSE_DIRECTION
+        w= 100 - w;                   /* flip about the axis at 50% */
+#   endif
+    w= (w*PB_LENGTH) / 100;              /* scale pixel coord to length of bar */
+
+    depth = (depth+7)/8;
+    fb += PROGRESS_BAR_X * depth + PROGRESS_BAR_Y * line;
+
+    for( l= 0; l < PROGRESS_BAR_HEIGHT; l++ ){
+        for( i= 0; i < PROGRESS_BAR_WIDTH; i++ ){
+#           if STRIPE_BAR
+                memcpy(fb, 
+                       ( PIXEL_FG(i,l, w)
+                         ? &fg_color[i*depth]
+                         : &bg_color[i*depth] ),
+                       depth);
+#           else
+                memcpy(fb, 
+                       ( PIXEL_FG(i,l, w)
+                         ? fg_color
+                         : bg_color ),
+                       depth);
+#           endif
+            fb+=depth;
+	}
+        fb+= line - PROGRESS_BAR_WIDTH * depth;
+    }
+    fbcon_write( text, TEXT_X, TEXT_Y,  MAX_TEXT_LEN, fg_text, bg_text );
+}
+
+
+void fbcon_progress_setup(unsigned char *fb, unsigned int line){
+   /* line = number of bytes/screen line, _not_ the number of pixels. */
+   struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+   int depth = LPP_BPP;
+   int y;
+
+#  if STRIPE_BAR
+#      if PROGRESS_VERTICALLY
+          /* Stripe is layed out in the direction the fb runs, horizontally. */
+          memcpy(&fg_color,
+                 (fb + (PROGRESS_BAR_X)*depth  + line * PROGRESS_BAR_Y),
+                 depth * PB_THICKNESS);
+          memcpy(&bg_color,
+                 (fb + (PROGRESS_BAR_X)*depth + line * (PROGRESS_BAR_Y + 1)),
+	         depth * PB_THICKNESS);
+#      else
+           /* Stripe is vertical, must copy a pixel at a time. */
+	   for( y= 0; y<PB_THICKNESS; y++){
+                memcpy(&fg_color[y*depth],
+                       (fb + (PROGRESS_BAR_X)*depth
+                        + line * (PROGRESS_BAR_Y + y)),
+                       depth);
+                memcpy(&bg_color[y*depth],
+                       (fb + (PROGRESS_BAR_X + 1)*depth
+                        + line * (PROGRESS_BAR_Y + y)),
+                       depth);
+	   }
+#      endif
+#  else
+       /* fg and bg colors are defined by a single pixel */
+       memcpy(&fg_color,
+              (fb + (PROGRESS_BAR_X)*depth + line * PROGRESS_BAR_Y),
+              depth);
+       memcpy(&bg_color,
+              (fb + (PROGRESS_BAR_X + APPLY_X_OFFSET(1))*depth
+                  + line * (PROGRESS_BAR_Y + APPLY_Y_OFFSET(1))),
+              depth);
+#  endif
+   memcpy(&fg_text,
+          (fb + (PROGRESS_BAR_X + APPLY_X_OFFSET(2))*depth
+              + line * (PROGRESS_BAR_Y + APPLY_Y_OFFSET(2))),
+          depth);
+   memcpy(&bg_text,
+          (fb + (PROGRESS_BAR_X + APPLY_X_OFFSET(3))*depth
+              + line * (PROGRESS_BAR_Y + APPLY_Y_OFFSET(3))),
+          depth);
+
+   for( y= 0; y<ICON_EDGE_LENGTH; y++ ){
+     memcpy(&warning[y*ICON_EDGE_LENGTH],
+            (fb + (PROGRESS_BAR_X + APPLY_X_OFFSET(4))*depth 
+             +line * (PROGRESS_BAR_Y + y + APPLY_Y_OFFSET(4))),
+            ICON_EDGE_LENGTH*depth);
+     memcpy(&failure[y*ICON_EDGE_LENGTH],
+            (fb + (PROGRESS_BAR_X + APPLY_X_OFFSET(4 + ICON_EDGE_LENGTH))*depth
+             + line
+               * (PROGRESS_BAR_Y + y + APPLY_Y_OFFSET(4 + ICON_EDGE_LENGTH))),
+            ICON_EDGE_LENGTH*depth);
+   }
+
+   ignore_proc= 0;
+   fbcon_progress(0, "booting...");
+}
diff -Nurp linux-2.4.20/drivers/video/fbprogress.h linux-2.4.20/drivers/video/fbprogress.h
--- linux-2.4.20/drivers/video/fbprogress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20/drivers/video/fbprogress.h	2003-01-27 20:41:11.000000000 +0100
@@ -0,0 +1,13 @@
+#define PROGRESS_BAR_X      50
+#define PROGRESS_BAR_Y      58
+#define PROGRESS_CORNER_X   58
+#define PROGRESS_CORNER_Y   412
+#define STRIPE_BAR          1
+#define PROGRESS_VERTICALLY 1
+#define REVERSE_DIRECTION   1
+#define TEXT_X              14
+#define TEXT_Y              468
+#define MAX_TEXT_LEN        60
+#define MESSAGE_LENGTH      80
+#define ICON_X              3
+#define ICON_Y              467
diff -Nurp linux-2.4.20/include/linux/boot_font.h linux-2.4.20/include/linux/boot_font.h
--- linux-2.4.20/include/linux/boot_font.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20/include/linux/boot_font.h	2003-01-23 10:44:33.000000000 +0100
@@ -0,0 +1,72 @@
+unsigned char font[] = {
+       0 ,0 ,0 ,30 ,32 ,62 ,33 ,33 ,94 ,0 ,0 ,
+       0 ,1 ,1 ,29 ,35 ,33 ,33 ,33 ,31 ,0 ,0 ,
+       0 ,0 ,0 ,30 ,33 ,1 ,1 ,33 ,30 ,0 ,0 ,
+       0 ,32 ,32 ,46 ,49 ,33 ,33 ,33 ,62 ,0 ,0 ,
+       0 ,0 ,0 ,30 ,33 ,63 ,1 ,33 ,30 ,0 ,0 ,
+       0 ,56 ,4 ,4 ,30 ,4 ,4 ,4 ,4 ,0 ,0 ,
+       0 ,0 ,16 ,14 ,17 ,17 ,14 ,1 ,30 ,33 ,30 ,
+       0 ,1 ,1 ,29 ,35 ,33 ,33 ,33 ,33 ,0 ,0 ,
+       8 ,8 ,0 ,12 ,8 ,8 ,8 ,8 ,62 ,0 ,0 ,
+       16 ,16 ,0 ,28 ,16 ,16 ,16 ,16 ,16 ,17 ,14 ,
+       0 ,1 ,1 ,17 ,9 ,7 ,9 ,17 ,33 ,0 ,0 ,
+       0 ,12 ,8 ,8 ,8 ,8 ,8 ,8 ,62 ,0 ,0 ,
+       0 ,0 ,0 ,55 ,73 ,73 ,73 ,65 ,65 ,0 ,0 ,
+       0 ,0 ,0 ,29 ,35 ,33 ,33 ,33 ,33 ,0 ,0 ,
+       0 ,0 ,0 ,30 ,33 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,0 ,0 ,29 ,35 ,33 ,33 ,33 ,31 ,1 ,1 ,
+       0 ,0 ,0 ,62 ,33 ,33 ,33 ,49 ,46 ,32 ,32 ,
+       0 ,0 ,0 ,59 ,38 ,2 ,2 ,2 ,2 ,0 ,0 ,
+       0 ,0 ,0 ,30 ,33 ,30 ,32 ,33 ,30 ,0 ,0 ,
+       0 ,4 ,4 ,30 ,4 ,4 ,4 ,36 ,24 ,0 ,0 ,
+       0 ,0 ,0 ,33 ,33 ,33 ,33 ,49 ,46 ,0 ,0 ,
+       0 ,0 ,0 ,34 ,34 ,20 ,20 ,8 ,8 ,0 ,0 ,
+       0 ,0 ,0 ,65 ,65 ,73 ,73 ,73 ,54 ,0 ,0 ,
+       0 ,0 ,0 ,51 ,18 ,12 ,12 ,18 ,51 ,0 ,0 ,
+       0 ,0 ,0 ,33 ,33 ,33 ,33 ,62 ,32 ,33 ,30 ,
+       0 ,0 ,0 ,63 ,16 ,8 ,4 ,2 ,63 ,0 ,0 ,
+       0 ,12 ,18 ,33 ,33 ,63 ,33 ,33 ,33 ,0 ,0 ,
+       0 ,31 ,33 ,33 ,31 ,33 ,33 ,33 ,31 ,0 ,0 ,
+       0 ,30 ,33 ,1 ,1 ,1 ,1 ,33 ,30 ,0 ,0 ,
+       0 ,31 ,33 ,33 ,33 ,33 ,33 ,33 ,31 ,0 ,0 ,
+       0 ,62 ,2 ,2 ,30 ,2 ,2 ,2 ,62 ,0 ,0 ,
+       0 ,62 ,2 ,2 ,30 ,2 ,2 ,2 ,2 ,0 ,0 ,
+       0 ,30 ,33 ,1 ,57 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,33 ,33 ,33 ,63 ,33 ,33 ,33 ,33 ,0 ,0 ,
+       0 ,62 ,8 ,8 ,8 ,8 ,8 ,8 ,62 ,0 ,0 ,
+       0 ,60 ,16 ,16 ,16 ,16 ,16 ,17 ,14 ,0 ,0 ,
+       0 ,34 ,18 ,10 ,6 ,6 ,10 ,18 ,34 ,0 ,0 ,
+       0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,62 ,0 ,0 ,
+       0 ,65 ,99 ,85 ,85 ,73 ,73 ,65 ,65 ,0 ,0 ,
+       0 ,33 ,35 ,37 ,37 ,41 ,41 ,49 ,33 ,0 ,0 ,
+       0 ,30 ,33 ,33 ,33 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,31 ,33 ,33 ,33 ,31 ,1 ,1 ,1 ,0 ,0 ,
+       0 ,30 ,33 ,33 ,33 ,33 ,37 ,41 ,30 ,32 ,0 ,
+       0 ,31 ,33 ,33 ,33 ,31 ,9 ,17 ,33 ,0 ,0 ,
+       0 ,30 ,33 ,1 ,30 ,32 ,32 ,33 ,30 ,0 ,0 ,
+       0 ,62 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,0 ,0 ,
+       0 ,33 ,33 ,33 ,33 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,65 ,65 ,34 ,34 ,20 ,20 ,8 ,8 ,0 ,0 ,
+       0 ,65 ,65 ,65 ,73 ,73 ,73 ,73 ,54 ,0 ,0 ,
+       0 ,99 ,34 ,20 ,8 ,8 ,20 ,34 ,99 ,0 ,0 ,
+       0 ,65 ,65 ,34 ,20 ,8 ,8 ,8 ,8 ,0 ,0 ,
+       0 ,63 ,32 ,16 ,8 ,4 ,2 ,1 ,63 ,0 ,0 ,
+       0 ,12 ,18 ,33 ,33 ,33 ,33 ,18 ,12 ,0 ,0 ,
+       0 ,8 ,12 ,10 ,8 ,8 ,8 ,8 ,62 ,0 ,0 ,
+       0 ,30 ,33 ,32 ,16 ,12 ,2 ,1 ,63 ,0 ,0 ,
+       0 ,30 ,33 ,32 ,28 ,32 ,32 ,33 ,30 ,0 ,0 ,
+       0 ,16 ,24 ,20 ,18 ,17 ,63 ,16 ,16 ,0 ,0 ,
+       0 ,63 ,1 ,1 ,31 ,33 ,32 ,33 ,30 ,0 ,0 ,
+       0 ,28 ,2 ,1 ,31 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,63 ,32 ,16 ,8 ,4 ,4 ,2 ,2 ,0 ,0 ,
+       0 ,30 ,33 ,33 ,30 ,33 ,33 ,33 ,30 ,0 ,0 ,
+       0 ,30 ,33 ,33 ,33 ,62 ,32 ,16 ,14 ,0 ,0 ,
+       16 ,8 ,8 ,4 ,4 ,4 ,4 ,8 ,8 ,16 ,0 ,
+       2 ,4 ,4 ,8 ,8 ,8 ,8 ,4 ,4 ,2 ,0 ,
+       0 ,0 ,0 ,4 ,4 ,0 ,0 ,4 ,4 ,0 ,0 ,
+       0 ,0 ,0 ,4 ,4 ,0 ,0 ,4 ,4 ,2 ,0 ,
+       0 ,0 ,0 ,0 ,0 ,63 ,0 ,0 ,0 ,0 ,0 ,
+       0 ,0 ,0 ,8 ,8 ,62 ,8 ,8 ,0 ,0 ,0 ,
+       0 ,0 ,0 ,0 ,0 ,0 ,0 ,4 ,4 ,0 ,0 
+};
+
diff -Nurp linux-2.4.20/init/do_mounts.c linux-2.4.20/init/do_mounts.c
--- linux-2.4.20/init/do_mounts.c	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.20/init/do_mounts.c	2003-01-23 10:44:30.000000000 +0100
@@ -18,6 +18,13 @@
 
 #define BUILD_CRAMDISK
 
+#if defined(CONFIG_LPP)
+extern void fbcon_progress( unsigned int progress, char *text);
+#define PROGRESS(value, text) fbcon_progress(value,text)
+#else
+#define PROGRESS(value,text)
+#endif
+
 extern int get_filesystem_list(char * buf);
 
 extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
@@ -883,11 +890,13 @@ void prepare_namespace(void)
 		}
 	} else if (is_floppy && rd_doload && rd_load_disk(0))
 		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	PROGRESS(48, "mounting root filesystem");
 	mount_root();
 out:
 	sys_umount("/dev", 0);
 	sys_mount(".", "/", NULL, MS_MOVE, NULL);
 	sys_chroot(".");
+	PROGRESS(49, "mounting devfs filesystem");
 	mount_devfs_fs ();
 }
 
diff -Nurp linux-2.4.20/init/main.c linux-2.4.20/init/main.c
--- linux-2.4.20/init/main.c	2002-08-03 02:39:46.000000000 +0200
+++ linux-2.4.20/init/main.c	2003-01-23 10:44:30.000000000 +0100
@@ -69,6 +69,14 @@ extern int irda_device_init(void);
 #include <asm/smp.h>
 #endif
 
+#if defined(CONFIG_LPP)
+extern void fbcon_progress( unsigned int progress, char *text );
+extern void fbcon_register_progress(void);
+#define PROGRESS(value,text) fbcon_progress(value,text)
+#else
+#define PROGRESS(value,text)
+#endif
+
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
@@ -471,6 +479,8 @@ static void __init do_basic_setup(void)
 	 */
 	child_reaper = current;
 
+	PROGRESS(1,"booting...");
+
 #if defined(CONFIG_MTRR)	/* Do this after SMP initialization */
 /*
  * We should probably create some architecture-dependent "fixup after
@@ -523,7 +533,8 @@ static void __init do_basic_setup(void)
 	tc_init();
 #endif
 
-	/* Networking initialization needs a process context */ 
+	/* Networking initialization needs a process context */
+	PROGRESS(3,"initializing network context");
 	sock_init();
 
 	start_context_thread();
@@ -568,6 +579,11 @@ static int init(void * unused)
 	 * trying to recover a really broken machine.
 	 */
 
+	PROGRESS(50, "starting init");
+	#ifdef CONFIG_LPP
+	fbcon_register_progress();
+#endif
+
 	if (execute_command)
 		execve(execute_command,argv_init,envp_init);
 	execve("/sbin/init",argv_init,envp_init);

