/[gxemul]/upstream/0.3.8/doc/technical.html
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.8/doc/technical.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/html
File size: 17906 byte(s)
0.3.8
1 <html><head><title>Gavare's eXperimental Emulator:&nbsp;&nbsp;&nbsp;Technical details</title>
2 <meta name="robots" content="noarchive,nofollow,noindex"></head>
3 <body bgcolor="#f8f8f8" text="#000000" link="#4040f0" vlink="#404040" alink="#ff0000">
4 <table border=0 width=100% bgcolor="#d0d0d0"><tr>
5 <td width=100% align=center valign=center><table border=0 width=100%><tr>
6 <td align="left" valign=center bgcolor="#d0efff"><font color="#6060e0" size="6">
7 <b>Gavare's eXperimental Emulator:</b></font><br>
8 <font color="#000000" size="6"><b>Technical details</b>
9 </font></td></tr></table></td></tr></table><p>
10
11 <!--
12
13 $Id: technical.html,v 1.72 2006/02/18 15:18:15 debug Exp $
14
15 Copyright (C) 2004-2006 Anders Gavare. All rights reserved.
16
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions are met:
19
20 1. Redistributions of source code must retain the above copyright
21 notice, this list of conditions and the following disclaimer.
22 2. Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
25 3. The name of the author may not be used to endorse or promote products
26 derived from this software without specific prior written permission.
27
28 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 SUCH DAMAGE.
39
40 -->
41
42
43
44 <a href="./">Back to the index</a>
45
46 <p><br>
47 <h2>Technical details</h2>
48
49 <p>This page describes some of the internals of GXemul.
50
51 <p>
52 <ul>
53 <li><a href="#speed">Speed and emulation modes</a>
54 <li><a href="#net">Networking</a>
55 <li><a href="#devices">Emulation of hardware devices</a>
56 </ul>
57
58
59
60
61
62
63 <p><br>
64 <a name="speed"></a>
65 <h3>Speed and emulation modes</h3>
66
67 So, how fast is GXemul? There is no short answer to this. There is
68 especially no answer to the question <b>What is the slowdown factor?</b>,
69 because the host architecture and emulated architecture can usually not be
70 compared just like that.
71
72 <p>Performance depends on several factors, including (but not limited to)
73 host architecture, host clock speed, which compiler and compiler flags
74 were used to build the emulator, what the workload is, and so on. For
75 example, if an emulated operating system tries to read a block from disk,
76 from its point of view the read was instantaneous (no waiting). So 1 MIPS
77 in an emulated OS might have taken more than one million instructions on a
78 real machine.
79
80 <p>Also, if the emulator says it has executed 1 million instructions, and
81 the CPU family in question was capable of scalar execution (i.e. one cycle
82 per instruction), it might still have taken more than 1 million cycles on
83 a real machine because of cache misses and similar micro-architectural
84 penalties that are not simulated by GXemul.
85
86 <p>Because of these issues, it is in my opinion best to measure
87 performance as the actual (real-world) time it takes to perform a task
88 with the emulator. Typical examples would be "How long does it take to
89 install NetBSD?", or "How long does it take to compile XYZ inside NetBSD
90 in the emulator?".
91
92 <p>So, how fast is it? :-)&nbsp;&nbsp;&nbsp;Answer: it varies.
93
94 <p>The emulation technique used varies depending on which processor type
95 is being emulated. (One of my main goals with GXemul is to experiment with
96 different kinds of emulation, so these might change in the future.)
97
98 <ul>
99 <li><b>MIPS:</b><br>
100 There are two emulation modes. The most important one is an
101 implementation of a <i>dynamic binary translator</i>.
102 (Compared to real binary translators, though, GXemul's bintrans
103 subsystem is very simple and does not perform very well.)
104 This mode can be used on Alpha and i386 host. The other emulation
105 mode is simple interpretation, where an instruction is read from
106 emulated memory, and interpreted one-at-a-time. (Slow, but it
107 works. It can be forcefully used by using the <tt>-B</tt> command
108 line option.)
109 <p>
110 <li><b>All other modes:</b><br>
111 These use a kind of dynamic translation system. This system does
112 not recompile anything into native code, it only uses tables of
113 pointers to functions written in (sometimes machine-generated) C
114 code. Speed is lower than what can be achieved using real binary
115 translation into native code, but higher than when traditional
116 interpretation is used. With some tricks, it will hopefully still
117 give reasonable speed. The ARM and PowerPC
118 emulation modes use this kind of translation.
119 </ul>
120
121
122
123
124
125
126 <p><br>
127 <a name="net"></a>
128 <h3>Networking</h3>
129
130 <font color="#ff0000">NOTE/TODO: This section is very old and a bit
131 out of date.</font>
132
133 <p>Running an entire operating system under emulation is very interesting
134 in itself, but for several reasons, running a modern OS without access to
135 TCP/IP networking is a bit akward. Hence, I feel the need to implement
136 TCP/IP (networking) support in the emulator.
137
138 <p>
139 As far as I have understood it, there seems to be two different ways to go:
140
141 <ol>
142 <li>Forward ethernet packets from the emulated ethernet controller to
143 the host machine's ethernet controller, and capture incoming
144 packets on the host's controller, giving them back to the
145 emulated OS. Characteristics are:
146 <ul>
147 <li>Requires <i>direct</i> access to the host's NIC, which
148 means on most platforms that the emulator cannot be
149 run as a normal user!
150 <li>Reduced portability, as not every host operating system
151 uses the same programming interface for dealing with
152 hardware ethernet controllers directly.
153 <li>When run on a switched network, it might be problematic to
154 connect from the emulated OS to the OS running on the
155 host, as packets sent out on the host's NIC are not
156 received by itself. (?)
157 <li>All specific networking protocols will be handled by the
158 physical network.
159 </ul>
160 <p>
161 or
162 <p>
163 <li>Whenever the emulated ethernet controller wishes to send a packet,
164 the emulator looks at the packet and creates a response. Packets
165 that can have an immediate response never go outside the emulator,
166 other packet types have to be converted into suitable other
167 connection types (UDP, TCP, etc). Characteristics:
168 <ul>
169 <li>Each packet type sent out on the emulated NIC must be handled.
170 This means that I have to do a lot of coding.
171 (I like this, because it gives me an opportunity to
172 learn about networking protocols.)
173 <li>By not relying on access to the host's NIC directly,
174 portability is maintained. (It would be sad if the networking
175 portion of a portable emulator isn't as portable as the
176 rest of the emulator.)
177 <li>The emulator can be run as a normal user process, does
178 not require root privilegies.
179 <li>Connecting from the emulated OS to the host's OS should
180 not be problematic.
181 <li>The emulated OS will experience the network just as a single
182 machine behind a NAT gateway/firewall would. The emulated
183 OS is thus automatically protected from the outside world.
184 </ul>
185 </ol>
186
187 <p>
188 Some emulators/simulators use the first approach, while others use the
189 second. I think that SIMH and QEMU are examples of emulators using the
190 first and second approach, respectively.
191
192 <p>
193 Since I have choosen the second kind of implementation, I have to write
194 support explicitly for any kind of network protocol that should be
195 supported. As of 2004-07-09, the following has been implemented and seems
196 to work under at least NetBSD/pmax and OpenBSD/pmax under DECstation 5000/200
197 emulation (-E dec -e 3max):
198
199 <p>
200 <ul>
201 <li>ARP requests sent out from the emulated NIC are interpreted,
202 and converted to ARP responses. (This is used by the emulated OS
203 to find out the MAC address of the gateway.)
204 <li>ICMP echo requests (that is the kind of packet produced by the
205 <b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo
206 replies, <i>regardless of the IP address</i>. This means that
207 running ping from within the emulated OS will <i>always</i>
208 receive a response. The ping packets never leave the emulated
209 environment.
210 <li>UDP packets are interpreted and passed along to the outside world.
211 If the emulator receives an UDP packet from the outside world, it
212 is converted into an UDP packet for the emulated OS. (This is not
213 implemented very well yet, but seems to be enough for nameserver
214 lookups, tftp file transfers, and NFS mounts using UDP.)
215 <li>TCP packets are interpreted one at a time, similar to how UDP
216 packets are handled (but more state is kept for each connection).
217 <font color="#ff0000">NOTE: Much of the TCP handling code is very
218 ugly and hardcoded.</font>
219 <!--
220 <li>RARP is not implemented yet. (I haven't needed it so far.)
221 -->
222 </ul>
223
224 <p>
225 The gateway machine, which is the only "other" machine that the emulated
226 OS sees on its emulated network, works as a NAT-style firewall/gateway. It
227 usually has a fixed IPv4 address of <tt>10.0.0.254</tt>. An OS running in
228 the emulator would usually have an address of the form <tt>10.x.x.x</tt>;
229 a typical choice would be <tt>10.0.0.1</tt>.
230
231 <p>
232 Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following
233 commands should configure the emulated NIC:
234 <pre>
235 # <b>ifconfig le0 10.0.0.1</b>
236 # <b>route add default 10.0.0.254</b>
237 add net default: gateway 10.0.0.254
238 </pre>
239
240 <p>
241 If you want nameserver lookups to work, you need a valid /etc/resolv.conf
242 as well:
243 <pre>
244 # <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b>
245 </pre>
246 (But replace <tt>129.16.1.3</tt> with the actual real-world IP address of
247 your nearest nameserver.)
248
249 <p>
250 Now, host lookups should work:
251 <pre>
252 # <b>host -a www.netbsd.org</b>
253 Trying null domain
254 rcode = 0 (Success), ancount=2
255 The following answer is not authoritative:
256 The following answer is not verified as authentic by the server:
257 www.netbsd.org 86400 IN AAAA 2001:4f8:4:7:290:27ff:feab:19a7
258 www.netbsd.org 86400 IN A 204.152.184.116
259 For authoritative answers, see:
260 netbsd.org 83627 IN NS uucp-gw-2.pa.dec.com
261 netbsd.org 83627 IN NS ns.netbsd.org
262 netbsd.org 83627 IN NS adns1.berkeley.edu
263 netbsd.org 83627 IN NS adns2.berkeley.edu
264 netbsd.org 83627 IN NS uucp-gw-1.pa.dec.com
265 Additional information:
266 ns.netbsd.org 83627 IN A 204.152.184.164
267 uucp-gw-1.pa.dec.com 172799 IN A 204.123.2.18
268 uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19
269 </pre>
270
271 <p>
272 At this point, UDP and TCP should (mostly) work.
273
274 <p>
275 Here is an example of how to configure a server machine and an emulated
276 client machine for sharing files via NFS:
277
278 <p>
279 (This is very useful if you want to share entire directory trees
280 between the emulated environment and another machine. These instruction
281 will work for FreeBSD, if you are running something else, use your
282 imagination to modify them.)
283
284 <p>
285 <ul>
286 <li>On the server, add a line to your /etc/exports file, exporting
287 the files you wish to use in the emulator:<pre>
288 <b>/tftpboot -mapall=nobody -ro 123.11.22.33</b>
289 </pre>
290 where 123.11.22.33 is the IP address of the machine running the
291 emulator process, as seen from the outside world.
292 <p>
293 <li>Then start up the programs needed to serve NFS via UDP. Note the
294 -n argument to mountd. This is needed to tell mountd to accept
295 connections from unprivileged ports (because the emulator does
296 not need to run as root).<pre>
297 # <b>portmap</b>
298 # <b>nfsd -u</b> &lt;--- u for UDP
299 # <b>mountd -n</b>
300 </pre>
301 <li>In the guest OS in the emulator, once you have ethernet and IPv4
302 configured so that you can use UDP, mounting the filesystem
303 should now be possible: (this example is for NetBSD/pmax
304 or OpenBSD/pmax)<pre>
305 # <b>mount -o ro,-r=1024,-w=1024,-U,-3 my.server.com:/tftpboot /mnt</b>
306 or
307 # <b>mount my.server.com:/tftpboot /mnt</b>
308 </pre>
309 If you don't supply the read and write sizes, there is a risk
310 that the default values are too large. The emulator currently
311 does not handle fragmentation/defragmentation of <i>outgoing</i>
312 packets, so going above the ethernet frame size (1518) is a very
313 bad idea. Incoming packets (reading from nfs) should work, though,
314 for example during an NFS install.
315 </ul>
316
317 The example above uses read-only mounts. That is enough for things like
318 letting NetBSD/pmax or OpenBSD/pmax install via NFS, without the need for
319 a CDROM ISO image. You can use a read-write mount if you wish to share
320 files in both directions, but then you should be aware of the
321 fragmentation issue mentioned above.
322
323
324
325
326
327
328
329 <p><br>
330 <a name="devices"></a>
331 <h3>Emulation of hardware devices</h3>
332
333 Each file called <tt>dev_*.c</tt> in the <tt>src/device/</tt> directory is
334 responsible for one hardware device. These are used from
335 <tt>src/machines/machine_*.c</tt>, when initializing which hardware a particular
336 machine model will be using, or when adding devices to a machine using the
337 <tt>device()</tt> command in configuration files.
338
339 <p>(I'll be using the name "<tt>foo</tt>" as the name of the device in all
340 these examples. This is pseudo code, it might need some modification to
341 actually compile and run.)
342
343 <p>Each device should have the following:
344
345 <p>
346 <ul>
347 <li>A <tt>devinit</tt> function in <tt>src/devices/dev_foo.c</tt>. It
348 would typically look something like this:
349 <pre>
350 DEVINIT(foo)
351 {
352 struct foo_data *d = malloc(sizeof(struct foo_data));
353
354 if (d == NULL) {
355 fprintf(stderr, "out of memory\n");
356 exit(1);
357 }
358 memset(d, 0, sizeof(struct foo_data));
359
360 /*
361 * Set up stuff here, for example fill d with useful
362 * data. devinit contains settings like address, irq_nr,
363 * and other things.
364 *
365 * ...
366 */
367
368 memory_device_register(devinit->machine->memory, devinit->name,
369 devinit->addr, DEV_FOO_LENGTH,
370 dev_foo_access, (void *)d, DM_DEFAULT, NULL);
371
372 /* This should only be here if the device
373 has a tick function: */
374 machine_add_tickfunction(machine, dev_foo_tick, d,
375 FOO_TICKSHIFT);
376
377 /* Return 1 if the device was successfully added. */
378 return 1;
379 }
380 </pre><br>
381
382 <p><tt>DEVINIT(foo)</tt> is defined as <tt>int devinit_foo(struct devinit *devinit)</tt>,
383 and the <tt>devinit</tt> argument contains everything that the device driver's
384 initialization function needs.
385
386 <p>
387 <li>At the top of <tt>dev_foo.c</tt>, the <tt>foo_data</tt> struct
388 should be defined.
389 <pre>
390 struct foo_data {
391 int irq_nr;
392 /* ... */
393 }
394 </pre><br>
395 (There is an exception to this rule; ugly hacks which allow
396 code in <tt>src/machine.c</tt> to use some structures makes it
397 necessary to place the <tt>struct foo_data</tt> in
398 <tt>src/include/devices.h</tt> instead of in <tt>dev_foo.c</tt>
399 itself. This is useful for example for interrupt controllers.)
400 <p>
401 <li>If <tt>foo</tt> has a tick function (that is, something that needs to be
402 run at regular intervals) then <tt>FOO_TICKSHIFT</tt> and a tick
403 function need to be defined as well:
404 <pre>
405 #define FOO_TICKSHIFT 14
406
407 void dev_foo_tick(struct cpu *cpu, void *extra)
408 {
409 struct foo_data *d = (struct foo_data *) extra;
410
411 if (.....)
412 cpu_interrupt(cpu, d->irq_nr);
413 else
414 cpu_interrupt_ack(cpu, d->irq_nr);
415 }
416 </pre><br>
417
418 <li>Does this device belong to a standard bus?
419 <ul>
420 <li>If this device should be detectable as a PCI device, then
421 glue code should be added to
422 <tt>src/devices/bus_pci.c</tt>.
423 <li>If this is a legacy ISA device which should be usable by
424 any machine which has an ISA bus, then the device should
425 be added to <tt>src/devices/bus_isa.c</tt>.
426 </ul>
427 <p>
428 <li>And last but not least, the device should have an access function.
429 The access function is called whenever there is a load or store
430 to an address which is in the device' memory mapped region. To
431 simplify things a little, a macro <tt>DEVICE_ACCESS(x)</tt>
432 is expanded into<pre>
433 int dev_x_access(struct cpu *cpu, struct memory *mem,
434 uint64_t relative_addr, unsigned char *data, size_t len,
435 int writeflag, void *extra)
436 </pre> The access function can look like this:
437 <pre>
438 DEVICE_ACCESS(foo)
439 {
440 struct foo_data *d = extra;
441 uint64_t idata = 0, odata = 0;
442
443 idata = memory_readmax64(cpu, data, len);
444 switch (relative_addr) {
445 /* .... */
446 }
447
448 if (writeflag == MEM_READ)
449 memory_writemax64(cpu, data, len, odata);
450
451 /* Perhaps interrupts need to be asserted or
452 deasserted: */
453 dev_foo_tick(cpu, extra);
454
455 /* Return successfully. */
456 return 1;
457 }
458 </pre><br>
459 </ul>
460
461 <p>
462 The return value of the access function has until 2004-07-02 been a
463 true/false value; 1 for success, or 0 for device access failure. A device
464 access failure (on MIPS) will result in a DBE exception.
465
466 <p>
467 Some devices are converted to support arbitrary memory latency
468 values. The return value is the number of cycles that the read or
469 write access took. A value of 1 means one cycle, a value of 10 means 10
470 cycles. Negative values are used for device access failures, and the
471 absolute value of the value is then the number of cycles; a value of -5
472 means that the access failed, and took 5 cycles.
473
474 <p>
475 To be compatible with pre-20040702 devices, a return value of 0 is treated
476 by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1.
477
478
479
480
481
482
483 </body>
484 </html>

  ViewVC Help
Powered by ViewVC 1.1.26