[LinuxBIOS] inifinite loop after raminit

Jon Dufresne jon.dufresne at gmail.com
Tue Nov 28 16:28:27 CET 2006


I can get the bios to leave raminit and begin to copy the bios to ram.
I believe I initialized the SDRAM right, but I have yet to fully
verify this due to an infinite loop.

The loop looks like it is in the file src/arch/i386/init/crt0.S.lb

I have experience with using assembly and understand assembly
concepts, however, my x86 specific assembly is a bit weak. I have
mostly used MIPS and Motorolla 68HC11 assembly.

I put debug messages into the file to help isolate where the loop
occurs, however this only confused me more. I would appreciate any
help in discovering why I am looping this way.

If you look below, after I reach "point 4" I should either jump to
right above "point 3" or continue on to "point 5", however, the
program appears to jump to around "point 2" and then from point 2 it
somehow gets to "point 5", once at point 5 I have no idea why it gets
back to point 2. At this point the program infinitely ping pongs
between point 2 and point 5.

Is this an indication that my ram isn't initialized right, or am I
missing something else.

As always I appreicate any help you can give.

***** Here are my modifications and console output ******

#include <arch/asm.h>
#include <arch/intel.h>
#include <console/loglevel.h>	

/*
 * This is the entry code the code in .reset section
 * jumps to this address.
 *
 */
.section ".rom.data", "a", @progbits
.section ".rom.text", "ax", @progbits

	intel_chip_post_macro(0x01)             /* delay for chipsets */

#include "crt0_includes.h"

#if USE_DCACHE_RAM == 0
#ifndef CONSOLE_DEBUG_TX_STRING
	/* uses:	 esp, ebx, ax, dx */
# define __CRT_CONSOLE_TX_STRING(string) \
	mov	string, %ebx	; \
	CALLSP(crt_console_tx_string)

# if defined(TTYS0_BASE) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
#  define CONSOLE_DEBUG_TX_STRING(string)        __CRT_CONSOLE_TX_STRING(string)
# else
#  define CONSOLE_DEBUG_TX_STRING(string)
# endif
#endif

	/* clear boot_complete flag */
	xorl	%ebp, %ebp
__main:
	CONSOLE_DEBUG_TX_STRING($str_copying_to_ram)

	/*
	 *	Copy data into RAM and clear the BSS. Since these segments
	 *	isn\'t really that big we just copy/clear using bytes, not
	 *	double words.
	 */
	intel_chip_post_macro(0x11)		/* post 11 */

	cld				/* clear direction flag */
	
	/* copy linuxBIOS from it's initial load location to
	 * the location it is compiled to run at.
	 * Normally this is copying from FLASH ROM to RAM.
	 */
#if !CONFIG_COMPRESS
	CONSOLE_DEBUG_TX_STRING($str0)
	movl	$_liseg, %esi
	movl	$_iseg,  %edi
	movl	$_eiseg, %ecx
	subl	%edi, %ecx
	rep	movsb
#else
	CONSOLE_DEBUG_TX_STRING($str1)
	leal	4+_liseg, %esi
	leal	_iseg, %edi
	movl	%ebp, %esp	/* preserve %ebp */
	movl	$-1, %ebp	/* last_m_off = -1 */
	jmp	dcl1_n2b

/* ------------- DECOMPRESSION -------------

 Input:
   %esi - source
   %edi - dest
   %ebp - -1
   cld

 Output:
   %eax - 0
   %ecx - 0
*/

.macro getbit bits
.if	\bits == 1
	addl	%ebx, %ebx
	CONSOLE_DEBUG_TX_STRING($str2)
	jnz	1f
.endif
	movl	(%esi), %ebx
	subl	$-4, %esi	/* sets carry flag */
	adcl	%ebx, %ebx
1:
.endm

decompr_literals_n2b:
	movsb

decompr_loop_n2b:
	addl	%ebx, %ebx
	CONSOLE_DEBUG_TX_STRING($str3)
	jnz	dcl2_n2b
dcl1_n2b:
	getbit	32
dcl2_n2b:
	CONSOLE_DEBUG_TX_STRING($str4)
	jc	decompr_literals_n2b
	xorl	%eax, %eax
	incl	%eax		/* m_off = 1 */
loop1_n2b:
	getbit	1
	adcl	%eax, %eax	/* m_off = m_off*2 + getbit() */
	getbit	1
	CONSOLE_DEBUG_TX_STRING($str5)
	jnc	loop1_n2b	/* while(!getbit()) */
	xorl	%ecx, %ecx
	subl	$3, %eax
	CONSOLE_DEBUG_TX_STRING($str6)
	jb	decompr_ebpeax_n2b	/* if (m_off == 2) goto decompr_ebpeax_n2b ? */
	shll	$8, %eax	
	movb	(%esi), %al	/* m_off = (m_off - 3)*256 + src[ilen++] */
	incl	%esi
	xorl	$-1, %eax
	CONSOLE_DEBUG_TX_STRING($str7)
	jz	decompr_end_n2b	/* if (m_off == 0xffffffff) goto decomp_end_n2b */
	movl	%eax, %ebp	/* last_m_off = m_off ?*/
decompr_ebpeax_n2b:
	getbit	1		
	adcl	%ecx, %ecx	/* m_len = getbit() */
	getbit	1
	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit()) */
	jnz	decompr_got_mlen_n2b	/* if (m_len == 0) goto decompr_got_mlen_n2b */
	incl	%ecx		/* m_len++ */
loop2_n2b:
	getbit	1	
	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit() */
	getbit	1
	jnc	loop2_n2b	/* while(!getbit()) */
	incl	%ecx
	incl	%ecx		/* m_len += 2 */
decompr_got_mlen_n2b:
	cmpl	$-0xd00, %ebp
	adcl	$1, %ecx	/* m_len = m_len + 1 + (last_m_off > 0xd00) */
	movl	%esi, %edx
	leal	(%edi,%ebp), %esi	/* m_pos = dst + olen + -m_off  */
	rep
	movsb			/* dst[olen++] = *m_pos++ while(m_len > 0) */
	movl	%edx, %esi
	jmp	decompr_loop_n2b
decompr_end_n2b:
	intel_chip_post_macro(0x12)		/* post 12 */

	movl	%esp, %ebp
#endif

	CONSOLE_DEBUG_TX_STRING($str_pre_main)
	leal	_iseg, %edi
	jmp	*%edi

.Lhlt:	
	intel_chip_post_macro(0xee)	/* post fe */
	hlt
	jmp	.Lhlt

#ifdef __CRT_CONSOLE_TX_STRING
	/* Uses esp, ebx, ax, dx  */
crt_console_tx_string:
	mov	(%ebx), %al
	inc	%ebx
	cmp	$0, %al
	jne	9f
	RETSP
9:
/* Base Address */
#ifndef TTYS0_BASE
#define TTYS0_BASE	0x3f8
#endif
/* Data */
#define TTYS0_RBR (TTYS0_BASE+0x00)

/* Control */
#define TTYS0_TBR TTYS0_RBR
#define TTYS0_IER (TTYS0_BASE+0x01)
#define TTYS0_IIR (TTYS0_BASE+0x02)
#define TTYS0_FCR TTYS0_IIR
#define TTYS0_LCR (TTYS0_BASE+0x03)
#define TTYS0_MCR (TTYS0_BASE+0x04)
#define TTYS0_DLL TTYS0_RBR
#define TTYS0_DLM TTYS0_IER

/* Status */
#define TTYS0_LSR (TTYS0_BASE+0x05)
#define TTYS0_MSR (TTYS0_BASE+0x06)
#define TTYS0_SCR (TTYS0_BASE+0x07)
	
	mov	%al, %ah
10:	mov	$TTYS0_LSR, %dx
	inb	%dx, %al
	test	$0x20, %al
	je	10b
	mov	$TTYS0_TBR, %dx
	mov	%ah, %al
	outb	%al, %dx

	jmp crt_console_tx_string
#endif /* __CRT_CONSOLE_TX_STRING */

#if defined(CONSOLE_DEBUG_TX_STRING) && (ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG)
.section ".rom.data"
str_copying_to_ram:  .string "Copying LinuxBIOS to ram blah.\r\n"
str_pre_main:        .string "Jumping to LinuxBIOS.\r\n"
str0: .string "point 0\r\n"
str1: .string "point 1\r\n"
str2: .string "point 2\r\n"
str3: .string "point 3\r\n"
str4: .string "point 4\r\n"
str5: .string "point 5\r\n"
str6: .string "point 6\r\n"
str7: .string "point 7\r\n"
str8: .string "point 8\r\n"
str9: .string "point 9\r\n"
str10: .string "point 10\r\n"


.previous

#endif /* ASM_CONSOLE_LOGLEVEL > BIOS_DEBUG */

#endif /* USE_DCACHE_RAM */



**** And here is my output *****

Copying LinuxBIOS to ram blah.
point 1
point 4
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5
point 2
point 2
point 5


**** and it continues in this fashion. ****




More information about the coreboot mailing list