From bf962df2daeb032fbeb5a15890523f28f015241f Mon Sep 17 00:00:00 2001 From: bean Date: Mon, 24 Mar 2008 04:13:37 +0000 Subject: [PATCH] 2008-03-24 Bean * disk/i386/pc/biosdisk.c (cd_start): Removed. (cd_count): Removed. (cd_drive): New variable. (grub_biosdisk_get_drive): Don't check for (cdN) device. (grub_biosdisk_call_hook): Likewise. (grub_biosdisk_iterate): Change cdrom detection method. (grub_biosdisk_open): Replace cd_start with cd_drive. (GRUB_MOD_INIT): Use grub_biosdisk_get_cdinfo_int13_extension to detect cdrom device. * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_MACHINE_CDROM_START): Removed. (GRUB_BIOSDISK_MACHINE_CDROM_END): Removed. (GRUB_BIOSDISK_CDTYPE_NO_EMUL): New macro. (GRUB_BIOSDISK_CDTYPE_1_2_M): Likewise. (GRUB_BIOSDISK_CDTYPE_1_44_M): Likewise. (GRUB_BIOSDISK_CDTYPE_2_88_M): Likewise. (GRUB_BIOSDISK_CDTYPE_HARDDISK): Likewise. (GRUB_BIOSDISK_CDTYPE_MASK): Likewise. (grub_biosdisk_cdrp): New structure. (grub_biosdisk_get_cdinfo_int13_extensions): New function. * include/grub/i386/pc/kernel.h (grub_boot_drive): Export this variable. * kern/i386/pc/init.c (make_install_device): Don't use (cdN) as root device. * kern/i386/pc/startup.S (grub_biosdisk_get_cdinfo_int13_extensions): New function. --- ChangeLog | 32 ++++++++++++++++++++ disk/i386/pc/biosdisk.c | 52 +++++++++++++-------------------- include/grub/i386/pc/biosdisk.h | 28 ++++++++++++++++-- include/grub/i386/pc/kernel.h | 2 +- kern/i386/pc/init.c | 10 ++----- kern/i386/pc/startup.S | 15 +++++++++- 6 files changed, 95 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f411de40..620f68bf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2008-03-24 Bean + + * disk/i386/pc/biosdisk.c (cd_start): Removed. + (cd_count): Removed. + (cd_drive): New variable. + (grub_biosdisk_get_drive): Don't check for (cdN) device. + (grub_biosdisk_call_hook): Likewise. + (grub_biosdisk_iterate): Change cdrom detection method. + (grub_biosdisk_open): Replace cd_start with cd_drive. + (GRUB_MOD_INIT): Use grub_biosdisk_get_cdinfo_int13_extension to + detect cdrom device. + + * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_MACHINE_CDROM_START): + Removed. + (GRUB_BIOSDISK_MACHINE_CDROM_END): Removed. + (GRUB_BIOSDISK_CDTYPE_NO_EMUL): New macro. + (GRUB_BIOSDISK_CDTYPE_1_2_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_1_44_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_2_88_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_HARDDISK): Likewise. + (GRUB_BIOSDISK_CDTYPE_MASK): Likewise. + (grub_biosdisk_cdrp): New structure. + (grub_biosdisk_get_cdinfo_int13_extensions): New function. + + * include/grub/i386/pc/kernel.h (grub_boot_drive): Export this variable. + + * kern/i386/pc/init.c (make_install_device): Don't use (cdN) as root + device. + + * kern/i386/pc/startup.S (grub_biosdisk_get_cdinfo_int13_extensions): + New function. + 2008-03-20 Robert Millan Remove 2 TiB limit in ata.mod. diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index ddcc6663b..793c11df7 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -26,15 +27,14 @@ #include #include -static int cd_start = GRUB_BIOSDISK_MACHINE_CDROM_START; -static int cd_count = 0; +int cd_drive = 0; static int grub_biosdisk_get_drive (const char *name) { unsigned long drive; - if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd') + if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') goto fail; drive = grub_strtoul (name + 2, 0, 10); @@ -43,8 +43,6 @@ grub_biosdisk_get_drive (const char *name) if (name[0] == 'h') drive += 0x80; - else if (name[0] == 'c') - drive += cd_start; return (int) drive ; @@ -58,9 +56,6 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) { char name[10]; - if (drive >= cd_start) - grub_sprintf (name, "cd%d", drive - cd_start); - else grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); return hook (name); } @@ -91,9 +86,11 @@ grub_biosdisk_iterate (int (*hook) (const char *name)) return 1; } - for (drive = cd_start; drive < cd_start + cd_count; drive++) - if (grub_biosdisk_call_hook (hook, drive)) + if (cd_drive) + { + if (grub_biosdisk_call_hook (hook, cd_drive)) return 1; + } return 0; } @@ -109,7 +106,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) if (drive < 0) return grub_errno; - disk->has_partitions = ((drive & 0x80) && (drive < cd_start)); + disk->has_partitions = ((drive & 0x80) && (drive != cd_drive)); disk->id = drive; data = (struct grub_biosdisk_data *) grub_malloc (sizeof (*data)); @@ -119,7 +116,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) data->drive = drive; data->flags = 0; - if (drive >= cd_start) + if ((cd_drive) && (drive == cd_drive)) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; @@ -154,7 +151,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) } } - if (drive < cd_start) + if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM)) { if (grub_biosdisk_get_diskinfo_standard (drive, &data->cylinders, @@ -364,7 +361,8 @@ grub_disk_biosdisk_fini (void) GRUB_MOD_INIT(biosdisk) { - int drive, found = 0; + struct grub_biosdisk_cdrp *cdrp + = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; if (grub_disk_firmware_is_tainted) { @@ -373,25 +371,15 @@ GRUB_MOD_INIT(biosdisk) } grub_disk_firmware_fini = grub_disk_biosdisk_fini; + grub_memset (cdrp, 0, sizeof (*cdrp)); + cdrp->size = sizeof (*cdrp); + cdrp->media_type = 0xFF; + if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) && + ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) + == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) + cd_drive = cdrp->drive_no; + grub_disk_dev_register (&grub_biosdisk_dev); - - for (drive = GRUB_BIOSDISK_MACHINE_CDROM_START; - drive < GRUB_BIOSDISK_MACHINE_CDROM_END; drive++) - { - if (grub_biosdisk_check_int13_extensions (drive)) - { - if (! found) - cd_start = drive; - found++; - } - else - { - if (found) - break; - } - } - - cd_count = found; } GRUB_MOD_FINI(biosdisk) diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h index 770f94254..05d5dc571 100644 --- a/include/grub/i386/pc/biosdisk.h +++ b/include/grub/i386/pc/biosdisk.h @@ -25,8 +25,13 @@ #define GRUB_BIOSDISK_FLAG_LBA 1 #define GRUB_BIOSDISK_FLAG_CDROM 2 -#define GRUB_BIOSDISK_MACHINE_CDROM_START 0xe0 -#define GRUB_BIOSDISK_MACHINE_CDROM_END 0xf0 +#define GRUB_BIOSDISK_CDTYPE_NO_EMUL 0 +#define GRUB_BIOSDISK_CDTYPE_1_2_M 1 +#define GRUB_BIOSDISK_CDTYPE_1_44_M 2 +#define GRUB_BIOSDISK_CDTYPE_2_88_M 3 +#define GRUB_BIOSDISK_CDTYPE_HARDDISK 4 + +#define GRUB_BIOSDISK_CDTYPE_MASK 0xF struct grub_biosdisk_data { @@ -74,6 +79,23 @@ struct grub_biosdisk_drp grub_uint8_t dummy[16]; } __attribute__ ((packed)); +struct grub_biosdisk_cdrp +{ + grub_uint8_t size; + grub_uint8_t media_type; + grub_uint8_t drive_no; + grub_uint8_t controller_no; + grub_uint32_t image_lba; + grub_uint16_t device_spec; + grub_uint16_t cache_seg; + grub_uint16_t load_seg; + grub_uint16_t length_sec512; + grub_uint8_t cylinders; + grub_uint8_t sectors; + grub_uint8_t heads; + grub_uint8_t dummy[16]; +} __attribute__ ((packed)); + /* Disk Address Packet. */ struct grub_biosdisk_dap { @@ -90,6 +112,8 @@ int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hof int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive); int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive, void *drp); +int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive, + void *cdrp); int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive, unsigned long *cylinders, unsigned long *heads, diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 848dad10d..43a8d5b6e 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -71,7 +71,7 @@ extern grub_int32_t grub_memdisk_image_size; extern char grub_prefix[]; /* The boot BIOS drive number. */ -extern grub_int32_t grub_boot_drive; +extern grub_int32_t EXPORT_VAR(grub_boot_drive); /* The root BIOS drive number. */ extern grub_int32_t grub_root_drive; diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index 72374929c..757f5d5c5 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -77,13 +76,8 @@ make_install_device (void) if (grub_root_drive == 0xFF) grub_root_drive = grub_boot_drive; - if (grub_root_drive >= GRUB_BIOSDISK_MACHINE_CDROM_START) - grub_sprintf (dev, "(cd%u", - grub_root_drive - GRUB_BIOSDISK_MACHINE_CDROM_START); - else - grub_sprintf (dev, "(%cd%u", - (grub_root_drive & 0x80) ? 'h' : 'f', - grub_root_drive & 0x7f); + grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f', + grub_root_drive & 0x7f); if (grub_install_dos_part >= 0) grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1); diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index bf3d4eee3..35b19fda7 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -779,6 +779,17 @@ FUNCTION(grub_biosdisk_check_int13_extensions) ret +/* + * int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp) + * + * Return the cdrom information of DRIVE in CDRP. If an error occurs, + * then return non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions) + movw $0x4B01, %cx + jmp 1f + /* * int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) * @@ -787,6 +798,8 @@ FUNCTION(grub_biosdisk_check_int13_extensions) */ FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions) + movb $0x48, %ch +1: pushl %ebp pushl %ebx pushl %esi @@ -802,7 +815,7 @@ FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions) call prot_to_real .code16 - movb $0x48, %ah + movw %cx, %ax movw %bx, %ds int $0x13 /* do the operation */ movb %ah, %bl /* save return value in %bl */