From: Stas Sergeev <stssppnn@yahoo.com>
To: linux-msdos@vger.kernel.org
Subject: Re: Using Linux+dosemu to install Windows
Date: Fri, 26 Jul 2002 18:02:19 +0400 [thread overview]
Message-ID: <3D41566B.5030903@yahoo.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1369 bytes --]
Hello.
Patrick J. LoPresti wrote:
> By instrumenting the code a bit, I learned
> that winnt.exe is attempting to invoke the pushfd and popfd
> instructions (opcodes 0x9c and 0x9d, respectively), which
> dosemu does not support.
Good investigation but actually
you are hacking the wrong place.
These instructions are handled in
handle_vm86_fault() which is in
/usr/src/linux/arch/i386/kernel/vm86.c
The attached patch must be a good
start for fixing the problem. It is
against the latest 2.4.19-pre-ac
kernels and probably can't be applied
to 2.4.18 because -ac tree have a lot
of changes in vm86.
> All winnt.exe is really doing is trying to determine whether the
> processor is a 486 or higher. It does this by using pushfd and popfd
> to attempt to alter the next-to-highest bit of the EFLAGS register.
No, it tries to alter the AC flag which
is a bit 2 of the higher word of eflags.
But dosemu explicitly clears this flag
because due to some unknown bugs it
sometimes sets spuriously.
grep the do_vm86.c for the string "BUG:"
and comment the relevant code, then
winnt.exe will work.
> So, my question boils down to this: How can I modify the EFLAGS
> register from within vm86_GP_fault()? If someone will tell me this, I
> will submit a patch to add support for emulating the pushf/pushfd and
> popf/popfd opcodes.
Well, but this won't solve the AC
problem...
[-- Attachment #2: vm86_pref.diff --]
[-- Type: text/plain, Size: 3995 bytes --]
--- linux/arch/i386/kernel/vm86.c Sat Jun 15 19:46:46 2002
+++ linux/arch/i386/kernel/vm86.c Fri Jul 26 14:25:35 2002
@@ -502,8 +502,9 @@
void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
{
- unsigned char *csp, *ssp;
+ unsigned char *csp, *ssp, opcode;
unsigned short ip, sp;
+ int prefix66, pref_done;
#define CHECK_IF_IN_TRAP \
if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
@@ -518,63 +519,61 @@
sp = SP(regs);
ip = IP(regs);
- switch (popb(csp, ip, simulate_sigsegv)) {
-
- /* operand size override */
- case 0x66:
- switch (popb(csp, ip, simulate_sigsegv)) {
+ prefix66 = 0;
+ pref_done = 0;
+ do {
+ switch (opcode = popb(csp, ip, simulate_sigsegv)) {
+ case 0x66: /* operand prefix */ prefix66=1; break;
+ case 0x67: /* address prefix */ break;
+ case 0x2e: /* CS */ break;
+ case 0x3e: /* DS */ break;
+ case 0x26: /* ES */ break;
+ case 0x36: /* SS */ break;
+ case 0x65: /* GS */ break;
+ case 0x64: /* FS */ break;
+ case 0xf2: /* repnz */ break;
+ case 0xf3: /* rep */ break;
+ default: pref_done = 1;
+ }
- /* pushfd */
- case 0x9c:
- pushl(ssp, sp, get_vflags(regs), simulate_sigsegv);
- SP(regs) -= 4;
- IP(regs) += 2;
- VM86_FAULT_RETURN;
+ if (!pref_done)
+ IP(regs)++; /* prefix found, adjust IP */
+ else
+ break; /* no more prefixes */
+ } while (1);
- /* popfd */
- case 0x9d:
- {
- unsigned long newflags=popl(ssp, sp, simulate_sigsegv);
- SP(regs) += 4;
- IP(regs) += 2;
- CHECK_IF_IN_TRAP;
- set_vflags_long(newflags, regs);
- VM86_FAULT_RETURN;
- }
-
- /* iretd */
- case 0xcf:
- {
- unsigned long newip=popl(ssp, sp, simulate_sigsegv);
- unsigned long newcs=popl(ssp, sp, simulate_sigsegv);
- unsigned long newflags=popl(ssp, sp, simulate_sigsegv);
- SP(regs) += 12;
- IP(regs) = (unsigned short)newip;
- regs->cs = (unsigned short)newcs;
- CHECK_IF_IN_TRAP;
- set_vflags_long(newflags, regs);
- VM86_FAULT_RETURN;
- }
- /* need this to avoid a fallthrough */
- default:
- return_to_32bit(regs, VM86_UNKNOWN);
- }
+ switch (opcode) {
/* pushf */
case 0x9c:
- pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);
- SP(regs) -= 2;
+ if (prefix66) {
+ pushl(ssp, sp, get_vflags(regs), simulate_sigsegv);
+ SP(regs) -= 4;
+ } else {
+ pushw(ssp, sp, get_vflags(regs), simulate_sigsegv);
+ SP(regs) -= 2;
+ }
IP(regs)++;
VM86_FAULT_RETURN;
/* popf */
case 0x9d:
{
- unsigned short newflags=popw(ssp, sp, simulate_sigsegv);
- SP(regs) += 2;
+ unsigned long newflags;
+ if (prefix66) {
+ newflags=popl(ssp, sp, simulate_sigsegv);
+ SP(regs) += 4;
+ } else {
+ newflags = popw(ssp, sp, simulate_sigsegv);
+ SP(regs) += 2;
+ }
IP(regs)++;
CHECK_IF_IN_TRAP;
- set_vflags_short(newflags, regs);
+ if (prefix66) {
+ set_vflags_long(newflags, regs);
+ } else {
+ set_vflags_short(newflags, regs);
+ }
VM86_FAULT_RETURN;
}
@@ -593,14 +592,28 @@
/* iret */
case 0xcf:
{
- unsigned short newip=popw(ssp, sp, simulate_sigsegv);
- unsigned short newcs=popw(ssp, sp, simulate_sigsegv);
- unsigned short newflags=popw(ssp, sp, simulate_sigsegv);
- SP(regs) += 6;
+ unsigned long newip;
+ unsigned long newcs;
+ unsigned long newflags;
+ if (prefix66) {
+ newip=popl(ssp, sp, simulate_sigsegv);
+ newcs=popl(ssp, sp, simulate_sigsegv);
+ newflags=popl(ssp, sp, simulate_sigsegv);
+ SP(regs) += 12;
+ } else {
+ newip = popw(ssp, sp, simulate_sigsegv);
+ newcs = popw(ssp, sp, simulate_sigsegv);
+ newflags = popw(ssp, sp, simulate_sigsegv);
+ SP(regs) += 6;
+ }
IP(regs) = newip;
regs->cs = newcs;
CHECK_IF_IN_TRAP;
- set_vflags_short(newflags, regs);
+ if (prefix66) {
+ set_vflags_long(newflags, regs);
+ } else {
+ set_vflags_short(newflags, regs);
+ }
VM86_FAULT_RETURN;
}
next reply other threads:[~2002-07-26 14:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-07-26 14:02 Stas Sergeev [this message]
[not found] ` <mit.lcs.mail.linux-msdos/3D41566B.5030903@yahoo.com>
2002-07-26 16:06 ` Using Linux+dosemu to install Windows Patrick J. LoPresti
-- strict thread matches above, loose matches on Subject: below --
2002-07-28 7:09 Stas Sergeev
2002-07-27 21:10 Stas Sergeev
2002-07-27 22:11 ` Bart Oldeman
2002-07-26 16:47 Stas Sergeev
[not found] ` <mit.lcs.mail.linux-msdos/3D417D1E.50902@yahoo.com>
2002-07-27 15:02 ` Patrick J. LoPresti
2002-07-26 3:50 Patrick J. LoPresti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D41566B.5030903@yahoo.com \
--to=stssppnn@yahoo.com \
--cc=linux-msdos@vger.kernel.org \
--cc=stas.orel@mailcity.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.