[SeaBIOS] vga bios woes

Daniel Verkamp daniel at drv.nu
Fri Jan 4 02:43:06 CET 2013

On Thu, Jan 3, 2013 at 2:31 PM, Alex Williamson
<alex.williamson at redhat.com> wrote:
> Hi,
> I was playing a bit with vfio-based PCI device assignment of VGA in qemu
> and I seem to be hitting a wall just trying to jump into the VGA BIOS.
> I'm booting qemu with -vga none and assigning a radeon hd5450 via
> vfio-pci with some extra code to handle passing legacy accesses through
> to the host.  Legacy access hardly seems to matter though as the
> experiment quickly dies when the vcpu starts executing zero'd memory.
> gdb shows me something like this:
> 0x000f257c <__callrom+72>:      66 c7 44 24 16 ff ff    movw   $0xffff,0x16(%esp)
> 0x000f2583 <__callrom+79>:      66 c7 44 24 1a ff ff    movw   $0xffff,0x1a(%esp)
> 0x000f258a <__callrom+86>:      66 c7 44 24 08 00 f0    movw   $0xf000,0x8(%esp)
> 0x000f2591 <__callrom+93>:      b8 80 d1 0f 00  mov    $0xfd180,%eax
> 0x000f2596 <__callrom+98>:      66 89 44 24 0a  mov    %ax,0xa(%esp)
> 0x000f259b <__callrom+103>:     c1 e5 10        shl    $0x10,%ebp
> 0x000f259e <__callrom+106>:     0f b7 d7        movzwl %di,%edx
> 0x000f25a1 <__callrom+109>:     09 ea   or     %ebp,%edx
> 0x000f25a3 <__callrom+111>:     89 54 24 26     mov    %edx,0x26(%esp)
> 0x000f25a7 <__callrom+115>:     89 e0   mov    %esp,%eax
> 0x000f25a9 <__callrom+117>:     3d 00 70 00 00  cmp    $0x7000,%eax
> 0x000f25ae <__callrom+122>:     76 0a   jbe    0xf25ba <__callrom+134>
> 0x000f25ba <__callrom+134>:     89 f0   mov    %esi,%eax
> 0x000f25bc <__callrom+136>:     bb 58 68 00 00  mov    $0x6858,%ebx
> 0x000f25c1 <__callrom+141>:     e8 31 98 00 00  call   0xfbdf7
> 0x000fbdf7:     ba 01 be 00 00  mov    $0xbe01,%edx
> 0x000fbdfc:     e9 0e ff ff ff  jmp    0xfbd0f
> 0x000fbd0f:     89 c1   mov    %eax,%ecx
> 0x000fbd11:     b8 30 00 00 00  mov    $0x30,%eax
> 0x000fbd16:     8e d8   mov    %eax,%ds
> 0x000fbd18:     8e c0   mov    %eax,%es
> 0x000fbd1a:     8e d0   mov    %eax,%ss
> 0x000fbd1c:     8e e0   mov    %eax,%fs
> 0x000fbd1e:     8e e8   mov    %eax,%gs
> 0x000fbd20:     66 ea 26 bd 28 00       ljmpw  $0x28,$0xbd26
> 0x0000bd26:     00 00   add    %al,(%eax)

I think GDB is probably getting lost at the far jump (ljmpw).  To my
knowledge, GDB does not understand the x86 segmented real-mode memory

The trace above is __callrom() -> farcall16big() -> call16big() ->
__call16big() -> transition16big in romlayout.S, which contains the
ljmpw in question.

> Trying to follow the code into __callrom(), I'm really confused how the
> option rom init vector is actually used since callrom() passes the
> option rom header offset to the init vector rather than anything
> actually resembling the value of the init vector.  I really don't know
> x86 though, so maybe I'm missing something.

The far address of the ROM initialization vector (seg:offset) is being
loaded into br.code, which will get used later on in the farcall
helper functions noted above.  The offset is set to
OPTION_ROM_INITVECTOR by callrom(), which is 3; this is relative to
the segment of the ROM header (hence the FLATPTR_TO_SEG in __callrom).
 The ROM header should have a jump at that location to the real
initialization code.

I don't have any real tips on how to make this work - hopefully
someone else will know the magic incantation to clue in GDB to the new
code segment.

This blog post also looks relevant:

-- Daniel

More information about the SeaBIOS mailing list