提交 46d4767d 编写于 作者: B bellard

better BIOS ATA translation support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1153 c046a42c-6fe2-441c-8c8c-71466251a162
上级 e35c55fe
...@@ -348,6 +348,11 @@ void bdrv_set_type_hint(BlockDriverState *bs, int type) ...@@ -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) ...@@ -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 { ...@@ -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;
......
...@@ -1826,11 +1826,11 @@ struct partition { ...@@ -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) ...@@ -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, ...@@ -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;
......
...@@ -217,19 +217,23 @@ static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table ...@@ -217,19 +217,23 @@ 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]);
bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors); if (translation == BIOS_ATA_TRANSLATION_AUTO) {
if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
/* No translation. */ if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
translation = 0; /* No translation. */
translation = 0;
} else {
/* LBA translation. */
translation = 1;
}
} else { } else {
/* LBA translation. */ translation--;
translation = 1;
} }
val |= translation << (i * 2); val |= translation << (i * 2);
} }
......
...@@ -343,6 +343,12 @@ Change gdb connection port. ...@@ -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
......
...@@ -2537,7 +2537,8 @@ void help(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
}
} }
} }
......
...@@ -383,13 +383,18 @@ void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size); ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册