Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
qemu [2008/05/29 12:21] stefanha |
qemu [2009/04/15 19:55] (current) warthog9 Flip from .usb to pdsk as .usb no longer works |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== How to use gPXE with QEMU ====== | ====== How to use gPXE with QEMU ====== | ||
- | ===== QEMU 0.9.1 or later ===== | + | ===== Step by step ===== |
- | In QEMU 0.9.1, there is a new option, ''-bootp'', which advertises a filename in BOOTP replies from QEMU's internal DHCP server. Combined with ''-net user'', this option eliminates the need for a special DHCP server setup and TUN/TAP devices. | + | - Install Qemu |
+ | - Compile or download gpxe.pdsk. | ||
+ | - Type on the command line: <code> qemu -fda gpxe.pdsk -net nic -net user -bootp http://etherboot.org/gtest/gtest.gpxe </code> | ||
- | An example command (modified contrib/bochs/README.qemu): | + | ===== Quick start ===== |
+ | First make sure you have ''gpxe.pdsk'' or ''ns8390.pdsk''. You can download them from [[http://rom-o-matic.net/|ROM-o-matic.net]] or [[download|build them yourself]]. | ||
- | ''qemu -net nic,model=rtl8139 -net user -boot a -fda ../../src/bin/rtl8139.pdsk -bootp http://server/file.gpxe'' | + | Here is how to **boot over HTTP**: |
+ | <code> | ||
+ | qemu -bootp http://server/file gpxe.pdsk | ||
+ | </code> | ||
- | Note that you can use this in conjunction with the ''-tftp'' option to test gPXE locally. See the [[http://bellard.org/qemu/qemu-doc.html|QEMU documentation]]. For example, where ''gpxe/src/bin/gpxe.usb'' is the USB image built by the default gPXE ''make'': | + | Or to **boot using PXE**: |
+ | <code> | ||
+ | qemu -bootp tftp://10.0.2.2//pxefile -tftp /path/to/pxedir -fda gpxe.pdsk | ||
+ | </code> | ||
- | ''qemu -bootp tftp://10.0.2.2/pxelinux.0 -tftp /path/to/pxelinux/dir gpxe/src/bin/gpxe.usb'' | + | QEMU's built-in TFTP server serves files from ''/path/to/pxedir'' at IP address 10.0.2.2. |
- | ===== QEMU 0.9.0 or earlier ===== | + | NOTES: |
- | For versions of QEMU before 0.9.1, the instructions from [[http://git.etherboot.org/?p=gpxe.git;a=blob;f=contrib/bochs/README.qemu;hb=HEAD|contrib/bochs/README.qemu]] can be used. | + | The ''-bootp'' option was added in QEMU 0.9.1. For versions of QEMU before 0.9.1, the instructions from [[http://git.etherboot.org/?p=gpxe.git;a=blob;f=contrib/bochs/README.qemu;hb=HEAD|contrib/bochs/README.qemu]] can be used. |
+ | |||
+ | gPXE will strip one of the slashes immediately to the left of the actual filename in the -bootp URI you see above. QEMU 0.9.1 //demands// that there be a leading slash before the filename, so use the two slashes as you see them above unless your QEMU behaves differently. | ||
===== Debugging gPXE with QEMU ===== | ===== Debugging gPXE with QEMU ===== | ||
- | The QEMU monitor (''CTRL+ALT+2'') supports debug commands to inspect registers and memory (try ''help'' or tab complete). Some useful commands include ''stop'', ''info registers'', and ''x'' (dump memory). | + | The QEMU monitor (''CTRL+ALT+2'') supports debug commands to inspect registers and memory (try ''help'' or tab complete). |
+ | |||
+ | * ''stop'' - Stops guest execution, continue using ''c''. | ||
+ | * ''info registers'' - Prints the CPU state including all registers. | ||
+ | * ''x'' - Dumps memory: | ||
+ | <code> | ||
+ | x/5ih 0x10000 Disassemble 5 instructions in 16-bit mode at physical address 0x10000 | ||
+ | x/iw 0xf600 + 0xa00 Disassemble 1 instruction in 32-bit mode at physical address 0xf600 + 0xa00 = 0x10000 | ||
+ | x/xw 0x10000 Dump 32-bit value at physical address 0x10000 | ||
+ | x/xh 0x10000 Dump 16-bit value at physical address 0x10000 | ||
+ | x/xb 0x10000 Dump 8-bit value at physical address 0x10000 | ||
+ | </code> | ||
+ | |||
+ | ==== Address calculation ==== | ||
+ | The QEMU monitor (and GDB stub) only deals with paged or physical addresses. Since gPXE does not use paging, QEMU does no address translation automatically. | ||
+ | |||
+ | **Physical addresses** can be used unmodified. This is what QEMU expects you to enter. | ||
- | ==== Memory dumps ==== | + | **Real-mode addresses** need to be translated. For example, 0400:f002 is (0x400 << 4) + 0xf002 = 0x13002 physical. |
- | Unfortunately, QEMU only honors paged virtual memory. Since gPXE sets up a virtual memory segment with a non-zero base address, all virtual addresses need to be adjusted before using them to inspect memory in QEMU. | + | |
- | The virtual memory offset is available inside gPXE as ''virt_offset'' (see ''arch/i386/transitions/librm.S''). It can be printed out by placing a ''printf'' call in ''core/main.c''. | + | **Protected-mode addresses** need to be translated. For example, we want to calculate the physical address of the EIP value: |
+ | <code> | ||
+ | EAX=00000000 EBX=00055398 ECX=000556d4 EDX=00055398 | ||
+ | ESI=f824d8d0 EDI=000adc58 EBP=00009ce8 ESP=00002d7e | ||
+ | EIP=000004f5 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=1 | ||
+ | ES =9ce8 0009ce80 0000ffff 00009309 | ||
+ | CS =9c8b 0009c8b0 0000ffff 00009b09 | ||
+ | SS =9ce8 0009ce80 0000ffff 00009309 | ||
+ | DS =9ce8 0009ce80 0000ffff 00009309 | ||
+ | FS =9ce8 0009ce80 0000ffff 00009309 | ||
+ | GS =9ce8 0009ce80 0000ffff 00009309 | ||
+ | </code> | ||
+ | Since instructions are loaded from CS:EIP, we need 0x9c8b0 + 0x4f5 = 0x9cda5. | ||
- | When dumping memory, remember to add the value of ''virt_offset'' to any virtual memory addresses. QEMU is effectively using physical memory only. | + | **Remember that QEMU understands expressions as addresses** (e.g. ''0x9c8b0 + 0x4f5''). |