mirror of https://github.com/xqemu/xqemu.git
better BIOS ATA translation support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1153 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e35c55fe38
commit
46d4767d93
10
block.c
10
block.c
|
@ -348,6 +348,11 @@ void bdrv_set_type_hint(BlockDriverState *bs, int type)
|
||||||
type == BDRV_TYPE_FLOPPY));
|
type == BDRV_TYPE_FLOPPY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
|
||||||
|
{
|
||||||
|
bs->translation = translation;
|
||||||
|
}
|
||||||
|
|
||||||
void bdrv_get_geometry_hint(BlockDriverState *bs,
|
void bdrv_get_geometry_hint(BlockDriverState *bs,
|
||||||
int *pcyls, int *pheads, int *psecs)
|
int *pcyls, int *pheads, int *psecs)
|
||||||
{
|
{
|
||||||
|
@ -361,6 +366,11 @@ int bdrv_get_type_hint(BlockDriverState *bs)
|
||||||
return bs->type;
|
return bs->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bdrv_get_translation_hint(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
return bs->translation;
|
||||||
|
}
|
||||||
|
|
||||||
int bdrv_is_removable(BlockDriverState *bs)
|
int bdrv_is_removable(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bs->removable;
|
return bs->removable;
|
||||||
|
|
|
@ -68,7 +68,7 @@ struct BlockDriverState {
|
||||||
|
|
||||||
/* NOTE: the following infos are only hints for real hardware
|
/* NOTE: the following infos are only hints for real hardware
|
||||||
drivers. They are not used by the block driver */
|
drivers. They are not used by the block driver */
|
||||||
int cyls, heads, secs;
|
int cyls, heads, secs, translation;
|
||||||
int type;
|
int type;
|
||||||
char device_name[32];
|
char device_name[32];
|
||||||
BlockDriverState *next;
|
BlockDriverState *next;
|
||||||
|
|
21
hw/ide.c
21
hw/ide.c
|
@ -1826,11 +1826,11 @@ struct partition {
|
||||||
uint32_t nr_sects; /* nr of sectors in partition */
|
uint32_t nr_sects; /* nr of sectors in partition */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/* try to guess the IDE geometry from the MSDOS partition table */
|
/* try to guess the IDE physical geometry from the MSDOS partition table */
|
||||||
static void ide_guess_geometry(IDEState *s)
|
static void ide_guess_geometry(IDEState *s)
|
||||||
{
|
{
|
||||||
uint8_t buf[512];
|
uint8_t buf[512];
|
||||||
int ret, i;
|
int ret, i, heads, sectors, cylinders;
|
||||||
struct partition *p;
|
struct partition *p;
|
||||||
uint32_t nr_sects;
|
uint32_t nr_sects;
|
||||||
|
|
||||||
|
@ -1848,9 +1848,18 @@ static void ide_guess_geometry(IDEState *s)
|
||||||
if (nr_sects && p->end_head) {
|
if (nr_sects && p->end_head) {
|
||||||
/* We make the assumption that the partition terminates on
|
/* We make the assumption that the partition terminates on
|
||||||
a cylinder boundary */
|
a cylinder boundary */
|
||||||
s->heads = p->end_head + 1;
|
heads = p->end_head + 1;
|
||||||
s->sectors = p->end_sector & 63;
|
if (heads < 1 || heads > 16)
|
||||||
s->cylinders = s->nb_sectors / (s->heads * s->sectors);
|
continue;
|
||||||
|
sectors = p->end_sector & 63;
|
||||||
|
if (sectors == 0)
|
||||||
|
continue;
|
||||||
|
cylinders = s->nb_sectors / (heads * sectors);
|
||||||
|
if (cylinders < 1 || cylinders > 16383)
|
||||||
|
continue;
|
||||||
|
s->heads = heads;
|
||||||
|
s->sectors = sectors;
|
||||||
|
s->cylinders = cylinders;
|
||||||
#if 0
|
#if 0
|
||||||
printf("guessed partition: CHS=%d %d %d\n",
|
printf("guessed partition: CHS=%d %d %d\n",
|
||||||
s->cylinders, s->heads, s->sectors);
|
s->cylinders, s->heads, s->sectors);
|
||||||
|
@ -1885,7 +1894,7 @@ static void ide_init2(IDEState *ide_state, int irq,
|
||||||
} else {
|
} else {
|
||||||
ide_guess_geometry(s);
|
ide_guess_geometry(s);
|
||||||
if (s->cylinders == 0) {
|
if (s->cylinders == 0) {
|
||||||
/* if no geometry, use a LBA compatible one */
|
/* if no geometry, use a standard physical disk geometry */
|
||||||
cylinders = nb_sectors / (16 * 63);
|
cylinders = nb_sectors / (16 * 63);
|
||||||
if (cylinders > 16383)
|
if (cylinders > 16383)
|
||||||
cylinders = 16383;
|
cylinders = 16383;
|
||||||
|
|
16
hw/pc.c
16
hw/pc.c
|
@ -217,12 +217,13 @@ static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table
|
||||||
val = 0;
|
val = 0;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (hd_table[i]) {
|
if (hd_table[i]) {
|
||||||
int cylinders, heads, sectors;
|
int cylinders, heads, sectors, translation;
|
||||||
uint8_t translation;
|
/* NOTE: bdrv_get_geometry_hint() returns the physical
|
||||||
/* NOTE: bdrv_get_geometry_hint() returns the geometry
|
geometry. It is always such that: 1 <= sects <= 63, 1
|
||||||
that the hard disk returns. It is always such that: 1 <=
|
<= heads <= 16, 1 <= cylinders <= 16383. The BIOS
|
||||||
sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
|
geometry can be different if a translation is done. */
|
||||||
16383. The BIOS geometry can be different. */
|
translation = bdrv_get_translation_hint(hd_table[i]);
|
||||||
|
if (translation == BIOS_ATA_TRANSLATION_AUTO) {
|
||||||
bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors);
|
bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors);
|
||||||
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
|
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
|
||||||
/* No translation. */
|
/* No translation. */
|
||||||
|
@ -231,6 +232,9 @@ static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table
|
||||||
/* LBA translation. */
|
/* LBA translation. */
|
||||||
translation = 1;
|
translation = 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
translation--;
|
||||||
|
}
|
||||||
val |= translation << (i * 2);
|
val |= translation << (i * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,6 +343,12 @@ Change gdb connection port.
|
||||||
Do not start CPU at startup (you must type 'c' in the monitor).
|
Do not start CPU at startup (you must type 'c' in the monitor).
|
||||||
@item -d
|
@item -d
|
||||||
Output log in /tmp/qemu.log
|
Output log in /tmp/qemu.log
|
||||||
|
@item -hdachs c,h,s,[,t]
|
||||||
|
Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
|
||||||
|
@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
|
||||||
|
translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
|
||||||
|
all thoses parameters. This option is useful for old MS-DOS disk
|
||||||
|
images.
|
||||||
@item -isa
|
@item -isa
|
||||||
Simulate an ISA-only system (default is PCI system).
|
Simulate an ISA-only system (default is PCI system).
|
||||||
@item -std-vga
|
@item -std-vga
|
||||||
|
|
31
vl.c
31
vl.c
|
@ -2537,7 +2537,8 @@ void help(void)
|
||||||
"-s wait gdb connection to port %d\n"
|
"-s wait gdb connection to port %d\n"
|
||||||
"-p port change gdb connection port\n"
|
"-p port change gdb connection port\n"
|
||||||
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
|
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
|
||||||
"-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
|
"-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
|
||||||
|
" translation (t=none or lba) (usually qemu can guess them)\n"
|
||||||
"-L path set the directory for the BIOS and VGA BIOS\n"
|
"-L path set the directory for the BIOS and VGA BIOS\n"
|
||||||
#ifdef USE_CODE_COPY
|
#ifdef USE_CODE_COPY
|
||||||
"-no-code-copy disable code copy acceleration\n"
|
"-no-code-copy disable code copy acceleration\n"
|
||||||
|
@ -2753,7 +2754,7 @@ int main(int argc, char **argv)
|
||||||
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
|
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
|
||||||
const char *kernel_filename, *kernel_cmdline;
|
const char *kernel_filename, *kernel_cmdline;
|
||||||
DisplayState *ds = &display_state;
|
DisplayState *ds = &display_state;
|
||||||
int cyls, heads, secs;
|
int cyls, heads, secs, translation;
|
||||||
int start_emulation = 1;
|
int start_emulation = 1;
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
||||||
|
@ -2788,6 +2789,7 @@ int main(int argc, char **argv)
|
||||||
kernel_cmdline = "";
|
kernel_cmdline = "";
|
||||||
has_cdrom = 1;
|
has_cdrom = 1;
|
||||||
cyls = heads = secs = 0;
|
cyls = heads = secs = 0;
|
||||||
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||||
pstrcpy(monitor_device, sizeof(monitor_device), "vc");
|
pstrcpy(monitor_device, sizeof(monitor_device), "vc");
|
||||||
|
|
||||||
pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
|
pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
|
||||||
|
@ -2857,17 +2859,34 @@ int main(int argc, char **argv)
|
||||||
const char *p;
|
const char *p;
|
||||||
p = optarg;
|
p = optarg;
|
||||||
cyls = strtol(p, (char **)&p, 0);
|
cyls = strtol(p, (char **)&p, 0);
|
||||||
|
if (cyls < 1 || cyls > 16383)
|
||||||
|
goto chs_fail;
|
||||||
if (*p != ',')
|
if (*p != ',')
|
||||||
goto chs_fail;
|
goto chs_fail;
|
||||||
p++;
|
p++;
|
||||||
heads = strtol(p, (char **)&p, 0);
|
heads = strtol(p, (char **)&p, 0);
|
||||||
|
if (heads < 1 || heads > 16)
|
||||||
|
goto chs_fail;
|
||||||
if (*p != ',')
|
if (*p != ',')
|
||||||
goto chs_fail;
|
goto chs_fail;
|
||||||
p++;
|
p++;
|
||||||
secs = strtol(p, (char **)&p, 0);
|
secs = strtol(p, (char **)&p, 0);
|
||||||
if (*p != '\0') {
|
if (secs < 1 || secs > 63)
|
||||||
|
goto chs_fail;
|
||||||
|
if (*p == ',') {
|
||||||
|
p++;
|
||||||
|
if (!strcmp(p, "none"))
|
||||||
|
translation = BIOS_ATA_TRANSLATION_NONE;
|
||||||
|
else if (!strcmp(p, "lba"))
|
||||||
|
translation = BIOS_ATA_TRANSLATION_LBA;
|
||||||
|
else if (!strcmp(p, "auto"))
|
||||||
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||||
|
else
|
||||||
|
goto chs_fail;
|
||||||
|
} else if (*p != '\0') {
|
||||||
chs_fail:
|
chs_fail:
|
||||||
cyls = 0;
|
fprintf(stderr, "qemu: invalid physical CHS format\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3230,8 +3249,10 @@ int main(int argc, char **argv)
|
||||||
hd_filename[i]);
|
hd_filename[i]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (i == 0 && cyls != 0)
|
if (i == 0 && cyls != 0) {
|
||||||
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
|
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
|
||||||
|
bdrv_set_translation_hint(bs_table[i], translation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
vl.h
5
vl.h
|
@ -383,13 +383,18 @@ void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
|
||||||
#define BDRV_TYPE_HD 0
|
#define BDRV_TYPE_HD 0
|
||||||
#define BDRV_TYPE_CDROM 1
|
#define BDRV_TYPE_CDROM 1
|
||||||
#define BDRV_TYPE_FLOPPY 2
|
#define BDRV_TYPE_FLOPPY 2
|
||||||
|
#define BIOS_ATA_TRANSLATION_AUTO 0
|
||||||
|
#define BIOS_ATA_TRANSLATION_NONE 1
|
||||||
|
#define BIOS_ATA_TRANSLATION_LBA 2
|
||||||
|
|
||||||
void bdrv_set_geometry_hint(BlockDriverState *bs,
|
void bdrv_set_geometry_hint(BlockDriverState *bs,
|
||||||
int cyls, int heads, int secs);
|
int cyls, int heads, int secs);
|
||||||
void bdrv_set_type_hint(BlockDriverState *bs, int type);
|
void bdrv_set_type_hint(BlockDriverState *bs, int type);
|
||||||
|
void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
|
||||||
void bdrv_get_geometry_hint(BlockDriverState *bs,
|
void bdrv_get_geometry_hint(BlockDriverState *bs,
|
||||||
int *pcyls, int *pheads, int *psecs);
|
int *pcyls, int *pheads, int *psecs);
|
||||||
int bdrv_get_type_hint(BlockDriverState *bs);
|
int bdrv_get_type_hint(BlockDriverState *bs);
|
||||||
|
int bdrv_get_translation_hint(BlockDriverState *bs);
|
||||||
int bdrv_is_removable(BlockDriverState *bs);
|
int bdrv_is_removable(BlockDriverState *bs);
|
||||||
int bdrv_is_read_only(BlockDriverState *bs);
|
int bdrv_is_read_only(BlockDriverState *bs);
|
||||||
int bdrv_is_inserted(BlockDriverState *bs);
|
int bdrv_is_inserted(BlockDriverState *bs);
|
||||||
|
|
Loading…
Reference in New Issue