strange behavior patched At91bootstrap-2.5 on Olimex SAM9-L9

All design tool related questions: compiler, assembler, linker. Embedded programming questions: assembler, C code.

Moderator: nferre

knossos
Posts: 10
Joined: Thu May 14, 2009 8:26 am

strange behavior patched At91bootstrap-2.5 on Olimex SAM9-L9

Fri May 15, 2009 11:30 am

Hi,

I patched the At91bootstrap-2.5 code so that it supports the SAM9-L9260 board (AT91SAM9260).
Using the newest buildroot http://buildroot.uclibc.org (configured to produce ARM (LE) EABI code) I can compile
the bootstrap loader code:

Code: Select all

$ make
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSAM9L9260  -c -o crt0_gnu.o crt0_gnu.S 
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o main.o main.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o board/sam9l9260/sam9l9260.o board/sam9l9260/sam9l9260.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/debug.o driver/debug.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/gpio.o driver/gpio.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/pmc.o driver/pmc.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/sdramc.o driver/sdramc.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/string.o driver/string.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/udiv.o driver/udiv.c
arm-linux-gcc  -g -mcpu=arm9 -Os -Wall -DAT91SAM9260 -Iboard/sam9l9260/nandflash -Iinclude -DTOP_OF_MEM=0x301000 -DSPI_MODE_0 -DSPI_BOOT_CS1 -DSPI_CLK=5000000 -DSAM9L9260  -c -o driver/nandflash.o driver/nandflash.c
driver/nandflash.c: In function 'load_nandflash':
driver/nandflash.c:489: warning: pointer targets in passing argument 5 of 'AT91F_NandRead' differ in signedness
driver/nandflash.c:395: warning: unused variable 'i'
mkdir -p result
echo  main.o board/sam9l9260/sam9l9260.o driver/debug.o driver/gpio.o driver/pmc.o driver/sdramc.o driver/string.o driver/udiv.o driver/nandflash.o
main.o board/sam9l9260/sam9l9260.o driver/debug.o driver/gpio.o driver/pmc.o driver/sdramc.o driver/string.o driver/udiv.o driver/nandflash.o
arm-linux-ld -nostartfiles -Map=result/sam9l9260-nandflashboot-2.3.4.map --cref -T elf32-littlearm.lds -Ttext 0x200000 -n -o result/sam9l9260-nandflashboot-2.3.4.elf crt0_gnu.o main.o board/sam9l9260/sam9l9260.o driver/debug.o driver/gpio.o driver/pmc.o driver/sdramc.o driver/string.o driver/udiv.o driver/nandflash.o
mkdir -p binaries
arm-linux-objcopy --strip-debug --strip-unneeded result/sam9l9260-nandflashboot-2.3.4.elf -O binary binaries/sam9l9260-nandflashboot-2.3.4.bin
  • Is it a good idea to use EABI, or should I rather stick to the old (and slower) OABI ?
Then, I used openocd r732 with the rockboxplayer setup (http://code.google.com/p/rockboxplayer/ ... DebugSetup)
to upload the created nandflash binary sam9l9260-nandflashboot-2.3.4.bin to the controllers sram at address 0x200000.

Code: Select all

Open On-Chip Debugger
> reset
executing script 'event/at91sam9260_pre_reset.script'
jtag_speed: 1200, 1200
JTAG device found: 0x0792603f (Manufacturer: 0x01f, Part: 0x7926, Version: 0x0)
target state: halted
target halted in ARM state due to breakpoint, current mode: Supervisor
cpsr: 0x000000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
executing script 'event/at91sam9260_post_reset.script'
jtag_speed: 0, 0
dcc downloads are enabled
> load_image /<some path>/at91bootstrap-2.5/binaries/sam9l9260-nandflashboot-2.3.4.bin 0x200000
3372 byte written at address 0x00200000
downloaded 3372 byte in 0.688635s
> resume 0x200000

At the serial console, this correctly produces:

Code: Select all

AT91Bootstrap loading from 0x8400...


NandFlash detected sucessfully: Samsung K9F4G08U0M 8bit 256Mb

My code responsible for the output of the NAND flash type is in driver/nandflash.c:

Code: Select all

    if (!pNandInitInfo)
    {
#ifdef CFG_DEBUG    
        dbg_print("\n\r-E- No NandFlash detected !!!\n\r");
#endif
        return -1;
    }
#ifdef CFG_DEBUG
        dbg_print("\n\rNandFlash detected sucessfully: ");

        if (pNandInitInfo!=NULL)
            nandID = pNandInitInfo->uNandID;

        switch (nandID)
        {
            case 0xecda:    dbg_print("Samsung K9F2G08U0M 256Mb\n\r"); break;
            case 0x2cca:    dbg_print("Micron MT29F2G16AAB 256Mb\n\r"); break;
            case 0xecdc:    dbg_print("Samsung K9F4G08U0M 8bit 256Mb\n\r"); break;
            default:        dbg_print("unknown\n\r"); break;
        }

        for (;;)
            asm("nop");

#endif
As you can see, I added an endless loop after the message has been printed so that execution stops at this point.

Now things start to get funny:
If I remove the endless loop (so that the rest of the code is executed), the bootstrap loader doesn't seem to work at all and no output is printed on the serial debug console.
I also added a breakpoint at the JUMP_ADDR (0x23f00000) which is never reached.

I looked at the dbg_print() code which busy-waits until all characters of the debug message have been written out on the serial port.
For my understanding, if there is a bug in the code which leads to a crash, all debug messages printed with dbg_print() before the crash should still appear on the serial debug console.
If this really is the case, I do no understand why the above code (with the endless loop at the end) works, but the code with the loop removed doesn't work at all (and neither prints anything on the serial debug console).


Also quite interesting is that the code runs just fine with the switch statement removed:

Code: Select all

    if (!pNandInitInfo)
    {
#ifdef CFG_DEBUG    
        dbg_print("\n\r-E- No NandFlash detected !!!\n\r");
#endif
        return -1;
    }
#ifdef CFG_DEBUG
        dbg_print("\n\rNandFlash detected sucessfully: ");

        if (pNandInitInfo!=NULL)
            nandID = pNandInitInfo->uNandID;

/*  -------------------------------------------------------------------------------
        switch (nandID)
        {
            case 0xecda:    dbg_print("Samsung K9F2G08U0M 256Mb\n\r"); break;
            case 0x2cca:    dbg_print("Micron MT29F2G16AAB 256Mb\n\r"); break;
            case 0xecdc:    dbg_print("Samsung K9F4G08U0M 8bit 256Mb\n\r"); break;
            default:        dbg_print("unknown\n\r"); break;
        }

        for (;;)
            asm("nop");
 ------------------------------------------------------------------------------- */

#endif
  • Do you know what is going on here ?
Though not really necessary, I would really like to have some debug code which prints out what type of NAND flash has been detected.
  • Since I heard that there are some strange problems caused by EABI, do you think that EABI might cause this problem ?
    Update: I just built the toolchain so that it creates OABI binaries. The problem is the same.
cheers,
knossos
knossos
Posts: 10
Joined: Thu May 14, 2009 8:26 am

Re: strange behavior patched At91bootstrap-2.5 on Olimex SAM9-L9

Fri May 15, 2009 2:16 pm

I think I found the problem by myself.

In my configuration the BMS pin is high which means that the controller boots using it's internal embedded ROM bootloader (the AT91SAM9260 Boot Program - AT91SAM9260 datasheet pp. 75).
From there it tries to load valid application code (either from SPI DataFlash or from NANDFlash) into internal SRAM.
More precisely, the "DataFlashBoot program" looks of a sequence of 8 valid ARM exception vectors can be found in the dataflash memory which is connected to SPI.
If nothing is found, it continues with the "NANDFlashBoot program" which does the same as the DataFlashBoot program, except for NAND flash.
If it finds a sequence of 8 valid ARM exception vectors, it copies the the content to its internal SRAM followed by a remap and a jump to the first address of the SRAM.

According to the datasheet, the controller has 2 internal SRAMS (SRAM0: 0x200000-0x201000, SRAM1: 0x300000-0x301000).
As we can see, both SRAMS are 4KBytes in size.
However, only the first SRAM (SRAM0) is available for user code, since the second SRAm (SRAM1) is used for variables and stacks.

This is what is done in at91bootstrap as well.
If we look at crt0_gnu.S, it initializes the stack pointer to TOP_OF_MEM (which is set to 0x301000 in our case).

This means however, that all bootloader code may not be larger than SRAM0 (which is 4Kbytes or 4096 bytes in size).
At a closer look it turned out, that my added debug code caused the final bootloader code to be larger than that (even though the code is size optimized by gcc's -O2 flag and stripped afterwards).
Even more precisely, we can have a look at the created memory map (sam9l9260-nandflashboot-2.3.4.map in my case).
In there we see that (as usual) all strings including the debug strings are at the end of the created binary.

Therefore I'm pretty sure that the following happened:
In the at91bootstrap binary are various accesses to strings (and other data) which are situated at the end of the binary.
However, since the binary was bigger than 4K, this also means that the address of this data is out of bounds (thus in the reserved memory area above 0x201000).
This most possibly leads to a memory access exception causing the CPU to reboot and the game to begin once again.


Another interesting observation I made is that not every crosscompile toolchain is suited to compile at91bootstrap.
With my gcc-4.3.2-uClibc-0.9.30 toolchain from buildroot.uclibc.org, the size optimized resulting binary (without my added debug code) is pretty maxed out with 4096 bytes.
However, the same code compiled with the toolchain from the ubuntu-arm port (https://wiki.ubuntu.com/ARM/RootfsFromScratch) is already 4112 bytes in size (and thus too big for the AT921SAM9260).


I hope this was helpful for you as well ;)

Return to “Development Tools”

Who is online

Users browsing this forum: No registered users and 3 guests