Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Nov 2011 10:26:22 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-current@freebsd.org
Cc:        John Nielsen <lists@jnielsen.net>, current@freebsd.org
Subject:   Re: loader crash / BTX halted on 9.0-RC2 DVD with AMD pseudo-RAID
Message-ID:  <201111221026.23015.jhb@freebsd.org>
In-Reply-To: <848DEEC1-570F-43F8-B432-A34F81014CD0@jnielsen.net>
References:  <848DEEC1-570F-43F8-B432-A34F81014CD0@jnielsen.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, November 21, 2011 1:45:36 pm John Nielsen wrote:
> This weekend I downloaded the Freebsd 9.0 RC2 amd64 ISO image and burned it 
to a DVD. I have a computer that currently runs Windows 7 but I plan to 
install FreeBSD on it in the near future so I booted it up from the DVD to 
check the hardware/driver status. Much to my dismay, the boot loader crashed 
right away (register dump followed by "BTX halted") and the computer 
immediately rebooted. I took a video with my phone so I could capture the 
crash message, screenshot here:
> 
> http://picpaste.com/pics/BTXcrash.1321899682.jpg
> 
> I then tried tweaking a few BIOS settings and found that turning off the 
built-in pseudo-RAID allowed the DVD to boot normally. I changed the SATA type 
from "RAID" to "AHCI". Fortunately I plan to use the controller in AHCI mode 
for the FreeBSD installation so this won't end up being a problem for me, but 
I still thought it was worth reporting.

Hmmm, so this is odd.  It died with an Invalid TSS exception on the iret 
instruction at the end of the return-from-real-mode trampoline in BTX.  
Looking at the dump I noticed that PSL_NT is set in %eflags, so for some 
reason the iret was trying to do a nested task return.  We shouldn't let
that flag leak out of any real mode code.  Try this patch perhaps:

Index: btx.S
===================================================================
--- btx.S	(revision 227815)
+++ btx.S	(working copy)
@@ -39,6 +39,8 @@
 		.set PSL_RESERVED_DEFAULT,0x00000002
 		.set PSL_T,0x00000100		# Trap flag
 		.set PSL_I,0x00000200		# Interrupt enable flag
+		.set PSL_D,0x00000400		# String instruction direction
+		.set PSL_NT,0x00004000		# Nested task flag
 		.set PSL_VM,0x00020000		# Virtual 8086 mode flag
 		.set PSL_AC,0x00040000		# Alignment check flag
 /*
@@ -609,8 +611,8 @@ rret_tramp:	movw $MEM_ESPR-0x08,%sp		# Reset stack
 		pushl %ds			#  regs
 		pushl %es
 		pushfl				# Save %eflags
-		cli				# Disable interrupts
-		std				# String ops dec
+		pushl $PSL_RESERVED_DEFAULT|PSL_D # Use clean %eflags with
+		popfl				#  string ops dec
 		xorw %ax,%ax			# Reset seg 
 		movw %ax,%ds			#  regs
 		movw %ax,%es			#  (%ss is already 0)
@@ -673,6 +675,7 @@ rret_tramp.1:	xorl %ecx,%ecx			# Zero
 		testl $V86F_FLAGS,%edx		# User wants flags?
 		jz rret_tramp.3			# No
 		movl MEM_ESPR-0x3c,%eax		# Read real mode flags
+		andl $~(PSL_T|PSL_NT),%eax	# Clear unsafe flags
 		movw %ax,-0x08(%esi)		# Update user flags (low 16)
 /*
  * Return to the user task

I haven't tested it yet, so only try this from a CD install for now.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111221026.23015.jhb>