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. ****