Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [PATCH] mutliboot2 second round



On Thu, Jan 30, 2020 at 09:24:44PM +0100, Joerg Sonnenberger wrote:
> I still don't get why you need 32bit C code or even the memmove. What
> exactly are the constraints of the entry point? 32bit protected mode without
> paging to an unknown physical address without any guarantees about
> alignment?

The initial memmove() is required because the code in locore assumes
the kernel loads at fixed address KERNTEXTOFF-KERNBASE (that is
2MB) while EFI loads it much higher (0x4136000 with OVMF/qmeu). I
understand this happens because there is EFI boot service data
memory in the way around 2MB. It gets released when bootloader
calls ExitBootServices(), which is why we can safely memmove() to 2MB.

Of course the approach is not bullet-proof, since some other EFI
implementation could have some other stuff around 2MB that
cannot be released. Addressing that would require intrusive change
in locore so that the code can run after loading a dynamic location 
other than KERNTEXTOFF-KERNBASE. 

Note that the memmove() at multiboot2 entry is a status quo: the
native NetBSD EFI bootstrap does it before starting the kernel.
Following the multiboot specification, we cannot take that for
granted, this is why it is done at multiboot2 entry instead of in
the bootloader.

On the 32 bit code: following your question, I revisited the build
with multiboot2_pre_reloc() built as 64 bit code. As I experienced
before, odd things happen in this multiboot2_pre_reloc(), which makes 
me wonder about the 64 bit features we are allowed to use before 
enabling long monde.

Here $rdi is char *mdi = 0xe23a038
   0x20a6a9 <multiboot2_pre_reloc>:     mov    (%rdi),%edx
   0x20a6ab <multiboot2_pre_reloc+2>:   cmp    $0x3fff,%edx
   0x20a6b1 <multiboot2_pre_reloc+8>:   
    ja     0x20a774 <multiboot2_pre_reloc+203>
   0x20a6b7 <multiboot2_pre_reloc+14>:  mov    %rdi,%r8

$rdi is still 0xe23a038, so should be $r8, but gdb seems
confused and tells me $r8 = 0. I assume this is a bug in 
the qemu/gdb debug interface and that $r8 is 0xe23a038.

   0x20a6ba <multiboot2_pre_reloc+17>:  movabs $0x1800220,%rdi
   0x20a6c4 <multiboot2_pre_reloc+27>:  mov    %r8,%rsi

And now $rsi = 0x20a140 while it should be 0xe23a038. That is
going to crash the function. For what it is worth, $rsi has
been 0x20a140 since the beginning of the function, which 
suggests mov %r8,%rsi was nilpotent (and probably mov %rdi,%r8
as well).

I am interested by any explacation about this behavior. Is 
it a qemu bug? Or did gcc use some feature unavailable at that
time? I assumed it was somehow the case, since running the same
code built with -m32 works around the problem.

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index