Re: Hook INT18 for IBM servers?

Glenn Brown <[email protected]>
Newsgroups gmane.network.etherboot.user
Message-ID <[email protected]>
Jarrod,

Here's what I remember about the IBM BIOS I was using (in an IBM xSeries 
346 machine), but our NICs have been used in lots of other IBM servers.

	It's not PnP.  It doesn't set AX:DX to point to a '$PnP'
	structure, and no such structure exists in RAM if you scan
	for one.

	The BIOS calls INT18 to attempt to boot.  There is no user
	interface to enable/disable individual PCI expansion ROMs.  By
	default, PCI option ROMs are enabled, and will get a turn to
	boot the machine.

	The IBM BIOS is not BBS compliant.  In particular, BBS says
	to use INT18 to return control to the BIOS, but IBM wants iret.
	If you use INT18 you will loop.

	Since the machine tries to boot from the NIC in the default
	boot configuration, IBM wanted our NIC to fail to boot quickly
	if the link is down.  Conventional twisted-pair Ethernet
	handles this by not installing an INT18 handler at POST if the
	link is down.  However, our NIC is 10Gb Ethernet, and some third
	party switches took >1s to bring the link up
	-- namely early HP ProCurve switches, but they've fixed that
	via a firmware upgrade -- so we modified Etherboot to defer the
	decision until INT18 was called, and early-exit if the link
	was down >1s after POST.  This change is probably moot, since
	this was to address early 10G switches, but link detection
	in 10GE fundamentally only requires a few nanoseconds.

Since iret is wedging your machine, I'd try the following:
	
	First, make iret be the first instruction executed in the
	INT18 handler.  If this returns control to the BIOS, then
	you know that your BIOS expects iret and the problem is
	probably the stack.  Undo this change once you've confirmed
	iret works as a trivial INT18 handler.

	Create a subroutine to print the 16-bit value in the AX
	register. This is not a great leap if you start with the
	Etherboot romprefix.S string printing function.  Then use
	this function to print registers at INT18 entry and before
	iret.  iret is probably failing because some register
	has not been properly restored.

As I recall, it was very tricky to ensure that the stack
pushes and pops were balanced by simply looking at the code.
I think there was even a bug in Etherboot internals that
failed to clean up memory allocation properly internally.  Isolating
this is practically impossible without a print function.

Digging through my archive of patches, I found the attached relevant 
patch, which prints the amount of allocated base memory.  If memory 
serves, and if this patch records the actual working code, this is how I 
found the leak in Etherboot.  You can easily print other
registers using the included print_ax function.  For example, you can 
print %es with
	push %ax /* Save AX */
	mov %es,%ax /* Move register-to-print into AX */
	call print_ax /* print the value in AX */
	pop %ax /* Restore AX */

Good luck!

--Glenn

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july

_______________________________________________
Etherboot-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/etherboot-discuss
print_basemem.patch (text/plain, 1.4 KB)
Index: src/arch/i386/prefix/romprefix.S
===================================================================
RCS file: /repository/etherboot/src/arch/i386/prefix/romprefix.S,v
retrieving revision 1.3
diff -a -u -a -u -r1.3 romprefix.S
--- src/arch/i386/prefix/romprefix.S	23 Mar 2007 18:22:41 -0000	1.3
+++ src/arch/i386/prefix/romprefix.S	26 May 2007 02:32:27 -0000
@@ -251,7 +256,9 @@
 	pushw	%ax
 	/* Relocate to free base memory, switch stacks */
 	pushw	$18			/* Preserve ROM length and CS & original AX and DS & original stack location & exit code & far ret addr */
+	call	print_basemem
 	call	prelocate
+	call	print_basemem
 	/* We are now running in RAM */
 	popw	%ax			/* discard stack length */
 	movw	%cs, %ax
@@ -435,3 +462,53 @@
 2:	ret
 
 #endif
+
+print_al:
+	pushw	%ax
+	pushw	%bx
+	movw	$0x0007, %bx
+	movb	$0x0e, %ah
+	int	$0x10
+	popw	%bx
+	popw	%ax
+	ret
+
+print_ax:
+	/* Save registers. */
+	pushw	%ax
+	pushw	%bx
+	pushw	%cx
+	movw	%ax,%bx
+	/* Print digits */
+	mov	$4,%cx
+1:	
+	mov	%bh,%al
+	shr	$4,%al
+	add	$'a',%al
+	call	print_al
+	shlw	$4,%bx
+	loop	1b
+	/* Print newline */
+	mov	$'\r',%al
+	call	print_al
+	mov	$'\n',%al
+	call	print_al
+	/* Restore registers and return */
+	popw	%cx
+	popw	%bx
+	popw	%ax
+	ret
+
+print_basemem:
+	pushw	%ax
+	pushw	%es
+	
+	movw	$0x40, %ax
+	movw	%ax, %es
+	movw	%es:(0x13), %ax		/* FBMS in kb to %ax */
+	call	print_ax
+
+	popw	%es
+	popw	%ax
+	ret
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.