* Bootloading within QEMU?
@ 2021-08-17 14:31 Kenneth Adam Miller
2021-08-17 15:56 ` Paolo Bonzini
0 siblings, 1 reply; 3+ messages in thread
From: Kenneth Adam Miller @ 2021-08-17 14:31 UTC (permalink / raw)
To: QEMU Developers
[-- Attachment #1: Type: text/plain, Size: 985 bytes --]
Hello,
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. 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.
It's difficult because the surrounding QEMU APIs that each target must use
isn't documented at all. There's a little bit of abstract documentation
that can be generated, same as what is publicly found. Reading that only
does so much good because there isn't much of a guide as to how to program
the surrounding QEMU libraries.
[-- Attachment #2: Type: text/html, Size: 1043 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Bootloading within QEMU?
2021-08-17 14:31 Bootloading within QEMU? Kenneth Adam Miller
@ 2021-08-17 15:56 ` Paolo Bonzini
2021-08-17 16:18 ` Peter Maydell
0 siblings, 1 reply; 3+ messages in thread
From: Paolo Bonzini @ 2021-08-17 15:56 UTC (permalink / raw)
To: Kenneth Adam Miller, QEMU Developers
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. 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.
Note that on platforms that use a fixed firmware file there's still the
possibility of using -kernel. In that case, the firmware initializes
the system, then places the binary in memory and jumps to it. qboot
(https://github.com/qemu/qboot) is a very small x86 firmware that is
able to boot a Linux or multiboot kernel.
Paolo
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Bootloading within QEMU?
2021-08-17 15:56 ` Paolo Bonzini
@ 2021-08-17 16:18 ` Peter Maydell
0 siblings, 0 replies; 3+ messages in thread
From: Peter Maydell @ 2021-08-17 16:18 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Kenneth Adam Miller, QEMU Developers
On Tue, 17 Aug 2021 at 16:57, Paolo Bonzini <pbonzini@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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-08-17 16:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-08-17 14:31 Bootloading within QEMU? Kenneth Adam Miller
2021-08-17 15:56 ` Paolo Bonzini
2021-08-17 16:18 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).