Revision e4bcb14c vl.c
b/vl.c | ||
---|---|---|
163 | 163 |
void *ioport_opaque[MAX_IOPORTS]; |
164 | 164 |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
165 | 165 |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
166 |
/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
|
|
166 |
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
|
|
167 | 167 |
to store the VM snapshots */ |
168 |
BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD]; |
|
169 |
BlockDriverState *pflash_table[MAX_PFLASH]; |
|
170 |
BlockDriverState *sd_bdrv; |
|
171 |
BlockDriverState *mtd_bdrv; |
|
168 |
DriveInfo drives_table[MAX_DRIVES+1]; |
|
169 |
int nb_drives; |
|
172 | 170 |
/* point to the block driver where the snapshots are managed */ |
173 | 171 |
BlockDriverState *bs_snapshots; |
174 | 172 |
int vga_ram_size; |
... | ... | |
232 | 230 |
unsigned int nb_prom_envs = 0; |
233 | 231 |
const char *prom_envs[MAX_PROM_ENVS]; |
234 | 232 |
#endif |
233 |
int nb_drives_opt; |
|
234 |
char drives_opt[MAX_DRIVES][1024]; |
|
235 | 235 |
|
236 | 236 |
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) |
237 | 237 |
|
... | ... | |
1758 | 1758 |
case 's': |
1759 | 1759 |
{ |
1760 | 1760 |
int i; |
1761 |
for (i = 0; i < MAX_DISKS; i++) { |
|
1762 |
if (bs_table[i]) |
|
1763 |
bdrv_commit(bs_table[i]); |
|
1761 |
for (i = 0; i < nb_drives; i++) { |
|
1762 |
bdrv_commit(drives_table[i].bdrv); |
|
1764 | 1763 |
} |
1765 |
if (mtd_bdrv) |
|
1766 |
bdrv_commit(mtd_bdrv); |
|
1767 | 1764 |
} |
1768 | 1765 |
break; |
1769 | 1766 |
case 'b': |
... | ... | |
4554 | 4551 |
|
4555 | 4552 |
} |
4556 | 4553 |
|
4554 |
static const char *get_word(char *buf, int buf_size, const char *p) |
|
4555 |
{ |
|
4556 |
char *q; |
|
4557 |
int substring; |
|
4558 |
|
|
4559 |
substring = 0; |
|
4560 |
q = buf; |
|
4561 |
while (*p != '\0') { |
|
4562 |
if (*p == '\\') { |
|
4563 |
p++; |
|
4564 |
if (*p == '\0') |
|
4565 |
break; |
|
4566 |
} else if (*p == '\"') { |
|
4567 |
substring = !substring; |
|
4568 |
p++; |
|
4569 |
continue; |
|
4570 |
} else if (!substring && (*p == ',' || *p == '=')) |
|
4571 |
break; |
|
4572 |
if (q && (q - buf) < buf_size - 1) |
|
4573 |
*q++ = *p; |
|
4574 |
p++; |
|
4575 |
} |
|
4576 |
if (q) |
|
4577 |
*q = '\0'; |
|
4578 |
|
|
4579 |
return p; |
|
4580 |
} |
|
4581 |
|
|
4557 | 4582 |
static int get_param_value(char *buf, int buf_size, |
4558 | 4583 |
const char *tag, const char *str) |
4559 | 4584 |
{ |
4560 | 4585 |
const char *p; |
4561 |
char *q; |
|
4562 | 4586 |
char option[128]; |
4563 | 4587 |
|
4564 | 4588 |
p = str; |
4565 | 4589 |
for(;;) { |
4566 |
q = option; |
|
4567 |
while (*p != '\0' && *p != '=') { |
|
4568 |
if ((q - option) < sizeof(option) - 1) |
|
4569 |
*q++ = *p; |
|
4570 |
p++; |
|
4571 |
} |
|
4572 |
*q = '\0'; |
|
4590 |
p = get_word(option, sizeof(option), p); |
|
4573 | 4591 |
if (*p != '=') |
4574 | 4592 |
break; |
4575 | 4593 |
p++; |
4576 | 4594 |
if (!strcmp(tag, option)) { |
4577 |
q = buf; |
|
4578 |
while (*p != '\0' && *p != ',') { |
|
4579 |
if ((q - buf) < buf_size - 1) |
|
4580 |
*q++ = *p; |
|
4581 |
p++; |
|
4582 |
} |
|
4583 |
*q = '\0'; |
|
4584 |
return q - buf; |
|
4595 |
(void)get_word(buf, buf_size, p); |
|
4596 |
return strlen(buf); |
|
4585 | 4597 |
} else { |
4586 |
while (*p != '\0' && *p != ',') { |
|
4587 |
p++; |
|
4588 |
} |
|
4598 |
p = get_word(NULL, 0, p); |
|
4589 | 4599 |
} |
4590 | 4600 |
if (*p != ',') |
4591 | 4601 |
break; |
... | ... | |
4594 | 4604 |
return 0; |
4595 | 4605 |
} |
4596 | 4606 |
|
4607 |
static int check_params(char *buf, int buf_size, |
|
4608 |
char **params, const char *str) |
|
4609 |
{ |
|
4610 |
const char *p; |
|
4611 |
int i; |
|
4612 |
|
|
4613 |
p = str; |
|
4614 |
for(;;) { |
|
4615 |
p = get_word(buf, buf_size, p); |
|
4616 |
if (*p != '=') |
|
4617 |
return -1; |
|
4618 |
p++; |
|
4619 |
for(i = 0; params[i] != NULL; i++) |
|
4620 |
if (!strcmp(params[i], buf)) |
|
4621 |
break; |
|
4622 |
if (params[i] == NULL) |
|
4623 |
return -1; |
|
4624 |
p = get_word(NULL, 0, p); |
|
4625 |
if (*p != ',') |
|
4626 |
break; |
|
4627 |
p++; |
|
4628 |
} |
|
4629 |
return 0; |
|
4630 |
} |
|
4631 |
|
|
4632 |
|
|
4597 | 4633 |
static int net_client_init(const char *str) |
4598 | 4634 |
{ |
4599 | 4635 |
const char *p; |
... | ... | |
4744 | 4780 |
} |
4745 | 4781 |
} |
4746 | 4782 |
|
4783 |
#define HD_ALIAS "file=\"%s\",index=%d,media=disk" |
|
4784 |
#ifdef TARGET_PPC |
|
4785 |
#define CDROM_ALIAS "index=1,media=cdrom" |
|
4786 |
#else |
|
4787 |
#define CDROM_ALIAS "index=2,media=cdrom" |
|
4788 |
#endif |
|
4789 |
#define FD_ALIAS "index=%d,if=floppy" |
|
4790 |
#define PFLASH_ALIAS "file=\"%s\",if=pflash" |
|
4791 |
#define MTD_ALIAS "file=\"%s\",if=mtd" |
|
4792 |
#define SD_ALIAS "file=\"%s\",if=sd" |
|
4793 |
|
|
4794 |
static int drive_add(const char *fmt, ...) |
|
4795 |
{ |
|
4796 |
va_list ap; |
|
4797 |
|
|
4798 |
if (nb_drives_opt >= MAX_DRIVES) { |
|
4799 |
fprintf(stderr, "qemu: too many drives\n"); |
|
4800 |
exit(1); |
|
4801 |
} |
|
4802 |
|
|
4803 |
va_start(ap, fmt); |
|
4804 |
vsnprintf(drives_opt[nb_drives_opt], sizeof(drives_opt[0]), fmt, ap); |
|
4805 |
va_end(ap); |
|
4806 |
|
|
4807 |
return nb_drives_opt++; |
|
4808 |
} |
|
4809 |
|
|
4810 |
int drive_get_index(BlockInterfaceType interface, int bus, int unit) |
|
4811 |
{ |
|
4812 |
int index; |
|
4813 |
|
|
4814 |
/* seek interface, bus and unit */ |
|
4815 |
|
|
4816 |
for (index = 0; index < nb_drives; index++) |
|
4817 |
if (drives_table[index].interface == interface && |
|
4818 |
drives_table[index].bus == bus && |
|
4819 |
drives_table[index].unit == unit) |
|
4820 |
return index; |
|
4821 |
|
|
4822 |
return -1; |
|
4823 |
} |
|
4824 |
|
|
4825 |
int drive_get_max_bus(BlockInterfaceType interface) |
|
4826 |
{ |
|
4827 |
int max_bus; |
|
4828 |
int index; |
|
4829 |
|
|
4830 |
max_bus = -1; |
|
4831 |
for (index = 0; index < nb_drives; index++) { |
|
4832 |
if(drives_table[index].interface == interface && |
|
4833 |
drives_table[index].bus > max_bus) |
|
4834 |
max_bus = drives_table[index].bus; |
|
4835 |
} |
|
4836 |
return max_bus; |
|
4837 |
} |
|
4838 |
|
|
4839 |
static int drive_init(const char *str, int snapshot, QEMUMachine *machine) |
|
4840 |
{ |
|
4841 |
char buf[128]; |
|
4842 |
char file[1024]; |
|
4843 |
BlockInterfaceType interface; |
|
4844 |
enum { MEDIA_DISK, MEDIA_CDROM } media; |
|
4845 |
int bus_id, unit_id; |
|
4846 |
int cyls, heads, secs, translation; |
|
4847 |
BlockDriverState *bdrv; |
|
4848 |
int max_devs; |
|
4849 |
int index; |
|
4850 |
char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", |
|
4851 |
"secs", "trans", "media", "snapshot", "file", NULL }; |
|
4852 |
|
|
4853 |
if (check_params(buf, sizeof(buf), params, str) < 0) { |
|
4854 |
fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", |
|
4855 |
buf, str); |
|
4856 |
return -1; |
|
4857 |
} |
|
4858 |
|
|
4859 |
file[0] = 0; |
|
4860 |
cyls = heads = secs = 0; |
|
4861 |
bus_id = 0; |
|
4862 |
unit_id = -1; |
|
4863 |
translation = BIOS_ATA_TRANSLATION_AUTO; |
|
4864 |
index = -1; |
|
4865 |
|
|
4866 |
if (!strcmp(machine->name, "realview") || |
|
4867 |
!strcmp(machine->name, "SS-5") || |
|
4868 |
!strcmp(machine->name, "SS-10") || |
|
4869 |
!strcmp(machine->name, "SS-600MP") || |
|
4870 |
!strcmp(machine->name, "versatilepb") || |
|
4871 |
!strcmp(machine->name, "versatileab")) { |
|
4872 |
interface = IF_SCSI; |
|
4873 |
max_devs = MAX_SCSI_DEVS; |
|
4874 |
} else { |
|
4875 |
interface = IF_IDE; |
|
4876 |
max_devs = MAX_IDE_DEVS; |
|
4877 |
} |
|
4878 |
media = MEDIA_DISK; |
|
4879 |
|
|
4880 |
/* extract parameters */ |
|
4881 |
|
|
4882 |
if (get_param_value(buf, sizeof(buf), "bus", str)) { |
|
4883 |
bus_id = strtol(buf, NULL, 0); |
|
4884 |
if (bus_id < 0) { |
|
4885 |
fprintf(stderr, "qemu: '%s' invalid bus id\n", str); |
|
4886 |
return -1; |
|
4887 |
} |
|
4888 |
} |
|
4889 |
|
|
4890 |
if (get_param_value(buf, sizeof(buf), "unit", str)) { |
|
4891 |
unit_id = strtol(buf, NULL, 0); |
|
4892 |
if (unit_id < 0) { |
|
4893 |
fprintf(stderr, "qemu: '%s' invalid unit id\n", str); |
|
4894 |
return -1; |
|
4895 |
} |
|
4896 |
} |
|
4897 |
|
|
4898 |
if (get_param_value(buf, sizeof(buf), "if", str)) { |
|
4899 |
if (!strcmp(buf, "ide")) { |
|
4900 |
interface = IF_IDE; |
|
4901 |
max_devs = MAX_IDE_DEVS; |
|
4902 |
} else if (!strcmp(buf, "scsi")) { |
|
4903 |
interface = IF_SCSI; |
|
4904 |
max_devs = MAX_SCSI_DEVS; |
|
4905 |
} else if (!strcmp(buf, "floppy")) { |
|
4906 |
interface = IF_FLOPPY; |
|
4907 |
max_devs = 0; |
|
4908 |
} else if (!strcmp(buf, "pflash")) { |
|
4909 |
interface = IF_PFLASH; |
|
4910 |
max_devs = 0; |
|
4911 |
} else if (!strcmp(buf, "mtd")) { |
|
4912 |
interface = IF_MTD; |
|
4913 |
max_devs = 0; |
|
4914 |
} else if (!strcmp(buf, "sd")) { |
|
4915 |
interface = IF_SD; |
|
4916 |
max_devs = 0; |
|
4917 |
} else { |
|
4918 |
fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf); |
|
4919 |
return -1; |
|
4920 |
} |
|
4921 |
} |
|
4922 |
|
|
4923 |
if (get_param_value(buf, sizeof(buf), "index", str)) { |
|
4924 |
index = strtol(buf, NULL, 0); |
|
4925 |
if (index < 0) { |
|
4926 |
fprintf(stderr, "qemu: '%s' invalid index\n", str); |
|
4927 |
return -1; |
|
4928 |
} |
|
4929 |
} |
|
4930 |
|
|
4931 |
if (get_param_value(buf, sizeof(buf), "cyls", str)) { |
|
4932 |
cyls = strtol(buf, NULL, 0); |
|
4933 |
} |
|
4934 |
|
|
4935 |
if (get_param_value(buf, sizeof(buf), "heads", str)) { |
|
4936 |
heads = strtol(buf, NULL, 0); |
|
4937 |
} |
|
4938 |
|
|
4939 |
if (get_param_value(buf, sizeof(buf), "secs", str)) { |
|
4940 |
secs = strtol(buf, NULL, 0); |
|
4941 |
} |
|
4942 |
|
|
4943 |
if (cyls || heads || secs) { |
|
4944 |
if (cyls < 1 || cyls > 16383) { |
|
4945 |
fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str); |
|
4946 |
return -1; |
|
4947 |
} |
|
4948 |
if (heads < 1 || heads > 16) { |
|
4949 |
fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str); |
|
4950 |
return -1; |
|
4951 |
} |
|
4952 |
if (secs < 1 || secs > 63) { |
|
4953 |
fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str); |
|
4954 |
return -1; |
|
4955 |
} |
|
4956 |
} |
|
4957 |
|
|
4958 |
if (get_param_value(buf, sizeof(buf), "trans", str)) { |
|
4959 |
if (!cyls) { |
|
4960 |
fprintf(stderr, |
|
4961 |
"qemu: '%s' trans must be used with cyls,heads and secs\n", |
|
4962 |
str); |
|
4963 |
return -1; |
|
4964 |
} |
|
4965 |
if (!strcmp(buf, "none")) |
|
4966 |
translation = BIOS_ATA_TRANSLATION_NONE; |
|
4967 |
else if (!strcmp(buf, "lba")) |
|
4968 |
translation = BIOS_ATA_TRANSLATION_LBA; |
|
4969 |
else if (!strcmp(buf, "auto")) |
|
4970 |
translation = BIOS_ATA_TRANSLATION_AUTO; |
|
4971 |
else { |
|
4972 |
fprintf(stderr, "qemu: '%s' invalid translation type\n", str); |
|
4973 |
return -1; |
|
4974 |
} |
|
4975 |
} |
|
4976 |
|
|
4977 |
if (get_param_value(buf, sizeof(buf), "media", str)) { |
|
4978 |
if (!strcmp(buf, "disk")) { |
|
4979 |
media = MEDIA_DISK; |
|
4980 |
} else if (!strcmp(buf, "cdrom")) { |
|
4981 |
if (cyls || secs || heads) { |
|
4982 |
fprintf(stderr, |
|
4983 |
"qemu: '%s' invalid physical CHS format\n", str); |
|
4984 |
return -1; |
|
4985 |
} |
|
4986 |
media = MEDIA_CDROM; |
|
4987 |
} else { |
|
4988 |
fprintf(stderr, "qemu: '%s' invalid media\n", str); |
|
4989 |
return -1; |
|
4990 |
} |
|
4991 |
} |
|
4992 |
|
|
4993 |
if (get_param_value(buf, sizeof(buf), "snapshot", str)) { |
|
4994 |
if (!strcmp(buf, "on")) |
|
4995 |
snapshot = 1; |
|
4996 |
else if (!strcmp(buf, "off")) |
|
4997 |
snapshot = 0; |
|
4998 |
else { |
|
4999 |
fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str); |
|
5000 |
return -1; |
|
5001 |
} |
|
5002 |
} |
|
5003 |
|
|
5004 |
get_param_value(file, sizeof(file), "file", str); |
|
5005 |
|
|
5006 |
/* compute bus and unit according index */ |
|
5007 |
|
|
5008 |
if (index != -1) { |
|
5009 |
if (bus_id != 0 || unit_id != -1) { |
|
5010 |
fprintf(stderr, |
|
5011 |
"qemu: '%s' index cannot be used with bus and unit\n", str); |
|
5012 |
return -1; |
|
5013 |
} |
|
5014 |
if (max_devs == 0) |
|
5015 |
{ |
|
5016 |
unit_id = index; |
|
5017 |
bus_id = 0; |
|
5018 |
} else { |
|
5019 |
unit_id = index % max_devs; |
|
5020 |
bus_id = index / max_devs; |
|
5021 |
} |
|
5022 |
} |
|
5023 |
|
|
5024 |
/* if user doesn't specify a unit_id, |
|
5025 |
* try to find the first free |
|
5026 |
*/ |
|
5027 |
|
|
5028 |
if (unit_id == -1) { |
|
5029 |
unit_id = 0; |
|
5030 |
while (drive_get_index(interface, bus_id, unit_id) != -1) { |
|
5031 |
unit_id++; |
|
5032 |
if (max_devs && unit_id >= max_devs) { |
|
5033 |
unit_id -= max_devs; |
|
5034 |
bus_id++; |
|
5035 |
} |
|
5036 |
} |
|
5037 |
} |
|
5038 |
|
|
5039 |
/* check unit id */ |
|
5040 |
|
|
5041 |
if (max_devs && unit_id >= max_devs) { |
|
5042 |
fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n", |
|
5043 |
str, unit_id, max_devs - 1); |
|
5044 |
return -1; |
|
5045 |
} |
|
5046 |
|
|
5047 |
/* |
|
5048 |
* ignore multiple definitions |
|
5049 |
*/ |
|
5050 |
|
|
5051 |
if (drive_get_index(interface, bus_id, unit_id) != -1) |
|
5052 |
return 0; |
|
5053 |
|
|
5054 |
/* init */ |
|
5055 |
|
|
5056 |
snprintf(buf, sizeof(buf), "drive%d", nb_drives); |
|
5057 |
bdrv = bdrv_new(buf); |
|
5058 |
drives_table[nb_drives].bdrv = bdrv; |
|
5059 |
drives_table[nb_drives].interface = interface; |
|
5060 |
drives_table[nb_drives].bus = bus_id; |
|
5061 |
drives_table[nb_drives].unit = unit_id; |
|
5062 |
nb_drives++; |
|
5063 |
|
|
5064 |
switch(interface) { |
|
5065 |
case IF_IDE: |
|
5066 |
case IF_SCSI: |
|
5067 |
switch(media) { |
|
5068 |
case MEDIA_DISK: |
|
5069 |
if (cyls != 0) { |
|
5070 |
bdrv_set_geometry_hint(bdrv, cyls, heads, secs); |
|
5071 |
bdrv_set_translation_hint(bdrv, translation); |
|
5072 |
} |
|
5073 |
break; |
|
5074 |
case MEDIA_CDROM: |
|
5075 |
bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM); |
|
5076 |
break; |
|
5077 |
} |
|
5078 |
break; |
|
5079 |
case IF_SD: |
|
5080 |
/* FIXME: This isn't really a floppy, but it's a reasonable |
|
5081 |
approximation. */ |
|
5082 |
case IF_FLOPPY: |
|
5083 |
bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY); |
|
5084 |
break; |
|
5085 |
case IF_PFLASH: |
|
5086 |
case IF_MTD: |
|
5087 |
break; |
|
5088 |
} |
|
5089 |
if (!file[0]) |
|
5090 |
return 0; |
|
5091 |
if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || |
|
5092 |
qemu_key_check(bdrv, file)) { |
|
5093 |
fprintf(stderr, "qemu: could not open disk image %s\n", |
|
5094 |
file); |
|
5095 |
return -1; |
|
5096 |
} |
|
5097 |
return 0; |
|
5098 |
} |
|
5099 |
|
|
4747 | 5100 |
/***********************************************************/ |
4748 | 5101 |
/* USB devices */ |
4749 | 5102 |
|
... | ... | |
5526 | 5879 |
|
5527 | 5880 |
if (bs_snapshots) |
5528 | 5881 |
return bs_snapshots; |
5529 |
for(i = 0; i <= MAX_DISKS; i++) {
|
|
5530 |
bs = bs_table[i];
|
|
5882 |
for(i = 0; i <= nb_drives; i++) {
|
|
5883 |
bs = drives_table[i].bdrv;
|
|
5531 | 5884 |
if (bdrv_can_snapshot(bs)) |
5532 | 5885 |
goto ok; |
5533 | 5886 |
} |
... | ... | |
5635 | 5988 |
|
5636 | 5989 |
/* create the snapshots */ |
5637 | 5990 |
|
5638 |
for(i = 0; i < MAX_DISKS; i++) {
|
|
5639 |
bs1 = bs_table[i];
|
|
5991 |
for(i = 0; i < nb_drives; i++) {
|
|
5992 |
bs1 = drives_table[i].bdrv;
|
|
5640 | 5993 |
if (bdrv_has_snapshot(bs1)) { |
5641 | 5994 |
if (must_delete) { |
5642 | 5995 |
ret = bdrv_snapshot_delete(bs1, old_sn->id_str); |
... | ... | |
5678 | 6031 |
saved_vm_running = vm_running; |
5679 | 6032 |
vm_stop(0); |
5680 | 6033 |
|
5681 |
for(i = 0; i <= MAX_DISKS; i++) {
|
|
5682 |
bs1 = bs_table[i];
|
|
6034 |
for(i = 0; i <= nb_drives; i++) {
|
|
6035 |
bs1 = drives_table[i].bdrv;
|
|
5683 | 6036 |
if (bdrv_has_snapshot(bs1)) { |
5684 | 6037 |
ret = bdrv_snapshot_goto(bs1, name); |
5685 | 6038 |
if (ret < 0) { |
... | ... | |
5739 | 6092 |
return; |
5740 | 6093 |
} |
5741 | 6094 |
|
5742 |
for(i = 0; i <= MAX_DISKS; i++) {
|
|
5743 |
bs1 = bs_table[i];
|
|
6095 |
for(i = 0; i <= nb_drives; i++) {
|
|
6096 |
bs1 = drives_table[i].bdrv;
|
|
5744 | 6097 |
if (bdrv_has_snapshot(bs1)) { |
5745 | 6098 |
ret = bdrv_snapshot_delete(bs1, name); |
5746 | 6099 |
if (ret < 0) { |
... | ... | |
5768 | 6121 |
return; |
5769 | 6122 |
} |
5770 | 6123 |
term_printf("Snapshot devices:"); |
5771 |
for(i = 0; i <= MAX_DISKS; i++) {
|
|
5772 |
bs1 = bs_table[i];
|
|
6124 |
for(i = 0; i <= nb_drives; i++) {
|
|
6125 |
bs1 = drives_table[i].bdrv;
|
|
5773 | 6126 |
if (bdrv_has_snapshot(bs1)) { |
5774 | 6127 |
if (bs == bs1) |
5775 | 6128 |
term_printf(" %s", bdrv_get_device_name(bs1)); |
... | ... | |
6519 | 6872 |
/* find if the memory block is available on a virtual |
6520 | 6873 |
block device */ |
6521 | 6874 |
sector_num = -1; |
6522 |
for(j = 0; j < MAX_DISKS; j++) { |
|
6523 |
if (bs_table[j]) { |
|
6524 |
sector_num = bdrv_hash_find(bs_table[j], |
|
6525 |
phys_ram_base + i, BDRV_HASH_BLOCK_SIZE); |
|
6526 |
if (sector_num >= 0) |
|
6527 |
break; |
|
6528 |
} |
|
6875 |
for(j = 0; j < nb_drives; j++) { |
|
6876 |
sector_num = bdrv_hash_find(drives_table[j].bdrv, |
|
6877 |
phys_ram_base + i, |
|
6878 |
BDRV_HASH_BLOCK_SIZE); |
|
6879 |
if (sector_num >= 0) |
|
6880 |
break; |
|
6529 | 6881 |
} |
6530 |
if (j == MAX_DISKS)
|
|
6882 |
if (j == nb_drives)
|
|
6531 | 6883 |
goto normal_compress; |
6532 | 6884 |
buf[0] = 1; |
6533 | 6885 |
buf[1] = j; |
... | ... | |
6578 | 6930 |
ram_decompress_buf(s, buf + 1, 9); |
6579 | 6931 |
bs_index = buf[1]; |
6580 | 6932 |
sector_num = be64_to_cpupu((const uint64_t *)(buf + 2)); |
6581 |
if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
|
|
6933 |
if (bs_index >= nb_drives) {
|
|
6582 | 6934 |
fprintf(stderr, "Invalid block device index %d\n", bs_index); |
6583 | 6935 |
goto error; |
6584 | 6936 |
} |
6585 |
if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i, |
|
6937 |
if (bdrv_read(drives_table[bs_index].bdrv, sector_num, |
|
6938 |
phys_ram_base + i, |
|
6586 | 6939 |
BDRV_HASH_BLOCK_SIZE / 512) < 0) { |
6587 | 6940 |
fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n", |
6588 | 6941 |
bs_index, sector_num); |
... | ... | |
7079 | 7432 |
"-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" |
7080 | 7433 |
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" |
7081 | 7434 |
"-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" |
7435 |
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" |
|
7436 |
" [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n" |
|
7437 |
" use 'file' as a drive image\n" |
|
7082 | 7438 |
"-mtdblock file use 'file' as on-board Flash memory image\n" |
7083 | 7439 |
"-sd file use 'file' as SecureDigital card image\n" |
7084 | 7440 |
"-pflash file use 'file' as a parallel flash image\n" |
... | ... | |
7224 | 7580 |
QEMU_OPTION_hdb, |
7225 | 7581 |
QEMU_OPTION_hdc, |
7226 | 7582 |
QEMU_OPTION_hdd, |
7583 |
QEMU_OPTION_drive, |
|
7227 | 7584 |
QEMU_OPTION_cdrom, |
7228 | 7585 |
QEMU_OPTION_mtdblock, |
7229 | 7586 |
QEMU_OPTION_sd, |
... | ... | |
7313 | 7670 |
{ "hdb", HAS_ARG, QEMU_OPTION_hdb }, |
7314 | 7671 |
{ "hdc", HAS_ARG, QEMU_OPTION_hdc }, |
7315 | 7672 |
{ "hdd", HAS_ARG, QEMU_OPTION_hdd }, |
7673 |
{ "drive", HAS_ARG, QEMU_OPTION_drive }, |
|
7316 | 7674 |
{ "cdrom", HAS_ARG, QEMU_OPTION_cdrom }, |
7317 | 7675 |
{ "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock }, |
7318 | 7676 |
{ "sd", HAS_ARG, QEMU_OPTION_sd }, |
... | ... | |
7425 | 7783 |
|
7426 | 7784 |
static BlockDriverState *get_bdrv(int index) |
7427 | 7785 |
{ |
7428 |
BlockDriverState *bs; |
|
7429 |
|
|
7430 |
if (index < 4) { |
|
7431 |
bs = bs_table[index]; |
|
7432 |
} else if (index < 6) { |
|
7433 |
bs = fd_table[index - 4]; |
|
7434 |
} else { |
|
7435 |
bs = NULL; |
|
7436 |
} |
|
7437 |
return bs; |
|
7786 |
if (index > nb_drives) |
|
7787 |
return NULL; |
|
7788 |
return drives_table[index].bdrv; |
|
7438 | 7789 |
} |
7439 | 7790 |
|
7440 | 7791 |
static void read_passwords(void) |
... | ... | |
7637 | 7988 |
const char *gdbstub_port; |
7638 | 7989 |
#endif |
7639 | 7990 |
uint32_t boot_devices_bitmap = 0; |
7640 |
int i, cdrom_index, pflash_index;
|
|
7991 |
int i; |
|
7641 | 7992 |
int snapshot, linux_boot, net_boot; |
7642 | 7993 |
const char *initrd_filename; |
7643 |
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; |
|
7644 |
const char *pflash_filename[MAX_PFLASH]; |
|
7645 |
const char *sd_filename; |
|
7646 |
const char *mtd_filename; |
|
7647 | 7994 |
const char *kernel_filename, *kernel_cmdline; |
7648 | 7995 |
const char *boot_devices = ""; |
7649 | 7996 |
DisplayState *ds = &display_state; |
7650 | 7997 |
int cyls, heads, secs, translation; |
7651 | 7998 |
char net_clients[MAX_NET_CLIENTS][256]; |
7652 | 7999 |
int nb_net_clients; |
8000 |
int hda_index; |
|
7653 | 8001 |
int optind; |
7654 | 8002 |
const char *r, *optarg; |
7655 | 8003 |
CharDriverState *monitor_hd; |
... | ... | |
7702 | 8050 |
machine = first_machine; |
7703 | 8051 |
cpu_model = NULL; |
7704 | 8052 |
initrd_filename = NULL; |
7705 |
for(i = 0; i < MAX_FD; i++) |
|
7706 |
fd_filename[i] = NULL; |
|
7707 |
for(i = 0; i < MAX_DISKS; i++) |
|
7708 |
hd_filename[i] = NULL; |
|
7709 |
for(i = 0; i < MAX_PFLASH; i++) |
|
7710 |
pflash_filename[i] = NULL; |
|
7711 |
pflash_index = 0; |
|
7712 |
sd_filename = NULL; |
|
7713 |
mtd_filename = NULL; |
|
7714 | 8053 |
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; |
7715 | 8054 |
vga_ram_size = VGA_RAM_SIZE; |
7716 | 8055 |
#ifdef CONFIG_GDBSTUB |
... | ... | |
7721 | 8060 |
nographic = 0; |
7722 | 8061 |
kernel_filename = NULL; |
7723 | 8062 |
kernel_cmdline = ""; |
7724 |
#ifdef TARGET_PPC |
|
7725 |
cdrom_index = 1; |
|
7726 |
#else |
|
7727 |
cdrom_index = 2; |
|
7728 |
#endif |
|
7729 | 8063 |
cyls = heads = secs = 0; |
7730 | 8064 |
translation = BIOS_ATA_TRANSLATION_AUTO; |
7731 | 8065 |
pstrcpy(monitor_device, sizeof(monitor_device), "vc"); |
... | ... | |
7743 | 8077 |
usb_devices_index = 0; |
7744 | 8078 |
|
7745 | 8079 |
nb_net_clients = 0; |
8080 |
nb_drives = 0; |
|
8081 |
nb_drives_opt = 0; |
|
8082 |
hda_index = -1; |
|
7746 | 8083 |
|
7747 | 8084 |
nb_nics = 0; |
7748 | 8085 |
/* default mac address of the first network interface */ |
... | ... | |
7753 | 8090 |
break; |
7754 | 8091 |
r = argv[optind]; |
7755 | 8092 |
if (r[0] != '-') { |
7756 |
hd_filename[0] = argv[optind++];
|
|
8093 |
hda_index = drive_add(HD_ALIAS, argv[optind++], 0);
|
|
7757 | 8094 |
} else { |
7758 | 8095 |
const QEMUOption *popt; |
7759 | 8096 |
|
... | ... | |
7813 | 8150 |
initrd_filename = optarg; |
7814 | 8151 |
break; |
7815 | 8152 |
case QEMU_OPTION_hda: |
8153 |
if (cyls == 0) |
|
8154 |
hda_index = drive_add(HD_ALIAS, optarg, 0); |
|
8155 |
else |
|
8156 |
hda_index = drive_add(HD_ALIAS |
|
8157 |
",cyls=%d,heads=%d,secs=%d%s", |
|
8158 |
optarg, 0, cyls, heads, secs, |
|
8159 |
translation == BIOS_ATA_TRANSLATION_LBA ? |
|
8160 |
",trans=lba" : |
|
8161 |
translation == BIOS_ATA_TRANSLATION_NONE ? |
|
8162 |
",trans=none" : ""); |
|
8163 |
break; |
|
7816 | 8164 |
case QEMU_OPTION_hdb: |
7817 | 8165 |
case QEMU_OPTION_hdc: |
7818 | 8166 |
case QEMU_OPTION_hdd: |
7819 |
{ |
|
7820 |
int hd_index; |
|
7821 |
hd_index = popt->index - QEMU_OPTION_hda; |
|
7822 |
hd_filename[hd_index] = optarg; |
|
7823 |
if (hd_index == cdrom_index) |
|
7824 |
cdrom_index = -1; |
|
7825 |
} |
|
8167 |
drive_add(HD_ALIAS, optarg, popt->index - QEMU_OPTION_hda); |
|
7826 | 8168 |
break; |
8169 |
case QEMU_OPTION_drive: |
|
8170 |
drive_add("%s", optarg); |
|
8171 |
break; |
|
7827 | 8172 |
case QEMU_OPTION_mtdblock: |
7828 |
mtd_filename = optarg;
|
|
8173 |
drive_add(MTD_ALIAS, optarg);
|
|
7829 | 8174 |
break; |
7830 | 8175 |
case QEMU_OPTION_sd: |
7831 |
sd_filename = optarg;
|
|
8176 |
drive_add(SD_ALIAS, optarg);
|
|
7832 | 8177 |
break; |
7833 | 8178 |
case QEMU_OPTION_pflash: |
7834 |
if (pflash_index >= MAX_PFLASH) { |
|
7835 |
fprintf(stderr, "qemu: too many parallel flash images\n"); |
|
7836 |
exit(1); |
|
7837 |
} |
|
7838 |
pflash_filename[pflash_index++] = optarg; |
|
8179 |
drive_add(PFLASH_ALIAS, optarg); |
|
7839 | 8180 |
break; |
7840 | 8181 |
case QEMU_OPTION_snapshot: |
7841 | 8182 |
snapshot = 1; |
... | ... | |
7874 | 8215 |
fprintf(stderr, "qemu: invalid physical CHS format\n"); |
7875 | 8216 |
exit(1); |
7876 | 8217 |
} |
8218 |
if (hda_index != -1) |
|
8219 |
snprintf(drives_opt[hda_index] + |
|
8220 |
strlen(drives_opt[hda_index]), |
|
8221 |
sizeof(drives_opt[0]) - |
|
8222 |
strlen(drives_opt[hda_index]), |
|
8223 |
",cyls=%d,heads=%d,secs=%d%s", |
|
8224 |
cyls, heads, secs, |
|
8225 |
translation == BIOS_ATA_TRANSLATION_LBA ? |
|
8226 |
",trans=lba" : |
|
8227 |
translation == BIOS_ATA_TRANSLATION_NONE ? |
|
8228 |
",trans=none" : ""); |
|
7877 | 8229 |
} |
7878 | 8230 |
break; |
7879 | 8231 |
case QEMU_OPTION_nographic: |
... | ... | |
7892 | 8244 |
kernel_cmdline = optarg; |
7893 | 8245 |
break; |
7894 | 8246 |
case QEMU_OPTION_cdrom: |
7895 |
if (cdrom_index >= 0) { |
|
7896 |
hd_filename[cdrom_index] = optarg; |
|
7897 |
} |
|
8247 |
drive_add("file=\"%s\"," CDROM_ALIAS, optarg); |
|
7898 | 8248 |
break; |
7899 | 8249 |
case QEMU_OPTION_boot: |
7900 | 8250 |
boot_devices = optarg; |
... | ... | |
7928 | 8278 |
} |
7929 | 8279 |
break; |
7930 | 8280 |
case QEMU_OPTION_fda: |
7931 |
fd_filename[0] = optarg; |
|
7932 |
break; |
|
7933 | 8281 |
case QEMU_OPTION_fdb: |
7934 |
fd_filename[1] = optarg; |
|
8282 |
drive_add("file=\"%s\"," FD_ALIAS, optarg, |
|
8283 |
popt->index - QEMU_OPTION_fda); |
|
7935 | 8284 |
break; |
7936 | 8285 |
#ifdef TARGET_I386 |
7937 | 8286 |
case QEMU_OPTION_no_fd_bootchk: |
... | ... | |
8312 | 8661 |
|
8313 | 8662 |
/* XXX: this should not be: some embedded targets just have flash */ |
8314 | 8663 |
if (!linux_boot && net_boot == 0 && |
8315 |
hd_filename[0] == NULL && |
|
8316 |
(cdrom_index >= 0 && hd_filename[cdrom_index] == NULL) && |
|
8317 |
fd_filename[0] == NULL && |
|
8318 |
pflash_filename[0] == NULL) |
|
8664 |
nb_drives_opt == 0) |
|
8319 | 8665 |
help(1); |
8320 | 8666 |
|
8321 | 8667 |
/* boot to floppy or the default cd if no hard disk defined yet */ |
8322 | 8668 |
if (!boot_devices[0]) { |
8323 |
if (hd_filename[0] != NULL) |
|
8324 |
boot_devices = "c"; |
|
8325 |
else if (fd_filename[0] != NULL) |
|
8326 |
boot_devices = "a"; |
|
8327 |
else |
|
8328 |
boot_devices = "d"; |
|
8669 |
boot_devices = "cad"; |
|
8329 | 8670 |
} |
8330 | 8671 |
setvbuf(stdout, NULL, _IOLBF, 0); |
8331 | 8672 |
|
... | ... | |
8402 | 8743 |
exit(1); |
8403 | 8744 |
} |
8404 | 8745 |
|
8405 |
/* we always create the cdrom drive, even if no disk is there */ |
|
8406 | 8746 |
bdrv_init(); |
8407 |
if (cdrom_index >= 0) { |
|
8408 |
bs_table[cdrom_index] = bdrv_new("cdrom"); |
|
8409 |
bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM); |
|
8410 |
} |
|
8411 | 8747 |
|
8412 |
/* open the virtual block devices */ |
|
8413 |
for(i = 0; i < MAX_DISKS; i++) { |
|
8414 |
if (hd_filename[i]) { |
|
8415 |
if (!bs_table[i]) { |
|
8416 |
char buf[64]; |
|
8417 |
snprintf(buf, sizeof(buf), "hd%c", i + 'a'); |
|
8418 |
bs_table[i] = bdrv_new(buf); |
|
8419 |
} |
|
8420 |
if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { |
|
8421 |
fprintf(stderr, "qemu: could not open hard disk image '%s'\n", |
|
8422 |
hd_filename[i]); |
|
8423 |
exit(1); |
|
8424 |
} |
|
8425 |
if (i == 0 && cyls != 0) { |
|
8426 |
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs); |
|
8427 |
bdrv_set_translation_hint(bs_table[i], translation); |
|
8428 |
} |
|
8429 |
} |
|
8430 |
} |
|
8748 |
/* we always create the cdrom drive, even if no disk is there */ |
|
8431 | 8749 |
|
8432 |
/* we always create at least one floppy disk */ |
|
8433 |
fd_table[0] = bdrv_new("fda"); |
|
8434 |
bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY); |
|
8750 |
if (nb_drives_opt < MAX_DRIVES) |
|
8751 |
drive_add(CDROM_ALIAS); |
|
8435 | 8752 |
|
8436 |
for(i = 0; i < MAX_FD; i++) { |
|
8437 |
if (fd_filename[i]) { |
|
8438 |
if (!fd_table[i]) { |
|
8439 |
char buf[64]; |
|
8440 |
snprintf(buf, sizeof(buf), "fd%c", i + 'a'); |
|
8441 |
fd_table[i] = bdrv_new(buf); |
|
8442 |
bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY); |
|
8443 |
} |
|
8444 |
if (fd_filename[i][0] != '\0') { |
|
8445 |
if (bdrv_open(fd_table[i], fd_filename[i], |
|
8446 |
snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { |
|
8447 |
fprintf(stderr, "qemu: could not open floppy disk image '%s'\n", |
|
8448 |
fd_filename[i]); |
|
8449 |
exit(1); |
|
8450 |
} |
|
8451 |
} |
|
8452 |
} |
|
8453 |
} |
|
8753 |
/* we always create at least on floppy */ |
|
8454 | 8754 |
|
8455 |
/* Open the virtual parallel flash block devices */ |
|
8456 |
for(i = 0; i < MAX_PFLASH; i++) { |
|
8457 |
if (pflash_filename[i]) { |
|
8458 |
if (!pflash_table[i]) { |
|
8459 |
char buf[64]; |
|
8460 |
snprintf(buf, sizeof(buf), "fl%c", i + 'a'); |
|
8461 |
pflash_table[i] = bdrv_new(buf); |
|
8462 |
} |
|
8463 |
if (bdrv_open(pflash_table[i], pflash_filename[i], |
|
8464 |
snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { |
|
8465 |
fprintf(stderr, "qemu: could not open flash image '%s'\n", |
|
8466 |
pflash_filename[i]); |
|
8467 |
exit(1); |
|
8468 |
} |
|
8469 |
} |
|
8470 |
} |
|
8755 |
if (nb_drives_opt < MAX_DRIVES) |
|
8756 |
drive_add(FD_ALIAS, 0); |
|
8471 | 8757 |
|
8472 |
sd_bdrv = bdrv_new ("sd"); |
|
8473 |
/* FIXME: This isn't really a floppy, but it's a reasonable |
|
8474 |
approximation. */ |
|
8475 |
bdrv_set_type_hint(sd_bdrv, BDRV_TYPE_FLOPPY); |
|
8476 |
if (sd_filename) { |
|
8477 |
if (bdrv_open(sd_bdrv, sd_filename, |
|
8478 |
snapshot ? BDRV_O_SNAPSHOT : 0) < 0) { |
|
8479 |
fprintf(stderr, "qemu: could not open SD card image %s\n", |
|
8480 |
sd_filename); |
|
8481 |
} else |
|
8482 |
qemu_key_check(sd_bdrv, sd_filename); |
|
8483 |
} |
|
8484 |
|
|
8485 |
if (mtd_filename) { |
|
8486 |
mtd_bdrv = bdrv_new ("mtd"); |
|
8487 |
if (bdrv_open(mtd_bdrv, mtd_filename, |
|
8488 |
snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || |
|
8489 |
qemu_key_check(mtd_bdrv, mtd_filename)) { |
|
8490 |
fprintf(stderr, "qemu: could not open Flash image %s\n", |
|
8491 |
mtd_filename); |
|
8492 |
bdrv_delete(mtd_bdrv); |
|
8493 |
mtd_bdrv = 0; |
|
8494 |
} |
|
8495 |
} |
|
8758 |
/* open the virtual block devices */ |
|
8759 |
|
|
8760 |
for(i = 0; i < nb_drives_opt; i++) |
|
8761 |
if (drive_init(drives_opt[i], snapshot, machine) == -1) |
|
8762 |
exit(1); |
|
8496 | 8763 |
|
8497 | 8764 |
register_savevm("timer", 0, 2, timer_save, timer_load, NULL); |
8498 | 8765 |
register_savevm("ram", 0, 2, ram_save, ram_load, NULL); |
Also available in: Unified diff