109 |
109 |
/* XXX: use a two level table to limit memory usage */
|
110 |
110 |
#define MAX_IOPORTS 65536
|
111 |
111 |
|
|
112 |
#define DISK_OPTIONS_SIZE 256
|
|
113 |
|
112 |
114 |
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
|
113 |
115 |
char phys_ram_file[1024];
|
114 |
116 |
void *ioport_opaque[MAX_IOPORTS];
|
... | ... | |
119 |
121 |
BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
|
120 |
122 |
/* point to the block driver where the snapshots are managed */
|
121 |
123 |
BlockDriverState *bs_snapshots;
|
|
124 |
BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS];
|
|
125 |
SCSIDiskInfo scsi_disks_info[MAX_SCSI_DISKS];
|
|
126 |
int scsi_hba_lsi; /* Count of scsi disks/cdrom using this lsi adapter */
|
122 |
127 |
int vga_ram_size;
|
123 |
128 |
int bios_size;
|
124 |
129 |
static DisplayState display_state;
|
... | ... | |
3814 |
3819 |
term_printf(" %s\n", vc->info_str);
|
3815 |
3820 |
}
|
3816 |
3821 |
}
|
3817 |
|
|
|
3822 |
|
|
3823 |
/* Parse IDE and SCSI disk options */
|
|
3824 |
static int disk_options_init(int num_ide_disks,
|
|
3825 |
char ide_disk_options[][DISK_OPTIONS_SIZE],
|
|
3826 |
int snapshot,
|
|
3827 |
int num_scsi_disks,
|
|
3828 |
char scsi_disk_options[][DISK_OPTIONS_SIZE],
|
|
3829 |
int cdrom_index,
|
|
3830 |
int cyls,
|
|
3831 |
int heads,
|
|
3832 |
int secs,
|
|
3833 |
int translation)
|
|
3834 |
{
|
|
3835 |
char buf[256];
|
|
3836 |
char dev_name[64];
|
|
3837 |
int id, i, j;
|
|
3838 |
int cdrom_device;
|
|
3839 |
int ide_cdrom_created = 0;
|
|
3840 |
int scsi_index;
|
|
3841 |
scsi_host_adapters temp_adapter;
|
|
3842 |
|
|
3843 |
/* Process any IDE disks/cdroms */
|
|
3844 |
for (i=0; i< num_ide_disks; i++) {
|
|
3845 |
for (j=0; j<MAX_DISKS; j++) {
|
|
3846 |
if (ide_disk_options[j][0] == '\0')
|
|
3847 |
continue;
|
|
3848 |
|
|
3849 |
if (get_param_value(buf, sizeof(buf),"type",ide_disk_options[j])) {
|
|
3850 |
if (!strcmp(buf, "disk")) {
|
|
3851 |
cdrom_device = 0;
|
|
3852 |
} else if (!strcmp(buf, "cdrom")) {
|
|
3853 |
cdrom_device = 1;
|
|
3854 |
ide_cdrom_created = 1;
|
|
3855 |
} else {
|
|
3856 |
fprintf(stderr, "qemu: invalid IDE disk type= value: %s\n", buf);
|
|
3857 |
return -1;
|
|
3858 |
}
|
|
3859 |
} else {
|
|
3860 |
cdrom_device = 0;
|
|
3861 |
}
|
|
3862 |
|
|
3863 |
if (cdrom_device) {
|
|
3864 |
snprintf(dev_name, sizeof(dev_name), "cdrom%c", i);
|
|
3865 |
} else {
|
|
3866 |
snprintf(dev_name, sizeof(dev_name), "hd%c", i + 'a');
|
|
3867 |
}
|
|
3868 |
|
|
3869 |
if (!(get_param_value(buf, sizeof(buf),"img",ide_disk_options[j]))) {
|
|
3870 |
fprintf(stderr, "qemu: missing IDE disk img= value.\n");
|
|
3871 |
return -1;
|
|
3872 |
}
|
|
3873 |
|
|
3874 |
if (!(bs_table[i] = bdrv_new(dev_name))) {
|
|
3875 |
fprintf(stderr, "qemu: unable to create new block device for:%s\n",dev_name);
|
|
3876 |
return -1;
|
|
3877 |
}
|
|
3878 |
|
|
3879 |
if (cdrom_device) {
|
|
3880 |
bdrv_set_type_hint(bs_table[i], BDRV_TYPE_CDROM);
|
|
3881 |
}
|
|
3882 |
|
|
3883 |
if (bdrv_open(bs_table[i], buf, snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
|
|
3884 |
fprintf(stderr, "qemu: could not open hard disk image: '%s'\n",
|
|
3885 |
buf);
|
|
3886 |
return -1;
|
|
3887 |
}
|
|
3888 |
if (i == 0 && cyls != 0) {
|
|
3889 |
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
|
|
3890 |
bdrv_set_translation_hint(bs_table[i], translation);
|
|
3891 |
}
|
|
3892 |
ide_disk_options[j][0] = '\0';
|
|
3893 |
|
|
3894 |
if (i == cdrom_index) {
|
|
3895 |
cdrom_index = -1;
|
|
3896 |
}
|
|
3897 |
break; /* finished with this IDE device*/
|
|
3898 |
}
|
|
3899 |
}
|
|
3900 |
|
|
3901 |
if (cdrom_index >= 0 && (!ide_cdrom_created)) {
|
|
3902 |
bs_table[cdrom_index] = bdrv_new("cdrom");
|
|
3903 |
bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
|
|
3904 |
}
|
|
3905 |
|
|
3906 |
for(i = 0; i < num_scsi_disks; i++) {
|
|
3907 |
|
|
3908 |
temp_adapter = SCSI_LSI_53C895A;
|
|
3909 |
scsi_hba_lsi++;
|
|
3910 |
|
|
3911 |
/*Check for sdx= parameter */
|
|
3912 |
if (get_param_value(buf, sizeof(buf), "sdx", scsi_disk_options[i])) {
|
|
3913 |
if (buf[0] >= 'a' && buf[0] <= 'g') {
|
|
3914 |
scsi_index = buf[0] - 'a';
|
|
3915 |
} else{
|
|
3916 |
fprintf(stderr, "qemu: sdx= option for SCSI must be one letter from a-g. %s \n",buf);
|
|
3917 |
exit(1);
|
|
3918 |
}
|
|
3919 |
} else {
|
|
3920 |
scsi_index = 0;
|
|
3921 |
}
|
|
3922 |
|
|
3923 |
/* Check for SCSI id specified. */
|
|
3924 |
if (get_param_value(buf, sizeof(buf),"id",scsi_disk_options[i])) {
|
|
3925 |
id = strtol(buf, NULL, 0);
|
|
3926 |
if (id < 0 || id > 6) {
|
|
3927 |
fprintf(stderr, "qemu: SCSI id must be from 0-6: %d\n", id);
|
|
3928 |
return -1;
|
|
3929 |
}
|
|
3930 |
/* Check if id already used */
|
|
3931 |
for(j = 0; j < MAX_SCSI_DISKS; j++) {
|
|
3932 |
if (scsi_disks_info[j].device_type != SCSI_NONE &&
|
|
3933 |
j != i &&
|
|
3934 |
scsi_disks_info[j].adapter == temp_adapter &&
|
|
3935 |
scsi_disks_info[j].id == id ) {
|
|
3936 |
fprintf(stderr, "qemu: SCSI id already used: %u\n", id);
|
|
3937 |
return -1;
|
|
3938 |
}
|
|
3939 |
}
|
|
3940 |
} else {
|
|
3941 |
id = -1;
|
|
3942 |
}
|
|
3943 |
scsi_disks_info[i].adapter = temp_adapter;
|
|
3944 |
scsi_disks_info[i].id = id;
|
|
3945 |
|
|
3946 |
if (get_param_value(buf, sizeof(buf),"type",scsi_disk_options[i])) {
|
|
3947 |
if (!strcmp(buf, "disk")) {
|
|
3948 |
cdrom_device = 0;
|
|
3949 |
} else if (!strcmp(buf, "cdrom")) {
|
|
3950 |
cdrom_device = 1;
|
|
3951 |
} else {
|
|
3952 |
fprintf(stderr, "qemu: invalid SCSI disk type= value: %s\n", buf);
|
|
3953 |
return -1;
|
|
3954 |
}
|
|
3955 |
} else {
|
|
3956 |
cdrom_device = 0;
|
|
3957 |
}
|
|
3958 |
|
|
3959 |
if (cdrom_device) {
|
|
3960 |
snprintf(dev_name, sizeof(buf), "cdrom%c", scsi_index);
|
|
3961 |
scsi_disks_info[scsi_index].device_type = SCSI_CDROM;
|
|
3962 |
} else {
|
|
3963 |
snprintf(dev_name, sizeof(buf), "sd%c", scsi_index + 'a');
|
|
3964 |
scsi_disks_info[scsi_index].device_type = SCSI_DISK;
|
|
3965 |
}
|
|
3966 |
|
|
3967 |
if (!(bs_scsi_table[scsi_index] = bdrv_new(dev_name))) {
|
|
3968 |
fprintf(stderr, "qemu: unable to create new block device for:%s\n",dev_name);
|
|
3969 |
return -1;
|
|
3970 |
}
|
|
3971 |
|
|
3972 |
/* Get image filename from options and then try to open it */
|
|
3973 |
if (get_param_value(buf, sizeof(buf),"img",scsi_disk_options[i])) {
|
|
3974 |
if (bdrv_open(bs_scsi_table[scsi_index], buf, 0) < 0) {
|
|
3975 |
fprintf(stderr, "qemu: could not open SCSI disk image img='%s'\n",buf);
|
|
3976 |
return -1;
|
|
3977 |
}
|
|
3978 |
} else {
|
|
3979 |
fprintf(stderr, "qemu: SCSI disk image not specified for sd%c \n", i + 'a');
|
|
3980 |
return -1;
|
|
3981 |
}
|
|
3982 |
}
|
|
3983 |
|
|
3984 |
return 0;
|
|
3985 |
}
|
|
3986 |
|
|
3987 |
|
3818 |
3988 |
/***********************************************************/
|
3819 |
3989 |
/* USB devices */
|
3820 |
3990 |
|
... | ... | |
5923 |
6093 |
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
|
5924 |
6094 |
"-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
|
5925 |
6095 |
"-boot [a|c|d] boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
|
|
6096 |
"-disk ide,img=file[,hdx=a..dd][,type=disk|cdrom] \n"
|
|
6097 |
" defaults are: hdx=a,type=disk \n"
|
|
6098 |
"-disk scsi,img=file[,sdx=a..g][,type=disk|cdrom][,id=n] \n"
|
|
6099 |
" defaults are: sdx=a,type=disk,id='auto assign' \n"
|
5926 |
6100 |
"-snapshot write to temporary files instead of disk image files\n"
|
5927 |
6101 |
#ifdef CONFIG_SDL
|
5928 |
6102 |
"-no-quit disable SDL window close capability\n"
|
... | ... | |
6103 |
6277 |
QEMU_OPTION_no_acpi,
|
6104 |
6278 |
QEMU_OPTION_no_reboot,
|
6105 |
6279 |
QEMU_OPTION_daemonize,
|
|
6280 |
QEMU_OPTION_disk,
|
6106 |
6281 |
};
|
6107 |
6282 |
|
6108 |
6283 |
typedef struct QEMUOption {
|
... | ... | |
6177 |
6352 |
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
|
6178 |
6353 |
{ "smp", HAS_ARG, QEMU_OPTION_smp },
|
6179 |
6354 |
{ "vnc", HAS_ARG, QEMU_OPTION_vnc },
|
|
6355 |
{ "disk", HAS_ARG, QEMU_OPTION_disk },
|
6180 |
6356 |
|
6181 |
6357 |
/* temporary options */
|
6182 |
6358 |
{ "usb", 0, QEMU_OPTION_usb },
|
... | ... | |
6395 |
6571 |
int i, cdrom_index;
|
6396 |
6572 |
int snapshot, linux_boot;
|
6397 |
6573 |
const char *initrd_filename;
|
6398 |
|
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
|
|
6574 |
const char *fd_filename[MAX_FD];
|
|
6575 |
char scsi_options[MAX_SCSI_DISKS] [DISK_OPTIONS_SIZE];
|
|
6576 |
char ide_options[MAX_DISKS] [DISK_OPTIONS_SIZE];
|
|
6577 |
int num_ide_disks;
|
|
6578 |
int num_scsi_disks;
|
6399 |
6579 |
const char *kernel_filename, *kernel_cmdline;
|
6400 |
6580 |
DisplayState *ds = &display_state;
|
6401 |
6581 |
int cyls, heads, secs, translation;
|
... | ... | |
6450 |
6630 |
register_machines();
|
6451 |
6631 |
machine = first_machine;
|
6452 |
6632 |
initrd_filename = NULL;
|
|
6633 |
for(i = 0; i < MAX_SCSI_DISKS; i++) {
|
|
6634 |
scsi_disks_info[i].device_type = SCSI_NONE;
|
|
6635 |
bs_scsi_table[i] = NULL;
|
|
6636 |
}
|
|
6637 |
|
|
6638 |
num_ide_disks = 0;
|
|
6639 |
num_scsi_disks = 0;
|
|
6640 |
|
6453 |
6641 |
for(i = 0; i < MAX_FD; i++)
|
6454 |
6642 |
fd_filename[i] = NULL;
|
6455 |
|
for(i = 0; i < MAX_DISKS; i++)
|
6456 |
|
hd_filename[i] = NULL;
|
|
6643 |
for(i = 0; i < MAX_DISKS; i++) {
|
|
6644 |
ide_options[i][0] = '\0';
|
|
6645 |
}
|
6457 |
6646 |
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
|
6458 |
6647 |
vga_ram_size = VGA_RAM_SIZE;
|
6459 |
6648 |
bios_size = BIOS_SIZE;
|
... | ... | |
6497 |
6686 |
break;
|
6498 |
6687 |
r = argv[optind];
|
6499 |
6688 |
if (r[0] != '-') {
|
6500 |
|
hd_filename[0] = argv[optind++];
|
|
6689 |
|
|
6690 |
/* Build new disk IDE syntax string */
|
|
6691 |
pstrcpy(ide_options[0],
|
|
6692 |
14,
|
|
6693 |
"hdx=a,img=");
|
|
6694 |
/*Add on image filename */
|
|
6695 |
pstrcpy(&(ide_options[0][13]),
|
|
6696 |
sizeof(ide_options[0])-13,
|
|
6697 |
argv[optind++]);
|
|
6698 |
num_ide_disks++;
|
6501 |
6699 |
} else {
|
6502 |
6700 |
const QEMUOption *popt;
|
6503 |
6701 |
|
... | ... | |
6547 |
6745 |
case QEMU_OPTION_hdd:
|
6548 |
6746 |
{
|
6549 |
6747 |
int hd_index;
|
|
6748 |
const char newIDE_DiskSyntax [][10] = {
|
|
6749 |
"hdx=a,img=", "hdx=b,img=", "hdx=c,img=", "hdx=d,img=" };
|
|
6750 |
|
6550 |
6751 |
hd_index = popt->index - QEMU_OPTION_hda;
|
6551 |
|
hd_filename[hd_index] = optarg;
|
6552 |
|
if (hd_index == cdrom_index)
|
6553 |
|
cdrom_index = -1;
|
|
6752 |
if (num_ide_disks >= MAX_DISKS){
|
|
6753 |
fprintf(stderr, "qemu: too many IDE disks defined.\n");
|
|
6754 |
exit(1);
|
|
6755 |
}
|
|
6756 |
/* Build new disk IDE syntax string */
|
|
6757 |
pstrcpy(ide_options[hd_index],
|
|
6758 |
11,
|
|
6759 |
newIDE_DiskSyntax[hd_index]);
|
|
6760 |
/* Add on image filename */
|
|
6761 |
pstrcpy(&(ide_options[hd_index][10]),
|
|
6762 |
sizeof(ide_options[0])-10,
|
|
6763 |
optarg);
|
|
6764 |
num_ide_disks++;
|
|
6765 |
}
|
|
6766 |
break;
|
|
6767 |
case QEMU_OPTION_disk: /*Combined IDE and SCSI, for disk and CDROM */
|
|
6768 |
{
|
|
6769 |
const char *p_input_char;
|
|
6770 |
char *p_output_string;
|
|
6771 |
char device[64];
|
|
6772 |
int disk_index;
|
|
6773 |
|
|
6774 |
p_input_char = optarg;
|
|
6775 |
p_output_string = device;
|
|
6776 |
while (*p_input_char != '\0' && *p_input_char != ',') {
|
|
6777 |
if ((p_output_string - device) < sizeof(device) - 1)
|
|
6778 |
*p_output_string++ = *p_input_char;
|
|
6779 |
p_input_char++;
|
|
6780 |
}
|
|
6781 |
*p_output_string = '\0';
|
|
6782 |
if (*p_input_char == ',')
|
|
6783 |
p_input_char++;
|
|
6784 |
|
|
6785 |
if (!strcmp(device, "scsi")) {
|
|
6786 |
if (num_scsi_disks >= MAX_SCSI_DISKS) {
|
|
6787 |
fprintf(stderr, "qemu: too many SCSI disks defined.\n");
|
|
6788 |
exit(1);
|
|
6789 |
}
|
|
6790 |
pstrcpy(scsi_options[num_scsi_disks],
|
|
6791 |
sizeof(scsi_options[0]),
|
|
6792 |
p_input_char);
|
|
6793 |
num_scsi_disks++;
|
|
6794 |
} else if (!strcmp(device,"ide")) {
|
|
6795 |
if (num_ide_disks >= MAX_DISKS) {
|
|
6796 |
fprintf(stderr, "qemu: too many IDE disks/cdroms defined.\n");
|
|
6797 |
exit(1);
|
|
6798 |
}
|
|
6799 |
disk_index = 0; /* default is hda */
|
|
6800 |
if (get_param_value(device, sizeof(device),"hdx",p_input_char)) {
|
|
6801 |
if (device[0] >= 'a' && device[0] <= 'd') {
|
|
6802 |
disk_index = device[0] - 'a';
|
|
6803 |
} else {
|
|
6804 |
fprintf(stderr, "qemu: invalid IDE disk hdx= value: %s\n", device);
|
|
6805 |
return -1;
|
|
6806 |
}
|
|
6807 |
}
|
|
6808 |
else disk_index=0;
|
|
6809 |
pstrcpy(ide_options[disk_index],
|
|
6810 |
sizeof(ide_options[0]),
|
|
6811 |
p_input_char);
|
|
6812 |
num_ide_disks++;
|
|
6813 |
} else {
|
|
6814 |
fprintf(stderr, "qemu: -disk option must specify IDE or SCSI: %s \n",device);
|
|
6815 |
exit(1);
|
|
6816 |
}
|
6554 |
6817 |
}
|
6555 |
6818 |
break;
|
6556 |
6819 |
case QEMU_OPTION_snapshot:
|
... | ... | |
6604 |
6867 |
kernel_cmdline = optarg;
|
6605 |
6868 |
break;
|
6606 |
6869 |
case QEMU_OPTION_cdrom:
|
6607 |
|
if (cdrom_index >= 0) {
|
6608 |
|
hd_filename[cdrom_index] = optarg;
|
|
6870 |
{
|
|
6871 |
char buf[24];
|
|
6872 |
if (num_ide_disks >= MAX_DISKS) {
|
|
6873 |
fprintf(stderr, "qemu: too many IDE disks/cdroms defined.\n");
|
|
6874 |
exit(1);
|
|
6875 |
}
|
|
6876 |
snprintf(buf, sizeof(buf), "type=cdrom,hdx=%c,img=", cdrom_index + 'a');
|
|
6877 |
/* Build new disk IDE syntax string */
|
|
6878 |
pstrcpy(ide_options[cdrom_index],
|
|
6879 |
25,
|
|
6880 |
buf);
|
|
6881 |
/* Add on image filename */
|
|
6882 |
pstrcpy(&(ide_options[cdrom_index][24]),
|
|
6883 |
sizeof(ide_options[0])-24,
|
|
6884 |
optarg);
|
|
6885 |
num_ide_disks++;
|
6609 |
6886 |
}
|
6610 |
6887 |
break;
|
6611 |
6888 |
case QEMU_OPTION_boot:
|
... | ... | |
6893 |
7170 |
kqemu_allowed = 0;
|
6894 |
7171 |
#endif
|
6895 |
7172 |
linux_boot = (kernel_filename != NULL);
|
6896 |
|
|
6897 |
|
if (!linux_boot &&
|
6898 |
|
hd_filename[0] == '\0' &&
|
6899 |
|
(cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
|
|
7173 |
|
|
7174 |
if (!linux_boot &&
|
|
7175 |
num_ide_disks == 0 &&
|
6900 |
7176 |
fd_filename[0] == '\0')
|
6901 |
7177 |
help();
|
6902 |
|
|
6903 |
|
/* boot to cd by default if no hard disk */
|
6904 |
|
if (hd_filename[0] == '\0' && boot_device == 'c') {
|
6905 |
|
if (fd_filename[0] != '\0')
|
6906 |
|
boot_device = 'a';
|
6907 |
|
else
|
6908 |
|
boot_device = 'd';
|
6909 |
|
}
|
6910 |
7178 |
|
6911 |
7179 |
setvbuf(stdout, NULL, _IOLBF, 0);
|
6912 |
7180 |
|
... | ... | |
6942 |
7210 |
exit(1);
|
6943 |
7211 |
}
|
6944 |
7212 |
|
6945 |
|
/* we always create the cdrom drive, even if no disk is there */
|
6946 |
7213 |
bdrv_init();
|
6947 |
|
if (cdrom_index >= 0) {
|
6948 |
|
bs_table[cdrom_index] = bdrv_new("cdrom");
|
6949 |
|
bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
|
|
7214 |
|
|
7215 |
/* open the virtual block devices, disks or CDRoms */
|
|
7216 |
if (disk_options_init(num_ide_disks,ide_options,snapshot,
|
|
7217 |
num_scsi_disks,scsi_options,
|
|
7218 |
cdrom_index,
|
|
7219 |
cyls, heads, secs, translation)){
|
|
7220 |
exit(1);
|
6950 |
7221 |
}
|
6951 |
7222 |
|
6952 |
|
/* open the virtual block devices */
|
6953 |
|
for(i = 0; i < MAX_DISKS; i++) {
|
6954 |
|
if (hd_filename[i]) {
|
6955 |
|
if (!bs_table[i]) {
|
6956 |
|
char buf[64];
|
6957 |
|
snprintf(buf, sizeof(buf), "hd%c", i + 'a');
|
6958 |
|
bs_table[i] = bdrv_new(buf);
|
6959 |
|
}
|
6960 |
|
if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
|
6961 |
|
fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
|
6962 |
|
hd_filename[i]);
|
6963 |
|
exit(1);
|
6964 |
|
}
|
6965 |
|
if (i == 0 && cyls != 0) {
|
6966 |
|
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
|
6967 |
|
bdrv_set_translation_hint(bs_table[i], translation);
|
6968 |
|
}
|
6969 |
|
}
|
|
7223 |
/* boot to floppy or default cd if no hard disk */
|
|
7224 |
if (num_ide_disks == 0 && boot_device == 'c') {
|
|
7225 |
if (fd_filename[0] != '\0')
|
|
7226 |
boot_device = 'a';
|
|
7227 |
else
|
|
7228 |
boot_device = 'd';
|
6970 |
7229 |
}
|
6971 |
7230 |
|
6972 |
7231 |
/* we always create at least one floppy disk */
|