Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
851e67a1
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
851e67a1
编写于
3月 29, 2003
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
primitive vm86 support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@57
c046a42c-6fe2-441c-8c8c-71466251a162
上级
fc2b4c48
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
117 addition
and
18 deletion
+117
-18
linux-user/main.c
linux-user/main.c
+90
-18
linux-user/qemu.h
linux-user/qemu.h
+27
-0
未找到文件。
linux-user/main.c
浏览文件 @
851e67a1
...
...
@@ -104,35 +104,99 @@ void write_dt(void *ptr, unsigned long addr, unsigned long limit,
uint64_t
gdt_table
[
6
];
//#define DEBUG_VM86
void
cpu_loop
(
struct
CPUX86State
*
env
)
{
int
err
;
uint8_t
*
pc
;
target_siginfo_t
info
;
for
(;;)
{
err
=
cpu_x86_exec
(
env
);
pc
=
env
->
seg_cache
[
R_CS
].
base
+
env
->
eip
;
switch
(
err
)
{
case
EXCP0D_GPF
:
if
(
pc
[
0
]
==
0xcd
&&
pc
[
1
]
==
0x80
)
{
/* syscall */
env
->
eip
+=
2
;
env
->
regs
[
R_EAX
]
=
do_syscall
(
env
,
env
->
regs
[
R_EAX
],
env
->
regs
[
R_EBX
],
env
->
regs
[
R_ECX
],
env
->
regs
[
R_EDX
],
env
->
regs
[
R_ESI
],
env
->
regs
[
R_EDI
],
env
->
regs
[
R_EBP
]);
if
(
env
->
eflags
&
VM_MASK
)
{
TaskState
*
ts
;
int
ret
;
#ifdef DEBUG_VM86
printf
(
"VM86 exception %04x:%08x %02x
\n
"
,
env
->
segs
[
R_CS
],
env
->
eip
,
pc
[
0
]);
#endif
/* VM86 mode */
ts
=
env
->
opaque
;
/* XXX: add all cases */
switch
(
pc
[
0
])
{
case
0xcd
:
/* int */
env
->
eip
+=
2
;
ret
=
TARGET_VM86_INTx
|
(
pc
[
1
]
<<
8
);
break
;
default:
/* real VM86 GPF exception */
ret
=
TARGET_VM86_UNKNOWN
;
break
;
}
#ifdef DEBUG_VM86
printf
(
"ret=0x%x
\n
"
,
ret
);
#endif
/* put the VM86 registers in the userspace register structure */
ts
->
target_v86
->
regs
.
eax
=
tswap32
(
env
->
regs
[
R_EAX
]);
ts
->
target_v86
->
regs
.
ebx
=
tswap32
(
env
->
regs
[
R_EBX
]);
ts
->
target_v86
->
regs
.
ecx
=
tswap32
(
env
->
regs
[
R_ECX
]);
ts
->
target_v86
->
regs
.
edx
=
tswap32
(
env
->
regs
[
R_EDX
]);
ts
->
target_v86
->
regs
.
esi
=
tswap32
(
env
->
regs
[
R_ESI
]);
ts
->
target_v86
->
regs
.
edi
=
tswap32
(
env
->
regs
[
R_EDI
]);
ts
->
target_v86
->
regs
.
ebp
=
tswap32
(
env
->
regs
[
R_EBP
]);
ts
->
target_v86
->
regs
.
esp
=
tswap32
(
env
->
regs
[
R_ESP
]);
ts
->
target_v86
->
regs
.
eip
=
tswap32
(
env
->
eip
);
ts
->
target_v86
->
regs
.
cs
=
tswap16
(
env
->
segs
[
R_CS
]);
ts
->
target_v86
->
regs
.
ss
=
tswap16
(
env
->
segs
[
R_SS
]);
ts
->
target_v86
->
regs
.
ds
=
tswap16
(
env
->
segs
[
R_DS
]);
ts
->
target_v86
->
regs
.
es
=
tswap16
(
env
->
segs
[
R_ES
]);
ts
->
target_v86
->
regs
.
fs
=
tswap16
(
env
->
segs
[
R_FS
]);
ts
->
target_v86
->
regs
.
gs
=
tswap16
(
env
->
segs
[
R_GS
]);
/* restore 32 bit registers */
env
->
regs
[
R_EBX
]
=
ts
->
vm86_saved_regs
.
ebx
;
env
->
regs
[
R_ECX
]
=
ts
->
vm86_saved_regs
.
ecx
;
env
->
regs
[
R_EDX
]
=
ts
->
vm86_saved_regs
.
edx
;
env
->
regs
[
R_ESI
]
=
ts
->
vm86_saved_regs
.
esi
;
env
->
regs
[
R_EDI
]
=
ts
->
vm86_saved_regs
.
edi
;
env
->
regs
[
R_EBP
]
=
ts
->
vm86_saved_regs
.
ebp
;
env
->
regs
[
R_ESP
]
=
ts
->
vm86_saved_regs
.
esp
;
env
->
eflags
=
ts
->
vm86_saved_regs
.
eflags
;
env
->
eip
=
ts
->
vm86_saved_regs
.
eip
;
cpu_x86_load_seg
(
env
,
R_CS
,
ts
->
vm86_saved_regs
.
cs
);
cpu_x86_load_seg
(
env
,
R_SS
,
ts
->
vm86_saved_regs
.
ss
);
cpu_x86_load_seg
(
env
,
R_DS
,
ts
->
vm86_saved_regs
.
ds
);
cpu_x86_load_seg
(
env
,
R_ES
,
ts
->
vm86_saved_regs
.
es
);
cpu_x86_load_seg
(
env
,
R_FS
,
ts
->
vm86_saved_regs
.
fs
);
cpu_x86_load_seg
(
env
,
R_GS
,
ts
->
vm86_saved_regs
.
gs
);
env
->
regs
[
R_EAX
]
=
ret
;
}
else
{
/* XXX: more precise info */
info
.
si_signo
=
SIGSEGV
;
info
.
si_errno
=
0
;
info
.
si_code
=
0
;
info
.
_sifields
.
_sigfault
.
_addr
=
0
;
queue_signal
(
info
.
si_signo
,
&
info
);
if
(
pc
[
0
]
==
0xcd
&&
pc
[
1
]
==
0x80
)
{
/* syscall */
env
->
eip
+=
2
;
env
->
regs
[
R_EAX
]
=
do_syscall
(
env
,
env
->
regs
[
R_EAX
],
env
->
regs
[
R_EBX
],
env
->
regs
[
R_ECX
],
env
->
regs
[
R_EDX
],
env
->
regs
[
R_ESI
],
env
->
regs
[
R_EDI
],
env
->
regs
[
R_EBP
]);
}
else
{
/* XXX: more precise info */
info
.
si_signo
=
SIGSEGV
;
info
.
si_errno
=
0
;
info
.
si_code
=
0
;
info
.
_sifields
.
_sigfault
.
_addr
=
0
;
queue_signal
(
info
.
si_signo
,
&
info
);
}
}
break
;
case
EXCP00_DIVZ
:
...
...
@@ -188,12 +252,15 @@ void usage(void)
/* XXX: currently only used for async signals (see signal.c) */
CPUX86State
*
global_env
;
/* used to free thread contexts */
TaskState
*
first_task_state
;
int
main
(
int
argc
,
char
**
argv
)
{
const
char
*
filename
;
struct
target_pt_regs
regs1
,
*
regs
=
&
regs1
;
struct
image_info
info1
,
*
info
=
&
info1
;
TaskState
ts1
,
*
ts
=
&
ts1
;
CPUX86State
*
env
;
int
optind
;
const
char
*
r
;
...
...
@@ -272,6 +339,11 @@ int main(int argc, char **argv)
env
=
cpu_x86_init
();
global_env
=
env
;
/* build Task State */
memset
(
ts
,
0
,
sizeof
(
TaskState
));
env
->
opaque
=
ts
;
ts
->
used
=
1
;
/* linux register setup */
env
->
regs
[
R_EAX
]
=
regs
->
eax
;
env
->
regs
[
R_EBX
]
=
regs
->
ebx
;
...
...
linux-user/qemu.h
浏览文件 @
851e67a1
...
...
@@ -33,6 +33,33 @@ struct image_info {
int
personality
;
};
/* Information about the current linux thread */
struct
vm86_saved_state
{
uint32_t
eax
;
/* return code */
uint32_t
ebx
;
uint32_t
ecx
;
uint32_t
edx
;
uint32_t
esi
;
uint32_t
edi
;
uint32_t
ebp
;
uint32_t
esp
;
uint32_t
eflags
;
uint32_t
eip
;
uint16_t
cs
,
ss
,
ds
,
es
,
fs
,
gs
;
};
/* NOTE: we force a big alignment so that the stack stored after is
aligned too */
typedef
struct
TaskState
{
struct
TaskState
*
next
;
struct
target_vm86plus_struct
*
target_v86
;
struct
vm86_saved_state
vm86_saved_regs
;
int
used
;
/* non zero if used */
uint8_t
stack
[
0
];
}
__attribute__
((
aligned
(
16
)))
TaskState
;
extern
TaskState
*
first_task_state
;
int
elf_exec
(
const
char
*
interp_prefix
,
const
char
*
filename
,
char
**
argv
,
char
**
envp
,
struct
target_pt_regs
*
regs
,
struct
image_info
*
infop
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录