diff -Naur --exclude=CVS --exclude='*.orig' lilo/Makefile lilosh/Makefile
--- lilo/Makefile	2006-02-01 21:16:29.000000000 +0000
+++ lilosh/Makefile	2006-02-01 21:23:37.000000000 +0000
@@ -40,7 +40,6 @@
 
 SHELL=/bin/sh
 
-CROSS_COMPILE = sh3-linux-
 CC	=$(CROSS_COMPILE)gcc
 LD	=$(CROSS_COMPILE)ld
 OBJCOPY =$(CROSS_COMPILE)objcopy
@@ -72,10 +71,10 @@
 		$(OBJCOPY) -R .comment -S second.exe -O binary second.bin
 
 first.exe:	first.o
-		$(LD) -EL -e start first.o -o first.exe -Ttext 0x8c200000
+		$(LD) -EL -e start first.o -o first.exe -Ttext 0x88a00000
 
 second.exe:	second.o string.o
-		$(LD) -T second.lds -EL second.o string.o -o second.exe -Ttext 0x8c201000
+		$(LD) -T second.lds -EL second.o string.o -o second.exe -Ttext 0x88a01000
 
 first.o:	first.S
 		$(CC) $(CFLAGS) -c first.S
diff -Naur --exclude=CVS --exclude='*.orig' lilo/boot.c lilosh/boot.c
--- lilo/boot.c	1997-06-20 12:48:28.000000000 +0000
+++ lilosh/boot.c	2006-01-31 19:46:21.000000000 +0000
@@ -11,6 +11,7 @@
 #include <errno.h>
 #include <a.out.h>
 #include <sys/stat.h>
+#include <asm/page.h>
 
 #include "config.h"
 #include "common.h"
@@ -70,6 +71,7 @@
     geo_close(&geo);
     if (verbose > 1)
 	printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");
+	memset(&descr->initrd, 0, sizeof(descr->initrd));
     if ((initrd = cfg_get_strg(cf_kernel,"initrd")) || (initrd = cfg_get_strg(
       cf_options,"initrd"))) {
 	if (!modern_kernel) die("Kernel doesn't support initial RAM disks");
diff -Naur --exclude=CVS --exclude='*.orig' lilo/bsect.c lilosh/bsect.c
--- lilo/bsect.c	1998-10-14 20:30:32.000000000 +0000
+++ lilosh/bsect.c	2004-10-01 19:05:58.000000000 +0000
@@ -189,11 +189,11 @@
 	}
     }
     bsect.par_1.prompt = cfg_get_flag(cf_options,"prompt");
-    if (delay*100/55 > 0xffff) die("Maximum delay is one hour.");
-	else bsect.par_1.delay = delay*100/55;
+    if (delay >= 36000) die("Maximum delay is one hour.");
+	else bsect.par_1.delay = delay;
     if (timeout == -1) bsect.par_1.timeout = 0xffff;
-    else if (timeout*100/55 >= 0xffff) die("Maximum timeout is one hour.");
-	else bsect.par_1.timeout = timeout*100/55;
+    else if (timeout >= 36000) die("Maximum timeout is one hour.");
+	else bsect.par_1.timeout = timeout;
     if (!(keytable = cfg_get_strg(cf_options,"keytable"))) {
 	int i;
 
diff -Naur --exclude=CVS --exclude='*.orig' lilo/defs.h lilosh/defs.h
--- lilo/defs.h	2006-02-01 21:16:29.000000000 +0000
+++ lilosh/defs.h	2004-05-19 16:39:08.000000000 +0000
@@ -1,2 +1,3 @@
 extern void *memcpy (void *__dest, const void *__src, unsigned int __n);
 extern int strlen (__const char *__s);
+extern void *memset(void *s, int c, unsigned int n);
diff -Naur --exclude=CVS --exclude='*.orig' lilo/first.S lilosh/first.S
--- lilo/first.S	2006-02-01 21:16:29.000000000 +0000
+++ lilosh/first.S	2006-02-01 22:02:02.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: first.S,v 1.16 2000/11/26 07:11:58 gniibe Exp $
+/* $Id: first.S,v 1.1.1.1 2002/05/15 06:44:39 bmann Exp $
  *
  * Primary boot loader
  *
@@ -54,7 +54,7 @@
 	!    /* ^--- Minor Version*/     
 #endif
 
-/* x86 LILO parameters (Not used for SuperH... yet) */
+/* x86 LILO parameters (port and sparam not used for SuperH... yet) */
 timeout:.word	0		! input timeout
 delay:	.word	0		! boot delay
 port:	.byte	0		! COM port (0 = unused, 1 = COM1, etc.)
@@ -67,11 +67,13 @@
 d1_cx:	.word	0
 d1_dx:	.word	0
 d1_al:	.byte	0
+	.byte	0	! align next .word
 
 /* Second descripter sector (Filled by LILO command) */
 d2_cx:	.word	0
 d2_dx:	.word	0
 d2_al:	.byte	0
+	.byte	0	! align next .word
 
 /* Default command-line sector (Filled by LILO command) */
 dc_cx:	.word	0
@@ -87,11 +89,13 @@
 ms_cx:	.word	0
 ms_dx:	.word	0
 ms_al:	.byte	0
+	.byte	0	! align next .word
 
 /* Second descripter sector (Filled by LILO command) */
 kt_cx:	.word	0		! keyboard translation table
 kt_dx:	.word	0
 kt_al:	.byte	0
+	.byte	0	! align next .long
 
 d_addr:				! second stage sector addresses
 
diff -Naur --exclude=CVS --exclude='*.orig' lilo/geometry.c lilosh/geometry.c
--- lilo/geometry.c	2006-02-01 21:15:51.000000000 +0000
+++ lilosh/geometry.c	2006-02-01 22:13:05.000000000 +0000
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 #include <linux/fd.h>
 #include <linux/hdreg.h>
+#include <linux/kdev_t.h>
 
 #include "config.h"
 #include "lilo.h"
@@ -37,7 +38,7 @@
 
 
 DT_ENTRY *disktab = NULL;
-int old_disktab = 0;
+static int old_disktab = 0;
 
 
 void geo_init(char *name)
@@ -297,6 +298,7 @@
 	case MAJOR_ESDI:
 	    /* fall through */
 	case MAJOR_XT:
+	    /* fall through */
 	    geo->device = 0x80+(MINOR(device) >> 6)+(MAJOR(device) == MAJOR_HD ?
 	      0 : last_dev(MAJOR_HD,64));
 	    if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)
@@ -353,6 +355,17 @@
 	    geo->sectors = hdprm.sectors;
 	    geo->start = hdprm.start;
 	    break;
+	case MAJOR_NAND:
+        /* fall through */
+        geo->device = 0x80+(MINOR(device));
+        if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)
+        die("geo_query_dev HDIO_GETGEO (dev 0x%04x): %s",device,
+          strerror(errno));
+        geo->heads = hdprm.heads;
+        geo->cylinders = hdprm.cylinders;
+        geo->sectors = hdprm.sectors;
+        geo->start = hdprm.start;
+        break;
 
 	default:
 	    die("Sorry, don't know how to handle device 0x%04x",device);
diff -Naur --exclude=CVS --exclude='*.orig' lilo/geometry.h lilosh/geometry.h
--- lilo/geometry.h	2006-02-01 21:15:51.000000000 +0000
+++ lilosh/geometry.h	2006-02-01 22:14:07.000000000 +0000
@@ -8,7 +8,6 @@
 
 #include "lilo.h"
 
-
 typedef struct {
     int device,heads;
     int cylinders,sectors;
@@ -29,6 +28,7 @@
 
 extern DT_ENTRY *disktab;
 
+
 void geo_init(char *name);
 
 /* Loads the disk geometry table. */
diff -Naur --exclude=CVS --exclude='*.orig' lilo/lilo.c lilosh/lilo.c
--- lilo/lilo.c	2006-02-01 21:15:51.000000000 +0000
+++ lilosh/lilo.c	2006-02-01 21:56:56.000000000 +0000
@@ -85,11 +85,11 @@
     if (verbose > 0) {
 	bsect_read(cfg_get_strg(cf_options,"boot"),&boot);
 	printf("Global settings:\n");
-	tsecs = (boot.par_1.delay*55+50)/100;
+	tsecs = boot.par_1.delay;
 	printf("  Delay before booting: %d.%d seconds\n",tsecs/10,tsecs % 10);
 	if (boot.par_1.timeout == 0xffff) printf("  No command-line timeout\n");
 	else {
-	    tsecs = (boot.par_1.timeout*55+50)/100;
+	    tsecs = boot.par_1.timeout;
 	    printf("  Command-line timeout: %d.%d seconds\n",tsecs/10,
 	      tsecs % 10);
 	}
@@ -411,11 +411,11 @@
 	    else if (st.st_mode & (S_IWGRP | S_IWOTH))
 		    fprintf(stderr,"Warning: %s should be writable only for "
 		      "root\n",config_file);
-		else if ((cfg_get_strg(cf_all,"password") || cfg_get_strg(
-		      cf_options,"password")) && (st.st_mode & (S_IRGRP |
-		      S_IROTH)))
-			fprintf(stderr,"Warning: %s should be readable only "
-			  "for root if using PASSWORD\n",config_file);
+	    else if ((cfg_get_strg(cf_all,"password") || cfg_get_strg(
+		  cf_options,"password")) && (st.st_mode & (S_IRGRP |
+		  S_IROTH)))
+		    fprintf(stderr,"Warning: %s should be readable only "
+		      "for root if using PASSWORD\n",config_file);
 	}
     }
     preload_dev_cache();
@@ -491,7 +491,7 @@
 	    md_disk.cylinders = geo.cylinders;
 	    md_disk.start = geo.start;
 	}
-	    
+
 	pass++;
 	if (uninstall)
 	    bsect_uninstall(uninst_dev ? uninst_dev : cfg_get_strg(cf_options,
@@ -517,8 +517,8 @@
 	  cf_options,"delay")) : 0,cfg_get_strg(cf_options,"timeout") ?
 	  to_number(cfg_get_strg(cf_options,"timeout")) : -1);
 	if (more) {
-            cfg_init(cf_top);
-            if (cfg_parse(cf_top)) cfg_error("Syntax error");
+	     cfg_init(cf_top);
+	     if (cfg_parse(cf_top)) cfg_error("Syntax error");
 	}
 	if (!bsect_number()) die("No images have been defined.");
 	check_fallback();
diff -Naur --exclude=CVS --exclude='*.orig' lilo/lilo.h lilosh/lilo.h
--- lilo/lilo.h	2006-02-01 21:15:44.000000000 +0000
+++ lilosh/lilo.h	2006-02-01 21:28:33.000000000 +0000
@@ -39,6 +39,7 @@
 #define MAJOR_DAC960	48 /* First Mylex DAC960 PCI RAID controller */
 #define MAJOR_IDE5	55 /* IDE on fifth interface */
 #define MAJOR_IDE6	57 /* IDE on sixth interface */
+#define MAJOR_NAND     240 /* proprietary (board-level) nand flash block device */
 #define COMPAQ_SMART2_MAJOR	72 /* First Smart/2 Major */
 
 #define MAX_IMAGES      ((SECTOR_SIZE*2-2)/sizeof(IMAGE_DESCR))
diff -Naur --exclude=CVS --exclude='*.orig' lilo/md-int.h lilosh/md-int.h
--- lilo/md-int.h	2006-02-01 21:15:51.000000000 +0000
+++ lilosh/md-int.h	2006-02-01 22:11:13.000000000 +0000
@@ -287,4 +287,4 @@
 #define RAID5_ALGORITHM_LEFT_SYMMETRIC		2
 #define RAID5_ALGORITHM_RIGHT_SYMMETRIC		3
 
-#endif _MD_H
+#endif /* _MD_H */
diff -Naur --exclude=CVS --exclude='*.orig' lilo/md-int.h~ lilosh/md-int.h~
--- lilo/md-int.h~	1970-01-01 00:00:00.000000000 +0000
+++ lilosh/md-int.h~	2006-02-01 21:15:51.000000000 +0000
@@ -0,0 +1,290 @@
+/*
+   md.h : Multiple Devices driver for Linux
+          Copyright (C) 1994-96 Marc ZYNGIER
+	  <zyngier@ufr-info-p7.ibp.fr> or
+	  <maz@gloups.fdn.fr>
+	  
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+   
+   You should have received a copy of the GNU General Public License
+   (for example /usr/src/linux/COPYING); if not, write to the Free
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
+
+#ifndef MD_INT_H
+#define MD_INT_H
+
+/* don't include the kernel RAID header! */
+#define _MD_H
+
+typedef unsigned int md_u32;
+typedef unsigned short md_u16;
+typedef unsigned char md_u8;
+
+#include <linux/major.h>
+#include <sys/ioctl.h>
+
+/*
+ * Different major versions are not compatible.
+ * Different minor versions are only downward compatible.
+ * Different patchlevel versions are downward and upward compatible.
+ */
+
+struct md_version {
+	int major;
+	int minor;
+	int patchlevel;
+};
+
+/*
+ * default readahead
+ */
+#define MD_READAHEAD	(256 * 1024)
+
+/* These are the ioctls for md versions < 0.50 */
+#define REGISTER_MD_DEV		_IO (MD_MAJOR, 1)
+#define START_MD     		_IO (MD_MAJOR, 2)
+#define STOP_MD      		_IO (MD_MAJOR, 3)
+
+/* status */
+#define RAID_VERSION            _IOR (MD_MAJOR, 0x10, struct md_version)
+#define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, md_array_info_t)
+#define GET_DISK_INFO           _IOR (MD_MAJOR, 0x12, md_disk_info_t)
+#define PRINT_RAID_DEBUG        _IO (MD_MAJOR, 0x13)
+
+/* configuration */
+#define CLEAR_ARRAY             _IO (MD_MAJOR, 0x20)
+#define ADD_NEW_DISK            _IOW (MD_MAJOR, 0x21, md_disk_info_t)
+#define HOT_REMOVE_DISK         _IO (MD_MAJOR, 0x22)
+#define SET_ARRAY_INFO          _IOW (MD_MAJOR, 0x23, md_array_info_t)
+#define SET_DISK_INFO           _IO (MD_MAJOR, 0x24)
+#define WRITE_RAID_INFO         _IO (MD_MAJOR, 0x25)
+#define UNPROTECT_ARRAY         _IO (MD_MAJOR, 0x26)
+#define PROTECT_ARRAY           _IO (MD_MAJOR, 0x27)
+#define HOT_ADD_DISK            _IO (MD_MAJOR, 0x28)
+
+/* usage */
+#define RUN_ARRAY               _IOW (MD_MAJOR, 0x30, struct md_param)
+#define START_ARRAY             _IO (MD_MAJOR, 0x31)
+#define STOP_ARRAY              _IO (MD_MAJOR, 0x32)
+#define STOP_ARRAY_RO           _IO (MD_MAJOR, 0x33)
+#define RESTART_ARRAY_RW        _IO (MD_MAJOR, 0x34)
+
+
+/* for raid < 0.50 only */
+#define MD_PERSONALITY_SHIFT	16
+
+#define MD_RESERVED       0UL
+#define LINEAR            1UL
+#define STRIPED           2UL
+#define RAID0             STRIPED
+#define RAID1             3UL
+#define RAID5             4UL
+#define TRANSLUCENT       5UL
+#define LVM               6UL
+#define MAX_PERSONALITY   7UL
+
+/*
+ * MD superblock.
+ *
+ * The MD superblock maintains some statistics on each MD configuration.
+ * Each real device in the MD set contains it near the end of the device.
+ * Some of the ideas are copied from the ext2fs implementation.
+ *
+ * We currently use 4096 bytes as follows:
+ *
+ *	word offset	function
+ *
+ *	   0  -    31	Constant generic MD device information.
+ *        32  -    63   Generic state information.
+ *	  64  -   127	Personality specific information.
+ *	 128  -   511	12 32-words descriptors of the disks in the raid set.
+ *	 512  -   911	Reserved.
+ *	 912  -  1023	Disk specific descriptor.
+ */
+
+/*
+ * If x is the real device size in bytes, we return an apparent size of:
+ *
+ *	y = (x & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES
+ *
+ * and place the 4kB superblock at offset y.
+ */
+#define MD_RESERVED_BYTES		(64 * 1024)
+#define MD_RESERVED_SECTORS		(MD_RESERVED_BYTES / 512)
+#define MD_RESERVED_BLOCKS		(MD_RESERVED_BYTES / BLOCK_SIZE)
+
+#define MD_NEW_SIZE_SECTORS(x)		((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
+#define MD_NEW_SIZE_BLOCKS(x)		((x & ~(MD_RESERVED_BLOCKS - 1)) - MD_RESERVED_BLOCKS)
+
+#define MD_SB_BYTES			4096
+#define MD_SB_WORDS			(MD_SB_BYTES / 4)
+#define MD_SB_BLOCKS			(MD_SB_BYTES / BLOCK_SIZE)
+#define MD_SB_SECTORS			(MD_SB_BYTES / 512)
+
+/*
+ * The following are counted in 32-bit words
+ */
+#define	MD_SB_GENERIC_OFFSET		0
+#define MD_SB_PERSONALITY_OFFSET	64
+#define MD_SB_DISKS_OFFSET		128
+#define MD_SB_DESCRIPTOR_OFFSET		992
+
+#define MD_SB_GENERIC_CONSTANT_WORDS	32
+#define MD_SB_GENERIC_STATE_WORDS	32
+#define MD_SB_GENERIC_WORDS		(MD_SB_GENERIC_CONSTANT_WORDS + MD_SB_GENERIC_STATE_WORDS)
+#define MD_SB_PERSONALITY_WORDS		64
+#define MD_SB_DISKS_WORDS		384
+#define MD_SB_DESCRIPTOR_WORDS		32
+#define MD_SB_RESERVED_WORDS		(1024 - MD_SB_GENERIC_WORDS - MD_SB_PERSONALITY_WORDS - MD_SB_DISKS_WORDS - MD_SB_DESCRIPTOR_WORDS)
+#define MD_SB_EQUAL_WORDS		(MD_SB_GENERIC_WORDS + MD_SB_PERSONALITY_WORDS + MD_SB_DISKS_WORDS)
+#define MD_SB_DISKS			(MD_SB_DISKS_WORDS / MD_SB_DESCRIPTOR_WORDS)
+
+/*
+ * Device "operational" state bits
+ */
+#define MD_DISK_FAULTY		0 /* disk is faulty / operational */
+#define MD_DISK_ACTIVE		1 /* disk is running or spare disk */
+#define MD_DISK_SYNC		2 /* disk is in sync with the raid set */
+
+typedef struct md_device_descriptor_s {
+	md_u32 number;		/* 0 Device number in the entire set	      */
+	md_u32 major;		/* 1 Device major number		      */
+	md_u32 minor;		/* 2 Device minor number		      */
+	md_u32 raid_disk;	/* 3 The role of the device in the raid set   */
+	md_u32 state;		/* 4 Operational state			      */
+	md_u32 reserved[MD_SB_DESCRIPTOR_WORDS - 5];
+} md_descriptor_t;
+
+#define MD_SB_MAGIC		0xa92b4efc
+
+/*
+ * Superblock state bits
+ */
+#define MD_SB_CLEAN		0
+#define MD_SB_ERRORS		1
+
+typedef struct md_superblock_s {
+	/*
+	 * Constant generic information
+	 */
+	md_u32 md_magic;		/*  0 MD identifier 			      */
+	md_u32 major_version;	/*  1 major version to which the set conforms */
+	md_u32 minor_version;	/*  2 minor version ...			      */
+	md_u32 patch_version;	/*  3 patchlevel version ...		      */
+	md_u32 gvalid_words;	/*  4 Number of used words in this section    */
+	md_u32 set_magic;	/*  5 Raid set identifier		      */
+	md_u32 ctime;		/*  6 Creation time			      */
+	md_u32 level;		/*  7 Raid personality			      */
+	md_u32 size;		/*  8 Apparent size of each individual disk   */
+	md_u32 nr_disks;	/*  9 total disks in the raid set	      */
+	md_u32 raid_disks;	/* 10 disks in a fully functional raid set    */
+	md_u32 md_minor;	/* 11 preferred MD minor device number	      */
+	md_u32 gstate_creserved[MD_SB_GENERIC_CONSTANT_WORDS - 12];
+
+	/*
+	 * Generic state information
+	 */
+	md_u32 utime;		/*  0 Superblock update time		      */
+	md_u32 state;		/*  1 State bits (clean, ...)		      */
+	md_u32 active_disks;	/*  2 Number of currently active disks	      */
+	md_u32 working_disks;	/*  3 Number of working disks		      */
+	md_u32 failed_disks;	/*  4 Number of failed disks		      */
+	md_u32 spare_disks;	/*  5 Number of spare disks		      */
+	md_u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 6];
+
+	/*
+	 * Personality information
+	 */
+	md_u32 layout;		/*  0 the array's physical layout	      */
+	md_u32 chunk_size;	/*  1 chunk size in bytes		      */
+	md_u32 pstate_reserved[MD_SB_PERSONALITY_WORDS - 2];
+
+	/*
+	 * Disks information
+	 */
+	md_descriptor_t disks[MD_SB_DISKS];
+
+	/*
+	 * Reserved
+	 */
+	md_u32 reserved[MD_SB_RESERVED_WORDS];
+
+	/*
+	 * Active descriptor
+	 */
+	md_descriptor_t descriptor;
+
+} md_superblock_t;
+
+/*
+ * options passed in raidstart:
+ */
+
+#define MAX_CHUNK_SIZE (4096*1024)
+
+struct md_param
+{
+	int			personality;	/* 1,2,3,4 */
+	int			chunk_size;	/* in bytes */
+	int			max_fault;	/* unused for now */
+};
+
+typedef struct md_array_info_s {
+	/*
+	 * Generic constant information
+	 */
+	md_u32 major_version;
+	md_u32 minor_version;
+	md_u32 patch_version;
+	md_u32 ctime;
+	md_u32 level;
+	md_u32 size;
+	md_u32 nr_disks;
+	md_u32 raid_disks;
+	md_u32 md_minor;
+	md_u32 not_persistent;
+
+	/*
+	 * Generic state information
+	 */
+	md_u32 utime;		/*  0 Superblock update time		      */
+	md_u32 state;		/*  1 State bits (clean, ...)		      */
+	md_u32 active_disks;	/*  2 Number of currently active disks	      */
+	md_u32 working_disks;	/*  3 Number of working disks		      */
+	md_u32 failed_disks;	/*  4 Number of failed disks		      */
+	md_u32 spare_disks;	/*  5 Number of spare disks		      */
+
+	/*
+	 * Personality information
+	 */
+	md_u32 layout;		/*  0 the array's physical layout	      */
+	md_u32 chunk_size;	/*  1 chunk size in bytes		      */
+
+} md_array_info_t;
+
+typedef struct md_disk_info_s {
+	/*
+	 * configuration/status of one particular disk
+	 */
+	md_u32 number;
+	md_u32 major;
+	md_u32 minor;
+	md_u32 raid_disk;
+	md_u32 state;
+
+} md_disk_info_t;
+
+
+/*
+ * Supported RAID5 algorithms
+ */
+#define RAID5_ALGORITHM_LEFT_ASYMMETRIC		0
+#define RAID5_ALGORITHM_RIGHT_ASYMMETRIC	1
+#define RAID5_ALGORITHM_LEFT_SYMMETRIC		2
+#define RAID5_ALGORITHM_RIGHT_SYMMETRIC		3
+
+#endif _MD_H
diff -Naur --exclude=CVS --exclude='*.orig' lilo/partition.c lilosh/partition.c
--- lilo/partition.c	1998-10-14 20:12:42.000000000 +0000
+++ lilosh/partition.c	2006-01-31 19:51:58.000000000 +0000
@@ -13,6 +13,8 @@
 #include <sys/stat.h>
 
 #include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kdev_t.h>
 
 #include "config.h"
 #include "lilo.h"
@@ -23,7 +25,7 @@
 
 
 /* For older kernels ... */
- 
+#if 0
 #ifndef DOS_EXTENDED_PARTITION
 #define DOS_EXTENDED_PARTITION EXTENDED_PARTITION
 #endif
@@ -31,6 +33,7 @@
 #ifndef LINUX_EXTENDED_PARTITION
 #define LINUX_EXTENDED_PARTITION EXTENDED_PARTITION
 #endif
+#endif
 
 
 void part_verify(int dev_nr,int type)
diff -Naur --exclude=CVS --exclude='*.orig' lilo/second.c lilosh/second.c
--- lilo/second.c	2006-02-01 21:16:41.000000000 +0000
+++ lilosh/second.c	2006-02-01 20:25:07.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: second.c,v 1.22 2000/11/26 07:11:16 gniibe Exp $
+/* $Id: second.c,v 1.6 2004/10/01 19:05:58 cpchen Exp $
  *
  * Secondary boot loader
  *
@@ -12,7 +12,35 @@
  */
 
 #include "defs.h"
+#include "common.h"
 
+#define TAB_CHAR	'\t'
+#define BACKSPACE	'\b'
+
+#define R64CNT		0xFFC80000
+#define RSECCNT		0xFFC80004
+#define RMINCNT		0xFFC80008
+#define RHRCNT		0xFFC8000C
+#define RSECAR		0xFFC80020
+#define RMINAR		0xFFC80024
+#define RHRAR		0xFFC80028
+#define RWKAR		0xFFC8002C
+#define RDAYAR		0xFFC80030
+#define RMONAR		0xFFC80034
+#define	RTCRCR1		0xFFC80038
+#define	RTCRCR2		0xFFC8003C
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+static inline char get_char(void);
+static void dump_image_names(DESCR_SECTORS *);
+static IMAGE_DESCR * descr_label_match(char *);
 static void put_string (unsigned char *);
 static int get_sector_address (unsigned long, int *, unsigned long *);
 static int load_sectors (unsigned long, unsigned long);
@@ -30,19 +58,35 @@
 static inline char highhex (int x) {  return hexchars[(x >> 4) & 0xf];  }
 static inline char lowhex (int x) {  return hexchars[x & 0xf];  }
 static void printouthex (int);
+static void set_delay(short delay);
+static inline int lilo_timeout() {
+	return *((char *) RTCRCR1) & 0x01;
+}
 
 static unsigned long base_pointer = 0;	/* Avoid BSS */
 static unsigned long kernel_image = 0;	/* Avoid BSS */
+static unsigned long initrd_start = 0;
+static unsigned long initrd_end = 0;
+
+#define INPUT_BUF_SIZE	256
+static char input_buffer[INPUT_BUF_SIZE];
 
 /* Sector descriptor */
 #define SD_DESCR1	24
+#define SD_DESCR1_MEM	0x3200
 #define SD_DESCR2	29
+#define SD_DESCR2_MEM	0x3400
 #define SD_DEFCMD	34
 /* 39 prompt (byte) */
 /* 40 length (word) */
 #define SD_MSG		42
 #define SD_KBDTBL	47
 
+/* use the section attribute and linker script to force the start function to 
+   the beginning of the second stage reserved area.  
+   This is where first.S will jmp */ 
+void start (unsigned long base) __attribute__((section(".entry")));
+
 static inline char *string_set (char *dest, const char *str)
 {
   int len = strlen (str);
@@ -53,11 +97,16 @@
 void
 start (unsigned long base)
 {
-  base_pointer = base;
+	base_pointer = base;
+	unsigned char ch;
+	int input_idx;
+	IMAGE_DESCR *image_descr;
+	int desc;
+	int defer_delay=0;
 
   put_string ("I");
-  load_sectors (SD_DESCR1, 0x3200);
-  load_sectors (SD_DESCR2, 0x3400);
+  load_sectors (SD_DESCR1, SD_DESCR1_MEM);
+  load_sectors (SD_DESCR2, SD_DESCR2_MEM);
   put_string ("L");
   /* XXX: checksum */
 
@@ -73,30 +122,72 @@
   /* XXX: check signature */
   /* Input command line */
   /* XXX: Is there default command line?  Use it! */
-  put_string ("boot: ");
-  put_string ("first-image\n");	/* XXX: should handle input commandline... */
 
-  /* Structure of descriptor
-   [ checksum 2byte ]
-   [ DESCR_SIZE:52-byte
-      (image-name (16-byte)
-       passwd     (16-byte)
-       rd_size    (4-byte)
-       initrd     (5-byte sector desc)
-       start      (5-byte sector desc)
-       start_page (16-bit)
-       flags      (16-bit)
-       vga_mode   (16-bit)
-      )
-   ] * 19
-  */
+	/* Structure of descriptor
+	[ checksum 2byte ]
+	[ DESCR_SIZE:52-byte
+	(image-name (16-byte)
+	passwd     (16-byte)
+	rd_size    (4-byte)
+	initrd     (5-byte sector desc)
+	start      (5-byte sector desc)
+	start_page (16-bit)
+	flags      (16-bit)
+	vga_mode   (16-bit)
+	)
+	] * 19
+	*/
+
+	input_buffer[0] = '\0';
+	if (((BOOT_SECTOR *) base_pointer)->par_1.prompt) {
+		if (((BOOT_SECTOR *) base_pointer)->par_1.timeout != 0xffff)
+			set_delay(((BOOT_SECTOR *) base_pointer)->par_1.timeout);
+boot_loop:
+		input_idx = 0;
+		put_string ("boot: ");
+		while ((ch=get_char()) != 0x0d && input_idx < INPUT_BUF_SIZE-1) {
+			switch (ch) {
+				case TAB_CHAR:
+					defer_delay = 1;
+					dump_image_names((DESCR_SECTORS *) (base_pointer + SD_DESCR1_MEM));
+					goto boot_loop;
+					break;
+				case BACKSPACE:
+					defer_delay = 1;
+					if (input_idx) --input_idx;
+					break;
+				case 0x00FF:
+					break;
+				default:
+					defer_delay = 1;
+					input_buffer[input_idx++] = ch;
+					break;
+			}
+			if (!defer_delay && lilo_timeout())
+				break;
+		}
+		input_buffer[input_idx++] = ' ';
+		input_buffer[input_idx] = '\0';
+		if ( ! (image_descr = descr_label_match(input_buffer)) ) {
+			put_string("No such image. [Tab] shows a list.\n");
+			goto boot_loop;
+		}
+	}
+	else {
+		// dispatch the default image after the delayed timeout
+		// 0 or default == immediate dispatch
+		set_delay(((BOOT_SECTOR *) base_pointer)->par_1.delay);
+		do {
+		} while (!lilo_timeout()); /* NULL */
+		image_descr = descr_label_match(input_buffer);
+	}
 
   put_string ("Loading ");
-  put_string ((char *)(base_pointer+0x3200+2)); /* Image name */
+	put_string (image_descr->name); /* Image name */
 
   kernel_image = base_pointer + 0x10000 - 0x400;
   {
-    int desc = 0x3200+2+16+16+4+5; /* kernel image */
+    desc = (int) image_descr+(16+16+4+5) - (int) base_pointer;
 
     /* Skip two sectors: Fallback command line and options */
     desc = load_sectors_with_maps (desc, 0, &kernel_image);
@@ -108,7 +199,21 @@
 	put_string (".");
       }
   }
-  put_string ("done.\n");
+  put_string ("done.\n\n");
+
+	desc = (int) image_descr+(16+16+4) - (int) base_pointer;
+	initrd_start = kernel_image = 0x88000000 + memory_size() / 2;
+	desc = load_sectors_with_maps (desc, 0, &kernel_image);
+	if (desc) {
+		put_string("ramdisk image loading");
+		put_string(".");
+		while (desc != 0) {
+			desc = load_sectors_with_maps (desc, 0, &kernel_image);
+			put_string(".");
+		}
+		put_string ("done.\n\n");
+	}
+	initrd_end = kernel_image;
 
 #if 0
   {
@@ -123,24 +228,39 @@
 
   /* XXX: kernel paramerter setting */
   {
-    unsigned long parm = base_pointer - 0x200000 + 0x1000;
+    unsigned long parm = base_pointer + (~0x9cf000+1);
     char *cmdline = (char *)(parm+256);
     int mem_size;
-    unsigned char *p;
+    unsigned char *p, *debug_p;
 
     *(long *)parm      = 1;	/* Read only mount? */
     *(long *)(parm+4)  = 0;	/* RAMDISK Flags */
     *(long *)(parm+8)  = 0x0301; /* Root device: XXX should get from cls.. */
     *(long *)(parm+12) = 1;	/* Loader type (LILO = 1) */
-    *(long *)(parm+16) = 0;	/* Initrd start */
-    *(long *)(parm+20) = 0;	/* Initrd size */
+	if (initrd_end - initrd_start) {
+		initrd_start += ~0x88030000 + 1;
+    	*(long *)(parm+16) = initrd_start;		/* Initrd start */
+    	initrd_end += ~0x88030000 + 1;			/* Initrd size */
+    	*(long *)(parm+20) = initrd_end + (~initrd_start + 1);/* Initrd size */
+	}
+	else {
+    	*(long *)(parm+16) = 0;	/* Initrd start */
+    	*(long *)(parm+20) = 0;	/* Initrd size */
+	}
     *(long *)(parm+24) = 0;	/* Not defined yet */
 
     /* XXX: Should take the line from command line sector... */
+	if (*input_buffer) {
+		debug_p = cmdline;
+		cmdline = string_set(cmdline, input_buffer);
+		*cmdline = '\0';
+	}
+
 #define DC_MAGIC	0xf4f2	/* magic number of default cmd. line sector */
     p = (unsigned char *)(base_pointer+0x3600);
     if(p[0] == (DC_MAGIC & 0xff) && p[1] == (DC_MAGIC >> 8))
       cmdline = string_set(cmdline, p+2);
+
     cmdline = string_set(cmdline, (char *)(base_pointer + 0x10000 - 0x200));
 
 #if 0
@@ -231,7 +351,7 @@
   /* There's next map */
   return 0x3000+505;
 }
-
+
 static int
 machine_type (void)
 {
@@ -296,6 +416,77 @@
 		: "memory");
 }
 
+static char inline
+get_char(void)
+{
+  register long __sc0 __asm__ ("r0") = 1; /* OUTPUT */
+
+  asm volatile ("trapa	#0x3F"
+		: "=z" (__sc0)
+		: "0" (__sc0)
+		: "memory");
+  return __sc0;
+}
+
+static IMAGE_DESCR *
+descr_label_match(char * boot_buffer)
+{
+	IMAGE_DESCR *descr =
+		((DESCR_SECTORS *) (base_pointer + SD_DESCR1_MEM))->d.descr;
+	char * buf_ptr=boot_buffer;
+	char * name;
+
+	while (*boot_buffer && (*boot_buffer == ' ' || *boot_buffer == '\t'))
+		++boot_buffer;
+
+	if ( ! *boot_buffer ) {
+		return descr;
+	}
+
+	for ( buf_ptr=boot_buffer; *descr->name; ++descr, buf_ptr=boot_buffer) {
+		name = descr->name;
+		for ( ; *name == *buf_ptr; ++name, ++buf_ptr) ;
+		if (!*name && (!*buf_ptr || *buf_ptr == ' ' || *buf_ptr == '\t')) {
+			// overwrite the boot_buffer with the string after the 
+			// boot image name.
+			while (*boot_buffer++ = *buf_ptr++) ;
+			return descr;
+		}
+	}
+	return NULL;
+}
+
+static void
+dump_image_names(DESCR_SECTORS *descr_area)
+{
+	int buf_idx=0, name_len;
+	char * name;
+	IMAGE_DESCR *descr = descr_area->d.descr;
+
+	put_string("\n");
+	for ( ; *descr->name; ++descr)
+	{
+		name = descr->name;
+		name_len = strlen(name);
+		memcpy(input_buffer + buf_idx, name, name_len);
+		buf_idx += name_len;
+		name_len = MAX_IMAGE_NAME+1 - name_len;
+		memset(input_buffer + buf_idx, ' ', name_len);
+		buf_idx += name_len;
+		if (  buf_idx >= 78 ) {
+			input_buffer[buf_idx++] = '\n';
+			input_buffer[buf_idx++] = '\0';
+			put_string(input_buffer);
+			buf_idx = 0;
+		}
+	}
+	if (buf_idx) {
+		input_buffer[buf_idx++] = '\n';
+		input_buffer[buf_idx] = '\0';
+		put_string(input_buffer);
+	}
+}
+
 static void inline
 put_string_1 (unsigned char *str, long len)
 {
@@ -344,15 +535,17 @@
   unsigned char *p = (unsigned char *)(sector_desc+base_pointer);
   int len;
 
+
   /* Number of sectors */
   len = (int)p[4];
   if (len == 0)
     return 0;
 
   /* p[2]: drive number */
-  if ((int)p[2] < 0xc0)
+  if ((int)p[2] < 0xc0) {
     /* XXX: should return error */
     put_string ("ERROR: Sector address is not in LBA\n");
+	}
 
   *devp = (int)p[2] & 0x0f;
 
@@ -394,8 +587,56 @@
 
   return -1;
 }
-
-#if 0
+
+static void set_delay(short delay)
+{
+	char rtc_sec, rtc_min, rtc_hr;
+	int alarm_time;
+	char arm_sec, arm_min, arm_hr;
+	char regval;
+	char tenths, seconds, minutes, hour;
+
+	// Make sure the RTC is running
+	*(char*)RTCRCR2 = 0x09;
+
+	// Make sure ENB bits are off
+	*(char*)RWKAR &= 0x7f;
+	*(char*)RDAYAR &= 0x7f;
+	*(char*)RMONAR &= 0x7f;
+
+	// Read time
+	do {
+		*(char*)RTCRCR1 = 0x00;    // Clear CF-bit
+		rtc_sec = *(char*)RSECCNT;
+		rtc_min = *(char*)RMINCNT;
+		rtc_hr = *(char*)RHRCNT;
+	} while ((*(char*)RTCRCR1 & 0x80) != 0);
+
+	BCD_TO_BIN(rtc_hr);
+	BCD_TO_BIN(rtc_min);
+	BCD_TO_BIN(rtc_sec);
+
+	alarm_time = ((rtc_hr * 60) + rtc_min) * 60 + rtc_sec + (delay / 10);
+
+	arm_sec = alarm_time % 60;
+	arm_min = (alarm_time / 60) % 60;
+	arm_hr = alarm_time / 3600;
+	if (arm_hr >= 24)
+		arm_hr = arm_hr - 24;
+
+	BIN_TO_BCD(arm_sec);
+	BIN_TO_BCD(arm_min);
+	BIN_TO_BCD(arm_hr);
+
+	*(char*)RSECAR = arm_sec | 0x80;
+	*(char*)RMINAR = arm_min | 0x80;
+	*(char*)RHRAR = arm_hr | 0x80;
+
+	// Clear AF bit
+	*(char*)RTCRCR1 = 0;
+}
+
+#if 1
 static void
 printouthex(int x)
 {
@@ -408,4 +649,14 @@
 
   put_string (z);
 }
+
+static void dump_desc(char * desc)
+{
+	printouthex((int) desc[0]);
+	printouthex((int) desc[1]);
+	printouthex((int) desc[2]);
+	printouthex((int) desc[3]);
+	printouthex((int) desc[4]);
+	put_string("\n");
+}
 #endif
diff -Naur --exclude=CVS --exclude='*.orig' lilo/second.lds lilosh/second.lds
--- lilo/second.lds	2006-02-01 21:16:41.000000000 +0000
+++ lilosh/second.lds	2006-01-31 22:44:27.000000000 +0000
@@ -83,6 +83,7 @@
   .plt      : { *(.plt)	}
   .text      :
   {
+    *(.entry)
     *(.text)
     *(.text.*)
     *(.stub)
diff -Naur --exclude=CVS --exclude='*.orig' lilo/string.c lilosh/string.c
--- lilo/string.c	2006-02-01 21:16:41.000000000 +0000
+++ lilosh/string.c	2004-05-19 16:39:08.000000000 +0000
@@ -20,3 +20,8 @@
 
 	return dest;
 }
+
+void * memset(void * dest, int val, unsigned int count)
+{
+	while (count--) *((char *)dest++) = val;
+}