Running QEMU as Embedded Guest

Programming, for all ages and all languages.
Post Reply
thewfool
Posts: 3
Joined: Tue Jan 27, 2015 5:15 pm

Running QEMU as Embedded Guest

Post by thewfool »

I am trying to get a custom embedded 386 computer to be virtualized with qemu. In order to avoid loading my program from disk, I'm including the target binary inside a custom kernel. This kernel is used as a bootloader, and uses nasm's incbin to include the raw binary dump of target. This works, and I am able to execute code, but if I run a checksum on the loaded data, it fails to match what it should be.

I'm loading the data in RAM at 0x20000, which overlaps the video memory. I suspect that the system is tinkering with these bits between the time that the "-kernel" parameter loads the kernel and the time it's actually executed. If I pass "-vga none" I would expect no video hardware to load, but qemu crashes before it even gets to my code.
The error I get is "(qemu) qemu: fatal: Trying to execute code outside RAM or ROM at 0x1badb002"

Does anyone know of an easy way to either manually load the program into RAM or make sure that the area is protected from the BIOS and Qemu updating it? Since I'm working on a custom board in a custom system, I can't rely on the standard memory maps.

Thanks!
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Running QEMU as Embedded Guest

Post by Combuster »

I'm loading the data in RAM at 0x20000, which overlaps the video memory.
Video memory starts at 0xA0000, and there's some system-critical memory owned by the firmware just before that. If your binary really is that big
- you probably made an error making that binary.
- you shouldn't be loading it to that address because it doesn't fit.

Also, there's a VGA device at 0xA0000 and not actual RAM. If you write to that address it might not get stored at all, nor can it typically be read back in the same way.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
thewfool
Posts: 3
Joined: Tue Jan 27, 2015 5:15 pm

Re: Running QEMU as Embedded Guest

Post by thewfool »

I take it from your comment that I don't fully understand the memory used by a default QEMU configuration. Where can I find out what the firmware owns?

To address your two points:

- The binary I'm using is a software release that is identical to the one running on physical hardware. It is an image that is loaded directly into ram at those locations. This is unchangeable on the real system. Because the binary is a RAM image, the symbols are all absolute (I have no relocation information, and I am not decoding ELF or any other encoding). I am able to follow the code in the debugger as it correctly completes many relative and absolute jumps. This leads me to have high confidence in the location and size.

- The binary needs to be placed at 0x20000 and it has 0xCC6D0 bytes. On the board that I am emulating, there is no video output, so the original developers did not have this limitation. I am probably being stupid, but that would place the binary image under 945 Kilobytes from the beginning of RAM. My board has a whopping 2MB, so it "fits". I think we agree that the firmware is reserving some of this space. Can I change this? The real board runs a custom firmware that is explicitly designed to use the space lower than 0x20000.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Running QEMU as Embedded Guest

Post by Combuster »

QEMU, and pretty much every other VM/emulator out there, implements an IBM PC-compatible clone. If your reference board has contiguous ram from A0000-FFFFF, then it's a completely different machine, and I doubt you can find anything that would be able to virtualise that out of the box. Most likely, your devices are equally incompatible with the ones you find on a desktop.

In other words, you'll have to modify the virtual hardware first, followed by writing custom firmware for your machine.

In addition QEMU doesn't actually emulate an i386. It emulates a copy of your computer's CPU. If you intent to continue, you'll probably want to get a copy of Bochs and modify that to match whatever hardware you actually have on the target platform.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
xenos
Member
Member
Posts: 1118
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Running QEMU as Embedded Guest

Post by xenos »

Combuster wrote:In addition QEMU doesn't actually emulate an i386. It emulates a copy of your computer's CPU.
Wait, doesn't QEMU have an option which CPU to emulate? Also, there are qemu-system-i386 and qemu-system-x86_64, both of which should emulate the desired architecture, regardless of whether they run on i386 or x86_64 hardware.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
thewfool
Posts: 3
Joined: Tue Jan 27, 2015 5:15 pm

Re: Running QEMU as Embedded Guest

Post by thewfool »

XenOS wrote:there are qemu-system-i386 and qemu-system-x86_64, both of which should emulate the desired architecture, regardless of whether they run on i386 or x86_64 hardware.
I am using qemu-system-i386, and not using KVM. I believe this does it's best to emulate the 386. If not, I'd like to understand it better.
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: Running QEMU as Embedded Guest

Post by Kevin »

Combuster wrote:In addition QEMU doesn't actually emulate an i386. It emulates a copy of your computer's CPU.
That's definitely not true. You can get something quite similar to your host CPU if you use KVM and specify an explicit -cpu host.

By default, however, you don't use KVM and unless you specify something else you the the qemu32 or qemu64 CPU type, depending on whether you're running qemu-system-i386 or qemu-system-x86_64. In any case, what you get by this emulation is something that is close enough to some generic x86 CPU that guests work with it, but it's by far not 100% accurate with respect to enabling the right features for the selected CPU model: Even if you specify -cpu 486, your guest will probably support more instructions than any 486 ever did. The CPU setting mostly affects the CPUID result, and for some of the flags it's actually their presence that enables the corresponding functionality, but there are also cases where CPUID wouldn't advertise the feature any more, but it would still be working.

Anyway, it's rather rare that code relies on CPUs not supporting a given feature, so this shouldn't be a serious problem.
Developer of tyndur - community OS of Lowlevel (German)
Post Reply