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 #include #include +#include #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 #include #include +#include #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 + or + + + 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 +#include + +/* + * 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 #include +#include +#include #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; +}