On Tue, 17 Aug 2021 at 16:57, Paolo Bonzini <pbonz...@redhat.com> wrote:
> On 17/08/21 16:31, Kenneth Adam Miller wrote:
> > I am trying to discover how to schedule QEMU to begin actual emulation
> > as currently my target correctly starts QEMU but only shows the shell,
> > and not even boot loading occurs within QEMU. I'm trying to learn from
> > example, and so will focus my questions only on X86.

x86 is the oldest of QEMU's target architectures and thus the
one most laden down with ancient "we wouldn't write it that way today"
code, backwards-compatibility cruft and other confusing encrustations.
It's not a good choice for trying to learn how a target architecture
should be structured, I'm afraid. Arm is good-in-parts but has a similar
amount of old code and back-compat junk (we have overhauled the translate.c
code massively, so that part is good, unlike the i386 translate.c which
is absolutely dreadful). You might try riscv, that's a lot newer.

> > I can see the
> > MachineClass and MachineState types, and I have tried to follow QEMU
> > with the debugger and found where QEMU calls qemu_init and
> > qemu_main_loop under qemu/softmmu/main.c, and even tried to follow
> > through from init to main loop to see where it would begin booting, but
> > I cannot see where the bootloader is scheduled or specified or started
> > from within the target occurs.
>
> There are two possibilities:
>
> 1) QEMU loads a fixed firmware file, usually at a fixed address in
> memory so that the reset vector of the CPU is inside the firmware.  This
> is what happens for example on x86.  The firmware ultimately boots the
> machine (e.g. on x86 you have BIOS->GRUB->Linux or something like that).
>
> 2) QEMU loads a binary specified on the command line---typically with
> -kernel, which is stored in current_machine->kernel_filename---and
> somehow arranges for the guest to execute that file when it starts.  For
> example one possibility is to write a jump instruction at the CPU reset
> vector (see riscv_setup_rom_reset_vec for an example).  The functions
> you want to look at for the loading part are load_elf_ram*, and
> load_uimage_as and load_image_targphys_as.

For a new architecture I would strongly suggest avoiding putting
any more magic into the "-kernel" handling than you can avoid.
You probably do want it to do "load a Linux kernel with whatever
the standard image format and boot protocol that implies", but
stick to exactly that (and if you can avoid it, don't even implement
that). Definitely don't overload it with "and if it's an ELF file then
load it like an ELF file too" or supporting 15 different kinds of file
format or other "do what I mean" handling.

You can do generic "load an ELF file" with the generic-loader
https://qemu-project.gitlab.io/qemu/system/generic-loader.html
which requires no architecture or board specific handling --
as the name suggests, it is generic ;-) . This makes it different
from the -kernel and -bios options, which both need at least
some handling in the board code.

A general recommendation: to the extent that you can do so, avoid
implementing behaviour in QEMU which is not just "same thing the
real hardware does". When you're implementing "what the hardware
does" you have a concrete specification that defines what the
"right thing" is, people writing code for it hopefully already
know what that behaviour is, and you can generally point your users
at the h/w docs for specifics rather than having to write them
up in the QEMU docs. As soon as you wander off into the realms
of "it would be kind of convenient if QEMU directly booted this
file I had lying around" (which usually implies emulating some
behaviour that is not that of the hardware but of firmware or
a bootloader) things get a lot murkier and you can end up with
a bit of a mess, especially over time. Worse, that mess is hard
to back out of because we don't like to break backwards-compatibility
for user command lines that worked with previous QEMU versions.
target/arm's "let's just pretend we're a bootloader because
it's convenient" code was initially about 100 lines long;
today it is more than ten times that size...

-- PMM

Reply via email to