Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Nov 2003 02:31:31 +0100
From:      Adrian Steinmann <ast@marabu.ch>
To:        Soren Kristensen <soren@soekris.com>
Cc:        msmith@freebsd.org
Subject:   BTX loader reboot on Soekris comBIOS1.22 fails (patches for btx.s and	loader/main.c enclosed)
Message-ID:  <200311160131.CAA21864@marabu.marabu.ch>
In-Reply-To: <3FB281B4.5060105@soekris.com>
References:  <32365.1068624044@critter.freebsd.dk> <3FB281B4.5060105@soekris.com>

next in thread | previous in thread | raw e-mail | index | archive | help
After "reboot" in the FreeBSD-stable BTX loader just hangs on Soekris
comBIOS 1.22 Soren asked me:
   ... how does the loader do the actual
   reboot ? And does it differ from how FreeBSD otherwise reboots ?

I have investigated this now: from FreeeBSD, /sbin/reboot first
tries a 8042 keyboard reset, i.e. it writes 0xFE to 0x064.

On FreeBSD-stable this is near line 441 in /usr/src/sys/i386/i386/vm_machdep.c
(unless a kernel config BROKEN_KEYBOARD_RESET is defined):

#if !defined(BROKEN_KEYBOARD_RESET)
        outb(IO_KBD + 4, 0xFE);
        DELAY(500000);  /* wait 0.5 sec to see if that did it */
        printf("Keyboard reset did not work, attempting CPU shutdown\n");
        DELAY(1000000); /* wait 1 sec for printf to complete */
#endif

this works on Soekris comBIOS 1.22.

If the above fails, vm_machdep.ch falls back to unmapping the address
space and invalidating TLD:

        /* force a shutdown by unmapping entire address space ! */
        bzero((caddr_t) PTD, PAGE_SIZE);

        /* "good night, sweet prince .... <THUNK!>" */
        invltlb();

but since the keyboard reset works work, this case is never used
(on Soekris) on /sbin/reboot.

In the BTX loader, the reboot command simply exits the loader, and
end up in exit near line 252 in /usr/src/sys/boot/i386/btx/btx/btx.s
which disables paging, flushes TLB, switches to real mode, flags a
warm boot (writes 0x1234 to 0x472) and then jumps to the BIOS reboot
handler:
-		ljmp $0xffff,$0x0		# reboot the machine

however in various literature it is mentioned that $0xf000,$0xfff0
is bound to work better on most platforms, so I tried
+		ljmp $0xf000,$0xfff0		# reboot the machine

which indeed works! (OpenBSD, for example, uses ljmp $0xf000,$0xfff0).

I prefer the KEYBOARD_RESET method because it follows the /sbin/reboot
style, but I think FreeBSD should consider using ljmp $0xf000,$0xfff0
instead of ljmp $0xffff,$0x0 in btx.s for better compatibility.
For this reason I'm copying msmith@ and jhb@ and hackers@

I hope you can confirm that Soekris comBIOS 1.22 acts strangly when
ljmp $0xffff,$0x0 is used.

The choice $0xffff,$0x0 was made Feb 2000 by jhb and msmith and was
committed to version btx.s 1.15 with these comments:

1) Fix a bug in the int15 function 87 emulation where we only copied half
   of what the BIOS asked for.  This caused the Mylex RAID adapter to go
   haywire and start trashing memory when you tried to boot from it.
2) Don't use interrupt 19 to reboot.  Instead, set the reboot flag to a warm
   boot and jump to the BIOS's reboot handler.  int 19 doesn't clear memory
   or restore the interrupt vector table, and thus really isn't safe.  For
   example, when booting off of PXE, the PXE BIOS eats up a chunk of memory
   for its internal data and structures.  Since we rebooted via int 19,
   using the 'reboot' command in the loader resulted in that memory not
   being reclaimed by the BIOS.  Thus, after a few PXE boots, the system
   was out of lower memory.
3) Catch any int 19 calls made by a BTX client or a user pressing
   Ctrl-Alt-Delete and shutdown BTX and reboot the machine cleanly.  This
   fixes Ctrl-Alt-Delete in the loader and in boot2 instead of presenting
   the user with a BTX fault.

These are the patches I have been using successfuly (only one is necessary):

Index: usr/src/sys/boot/i386/btx/btx/btx.s
===================================================================
RCS file: /usr/cvs/src/sys/boot/i386/btx/btx/btx.s,v
retrieving revision 1.15.2.4
diff -u -r1.15.2.4 btx.s
--- usr/src/sys/boot/i386/btx/btx/btx.s	28 Dec 2000 12:08:22 -0000	1.15.2.4
+++ usr/src/sys/boot/i386/btx/btx/btx.s	16 Nov 2003 00:26:28 -0000
@@ -293,7 +293,7 @@
 		testb $0x1,btx_hdr+0x7		# Reboot?
 exit.3:		jz exit.3			# No
 		movw $0x1234, BDA_BOOT		# Do a warm boot
-		ljmp $0xffff,$0x0		# reboot the machine
+		ljmp $0xf000,$0xfff0		# reboot the machine
 #
 # Set IRQ offsets by reprogramming 8259A PICs.
 #
Index: usr/src/sys/boot/i386/loader/main.c
===================================================================
RCS file: /usr/cvs/src/sys/boot/i386/loader/main.c,v
retrieving revision 1.17.2.7
diff -u -r1.17.2.7 main.c
--- usr/src/sys/boot/i386/loader/main.c	10 Oct 2002 15:53:27 -0000	1.17.2.7
+++ usr/src/sys/boot/i386/loader/main.c	16 Nov 2003 00:26:28 -0000
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <machine/bootinfo.h>
 #include <sys/reboot.h>
+#include <i386/isa/isa.h>

 #include "bootstrap.h"
 #include "libi386/libi386.h"
@@ -238,6 +239,13 @@
 	    (devsw[i]->dv_cleanup)();

     printf("Rebooting...\n");
+
+#if !defined(BROKEN_KEYBOARD_RESET)
+    isa_outb(IO_KBD + 4, 0xFE);
+    delay(1000000);
+    printf("Keyboard reset failed; exiting...\n");
+#endif
+
     delay(1000000);
     __exit(0);
 }



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