[SeaBIOS] MINIX 3.1.6 works in QEMU-0.12.3 only with KVM disabled

Antoine Leca Antoine.Leca.1 at gmail.com
Mon Mar 15 16:28:02 CET 2010


Hello folks,

I am working on Minix, and we detected a problem which might be related
with SeaBIOS.

In short, Minix' boot monitor (first written in 1992, and which supports
80286 architectures), while in 16-bit real mode, uses BIOS service 15/87
to move blocks into high memory.

It stopped working recently with kvm on Intel.

On 03/10/2010 12:26 PM, Erik van der Kouwe wrote on kvm mailing list:
>> I've submitted this bug report a week ago:
>> http://sourceforge.net/tracker/?func=detail&aid=2962575&group_id=180599&atid=893831 

To which Avi Kivity wrote on 2010-03-10 13:03:25 +0200:
> MINIX is using big real mode which is currently not well supported by
kvm on Intel hardware:
>
>> (qemu) info registers
>> EIP=0000f4a7 EFL=00023002 [-------] CPL=3 II=0 A20=1 SMM=0 HLT=0
>> ES =0000 00000000 0000ffff 0000f300
>> CS =f000 000f0000 0000ffff 0000f300
>> SS =9492 00094920 0000ffff 0000f300
>> DS =97ce 00097cec 0000ffff 0000f300
>
> A ds.base of 0x97cec cannot be translated to a real mode segment.

I searched the issue; if you are interested in the details, please read
http://groups.google.com/group/minix3/msg/40f44df0c434cfa6

I notice it might be related to the switch from Bochs to SeaBIOS.

http://bochs.sourceforge.net/cgi-bin/lxr/source/bios/rombios.c has:
3555     case 0x87:
...
3640       mov  eax, cr0
3641       or   al, #0x01
3642       mov  cr0, eax
3643       ;; far jump to flush CPU queue after transition to prot. mode
3644       JMP_AP(0x0020, protected_mode)
3645
3646 protected_mode:
3647       ;; GDT points to valid descriptor table, now load SS, DS, ES
...
3657       rep
3658         movsw  ;; move CX words from DS:SI to ES:DI
3659
3660       ;; make sure DS and ES limits are 64KB
3661       mov ax, #0x28
3662       mov ds, ax
3663       mov es, ax
3664
3665       ;; reset PG bit in CR0 ???
3666       mov  eax, cr0
3667       and  al, #0xFE
3668       mov  cr0, eax


In SeaBIOS, the applicable code is in src/system.c, and looks like
(now this is AT&T assembly):
  83 static void
  84 handle_1587(struct bregs *regs)
....
 127         // Enable protected mode
 128         "  movl %%cr0, %%eax\n"
 129         "  orl $" __stringify(CR0_PE) ", %%eax\n"
 130         "  movl %%eax, %%cr0\n"
 131
 132      // far jump to flush CPU queue after transition to prot. mode
 133         "  ljmpw $(4<<3), $1f\n"
 134
 135         // GDT points to valid descriptor table, now load DS, ES
...
 144         "  rep movsw\n"
 145
 146         // Disable protected mode
 147         "  movl %%cr0, %%eax\n"
 148         "  andl $~" __stringify(CR0_PE) ", %%eax\n"
 149         "  movl %%eax, %%cr0\n"

Note that while the basic scheme is the same, the "cleaning up" of lines
3660-3663 "make sure DS and ES limits are 64KB" is not present.

IIUC, the virtualized CPU goes back to real mode with those segments
sets as they are in protected mode, and yes with Minix boot monitor they
happenned to NOT be paragraph-aligned. And aligning it kills the bug...


Avi Kivity seems to think this is a possible explanation; and he does
not see any harm in adding that cleaning up, while it could have the
benefical property to avoid possible faults while virtualizing the CPU
(which is a bit tricky with Intel hardware in real mode.)


Is it possible to add such "cleaning up" to SeaBIOS too?


Antoine



More information about the SeaBIOS mailing list