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