[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
model.
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:
http://crustynation.net/wiki/doku.php?id=blog:gdb_real_mode
-- Daniel
More information about the SeaBIOS
mailing list