Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750764AbVJFJsx (ORCPT ); Thu, 6 Oct 2005 05:48:53 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1750775AbVJFJsw (ORCPT ); Thu, 6 Oct 2005 05:48:52 -0400 Received: from smtp4-g19.free.fr ([212.27.42.30]:42200 "EHLO smtp4-g19.free.fr") by vger.kernel.org with ESMTP id S1750764AbVJFJsv (ORCPT ); Thu, 6 Oct 2005 05:48:51 -0400 Message-ID: <2044.192.168.201.6.1128592126.squirrel@pc300> Date: Thu, 6 Oct 2005 10:48:46 +0100 (BST) From: "Etienne Lorrain" To: linux-kernel@vger.kernel.org Reply-To: etienne.lorrain@masroudeau.com User-Agent: SquirrelMail/1.4.5 MIME-Version: 1.0 X-Priority: 3 (Normal) Importance: Normal X-SA-Exim-Connect-IP: 192.168.2.240 X-SA-Exim-Mail-From: etienne.lorrain@masroudeau.com Subject: [PATCH 3/3] Gujin linux.kgz boot format Content-Type: multipart/mixed;boundary="----=_20051006104846_91423" X-SA-Exim-Version: 4.2 (built Thu, 03 Mar 2005 10:44:12 +0100) X-SA-Exim-Scanned: Yes (on cygne.masroudeau.com) Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 25571 Lines: 675 ------=_20051006104846_91423 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit 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 Etienne. ------=_20051006104846_91423 Content-Type: text/plain; name="patch2614rc3-3" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="patch2614rc3-3" 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' ------=_20051006104846_91423-- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/