From: Laurent Vivier <[EMAIL PROTECTED](none)> As for "-cdrom", this patch introduces a new parameter allowing to define more information for a disk.
The new parameter is "-disk": -disk file[,if=type][,bus=n][,unit=m][,cyls=c,heads=h,secs=s[,trans=t]] where "type" defines the bus type (by default "ide") "n" the bus number (by default 0) "m" the unit number (by default 0) and c,h,s and t define the disk geometry (like -hdachs) --- vl.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 173 insertions(+), 24 deletions(-) diff --git a/vl.c b/vl.c index a8c4a81..8408ce4 100644 --- a/vl.c +++ b/vl.c @@ -4701,6 +4701,114 @@ void do_info_network(void) } } +static int disk_init(const char *str, int snapshot) +{ + char buf[16]; + char interface[16]; + int bus_id, unit_id; + int cyls, heads, secs, translation; + char *p; + char *file; + + file = str; + p = str; + while (*p != '\0' && *p != ',') + p++; + if (*p == ',') { + *p = '\0'; + p++; + } + + cyls = heads = secs = 0; + bus_id = -1; + unit_id = -1; + translation = BIOS_ATA_TRANSLATION_AUTO; + pstrcpy(interface, sizeof(interface), "ide"); + + if (get_param_value(buf, sizeof(buf), "bus", p)) { + bus_id = strtol(buf, NULL, 0); + } + + if (get_param_value(buf, sizeof(buf), "unit", p)) { + unit_id = strtol(buf, NULL, 0); + } + + if (get_param_value(buf, sizeof(buf), "cyls", p)) { + cyls = strtol(buf, NULL, 0); + } + + if (get_param_value(buf, sizeof(buf), "heads", p)) { + heads = strtol(buf, NULL, 0); + } + + if (get_param_value(buf, sizeof(buf), "secs", p)) { + secs = strtol(buf, NULL, 0); + } + + if (get_param_value(buf, sizeof(buf), "if", p)) { + pstrcpy(interface, sizeof(interface), buf); + } + + if (get_param_value(buf, sizeof(buf), "trans", p)) { + if (!strcmp(buf, "none")) + translation = BIOS_ATA_TRANSLATION_NONE; + else if (!strcmp(buf, "lba")) + translation = BIOS_ATA_TRANSLATION_LBA; + else if (!strcmp(buf, "auto")) + translation = BIOS_ATA_TRANSLATION_AUTO; + else + translation = -1; + } + + if ( (cyls || secs || heads) && + ( (cyls < 1 || cyls > 16383) || + (heads < 1 || heads > 16) || + (secs < 1 || secs > 63) || + (translation == -1) ) ) { + fprintf(stderr, "qemu: invalid physical CHS format\n"); + return -1; + } + + if (strcmp(interface, "ide") == 0) { + static int disk_index = -1; + + disk_index++; + + if (bus_id == -1) { + bus_id = disk_index / 2; + if (unit_id == -1) + unit_id = disk_index % 2; + } else if (unit_id == -1) + unit_id = 0; + + disk_index = bus_id * 2 + unit_id; + + snprintf(buf, sizeof(buf), "hd%c", disk_index + 'a'); + + bs_table[disk_index] = bdrv_new(buf); + + if (bdrv_open(bs_table[disk_index], file, + snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { + fprintf(stderr, "qemu: could not open hard disk image '%s'\n", + file); + return -1; + } + + if (cyls != 0) { + bdrv_set_geometry_hint(bs_table[disk_index], + cyls, heads, secs); + bdrv_set_translation_hint(bs_table[disk_index], translation); + } + return 0; + } else if (strcmp(interface, "scsi") == 0) { + /* TODO */ + } + + fprintf(stderr, "unsupported bus type '%s' for cdrom '%s'\n", + interface, file); + return -1; +} + #define MAX_CDROMS 4 #ifdef TARGET_PPC #define DEFAULT_CDROM_BUS 0 @@ -7063,6 +7171,8 @@ static void help(int exitcode) "-fda/-fdb file use 'file' as floppy disk 0/1 image\n" "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" + "-disk file[,if=type][,bus=n][,unit=m][,cyls=c,heads=h,secs=s[,trans=t]]\n" + " use 'file' as a disk image\n" "-cdrom file[,if=type][,bus=n][,unit=m]\n" " use 'file' as cdrom image\n" " (by default cdrom is ide1 master (if=ide,bus=1,unit=0))\n" @@ -7214,6 +7324,7 @@ enum { QEMU_OPTION_hdb, QEMU_OPTION_hdc, QEMU_OPTION_hdd, + QEMU_OPTION_disk, QEMU_OPTION_cdrom, QEMU_OPTION_mtdblock, QEMU_OPTION_sd, @@ -7302,6 +7413,7 @@ const QEMUOption qemu_options[] = { { "hdb", HAS_ARG, QEMU_OPTION_hdb }, { "hdc", HAS_ARG, QEMU_OPTION_hdc }, { "hdd", HAS_ARG, QEMU_OPTION_hdd }, + { "disk", HAS_ARG, QEMU_OPTION_disk }, { "cdrom", HAS_ARG, QEMU_OPTION_cdrom }, { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock }, { "sd", HAS_ARG, QEMU_OPTION_sd }, @@ -7629,7 +7741,7 @@ int main(int argc, char **argv) int i, pflash_index; int snapshot, linux_boot; const char *initrd_filename; - const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; + const char *fd_filename[MAX_FD]; const char *pflash_filename[MAX_PFLASH]; const char *sd_filename; const char *mtd_filename; @@ -7637,9 +7749,12 @@ int main(int argc, char **argv) DisplayState *ds = &display_state; int cyls, heads, secs, translation; char net_clients[MAX_NET_CLIENTS][256]; + char disks[MAX_DISKS][256]; char cdroms[MAX_CDROMS][256]; int nb_net_clients; + int nb_disks; int nb_cdroms; + int hda_index = -1; int optind; const char *r, *optarg; CharDriverState *monitor_hd; @@ -7694,8 +7809,6 @@ int main(int argc, char **argv) initrd_filename = NULL; for(i = 0; i < MAX_FD; i++) fd_filename[i] = NULL; - for(i = 0; i < MAX_DISKS; i++) - hd_filename[i] = NULL; for(i = 0; i < MAX_PFLASH; i++) pflash_filename[i] = NULL; pflash_index = 0; @@ -7728,6 +7841,7 @@ int main(int argc, char **argv) usb_devices_index = 0; nb_net_clients = 0; + nb_disks = 0; nb_cdroms = 0; nb_nics = 0; @@ -7739,7 +7853,10 @@ int main(int argc, char **argv) break; r = argv[optind]; if (r[0] != '-') { - hd_filename[0] = argv[optind++]; + hda_index = nb_disks; + snprintf(disks[nb_disks], sizeof(disks[0]), + "%s,bus=0,unit=0", argv[optind++]); + nb_disks++; } else { const QEMUOption *popt; @@ -7799,15 +7916,51 @@ int main(int argc, char **argv) initrd_filename = optarg; break; case QEMU_OPTION_hda: + if (nb_disks >= MAX_DISKS) { + fprintf(stderr, "qemu: too many disks\n"); + exit(1); + } + hda_index = nb_disks; + if (cyls == 0) + snprintf(disks[nb_disks], sizeof(disks[0]), + "%s,bus=0,unit=0", optarg); + else { + snprintf(disks[nb_disks], sizeof(disks[0]), + "%s,bus=0,unit=0,cyls=%d,heads=%d,secs=%d%s", + optarg, cyls, heads, secs, + translation == BIOS_ATA_TRANSLATION_LBA ? + ",trans=lba" : + translation == BIOS_ATA_TRANSLATION_NONE ? + ",trans=none" : ""); + } + nb_disks++; + break; case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: case QEMU_OPTION_hdd: { int hd_index; + if (nb_disks >= MAX_DISKS) { + fprintf(stderr, "qemu: too many disks\n"); + exit(1); + } hd_index = popt->index - QEMU_OPTION_hda; - hd_filename[hd_index] = optarg; + snprintf(disks[nb_disks], sizeof(disks[0]), + "%s,bus=%d,unit=%d", optarg, + hd_index / 2, hd_index % 2); + nb_disks++; } break; + case QEMU_OPTION_disk: + if (nb_disks >= MAX_DISKS) { + fprintf(stderr, "qemu: too many disks\n"); + exit(1); + } + pstrcpy(disks[nb_disks], + sizeof(disks[0]), + optarg); + nb_disks++; + break; case QEMU_OPTION_mtdblock: mtd_filename = optarg; break; @@ -7858,6 +8011,15 @@ int main(int argc, char **argv) fprintf(stderr, "qemu: invalid physical CHS format\n"); exit(1); } + if (hda_index != -1) + snprintf(disks[hda_index] + strlen(disks[hda_index]), + sizeof(disks[0]) - strlen(disks[hda_index]), + ",cyls=%d,heads=%d,secs=%d%s", + cyls, heads, secs, + translation == BIOS_ATA_TRANSLATION_LBA ? + ",trans=lba" : + translation == BIOS_ATA_TRANSLATION_NONE ? + ",trans=none" : ""); } break; case QEMU_OPTION_nographic: @@ -8245,13 +8407,13 @@ int main(int argc, char **argv) if (!linux_boot && boot_device != 'n' && - hd_filename[0] == '\0' && + nb_disks == 0 && (nb_cdroms >= 0 && cdroms[0] == '\0') && fd_filename[0] == '\0') help(1); /* boot to floppy or the default cd if no hard disk defined yet */ - if (hd_filename[0] == '\0' && boot_device == 'c') { + if (nb_disks == 0 && boot_device == 'c') { if (fd_filename[0] != '\0') boot_device = 'a'; else @@ -8337,23 +8499,10 @@ int main(int argc, char **argv) exit(1); /* open the virtual block devices */ - for(i = 0; i < MAX_DISKS; i++) { - if (hd_filename[i]) { - char buf[64]; - snprintf(buf, sizeof(buf), "hd%c", i + 'a'); - bs_table[i] = bdrv_new(buf); - - if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { - fprintf(stderr, "qemu: could not open hard disk image '%s'\n", - hd_filename[i]); - exit(1); - } - if (i == 0 && cyls != 0) { - bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs); - bdrv_set_translation_hint(bs_table[i], translation); - } - } - } + + for(i = 0; i < nb_disks; i++) + if (disk_init(disks[i], snapshot) == -1) + exit(1); /* we always create at least one floppy disk */ fd_table[0] = bdrv_new("fda"); -- 1.4.4.4