This third part is open for debate: it is using some Gujin exported
 variables to search for the root filesystem: Gujin knows from which
 disk/partition it loads the KGZ kernel file - and so the real mode
 kernel function can deduce where is its root if it knows the order
 of the IDE interfaces and the initial name of the kernel at GZIP
 time (either "make /boot/kernel.kgz" or "make /kernel.kgz" with or
 without a separate partition for /boot).

Signed-off-by: Etienne Lorrain <[EMAIL PROTECTED]>
diff -uprN -X linux-2.6.13/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x 
'.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x 
asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x 
consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x 
scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map 
-x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x 
crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list 
linux-2.6.13-2/arch/i386/kernel/realmode.c 
linux-2.6.13-3/arch/i386/kernel/realmode.c
--- linux-2.6.13-2/arch/i386/kernel/realmode.c  2005-08-31 00:25:48.000000000 
+0100
+++ linux-2.6.13-3/arch/i386/kernel/realmode.c  2005-08-31 00:26:26.000000000 
+0100
@@ -1250,11 +1250,569 @@ vmlinuz_CMDLINE (char *command_line, con
        *cmdptr = '\0';
 }
 
+/**
+ ** OPTIONAL: If we want to use the data structures of Gujin to try to
+ ** find and match the root filesystem of the kernel loaded (that part
+ ** can be completely disabled):
+ **/
+#ifdef ROOT_EXTENSIVE_SEARCH
+
+struct desc_str {
+       unsigned inode;
+       unsigned filesize;
+       unsigned char disk;
+       unsigned char partition;        /* 0xFF for MBR */
+       unsigned char name_offset;      /* to after the pattern */
+        enum curdir_e { inRoot = 0, inSlashBoot, inSlashImage } curdir  : 3;
+        enum boottype_e { is_MBR, is_PBR, is_kernel_with_header,
+               is_kernel_without_header, is_initrd,
+               is_bdi_file, is_el_torito } boottype : 3;
+        unsigned char unused     : 2;
+#define NAME_LENGTH    52
+       char filename[NAME_LENGTH];
+} __attribute__ ((packed));
+
+struct gpl_compliant_str {
+       unsigned signature;
+       unsigned version;
+       unsigned feature;
+       unsigned size;
+       struct setjmp_buf {
+               unsigned esi, edi, ebp, ebx;
+               unsigned short gs, fs, es, ds;
+               unsigned short flags, ip, cs, sp, ss;
+       } __attribute__ ((packed)) jmpbuf;
+       /* unsigned short padding */
+       unsigned filename_array, gdt, regs, fourKbuffer;
+       unsigned LOADER, STATE, UI, MOUSE, DI, UTIL, BOOTWAY;
+};
+
+typedef struct {
+       unsigned char  header_id_0x01;
+       enum { platform_80x86 = 0, platform_PowerPC = 1,
+               platform_Mac = 2 } platform_id : 8;
+       unsigned short reserved;
+       unsigned char  manufacturer[0x1B - 0x04 +1];
+       unsigned short checksum;
+       unsigned char  signature1_0x55;
+       unsigned char  signature2_0xAA;
+} __attribute__ ((packed)) ISO9660_Validation_entry;
+
+typedef struct {
+       unsigned char  boot_indicator; /* 0x88: bootable, 0x00: non bootable */
+       enum { boot_media_noemul = 0, boot_media_120 = 1, boot_media_144 = 2,
+               boot_media_288 = 3, boot_media_hd = 4 } boot_media_type : 8;
+       unsigned short load_segment; /* 0x7c0 if null */
+       unsigned char  system_type;
+       unsigned char  unused;
+       unsigned short sector_count;
+       unsigned       sector_lba;
+       unsigned char  reserved[0x1F - 0x0C +1];
+} __attribute__ ((packed)) ISO9660_Default_entry;
+
+struct diskparam_str {
+       enum {  bios_chs, ebios_lba,
+               hardide_chs, hardide_lba, hardide_lba48, hardide_atapi,
+               dos_part
+       } access : 8;
+       unsigned char   disknb; /* BIOS number or DOS letter
+                                  or 0=master, non zero=slave */
+       unsigned char   biostype;       /* 1:floppy w/o change detect,
+                                                2: with, 3: HD */
+       unsigned char   drivetype;      /* 1: 360K, 2: 1.2M, 3: 720K,
+                                        4: 1.44M, 6: 2.88M, 0x10: ATAPI */
+       unsigned char   diskname[32];
+
+       struct ide_attribute_str {
+               unsigned smart                  : 1;
+               unsigned host_protected_area    : 1;
+               unsigned security               : 1;
+               unsigned lba48                  : 1;
+               unsigned removable              : 1;
+               unsigned SAORAB                 : 1;
+               unsigned config_overlay         : 1;
+               unsigned reserved               : 25;
+       } ide_attribute;
+       struct error_log_str {
+               unsigned read_media                     : 1;
+               unsigned write_media                    : 1;
+               unsigned access_over_disk_tryed         : 1;
+               unsigned access_over_partition_tryed    : 1;
+               unsigned no_ebios_fct                   : 1;
+               unsigned ebios_size_zero                : 1;
+               unsigned chs_bios_part_mismatch         : 1;
+               unsigned chs_ajusted_bootsect           : 1;
+               unsigned diskheader_ignored             : 1;
+               unsigned disk_locked                    : 1;
+               unsigned disk_was_pw_locked             : 1;
+               unsigned SMART_disabled                 : 1;
+               unsigned SMART_failure                  : 1;
+               unsigned analyse_partition_failed       : 1;
+               unsigned NB_PARTITION_exceded           : 1;
+               unsigned partition_overlap              : 1;
+               unsigned partition_over_limit           : 1;
+               unsigned beer_checksum_error            : 1;
+               unsigned beer_in_extended_partition     : 1;
+               unsigned reserved                       : 13;
+       } error_log;
+       unsigned short  bytepersector;
+       unsigned short  nbhead;           /* DOS: MediaDescriptorByte */
+       unsigned        nbcylinder;       /* DOS: ClustersOnDisk */
+       unsigned        BEER_size;
+       unsigned long long      BEER_sector;
+       unsigned long long      BEER_HostProtectedArea_start;
+       unsigned long long      BEER_ReservedAreaBootCodeAddress;
+       unsigned long long      BEER_disksize;
+         signed long long      fulldisk_offset; /* Nb sectors before MBR */
+       unsigned long long      fulldisk_size;   /* only if MBR is offseted */
+       unsigned long long      nbtotalsector;
+       unsigned long long      config_max_lba;
+       unsigned short  nbsectorpertrack; /* DOS: SectorPerCluster */
+
+       unsigned short  infobit;        /* Int13/48 extensions */
+       unsigned char   ebios_version;  /* if present, used if access = ebios */
+       unsigned char   ebios_extension;
+       ebios_bitmap_t  ebios_bitmap;
+       unsigned short  reserved3;      /* ebios_bitmap is 16 bits */
+
+       unsigned char  ebios_bustype[4];        /* exactly "ISA" or "PCI" */
+       unsigned char  ebios_Interface[8];      /* exactly "ATA", "ATAPI",
+                                                       "SCSI", "USB"...*/
+       union interface_path_u  ebios_bus;
+       union device_path_u     ebios_device;
+
+       unsigned short  reserved4;
+
+       unsigned short  ide_master_password_revision; /* if 
command_supported1.security */
+       unsigned short  ideIOadr;       /* if known, else 0 */
+       unsigned short  ideIOctrladr;   /* if known, else 0 */
+       unsigned char   lba_slave_mask; /* see Phenix Bios (head | mask) */
+       unsigned char   irq;            /* if known, else 0 */
+       unsigned char   multiplemode;   /* int 0x13/0x21,0x22,0x24 or hardide,
+                                               set but not used. */
+       unsigned char   BEER_device_index;
+       struct config_multiword_dma_s {
+               unsigned short  mode0    : 1;
+               unsigned short  mode1    : 1; /* and below */
+               unsigned short  mode2    : 1; /* and below */
+               unsigned short  reserved : 13;
+       } __attribute__ ((packed)) initial_multiDMA, maximum_multiDMA;
+       struct config_ultra_dma_s {
+               unsigned short  mode0    : 1;
+               unsigned short  mode1    : 1; /* and below */
+               unsigned short  mode2    : 1; /* and below */
+               unsigned short  mode3    : 1; /* and below */
+               unsigned short  mode4    : 1; /* and below */
+               unsigned short  mode5    : 1; /* and below */
+               unsigned short  reserved : 10;
+       } __attribute__ ((packed)) initial_ultraDMA, maximum_ultraDMA;
+       struct config_feature_s {
+               unsigned short  smart_feature   : 1;
+               unsigned short  smart_selftest  : 1;
+               unsigned short  smart_errorlog  : 1;
+               unsigned short  security        : 1;
+               unsigned short  standby_powerup : 1;
+               unsigned short  RW_DMA_queued   : 1;
+               unsigned short  acoustic        : 1;
+               unsigned short  host_prot_area  : 1;
+               unsigned short  lba48           : 1;
+               unsigned short  reserved        : 7;
+       } __attribute__ ((packed)) initial_feature, maximum_feature;
+       unsigned        CalibrationIdeloop; /* nanoseconds (10^-9) per loop */
+
+       /* Following three only for C/H/S partition, from standard BIOS: */
+       unsigned short  bios_nbcylinder;        /* max 1024 */
+       unsigned char   bios_nbhead;            /* max 256 */
+       unsigned char   bios_nbsectorpertrack;  /* max 63 */
+
+       unsigned char   bootable;       /* nonzero: bootable,
+                                > 1 when special bootsector recognised */
+       unsigned char   OSdisknumber;   /* as written in the boot block */
+
+       unsigned short  nbpartition;
+       unsigned short  nbOSnumber;
+       unsigned short  reserved5;
+       /* Following value is current extended primary partition,
+          if there is more than one extended primary partition. */
+       union {
+               unsigned    first_ext_partition_start; /* NOT A LONG LONG */
+               ISO9660_Validation_entry *ElToritoValidation; /* first one only 
*/
+               ISO9660_Default_entry *ElToritoCatalog; /* array index >= 1 */
+       };
+       struct partition_str {
+               unsigned long long      start, length;
+               /* OSnumber should be equal to the # in /dev/hda#: */
+               unsigned char   type, OSnumber;
+               struct partition_misc_str {
+                       /* order as found on disk: */
+                       unsigned char order             : 6;
+                       unsigned char fsanalyse_toobig  : 1;
+                       unsigned char fsanalyse_error   : 1;
+                       unsigned char maybe_root        : 1;
+                       unsigned char fat_bootable      : 1;
+                       unsigned char beer_partition    : 1;
+                       unsigned char swap_partition    : 1;
+                       unsigned char reserved          : 2;
+                       enum part_state {
+                               part_invalid = 0, part_active,
+                               part_inactive, part_extended
+                       } active                : 2;
+               } __attribute__ ((packed)) misc;
+#define MAX_DISKNAMESIZE       (64-20) /* bigger than "floppy" */
+               unsigned char   name[MAX_DISKNAMESIZE];
+       } __attribute__ ((packed)) *partition;
+
+       unsigned        nbfreelist;
+       struct freelist_str {
+               unsigned long long start, length;
+       } *freelist;
+       char set_max_password[32];
+       } *param;
+
+struct disk_interface_str {
+       unsigned        nbdisk;
+       unsigned char   max_disk, max_partition, max_freelist, max_IDE_found;
+       unsigned short  sizeof_diskparam_str, sizeof_partition_str;
+       unsigned short  sizeof_freelist_str, sizeof_IDE_found_str;
+       unsigned char   nb_bios_fd, nb_bios_hd, cannot_reset_floppy,
+                       nb_bios_blacklist;
+       unsigned char   bios_blacklist[4];
+       unsigned        reserved1[2];
+       unsigned char   (*readsector) (struct diskparam_str *dp, int partition,
+                               unsigned long long lba, unsigned number,
+                               farptr buffer);
+       unsigned char   (*writesector) (struct diskparam_str *dp, int partition,
+                               unsigned long long lba, unsigned number,
+                               farptr buffer);
+       int             (*ideSecurity) (struct diskparam_str *, char *,
+                                        unsigned);
+       unsigned long long last_lba_read_or_write;
+       struct diskparam_str *param;
+       unsigned        nb_IDE_found;
+       struct IDE_found_str {
+               unsigned short  ideIOadr;
+               unsigned short  ideIOctrladr;
+               unsigned char   irq;
+               unsigned char   bios_order;
+               unsigned short  reserved;
+       } *IDE_found;
+};
+
+CODE static inline int
+add_hexletter (unsigned short *val, unsigned char hexletter)
+{
+       if (hexletter >= '0' && hexletter <= '9')
+               *val = (*val << 4) + hexletter - '0';
+       else if (hexletter >= 'a' && hexletter <= 'f')
+               *val = (*val << 4) + hexletter - 'a' + 10;
+       else if (hexletter >= 'A' && hexletter <= 'F')
+               *val = (*val << 4) + hexletter - 'A' + 10;
+       else
+               return 1;
+       return 0;
+}
+
+/* If the "ide[0-9]=" are already given on the command line, that may
+   indicate the user wants a special order - and we probe that order
+   to guess the root partition: */
+CODE static inline void
+init_IDE_found_from_cmdline (struct IDE_found_str *IDE_found,
+               const unsigned nb_IDE_found, const char *cmdptr)
+{
+       while (*cmdptr) {
+               if (cmdptr[0] == 'i' && cmdptr[1] == 'd' && cmdptr[2] == 'e'
+                       && cmdptr[3] >= '0' && cmdptr[3] <= '9'
+                       && cmdptr[4] == '='
+                       && cmdptr[5] == '0' && cmdptr[6] == 'x') {
+                       unsigned short IOaddr = 0, IOctrladr = 0;
+                       unsigned short index = cmdptr[3] - '0';
+                       unsigned char irq = 0;
+
+                       cmdptr += 7;
+                       while (add_hexletter (&IOaddr, *cmdptr) == 0)
+                               cmdptr++;
+                       /* Why did you read up to here? Don't you trust me? */
+                       if (cmdptr[0] == ',' && cmdptr[1] == '0'
+                                            && cmdptr[2] == 'x') {
+                               cmdptr += 3;
+                               while (add_hexletter (&IOctrladr, *cmdptr) == 0)
+                                       cmdptr++;
+                               if (*cmdptr == ',') {
+                                       cmdptr++;
+                                       while (*cmdptr >= '0' && *cmdptr <= '9')
+                                               irq = (irq * 10) + *cmdptr++ - 
'0';
+                               }
+                       }
+
+                       /* first unknown char shall be spacing or end of string 
*/
+                       if (   (*cmdptr == ' ' || *cmdptr == '\0')
+                           && index < nb_IDE_found)
+                               IDE_found[index] = (struct IDE_found_str) {
+                                       .ideIOadr       = IOaddr,
+                                       .ideIOctrladr   = IOctrladr,
+                                       .irq            = irq,
+                                       .bios_order     = 0xFF,
+                                       .reserved       = 0
+                                       };
+               }
+               else
+                       cmdptr++;
+       }
+}
+
+/* If no "ide[0-9]=" given, we use the BIOS order found by Gujin;
+  if Gujin knows more IDEs (just one ide added like: ide2=0x...
+  but not ide0= and ide1=) add the obvious missing ones,
+  without erasing nor offseting the user given information: */
+CODE static inline void
+init_IDE_found_from_DI (struct IDE_found_str *IDE_found,
+               const unsigned nb_IDE_found,
+               const struct disk_interface_str *DI)
+{
+       unsigned cpt;
+
+       for (cpt = 0; cpt < DI->nb_IDE_found; cpt++) {
+               unsigned i, j;
+               for (i = 0; i < nb_IDE_found; i++)
+                       if (IDE_found[i].ideIOadr == 
DI->IDE_found[cpt].ideIOadr)
+                               break;
+               if (i < nb_IDE_found)
+                       continue; /* already given */
+               for (j = 0; j < nb_IDE_found; j++)
+                       if (IDE_found[j].ideIOadr == 0)
+                               break; /* first unused */
+               if (j < nb_IDE_found)
+                       IDE_found[j] = DI->IDE_found[cpt];
+       }
+}
+
+CODE static inline void
+finalise_cmdline (struct IDE_found_str *IDE_found, unsigned nb_IDE_found,
+                 char *command_line)
+{
+       static CONST char itoa_array[] = "0123456789abcdef";
+       unsigned cpt;
+       char *cmdptr = command_line;
+
+       while (*cmdptr != '\0')
+               cmdptr++;
+       for (cpt = 0; cpt < nb_IDE_found; cpt++) {
+               unsigned short val;
+               if (   IDE_found[cpt].ideIOadr == 0
+                   || IDE_found[cpt].bios_order == 0xFF)
+                       continue;
+               if (cmdptr - command_line > 1024)
+                       break;
+               *cmdptr++ = ' ';
+               *cmdptr++ = 'i'; *cmdptr++ = 'd'; *cmdptr++ = 'e';
+               *cmdptr++ = '0' + cpt;
+               *cmdptr++ = '='; *cmdptr++ = '0'; *cmdptr++ = 'x';
+               val = IDE_found[cpt].ideIOadr;
+               if (val & 0xF000)
+                       *cmdptr++ = itoa_array[val >> 12];
+               *cmdptr++ = itoa_array[(val >> 8) & 0x0F];
+               *cmdptr++ = itoa_array[(val >> 4) & 0x0F];
+               *cmdptr++ = itoa_array[(val >> 0) & 0x0F];
+               val = IDE_found[cpt].ideIOctrladr;
+               if (val) {
+                       *cmdptr++ = ',';
+                       *cmdptr++ = '0';
+                       *cmdptr++ = 'x';
+                       if (val & 0xF000)
+                               *cmdptr++ = itoa_array[val >> 12];
+                       *cmdptr++ = itoa_array[(val >> 8) & 0x0F];
+                       *cmdptr++ = itoa_array[(val >> 4) & 0x0F];
+                       *cmdptr++ = itoa_array[(val >> 0) & 0x0F];
+                       val = IDE_found[cpt].irq; /* < 100 */
+                       if (val) {
+                               *cmdptr++ = ',';
+                               *cmdptr++ = itoa_array[val / 10];
+                               *cmdptr++ = itoa_array[val % 10];
+                       }
+               }
+               *cmdptr = '\0';
+       }
+}
+
+/* root= parameter not present, set it depending on system_desc->disk,
+   system_desc->partition and the number of slash in the kernel name as
+   found in the GZIP name field.
+   Note that we assume that IF the kernel file loaded was in the top
+   directory AND the partition size is too small, it is a "/boot"
+   partition and the real root is the NEXT partition of type 0x83 if it exists.
+   Gujin prefers a lot having only one root partition containning everything
+   including "/boot", but try to stay compatible. */
+CODE static inline void
+add_root_parameter (const struct desc_str *system_desc, char *cmdptr,
+                       const struct IDE_found_str IDE_found[10],
+                       const unsigned nb_IDE_found,
+                       const struct disk_interface_str *DI,
+                       const unsigned nb_slash_in_kernelname)
+ {
+       const struct diskparam_str *const dp = &DI->param[system_desc->disk];
+       const unsigned min_part_size = 640 * 1024 * 1024 / dp->bytepersector;
+       unsigned OSnumber = dp->partition[system_desc->partition].OSnumber;
+       static CONST char root_pattern[] = " root=/dev/";
+
+       if (   system_desc->curdir == inRoot
+           && nb_slash_in_kernelname != 1 /* not really created in root dir */
+           && dp->partition[system_desc->partition].length < min_part_size) {
+               /* find the next bigger 0x83 partition on same disk: */
+               unsigned partition;
+               for (partition = system_desc->partition;
+                   partition < dp->nbpartition;
+                   partition++)
+                       if (   dp->partition[partition].length > min_part_size
+                           && dp->partition[partition].type == 0x83) {
+                               OSnumber = dp->partition[partition].OSnumber;
+                               break;
+                       }
+       }
+
+       if (dp->ideIOadr != 0) {
+               /* seriously looks like an IDE disk, isn't it? */
+               unsigned cptide;
+               for (cptide = 0; cptide < nb_IDE_found; cptide++)
+                       if (dp->ideIOadr == IDE_found[cptide].ideIOadr)
+                               break;
+               if (cptide < nb_IDE_found) {
+                       const char *ptr = root_pattern;
+                       while (*ptr)
+                               *cmdptr++ = *ptr++;
+                       *cmdptr++ = 'h';
+                       *cmdptr++ = 'd';
+                       *cmdptr++ = 'a' + 2 * cptide + !!(dp->lba_slave_mask & 
0x10);
+                       *cmdptr++ = '0' + OSnumber;
+                       *cmdptr = '\0';
+               }
+       } else {
+               /* count number of [E]BIOS hard disks and compare to the
+               number of IDE hard disk to know if there are SCSI disks: */
+               unsigned cpt_bios_disk = 0, cpt_ide_disk = 0, cptdisk;
+               unsigned char maybe_scsi = 0;
+               const char *ptr = root_pattern;
+
+               for (cptdisk = 0; cptdisk < DI->nbdisk; cptdisk++) {
+                       if (  DI->param[cptdisk].access == bios_chs
+                          || DI->param[cptdisk].access == ebios_lba) {
+                               if (DI->param[cptdisk].disknb >= 0x80) {
+                                       cpt_bios_disk++;
+                                       if (DI->param[cptdisk].ideIOadr == 0)
+                                               maybe_scsi = 1;
+                               } /* else floppy disk */
+                       }
+                       else if (DI->param[cptdisk].access == hardide_chs
+                           || DI->param[cptdisk].access == hardide_lba
+                           || DI->param[cptdisk].access == hardide_lba48)
+                               cpt_ide_disk++; /* not CDROM, not empty IDE */
+               }
+               while (*ptr)
+                       *cmdptr++ = *ptr++;
+               /* If we have the same amount or less BIOS disks than IDE
+               disks, we assume we have a normal (or a very old w/o EBIOS) PC
+               without SCSI or USB drives, then assume BIOS mapping like
+               IDE mapping: 0x80 master on IDE0; else we assume all SCSI
+               drives are after the BIOS/IDE drives: */
+               if (maybe_scsi != 0 && cpt_bios_disk > cpt_ide_disk
+                       && dp->disknb >= 0x80 + cpt_bios_disk)
+                       *cmdptr++ = 's';
+               else {
+                       cpt_bios_disk = 0; /* no sda to hda correction */
+                       *cmdptr++ = 'h';
+               }
+               *cmdptr++ = 'd';
+               /* If bootsector OSdisknumber initialised to something
+                       else than 0 or 0x80, we assume the user forced
+                       it and use that value ('a' for number 0x80): */
+               if ((dp->OSdisknumber & 0x7F) != 0)
+                       *cmdptr++ = 'a' + (dp->OSdisknumber & 0x7F);
+               else
+                       *cmdptr++ = 'a' + dp->disknb - 0x80 - cpt_bios_disk;
+               *cmdptr++ = '0' + OSnumber;
+               *cmdptr = '\0';
+       }
+}
+
+CODE static void
+vmlinuz_ROOT (const struct desc_str *system_desc,
+             const struct gpl_compliant_str *togpl,
+             char *command_line, unsigned nb_slash_in_kernelname)
+{
+       struct IDE_found_str IDE_found[10] = {};
+       const struct disk_interface_str *DI =
+                (const struct disk_interface_str *)togpl->DI;
+       char *cmdptr;
+
+#if 0
+       DBG("togpl = 0x", (unsigned)togpl, ": ");
+       DBG("signature = 0x", togpl->signature, ", ");
+       DBG("version = 0x", togpl->version, ", ");
+       DBG("feature = 0x", togpl->feature, ", ");
+       DBG("size = 0x", togpl->size, ", ");
+       DBG("offsetof(struct gpl_compliant_str, DI) + 4 = 0x",
+                offsetof(struct gpl_compliant_str, DI) + 4, "\r\n");
+       DBG_WAIT();
+#endif
+
+       if (togpl == 0 || togpl->signature != 16980327
+           || (togpl->version >> 8) != 1 || (togpl->feature & 1) == 0
+           || togpl->size <= offsetof(struct gpl_compliant_str, DI) + 4)
+               return;
+
+       init_IDE_found_from_cmdline (IDE_found,
+               sizeof(IDE_found)/sizeof(IDE_found[0]), command_line);
+       init_IDE_found_from_DI (IDE_found,
+               sizeof(IDE_found)/sizeof(IDE_found[0]), DI);
+
+#if 0
+       {
+       unsigned cpt;
+
+       for (cpt = 0; cpt < sizeof(IDE_found)/sizeof(IDE_found[0]); cpt++) {
+               DBG("IDE_found[cpt = 0x", cpt, "] : ");
+               DBG("ideIOadr = 0x", IDE_found[cpt].ideIOadr, ", ");
+               DBG("ideIOctrladr = 0x", IDE_found[cpt].ideIOctrladr, ", ");
+               DBG("irq = 0x", IDE_found[cpt].irq, ", ");
+               DBG("bios_order = 0x", IDE_found[cpt].bios_order, "\r\n");
+               }
+       DBG_WAIT();
+       }
+#endif
+
+       /* If "root=" is given, do not try to guess it: */
+       for (cmdptr = command_line; *cmdptr != '\0'; cmdptr++)
+               if (cmdptr[0] == 'r' && cmdptr[1] == 'o' && cmdptr[2] == 'o'
+                       && cmdptr[3] == 't' && cmdptr[4] == '=')
+                       break;
+
+       /* sizeof struct diskparam_str 256, sizeof struct partition_str 64 */
+       if (*cmdptr == '\0'
+           && sizeof (struct diskparam_str) == DI->sizeof_diskparam_str
+           && sizeof (struct partition_str) == DI->sizeof_partition_str
+           && DI->param[system_desc->disk].bytepersector != 0)
+               add_root_parameter (system_desc, cmdptr, IDE_found,
+                               sizeof(IDE_found)/sizeof(IDE_found[0]),
+                               DI, nb_slash_in_kernelname);
+
+       /* Add this after "root=", limited command line length */
+       finalise_cmdline (IDE_found,
+               sizeof(IDE_found)/sizeof(IDE_found[0]), command_line);
+}
+
+#else  /* ROOT_EXTENSIVE_SEARCH */
+
 struct desc_str;
 struct gpl_compliant_str;
+#define vmlinuz_ROOT(a, b, c, d)       /* nothing */
+
+#endif /* ROOT_EXTENSIVE_SEARCH */
 
 CODE static inline void
-vmlinuz_DISKS (union drive_info *drive1, union drive_info *drive2)
+vmlinuz_DISKS (union drive_info *drive1, union drive_info *drive2
+#ifdef ROOT_EXTENSIVE_SEARCH
+               , const struct disk_interface_str *DI
+#endif
+               )
 {
        unsigned nbsect;
        unsigned char status, disk = 0x80;
@@ -1262,6 +1820,18 @@ vmlinuz_DISKS (union drive_info *drive1,
        farptr vectoradr = (farptr)(0x41 * 4);
 
        while (disk <= 0x81) {
+#ifdef ROOT_EXTENSIVE_SEARCH
+               /* Some old and common SCSI card will do an invalid
+               instruction exception in _BIOSDISK_gettype, if the
+               BIOS has not been updated */
+               int cpt;
+               for (cpt = 0; cpt < DI->nb_bios_blacklist; cpt++)
+                       if (DI->bios_blacklist[cpt] == disk)
+                               break;
+               if (cpt < DI->nb_bios_blacklist)
+                       continue;
+#endif
+
                if (_BIOSDISK_gettype (disk, &nbsect, &status) == 0)
                        *drive = get_drive_info (vectoradr);
                disk++;
@@ -1366,7 +1936,11 @@ linux_set_params (unsigned local_return_
        vmlinuz_APM (&LnxParam->apm_bios_info);
 
        LnxParam->X86SpeedStepSmi = _X86SpeedStepSmi();
-       vmlinuz_DISKS (&LnxParam->drive1, &LnxParam->drive2);
+       vmlinuz_DISKS (&LnxParam->drive1, &LnxParam->drive2
+#ifdef ROOT_EXTENSIVE_SEARCH
+                       , (const struct disk_interface_str *)togpl->DI
+#endif
+                       );
        vmlinuz_CONFIG (&LnxParam->sys_desc_table);
        /* do vmlinuz_EDID() before vmlinuz_E820() so that if the later
         function describes more than 18 (and less than 32) blocks of memory,
@@ -1417,6 +1991,8 @@ linux_set_params (unsigned local_return_
                     ptr++)
                        if (*ptr == '/')
                                nb_slash_in_kernelname++;
+       vmlinuz_ROOT (system_desc, togpl, LnxParam->command_line,
+                       nb_slash_in_kernelname);
 
        test_vgaprint();
 
diff -uprN -X linux-2.6.13/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x 
'.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x 
asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x 
consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x 
scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map 
-x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x 
crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list 
linux-2.6.13-2/include/asm-i386/realmode.h 
linux-2.6.13-3/include/asm-i386/realmode.h
--- linux-2.6.13-2/include/asm-i386/realmode.h  2005-08-31 00:25:48.000000000 
+0100
+++ linux-2.6.13-3/include/asm-i386/realmode.h  2005-08-31 00:26:26.000000000 
+0100
@@ -9,6 +9,10 @@
  * loosing the EDD and EDID infomation which moved in Linux-2.6.12
  */
 
+/* try really hard to figure out the root filesystem when not given
+   on command line, uses Gujin data structures (GPL kernel) */
+#define ROOT_EXTENSIVE_SEARCH
+
 /* 16 bits segment in MSB, 16 bits offset in LSB: */
 typedef unsigned farptr;
 
diff -uprN -X linux-2.6.13/Documentation/dontdiff -x '*.orig' -x '*.cmd' -x 
'.tmp*' -x '*.o' -x '*.ko' -x '*.a' -x '*.so' -x '.config*' -x asm-offsets.s -x 
asm_offsets.h -x vmlinux.lds -x vsyscall.lds -x '*.mod.c' -x Module.symvers -x 
consolemap_deftbl.c -x defkeymap.c -x classlist.h -x devlist.h -x asm -x md -x 
scsi -x logo -x config -x .version -x zconf.tab.h -x elfconfig.h -x System.map 
-x zconf.tab.c -x lex.zconf.c -x compile.h -x config_data.h -x version.h -x 
crc32table.h -x autoconf.h -x gen-devlist -x initramfs_list 
linux-2.6.13-2/Makefile linux-2.6.13-3/Makefile
--- linux-2.6.13-2/Makefile     2005-08-31 00:25:48.000000000 +0100
+++ linux-2.6.13-3/Makefile     2005-08-31 00:26:26.000000000 +0100
@@ -1106,7 +1106,8 @@ help:
        @echo  'Other generic targets:'
        @echo  '  all             - Build all targets marked with [*]'
        @echo  '* vmlinux         - Build the bare kernel'
-       @echo  '  /boot/linux.kgz ROOT=/dev/hda1   - replace "hda1" with your 
root filesystem'
+       @echo  "  /boot/linux-$(KERNELRELEASE).kgz - create a boot kernel for 
the Gujin bootloader"
+       @echo  '  /boot/linux.kgz ROOT=/dev/hda1   - do not autodetect root 
filesystem at boot time'
        @echo  '  /boot/linux.kgz ROOT=auto        - root filesystem from 
current /proc/cmdline'
        @echo  '* modules         - Build all modules'
        @echo  '  modules_install - Install all modules'

Reply via email to