Revisión | 285dc330bd28aa0e097106875bb184e2707bbed5 (tree) |
---|---|
Tiempo | 2003-10-28 08:58:04 |
Autor | bellard <bellard@c046...> |
Commiter | bellard |
update
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@417 c046a42c-6fe2-441c-8c8c-71466251a162
@@ -1,4 +1,4 @@ | ||
1 | -version 0.4.4: | |
1 | +version 0.5.0: | |
2 | 2 | |
3 | 3 | - full hardware level VGA emulation |
4 | 4 | - graphical display with SDL |
@@ -16,8 +16,9 @@ version 0.4.4: | ||
16 | 16 | - preliminary SPARC target support (Thomas M. Ogrisegg) |
17 | 17 | - tun-fd option (Rusty Russell) |
18 | 18 | - automatic IDE geometry detection |
19 | - - renamed 'vl' to qemu and user qemu to qemu-{cpu}. | |
19 | + - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}. | |
20 | 20 | - added man page |
21 | + - added full soft mmy mode to launch unpatched OSes. | |
21 | 22 | |
22 | 23 | version 0.4.3: |
23 | 24 |
@@ -6,35 +6,17 @@ INSTALLATION | ||
6 | 6 | |
7 | 7 | Type |
8 | 8 | |
9 | - ./configure --interp-prefix=/usr/local/qemu-i386 | |
9 | + ./configure | |
10 | 10 | make |
11 | 11 | |
12 | -to build qemu and libqemu.a. | |
12 | +to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various | |
13 | +supported target CPUs). | |
13 | 14 | |
14 | 15 | Type |
15 | 16 | |
16 | 17 | make install |
17 | 18 | |
18 | -to install QEMU in /usr/local/bin | |
19 | - | |
20 | -* On x86 you should be able to launch any program by using the | |
21 | -libraries installed on your PC. For example: | |
22 | - | |
23 | - ./qemu -L / /bin/ls | |
24 | - | |
25 | -* On non x86 CPUs, you need first to download at least an x86 glibc | |
26 | -(qemu-XXX-i386-glibc21.tar.gz on the qemu web page). Ensure that | |
27 | -LD_LIBRARY_PATH is not set: | |
28 | - | |
29 | - unset LD_LIBRARY_PATH | |
30 | - | |
31 | -Then you can launch the precompiled 'ls' x86 executable: | |
32 | - | |
33 | - ./qemu /usr/local/qemu-i386/bin/ls-i386 | |
34 | - | |
35 | -You can look at /usr/local/qemu-i386/bin/qemu-conf.sh so that QEMU is | |
36 | -automatically launched by the Linux kernel when you try to launch x86 | |
37 | -executables. | |
19 | +to install QEMU in /usr/local | |
38 | 20 | |
39 | 21 | Tested tool versions |
40 | 22 | -------------------- |
@@ -6,11 +6,11 @@ x86 binary distribution: | ||
6 | 6 | |
7 | 7 | * wine-20020411 tarball |
8 | 8 | |
9 | - ./configure --prefix=/usr/local/qemu-i386/wine | |
9 | + ./configure --prefix=/usr/local/wine-i386 | |
10 | 10 | |
11 | 11 | All exe and libs were stripped. Some compile time tools and the |
12 | 12 | includes were deleted. |
13 | 13 | |
14 | 14 | * ldconfig was launched to build the library links: |
15 | 15 | |
16 | - ./qemu /usr/local/qemu-i386/bin/ldconfig-i386 -C /usr/local/qemu-i386/etc/ld.so.cache | |
16 | + qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C /usr/gnemul/qemu-i386/etc/ld.so.cache |
@@ -1,17 +1,20 @@ | ||
1 | +- tests for each target CPU | |
2 | +- ppc qemu test | |
1 | 3 | - optimize FPU operations (evaluate x87 stack pointer statically) and |
2 | 4 | fix cr0.TS emulation |
5 | +- fix some 16 bit sp push/pop overflow | |
6 | +- sysenter/sysexit emulation | |
7 | +- finish segment ops (call far, ret far, load_seg suppressed) | |
3 | 8 | - fix CCOP optimisation |
4 | 9 | - fix all remaining thread lock issues (must put TBs in a specific invalid |
5 | 10 | state, find a solution for tb_flush()). |
6 | 11 | - cpu loop optimisation (optimise ret case as the cpu state does not change) |
7 | 12 | - fix arm fpu rounding (at least for float->integer conversions) |
8 | -- add IPC syscalls | |
9 | 13 | |
10 | 14 | lower priority: |
11 | 15 | -------------- |
12 | -- sysenter/sysexit emulation | |
16 | +- add IPC syscalls | |
13 | 17 | - SMP support |
14 | -- finish segment ops (call far, ret far, load_seg suppressed) | |
15 | 18 | - use -msoft-float on ARM |
16 | 19 | - use kernel traps for unaligned accesses on ARM ? |
17 | 20 | - handle rare page fault cases (in particular if page fault in heplers or |
@@ -1 +1 @@ | ||
1 | -0.4.4 | |
\ No newline at end of file | ||
1 | +0.5.0 | |
\ No newline at end of file |
@@ -72,7 +72,7 @@ QEMU user mode emulation features: | ||
72 | 72 | |
73 | 73 | QEMU full system emulation features: |
74 | 74 | @itemize |
75 | -@item Using mmap() system calls to simulate the MMU | |
75 | +@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU. | |
76 | 76 | @end itemize |
77 | 77 | |
78 | 78 | @section x86 emulation |
@@ -110,14 +110,7 @@ memory access. | ||
110 | 110 | 10 byte @code{long double}s of x86 for floating point emulation to get |
111 | 111 | maximum performances. |
112 | 112 | |
113 | -@item Full system emulation only works if no data are mapped above the virtual address | |
114 | -0xc0000000 (yet). | |
115 | - | |
116 | -@item Some priviledged instructions or behaviors are missing. Only the ones | |
117 | -needed for proper Linux kernel operation are emulated. | |
118 | - | |
119 | -@item No memory separation between the kernel and the user processes is done. | |
120 | -It will be implemented very soon. | |
113 | +@item Some priviledged instructions or behaviors are missing, especially for segment protection testing (yet). | |
121 | 114 | |
122 | 115 | @end itemize |
123 | 116 |
@@ -177,9 +170,9 @@ unset LD_LIBRARY_PATH | ||
177 | 170 | Then you can launch the precompiled @file{ls} x86 executable: |
178 | 171 | |
179 | 172 | @example |
180 | -qemu-i386 /usr/local/qemu-i386/bin/ls-i386 | |
173 | +qemu-i386 tests/i386/ls | |
181 | 174 | @end example |
182 | -You can look at @file{/usr/local/qemu-i386/bin/qemu-conf.sh} so that | |
175 | +You can look at @file{qemu-binfmt-conf.sh} so that | |
183 | 176 | QEMU is automatically launched by the Linux kernel when you try to |
184 | 177 | launch x86 executables. It requires the @code{binfmt_misc} module in the |
185 | 178 | Linux kernel. |
@@ -258,16 +251,15 @@ available: | ||
258 | 251 | @enumerate |
259 | 252 | |
260 | 253 | @item |
261 | -@code{qemu} uses the host Memory Management Unit (MMU) to simulate | |
254 | +@code{qemu-fast} uses the host Memory Management Unit (MMU) to simulate | |
262 | 255 | the x86 MMU. It is @emph{fast} but has limitations because the whole 4 GB |
263 | 256 | address space cannot be used and some memory mapped peripherials |
264 | 257 | cannot be emulated accurately yet. Therefore, a specific Linux kernel |
265 | 258 | must be used (@xref{linux_compile}). |
266 | 259 | |
267 | 260 | @item |
268 | -@code{qemu-softmmu} uses a software MMU. It is about @emph{two times | |
269 | -slower} but gives a more accurate emulation. (XXX: Linux cannot be ran | |
270 | -unpatched yet). | |
261 | +@code{qemu} uses a software MMU. It is about @emph{two times | |
262 | +slower} but gives a more accurate emulation. | |
271 | 263 | |
272 | 264 | @end enumerate |
273 | 265 |
@@ -296,10 +288,10 @@ CMOS memory | ||
296 | 288 | |
297 | 289 | @section Quick Start |
298 | 290 | |
299 | -Download the linux image (@file{linux.img}) and type: | |
291 | +Download and uncompress the linux image (@file{linux.img}) and type: | |
300 | 292 | |
301 | 293 | @example |
302 | -qemu-softmmu linux.img | |
294 | +qemu linux.img | |
303 | 295 | @end example |
304 | 296 | |
305 | 297 | Linux should boot and give you a prompt. |
@@ -627,8 +619,10 @@ the real one. To know it, use the @code{ls -ls} command. | ||
627 | 619 | @node linux_compile |
628 | 620 | @section Linux Kernel Compilation |
629 | 621 | |
630 | -You should be able to use any kernel with QEMU provided you make the | |
631 | -following changes (only 2.4.x and 2.5.x were tested): | |
622 | +You can use any linux kernel with QEMU. However, if you want to use | |
623 | +@code{qemu-fast} to get maximum performances, you should make the | |
624 | +following changes to the Linux kernel (only 2.4.x and 2.5.x were | |
625 | +tested): | |
632 | 626 | |
633 | 627 | @enumerate |
634 | 628 | @item |
@@ -723,8 +717,6 @@ Then you can use gdb normally. For example, type 'c' to launch the kernel: | ||
723 | 717 | (gdb) c |
724 | 718 | @end example |
725 | 719 | |
726 | -WARNING: breakpoints and single stepping are not yet supported. | |
727 | - | |
728 | 720 | Here are some useful tips in order to use gdb on system code: |
729 | 721 | |
730 | 722 | @enumerate |
@@ -1019,16 +1011,6 @@ The new Plex86 project. | ||
1019 | 1011 | In the directory @file{tests/}, various interesting testing programs |
1020 | 1012 | are available. There are used for regression testing. |
1021 | 1013 | |
1022 | -@section @file{hello-i386} | |
1023 | - | |
1024 | -Very simple statically linked x86 program, just to test QEMU during a | |
1025 | -port to a new host CPU. | |
1026 | - | |
1027 | -@section @file{hello-arm} | |
1028 | - | |
1029 | -Very simple statically linked ARM program, just to test QEMU during a | |
1030 | -port to a new host CPU. | |
1031 | - | |
1032 | 1014 | @section @file{test-i386} |
1033 | 1015 | |
1034 | 1016 | This program executes most of the 16 bit and 32 bit x86 instructions and |
@@ -1044,6 +1026,22 @@ The Linux system call @code{vm86()} is used to test vm86 emulation. | ||
1044 | 1026 | Various exceptions are raised to test most of the x86 user space |
1045 | 1027 | exception reporting. |
1046 | 1028 | |
1029 | +@section @file{linux-test} | |
1030 | + | |
1031 | +This program tests various Linux system calls. It is used to verify | |
1032 | +that the system call parameters are correctly converted between target | |
1033 | +and host CPUs. | |
1034 | + | |
1035 | +@section @file{hello-i386} | |
1036 | + | |
1037 | +Very simple statically linked x86 program, just to test QEMU during a | |
1038 | +port to a new host CPU. | |
1039 | + | |
1040 | +@section @file{hello-arm} | |
1041 | + | |
1042 | +Very simple statically linked ARM program, just to test QEMU during a | |
1043 | +port to a new host CPU. | |
1044 | + | |
1047 | 1045 | @section @file{sha1} |
1048 | 1046 | |
1049 | 1047 | It is a simple benchmark. Care must be taken to interpret the results |
@@ -71,7 +71,7 @@ int __chk_error(const char *filename, int line, int ret) | ||
71 | 71 | |
72 | 72 | #define FILE_BUF_SIZE 300 |
73 | 73 | |
74 | -void file_test(void) | |
74 | +void test_file(void) | |
75 | 75 | { |
76 | 76 | int fd, i, len, ret; |
77 | 77 | uint8_t buf[FILE_BUF_SIZE]; |
@@ -499,7 +499,7 @@ void test_signal(void) | ||
499 | 499 | |
500 | 500 | int main(int argc, char **argv) |
501 | 501 | { |
502 | - file_test(); | |
502 | + test_file(); | |
503 | 503 | test_fork(); |
504 | 504 | test_time(); |
505 | 505 | test_socket(); |
@@ -507,4 +507,3 @@ int main(int argc, char **argv) | ||
507 | 507 | test_signal(); |
508 | 508 | return 0; |
509 | 509 | } |
510 | - |
@@ -1,62 +0,0 @@ | ||
1 | -#include <stdlib.h> | |
2 | -#include <stdio.h> | |
3 | -#include <string.h> | |
4 | -#include <signal.h> | |
5 | -#include <unistd.h> | |
6 | -#include <inttypes.h> | |
7 | -#include <pthread.h> | |
8 | -#include <sys/wait.h> | |
9 | -#include <sched.h> | |
10 | - | |
11 | -int thread1_func(void *arg) | |
12 | -{ | |
13 | - int i; | |
14 | - char buf[512]; | |
15 | - | |
16 | - for(i=0;i<10;i++) { | |
17 | - snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); | |
18 | - write(1, buf, strlen(buf)); | |
19 | - usleep(100 * 1000); | |
20 | - } | |
21 | - return 0; | |
22 | -} | |
23 | - | |
24 | -int thread2_func(void *arg) | |
25 | -{ | |
26 | - int i; | |
27 | - char buf[512]; | |
28 | - for(i=0;i<20;i++) { | |
29 | - snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); | |
30 | - write(1, buf, strlen(buf)); | |
31 | - usleep(120 * 1000); | |
32 | - } | |
33 | - return 0; | |
34 | -} | |
35 | - | |
36 | -#define STACK_SIZE 16384 | |
37 | - | |
38 | -void test_clone(void) | |
39 | -{ | |
40 | - uint8_t *stack1, *stack2; | |
41 | - int pid1, pid2, status1, status2; | |
42 | - | |
43 | - stack1 = malloc(STACK_SIZE); | |
44 | - pid1 = clone(thread1_func, stack1 + STACK_SIZE, | |
45 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"); | |
46 | - | |
47 | - stack2 = malloc(STACK_SIZE); | |
48 | - pid2 = clone(thread2_func, stack2 + STACK_SIZE, | |
49 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"); | |
50 | - | |
51 | - while (waitpid(pid1, &status1, 0) != pid1); | |
52 | - while (waitpid(pid2, &status2, 0) != pid2); | |
53 | - printf("status1=0x%x\n", status1); | |
54 | - printf("status2=0x%x\n", status2); | |
55 | - printf("End of clone test.\n"); | |
56 | -} | |
57 | - | |
58 | -int main(int argc, char **argv) | |
59 | -{ | |
60 | - test_clone(); | |
61 | - return 0; | |
62 | -} |
@@ -1,194 +0,0 @@ | ||
1 | -#define _GNU_SOURCE | |
2 | -#include <stdlib.h> | |
3 | -#include <stdio.h> | |
4 | -#include <string.h> | |
5 | -#include <signal.h> | |
6 | -#include <unistd.h> | |
7 | -#include <setjmp.h> | |
8 | -#include <sys/ucontext.h> | |
9 | - | |
10 | -jmp_buf jmp_env; | |
11 | - | |
12 | -void alarm_handler(int sig) | |
13 | -{ | |
14 | - printf("alarm signal=%d\n", sig); | |
15 | - alarm(1); | |
16 | -} | |
17 | - | |
18 | -#ifndef REG_EAX | |
19 | -#define REG_EAX EAX | |
20 | -#define REG_EBX EBX | |
21 | -#define REG_ECX ECX | |
22 | -#define REG_EDX EDX | |
23 | -#define REG_ESI ESI | |
24 | -#define REG_EDI EDI | |
25 | -#define REG_EBP EBP | |
26 | -#define REG_ESP ESP | |
27 | -#define REG_EIP EIP | |
28 | -#define REG_EFL EFL | |
29 | -#define REG_TRAPNO TRAPNO | |
30 | -#define REG_ERR ERR | |
31 | -#endif | |
32 | - | |
33 | -void dump_regs(struct ucontext *uc) | |
34 | -{ | |
35 | - printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" | |
36 | - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" | |
37 | - "EFL=%08x EIP=%08x trapno=%02x err=%08x\n", | |
38 | - uc->uc_mcontext.gregs[REG_EAX], | |
39 | - uc->uc_mcontext.gregs[REG_EBX], | |
40 | - uc->uc_mcontext.gregs[REG_ECX], | |
41 | - uc->uc_mcontext.gregs[REG_EDX], | |
42 | - uc->uc_mcontext.gregs[REG_ESI], | |
43 | - uc->uc_mcontext.gregs[REG_EDI], | |
44 | - uc->uc_mcontext.gregs[REG_EBP], | |
45 | - uc->uc_mcontext.gregs[REG_ESP], | |
46 | - uc->uc_mcontext.gregs[REG_EFL], | |
47 | - uc->uc_mcontext.gregs[REG_EIP], | |
48 | - uc->uc_mcontext.gregs[REG_TRAPNO], | |
49 | - uc->uc_mcontext.gregs[REG_ERR]); | |
50 | -} | |
51 | - | |
52 | -void sig_handler(int sig, siginfo_t *info, void *puc) | |
53 | -{ | |
54 | - struct ucontext *uc = puc; | |
55 | - | |
56 | - printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n", | |
57 | - strsignal(info->si_signo), | |
58 | - info->si_signo, info->si_errno, info->si_code, | |
59 | - (unsigned long)info->si_addr); | |
60 | - dump_regs(uc); | |
61 | - longjmp(jmp_env, 1); | |
62 | -} | |
63 | - | |
64 | -int v1; | |
65 | -int tab[2]; | |
66 | - | |
67 | -int main(int argc, char **argv) | |
68 | -{ | |
69 | - struct sigaction act; | |
70 | - volatile int val; | |
71 | - | |
72 | - act.sa_sigaction = sig_handler; | |
73 | - sigemptyset(&act.sa_mask); | |
74 | - act.sa_flags = SA_SIGINFO; | |
75 | - sigaction(SIGFPE, &act, NULL); | |
76 | - sigaction(SIGILL, &act, NULL); | |
77 | - sigaction(SIGSEGV, &act, NULL); | |
78 | - sigaction(SIGTRAP, &act, NULL); | |
79 | - | |
80 | - /* test division by zero reporting */ | |
81 | - if (setjmp(jmp_env) == 0) { | |
82 | - /* now divide by zero */ | |
83 | - v1 = 0; | |
84 | - v1 = 2 / v1; | |
85 | - } | |
86 | - | |
87 | - /* test illegal instruction reporting */ | |
88 | - if (setjmp(jmp_env) == 0) { | |
89 | - /* now execute an invalid instruction */ | |
90 | - asm volatile("ud2"); | |
91 | - } | |
92 | - | |
93 | - /* test SEGV reporting */ | |
94 | - if (setjmp(jmp_env) == 0) { | |
95 | - /* now store in an invalid address */ | |
96 | - *(char *)0x1234 = 1; | |
97 | - } | |
98 | - | |
99 | - /* test SEGV reporting */ | |
100 | - if (setjmp(jmp_env) == 0) { | |
101 | - /* read from an invalid address */ | |
102 | - v1 = *(char *)0x1234; | |
103 | - } | |
104 | - | |
105 | - printf("segment GPF exception:\n"); | |
106 | - if (setjmp(jmp_env) == 0) { | |
107 | - /* load an invalid segment */ | |
108 | - asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); | |
109 | - } | |
110 | - | |
111 | - printf("INT exception:\n"); | |
112 | - if (setjmp(jmp_env) == 0) { | |
113 | - asm volatile ("int $0xfd"); | |
114 | - } | |
115 | - | |
116 | - printf("INT3 exception:\n"); | |
117 | - if (setjmp(jmp_env) == 0) { | |
118 | - asm volatile ("int3"); | |
119 | - } | |
120 | - | |
121 | - printf("CLI exception:\n"); | |
122 | - if (setjmp(jmp_env) == 0) { | |
123 | - asm volatile ("cli"); | |
124 | - } | |
125 | - | |
126 | - printf("STI exception:\n"); | |
127 | - if (setjmp(jmp_env) == 0) { | |
128 | - asm volatile ("cli"); | |
129 | - } | |
130 | - | |
131 | - printf("INTO exception:\n"); | |
132 | - if (setjmp(jmp_env) == 0) { | |
133 | - /* overflow exception */ | |
134 | - asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); | |
135 | - } | |
136 | - | |
137 | - printf("BOUND exception:\n"); | |
138 | - if (setjmp(jmp_env) == 0) { | |
139 | - /* bound exception */ | |
140 | - tab[0] = 1; | |
141 | - tab[1] = 10; | |
142 | - asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); | |
143 | - } | |
144 | - | |
145 | - printf("OUTB exception:\n"); | |
146 | - if (setjmp(jmp_env) == 0) { | |
147 | - asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); | |
148 | - } | |
149 | - | |
150 | - printf("INB exception:\n"); | |
151 | - if (setjmp(jmp_env) == 0) { | |
152 | - asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); | |
153 | - } | |
154 | - | |
155 | - printf("REP OUTSB exception:\n"); | |
156 | - if (setjmp(jmp_env) == 0) { | |
157 | - asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); | |
158 | - } | |
159 | - | |
160 | - printf("REP INSB exception:\n"); | |
161 | - if (setjmp(jmp_env) == 0) { | |
162 | - asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); | |
163 | - } | |
164 | - | |
165 | - printf("HLT exception:\n"); | |
166 | - if (setjmp(jmp_env) == 0) { | |
167 | - asm volatile ("hlt"); | |
168 | - } | |
169 | - | |
170 | - printf("single step exception:\n"); | |
171 | - val = 0; | |
172 | - if (setjmp(jmp_env) == 0) { | |
173 | - asm volatile ("pushf\n" | |
174 | - "orl $0x00100, (%%esp)\n" | |
175 | - "popf\n" | |
176 | - "movl $0xabcd, %0\n" : "=m" (val) : : "cc", "memory"); | |
177 | - } | |
178 | - printf("val=0x%x\n", val); | |
179 | - | |
180 | -#if 1 | |
181 | - { | |
182 | - int i; | |
183 | - act.sa_handler = alarm_handler; | |
184 | - sigemptyset(&act.sa_mask); | |
185 | - act.sa_flags = 0; | |
186 | - sigaction(SIGALRM, &act, NULL); | |
187 | - alarm(1); | |
188 | - for(i = 0;i < 2; i++) { | |
189 | - sleep(1); | |
190 | - } | |
191 | - } | |
192 | -#endif | |
193 | - return 0; | |
194 | -} |