[PATCH 3/3] Gujin linux.kgz boot format

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  Attached third patch adds the autodetection of the root filesystem
 based on the disk / partition / directory of the kernel file loaded.

Signed-off-by: Etienne Lorrain <[email protected]>

  Etienne.
diff -uprN -X linux-2.6.14-rc3/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.14-rc3-2/arch/i386/kernel/realmode.c linux-2.6.14-rc3-3/arch/i386/kernel/realmode.c
--- linux-2.6.14-rc3-2/arch/i386/kernel/realmode.c	2005-10-04 15:45:57.015054296 +0200
+++ linux-2.6.14-rc3-3/arch/i386/kernel/realmode.c	2005-10-04 15:46:33.915444584 +0200
@@ -1234,11 +1234,578 @@ 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 */
+	} extrainfo;
+	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)
+{
+	const struct disk_interface_str *DI =
+		 (const struct disk_interface_str *)togpl->DI;
+	char *cmdptr;
+#if 0	/* problem with linker, so do not call memset */
+	struct IDE_found_str IDE_found[10] = {};
+#else
+	struct IDE_found_str IDE_found[10];
+	unsigned i = sizeof (IDE_found) / sizeof(IDE_found[0]);
+	while (--i)
+		IDE_found[i].ideIOadr = IDE_found[i].ideIOctrladr
+			= IDE_found[i].irq = IDE_found[i].bios_order
+			= IDE_found[i].reserved = 0;
+#endif
+
+#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;
@@ -1246,6 +1813,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)
 			get_drive_info (vectoradr, drive);
 		disk++;
@@ -1350,7 +1929,11 @@ linux_set_params (unsigned local_return_
 	vmlinuz_APM (&LnxParam->apm_bios_info);
 
 	_X86SpeedStepSmi (&LnxParam->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,
@@ -1401,6 +1984,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.14-rc3/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.14-rc3-2/include/asm-i386/realmode.h linux-2.6.14-rc3-3/include/asm-i386/realmode.h
--- linux-2.6.14-rc3-2/include/asm-i386/realmode.h	2005-10-04 15:45:57.091042744 +0200
+++ linux-2.6.14-rc3-3/include/asm-i386/realmode.h	2005-10-04 15:46:33.917444280 +0200
@@ -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.14-rc3/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.14-rc3-2/Makefile linux-2.6.14-rc3-3/Makefile
--- linux-2.6.14-rc3-2/Makefile	2005-10-04 15:45:57.093042440 +0200
+++ linux-2.6.14-rc3-3/Makefile	2005-10-04 15:46:33.919443976 +0200
@@ -1135,7 +1135,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'

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux