OTP Custom Boot Loader for 8 bit flash

Technical questions regarding the XTC tools and programming with XMOS.
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

OTP Custom Boot Loader for 8 bit flash

Post by GerhardNorkus »

Hi All,

I need to create a custom boot loader for an 8 bit flash ram instead of SPI. I need this so I can keep my parts count to a bare minimum as my device needs to be really small. I already have the necessary code in assembly for reading and writing to the ram (up to 50MB/s), but I need to modify XFlash and XBurn to use my page read/write/block erase calls instead of the SPI ones.

Any clues? Can an XMos employee help me with this? I would like to finish this before the week is over, if possible....


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

GerhardNorkus wrote:but I need to modify XFlash and XBurn to use my page read/write/block erase calls instead of the SPI ones.
Alternatively you can write your flash from a program you
run on the xcore; if you have a mechanism for field upgrades
just use that (and if you don't, you probably should!)
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Have you written your own boot loader before?

Did you burn it to OTP?
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Forgot to say thanks for the reply...

By the way, have you done any work with the SU1 (usb fb96 chip)?
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

Yes, I've written bootloaders. No, I've never written anything
to OTP; I've never had the need and I'm afraid of bricking my
boards. I went as far as reading from OTP, that was scary
already!

Nope, never used SU1 (I don't yet have any boards with one).

What's with all these questions? :-)
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Sorry to inquire in the wrong way!

I have been working with the SU1 since introduced. I am making miniature 3D scanners with video being stored on an onboard flash eeprom. Not much in the way of chips, just the xmos, a camera, power, SPI flash, and the eeprom. I have spun many boards and am trying to get a production board out that doesn't need the SPI flash so I can make the board even smaller....

There are other problems I wanted to post, but I didn't want to put them in this thread if you are unacquainted with the SU1 product...

Thanks anyway!
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Segher,

Attached is some code (xc, S, makefile, header, and xn file) I am using as a rudimentary first stage boot loader. I do not have shown the code I use to reset the PLL and ref clocks. The array being injected to the code location at 0x1B000 is a simple LED flasher that turns on and off port 1L at an interval of a second or so. It was compiled from a different project with -nostdlib and --bootable specified in the xmap flags section of the makefile. This boot loader was created in a similar fashion

Big question, however, is how do I ensure that _start always appears at the top of my binary? Attached also is a disassembly of the resultant xe file. Any clues?
EnvisicONFILoader.xc
CopyCode.S is as follows:
.text
.align 2

// void CopyCode(int nJumpLoc, int nCodeLen, unsigned short uBinArr[])
// r0 is the jump/copy address
// r1 is the code length
// r2 is the source array
// r3, and r11 do not need to be saved by the callee
.globl CopyCode
.align 2
.type CopyCode,@function
.set CopyCode.nstackwords,0
.globl CopyCode.nstackwords
.cc_top CopyCode.function
CopyCode:

sub r1, r1, 1
ld16s r3, r2[r1]
st16 r3, r0[r1]
bt r1, CopyCode

bau r0
retsp 0
.cc_bottom CopyCode.function
CopyCode.h


The makefile could not be attached, so here it is:


# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET = XS1-U8A-64-FB96-C5

# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME = EnvisicONFILoader

# The USED_MODULES variable lists other module used by the application.
USED_MODULES =

# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS_Debug = -O0 -g
XCC_FLAGS_Release = -O3 -g

XCC_MAP_FLAGS_Debug = -nostdlib --bootable
XCC_MAP_FLAGS_Release = -nostdlib

# The VERBOSE variable, if set to 1, enables verbose output from the make system.
VERBOSE = 0

XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common



The XN file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xmos.com http://www.xmos.com">
<Type>Device</Type>
<Name>XS1-U8A-64-FB96-C5 Device</Name>
<Declarations>
<Declaration>tileref tile[1]</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS1-UnA-64-FB96">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS1-L8A-64" SystemFrequency="500MHz" ReferenceFrequency="100MHz">
<Tile Number="0" Reference="tile[0]"/>
</Node>
</Nodes>
</Package>
</Packages>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>
You do not have the required permissions to view the files attached to this post.
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Oops, forgot to attach the disassembly file!




EnvisicONFILoader.xe: file format: xcore-xe

Loadable 1 for tile[0] (node "0", tile 0):

text data bss total
46 120 0 166

Disassembly of section .text (size: 46)

<_start>:
0x00010000: 41 77: entsp (u6) 0x1
0x00010002: 00 f0 15 d8: ldap (lu10) r11, 0x15 <.label0>
0x00010006: fb 37: set (1r) cp, r11
0x00010008: 00 f0 14 d8: ldap (lu10) r11, 0x14 <.label1>
0x0001000c: eb 37: set (1r) dp, r11
0x0001000e: 00 f0 00 6c: ldw (lru6) r0, cp[0x0]
0x00010012: 00 f0 80 60: ldaw (lru6) r2, dp[0x0]
0x00010016: fa 68: ldc (ru6) r3, 0x3a
0x00010018: 1c 90: add (2rus) r1, r3, 0x0
0x0001001a: 00 f0 01 d0: bl (lu10) 0x1 <CopyCode>
0x0001001e: c1 77: retsp (u6) 0x1

<CopyCode>:
0x00010020: 15 98: sub (2rus) r1, r1, 0x1
0x00010022: 39 80: ld16s (3r) r3, r2[r1]
0x00010024: 31 f8 ec 87: st16 (l3r) r3, r0[r1]
0x00010028: 45 74: bt (ru6) r1, -0x5 <CopyCode>
0x0001002a: f0 27: bau (1r) r0
0x0001002c: c0 77: retsp (u6) 0x0

Disassembly of section .cp.rodata.cst4 (size: 4)

<.CPM0>:
.label0 0x00010030: 00 b0 01 00:

Disassembly of section .dp.data (size: 116)

<_dp>:
<uBinArr>:
.label1 0x00010034: 41 77 00 f0:
0x00010038: 2b d8 fb 37:
0x0001003c: 00 f0 32 d8:
0x00010040: eb 37 00 d0:
0x00010044: 43 77 02 55:
0x00010048: 41 55 80 55:
0x0001004c: c1 86 01 e8:
0x00010050: c4 b6 00 f0:
0x00010054: 80 58 dd a6:
0x00010058: 00 f0 c0 6e:
0x0001005c: 00 69 00 f0:
0x00010060: 41 6d ce ae:
0x00010064: e7 14 18 17:
0x00010068: 09 e8 08 b7:
0x0001006c: 02 af 55 12:
0x00010070: d4 16 09 e8:
0x00010074: 08 b7 0b 77:
0x00010078: 00 f0 02 6c:
0x0001007c: 08 e8 00 f0:
0x00010080: 46 68 d4 fe:
0x00010084: ec 0f c0 77:
0x00010088: 00 f0 02 6c:
0x0001008c: 00 e8 c0 77:
0x00010090: 00 2d 31 01:
0x00010094: 00 5a 62 02:
0x00010098: 00 0b 01 00:
0x0001009c: 44 b0 01 00:
0x000100a0: 54 b0 01 00:
0x000100a4: 00 0b 01 00:
GerhardNorkus
Active Member
Posts: 55
Joined: Wed Jan 05, 2011 2:15 pm

Post by GerhardNorkus »

Oh yeah, I forgot also to explain about the injected code. After compiled, I split it out of the xe using:

xobjdump --split FlashExample.xe

I then created a binary to text program in visual C++ to convert the bin file dumped out to what you see in the EnvisicONFILoader.xc file.

This code should work on any XK-1A or XS1-SU1 board. It will flash the XS1_PORT_1L pin. I've used it on several different boards and they all behave the same.

Again, the purpose of this question is to find out if there is a keyword I can use to force _start to always appear as the first function in the binary generated...
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

Hi Gerhard,

All binaries generated the usual way have the entrypoint
at their lowest address. That is, to get anything else you
have to do things that you would not do by accident ;-)