Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

Flash programmer via ethernet

Altera_Forum
Honored Contributor II
3,392 Views

Now that I have ethernet working on my custom board, I'd like to use it to update the board, or at least the flash memory. It is mentioned in the existing board kit docs that board updates via http are somehow supported. Etherblaster is also a setting in one of the dialogs. Rather than reinvent the wheel, is there some existing code or feature I missed about this? 

 

If I rebuilt the flash programmer project to include ethernet, what else would I need to come up with to make it work?
0 Kudos
29 Replies
Altera_Forum
Honored Contributor II
1,752 Views

Hi, im trying to do something similar ... did you manage to resolve this? What sort of progress have you made on this?

0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

also take a look at the nios ethernet development kit (http://digital5.ece.tntech.edu/public/altera/books/ug/niosedk.pdf) doco for more information ...  

i do hope that this is possible
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

It sounds like what you're looking for is a boot monitor that supports remote upgrade over ethernet. There's a couple of different monitors available for Nios II. The one I'm most familiar with is Redboot, which is supplied as a part of the eCos operating system. This includes the features you're asking for. There is also a port of UBoot available which I believe will do the same job. Both of these are available for download through this forum.

0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

> There is also a port of UBoot available which I believe will do the same job 

 

Yes, u-boot supports file download via tftp, NFS, serial (kermit/SREC),  

and flash programming ... along with the associated support for BOOTP/DHCP, 

ping, netconsole, etc. 

 

u-boot however, is purely "pull" model for file download ... i.e. all download 

activity is initiated on the target via command line interface. So a "remote" 

upgrade would require u-boot to be configured with netconsole suport, or 

you'll need remote access to the serial/JTAG-uart port. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Halfway thru writing my own ethernet downloader, I decided to check out the alternatives. 

 

The Redboot docs indicate that no port exists for Nios boards. If someone has one, maybe they could post it. 

 

u-boot looks more promising. I was able to build for the "PK1C20" board configuration, and it can download and partially run on a 1S10_ES kit board I have. The console works but the ethernet does not, so there must be some critical differences between these boards.  

 

The image is smaller than I expected at ~100kB. This is probably smaller than my own downloader code, but with more features.  

I'd like to see it fully working on the 1S10 board before I spend my days porting u-boot to run on my custom board (The README is rather large). Does anyone know of more ports available or what I need to change to get it fully working on my kit board?
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Hi tns1, 

 

> The Redboot docs indicate that no port exists for Nios boards. If someone 

> has one, maybe they could post it. 

 

Redboot is included with ecos. 

 

> The image is smaller than I expected at ~100kB. This is probably smaller than my 

> own downloader code, but with more features. 

 

You can reduce the size further by eliminating features you don't need. This is done in 

the board's config file. For the PK1C20, the config file is include/configs/PK1C20.h. 

For example, you can exclude the hush parser (scripting) and long help: 

Undefine CFG_LONGHELP and CFG_HUSH_PARSER. 

 

> The console works but the ethernet does not 

 

Please provide some details. 

 

> Does anyone know of more ports available or what I need to change to get it fully 

> working on my kit board? 

 

Unfortunately, I don't have a 1S10 board to test with. But here are some things you 

might want to check: 

 

1. Make sure your ethernet environment variables are set correctly. Here's a list variables 

you may need to modify/create: 

-- serverip - ip address of the tftp server 

-- netmask - you're network's netmask 

-- gatewayip - the ip address of the primary gateway (if needed). 

 

2. Before trying tftpboot, use the ping command to test connectivity. 

 

3. In include/configs/PK1C20.h: 

-- check the ethernet macros to make sure they're correct (for the 1s10 board). 

E.g. CONFIG_SMC91111_BASE etc. 

-- check the timer macros (CFG_NIOS_TMRxxxx) -- you may be timing out early. 

 

4. In drivers/smc91111.c change the SMC_DEBUG macro to 3. This will provide lots of debug 

output to the console. 

 

5. Finally, you can review the config files for the Nios-32 port (DK1C20.h and DK1S10) for 

some clues. But be warned .... the Nios-32 config files have been confounded by a well 

intended, but poorly executed attempt at making things flexible ;-) 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Thanks Scott, 

I found my main problem was those env variables. The 1S10_ES kit board (DK1S10?) must be very close to the PK1C20 configuration since most things are working. I have tested downloading images to this board using srec over serial, binary over serial and tftp (after installing the free solarwinds tftp server). I burned u-boot into the board using u-boot itself as in the USING directions.  

 

u-boot is pretty slick. It give you most of the features you would want from a boot monitor program. I have not been able to download and run the supplied hello world example, though. I used the "loads" and it did load, but a "go 800000" just seems to reboot u-boot. The example output is supposed to appear in the u-boot console window isnt it (not the jtag uart or debug port) ? 

 

It would be nice to have the following: 

A way to connect to the u-boot console over ethernet. As you mentioned, u-boot downloads are "pull" model, but if I could use telnet or ssh to get to the console, it would be exactly what I am looking for.  

 

A command that tells you where u-boot is executing from, and what system resources it is using. This is not very clear. 

 

A little more description for the configuration options. The custom board I need to port to has a different memory map and no SDRAM bank. It is not clear if I simply remove CFG options, and what option controls where u-boot relocates to.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Hi tns1, 

 

Glad to hear things are working :-) 

 

> I have not been able to download and run the supplied hello world example, though. 

 

This is currently broken. The global pointer is not being handled properly ... I'll add 

it to the TODO list ;-) 

 

> A way to connect to the u-boot console over ethernet. 

 

You could try configuring "net console" ... which basically sends console output to 

a particular ipaddr:udp port (and accepts input on a particular port). I haven't tried it yet. 

If you need some help you can post questions on the u-boot-users mailing list. 

 

> A command that tells you where u-boot is executing from, and what system resources 

> it is using. 

 

There are a few commands that might have some of the info you need: "bdinfo", "flinfo", "irqinfo". 

It's very easy to add custom commands to get precisely what you need using the 

U_BOOT_CMD macro. You can see common/cmd_misc.c for some examples. Just implement 

your custom commands in your board-specific directory. 

 

> The custom board I need to port to has a different memory map and no SDRAM bank. 

 

Not a problem. You _should_ be able to just customize the macros in your board's 

config file. 

 

> A little more description for the configuration options. 

 

Most of the configuration options are described in the main README (although several 

are admittedly a bit short on details). There is also some additional information in the doc 

directory ... and lots of info that may be useful at: 

 

http://www.denx.de/twiki/bin/view/dulg/manual (http://www.denx.de/twiki/bin/view/dulg/manual

 

> It is not clear if I simply remove CFG options, and what option controls where u-boot 

> relocates to. 

 

For basic memory macros, you should leave them defined with a length of zero. The relocation 

address is controlled by the TEXT_BASE definition in the board-specific config.mk file. 

See board/psyent/pk1c20/config.mk for example. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Scott, 

Thanks for the help so far. I have u-boot up on my custom board, but have run into a few things.  

 

I needed to add# if defined() for the SDRAM init portion in board.c, since I have none. 

My niosII has no cache so I have set those CFG entries to 0. 

I discovered that once you have built, you cannot copy the source tree to another folder and rebuild. There are some absolute paths created by the make that are not cleaned.  

 

All I have is 2MB of ram @ x800000, and I would like to keep at least the lower MB clear for application downloads. It looks like u-boot consumes about 6 sectors (64k*6=384k) in the default configuration once you add up all the link sections, so I set TEXT_BASE for the upper 2 sectors.  

It does load & run, but I have found thru memory testing that u-boot still keeps a few necessary objects in lower memory. Most notably, there are vectors at x800020 even though my CFG_RESET_ADDR and CFG_EXCEPTION_ADDR are both set much higher. Also more than one item in x830000 - x900000 region. I haven't yet found why these objects are there and or how to fix it.  

 

My ethernet does not work with the default driver, but it is using a 16bit interface so I expected some fixing would be needed there.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Hi tns1, 

 

Glad to hear you have u-boot running on your custom board. 

 

When you say you have only 2 MB ram, and that the size of your u-boot image is 

about 384k, I'm guessing you're using your elf file on a ROM-less target with the epcs 

bootloader ... correct? Or do you have some (parallel) flash? 

 

Other than relocating itself to TEXT_BASE, the only other code that is copied when 

u-boot starts up is the exception trampoline, which is copied to CFG_EXCEPTION_ADDR. 

This is a very small piece of code (3 instructions) that simply jumps to the exception handler 

(see cpu/nios2/start.S -- "_except_start"). This allows you to set TEXT_BASE 

anywhere in RAM (not just at exception address - 0x20). 

 

The u-boot "global data" struct, the heap, and the stack are placed immediately below 

TEXT_BASE (see include/configs/PK1C20.h -- CFG_MALLOC_BASE, CFG_SP_INIT, etc). 

All of which is configured to be about 128k for the PK1C20. 

 

Other than the above, the only thing that extends below the heap is the stack. So you 

shouldn't be seeing any memory use at the base of your ram. If TEXT_BASE is set to 

0x009c_0000, for example, you shouldn't see anything (other than the stack) below 

say, 0x009a_0000. 

 

What address are you using for TEXT_BASE, and exception/reset? 

 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Scott, 

 

My system has the same 8MB flash device as the PK1C20 at 0x0, and 2MB sram at 0x800000. My HW has already been fully tested under uCos, and I thought the bootloader functions would be a nice addition. 

 

The download image is the same size (90KB) as the PK1C20 consuming 2 sectors of flash. The ram usage described in the CFG settings is roughly: 128K of relocated code, 64K of env space, 128K of heap, plus whatever stack space say 64K. This all adds up to 384K of RAM in rough numbers. I was saying sectors before, but of course this is ram so it is not quite so bad. The code does not fill up the entire 128K, and the stack wont use up the entire 64K. Probably closer to 300K actual ram use. If I am missing something, let me know. 

 

I have not burned u-boot into my flash on this board. I have download u-boot over jtag to get it running, but have been unable to use u-boot to download an image of itself for flashing because this step crashes.  

 

My TEXT_BASE is 0x9D0000, so I would expect no u-boot use below 0x9A0000 (256K). When I do a mw.b for the memory from 0x800000 to 0x9D0000, u-boot crashes (locks) apparently because I am writing over some parts it is actively using. There are two regions. First, I see three long words at 0x800020 that I verified with objdump are the trampoline instructions you mentioned, but writing over them causes u-boot to either reset, lockup or stop working correctly (depends on which one I write over). If I understand the trampoline, it is only using during relocation, and it should&#39;t matter what happens to that memory afterwards. Also my <myboard>.h file I created defines CFG_EXCEPTION_ADDR to be x900020. Isn&#39;t this where the trampoline should be? 

 

Likewise there is a region from x8cfa00 - x8d0000 (~1500 bytes) that seems to be a critical area of some kind. When I try to write over this region I get a lockup. A subsequent download and md shows this region to be unchanged as if it were .data or vector table. Lots of xdeadbeef entries in the region.  

 

Hmm.. I don&#39;t think I am getting a good build. I see some inconsistent behavior. The prompt doesn&#39;t appear after the splash screen when I re-download after a crash as if u-boot were not inited properly.  

 

Some things I have changed: 

TEXT_BASE 0x9D0000 

CFG_RESET_ADDR 0x900000 

CFG_EXCEPTION_ADDR 0x900020 

CFG_NIOS_TMRMS 1 

base addresses for uarts etc are different in general 

I started with u-boot 1.1.2 src.  

 

If I change the first three to 0x900000, 0x800000, 0x800020 I get more consistent behavior, but I still cant use the lower memory.  

 

BTW the netconsole stuff appears to be just stubs.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Hi tns1, 

 

> When I do a mw.b for the memory from 0x800000 to 0x9D0000, u-boot crashes (locks) 

> apparently because I am writing over some parts it is actively using. 

 

Yes, you&#39;re overwriting the stack and the heap. 

 

> First, I see three long words at 0x800020 that I verified with objdump are the trampoline 

> instructions you mentioned, but writing over them causes u-boot to either reset, lockup or 

> stop working correctly (depends on which one I write over).  

 

If this is the case, your exception address is probably 0x800020. When the timer interrupt 

fires and the exception is taken, the core executes corrupted code. 

 

> Also my <myboard>.h file I created defines CFG_EXCEPTION_ADDR to be x900020. Isn&#39;t this 

> where the trampoline should be? 

 

There are two critical macros that must be correct in your config file: CFG_RESET_ADDR and 

CFG_EXCEPTION_ADDR. These _must_ match your hardware configuration (cpu settings in SOPC builder). 

The u-boot build process is not very sophisticated -- this is good and bad. The good part is that it&#39;s 

simple -- you only need a shell and the cross-development tools to build it -- no interactions with an 

IDE, etc -- you can edit & control the whole process with a text editor. The bad part is, well ... 

it&#39;s simple ;-) so it won&#39;t automagically update the config file for you (or warn you) when your config 

file doesn&#39;t match your actual hardware. 

 

> If I understand the trampoline, it is only using during relocation, and it should&#39;t matter what 

> happens to that memory afterwards. 

 

Correct. The trampoline gets copied to CFG_EXCEPTION_ADDR when u-boot relocates itself. 

This allows u-boot to stored at the reset address (e.g. flash) or any other arbitrary address. 

When u-boot begins execution, it copies itself to TEXT_BASE (ram) and jumps to the relocated 

u-boot image. After a few more initializations (e.g. clearing bss, etc), u-boot checks to see if the 

trampoline is at the proper exception address. If it&#39;s not, it copies the trampoline to 

CFG_EXCEPTION_ADDR. The trampoline code does nothing more than jump to u-boot&#39;s 

exception handler. 

 

NOTE: In some cases, the trampoline does not need to be copied. This would be the case 

when TEXT_BASE is set to the exception address minus 0x0020 -- since the trampoline code is 

conveniently located at the start address + 0x0020 it&#39;s already where it needs to be.  

 

> If I change the first three to 0x900000, 0x800000, 0x800020 I get more consistent behavior, 

 

Yes, this makes sense. This would indicate that your actual hardware configuration has the 

exception address set to 0x80_0020. BTW: the "irqinfo" command shows the timer interrupt 

count. The count should be incrementing if everything is operating ok. 

 

> but I still cant use the lower memory.  

 

I had a similar problem since I mapped the low-end of SDRAM into a PCI window. When the 

host cleared the memory, my core would basically lock up once the timer interrupt fired. 

(It would simply execute jmp 0). The solution was to define a small section of on-chip 

RAM (0x40 bytes) and set the exception address to offset 0x20 in this memory. This kept 

SOPC builder happy, and prevented the host from trashing my interrupts ;-) 

 

> I have been unable to use u-boot to download an image of itself for flashing because this 

> step crashes. 

 

I believe this is all related -- the downloaded image is probably corrupting the trampoline, 

the heap, or the stack. Based on your ealier comments, you&#39;re probably downloading to 

0x80_0000 for subsequent copy into flash. This overwrites the trampoline and causes a 

crash once the timer interrupt fires. 

 

> My HW has already been fully tested under uCos, and I thought the bootloader functions 

> would be a nice addition. 

 

Absolutely ... and I&#39;ll do my best to help you get there :-) Once things are stable, I think you&#39;ll 

really enjoy the more "interesting" features like cramfs/jffs2 support and scripting. 

 

Try the following: 

 

1. Add some on-chip memory and set the exception address to offset 0x20 in the memory. 

2. Update you config file with the actual reset/exception addresses from SOPC builder. 

3. Rebuild u-boot and strip the elf. 

4. Determine the actual u-boot size using objdump and set TEXT_BASE appropriately. 

5. Rebuild. 

 

Hope this helps, 

--Scott 

 

PS: 

 

> I discovered that once you have built, you cannot copy the source tree to another 

> folder and rebuild.  

 

use &#39;make distclean&#39; prior to copying the source tree -- it should remove any absolute 

path references. In the new tree you&#39;ll have to make xxx_config again though.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

OK, now that I understand things better I have it flashed and running. I&#39;ve added the map info to the bdinfo cmd like so: 

 

==> bdinfo 

flash start = 0x00000000 

flash size = 0x00800000 

flash offset= 0x00000000 

sram start = 0x00800000 

sram size = 0x00200000 

ethaddr = 01:00:00:00:00:00 

ip_addr = 192.168.1.113 

baudrate = 115200 bps 

 

reset addr = 0x00000000 

except addr = 0x00800020 

monitor size= 0x00020000 

monitor base= 0x009D0000 

heap size = 0x00030000 

heap base = 0x009A0000 

env size = 0x00010000 

env base = 0x009A0000 

globals size= 0x00000080 

globals base= 0x0099FF80 

stack top = 0x0099FF80 

==> 

 

Of course now that I have it working I&#39;ll probably never need the info http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/wink.gif  

 

My ram is free from 800100 to at least 99F000 

 

Now to get the ethernet working.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Scott, 

Got the ethernet up. On my custom board the lan chip is wired up differently than the kit; 16bit interface but with registers on word boundaries. Apparently the same as existing ADNPESC1 configuration. 

 

Now I can ping and tftpboot. One quirk is that tftpboot hangs after the download. It does not report the bytes transferred or return to a prompt. By resetting and doing a cmp, I can tell the download was correct and proceed to burning flash. The same thing also happens with loadb, so its not an ethernet problem. I dont get the prompt back with loads either. I am using an offset of 801000 and image sizes too small to collide with anything.  

 

On the kit board I did not have these problems. Any ideas? 

 

You mentioned the timer earlier. I had originally set CFG_NIOS_TMRMS to 1 thinking I had to match the default hw. I changed it back to 10 after reading the comments.  

 

thanks again
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Solved it.  

Since I have no cache at all, I had set all the cache CFG macros to 0. This will cause cache_flush routine to hang. I set the macros back to the PK1C20 defaults and all the downloads finish properly. I guess it does not matter that I have no cache.  

 

As far as I can tell, u-boot is working on both boards now. If anyone you would like the mods for the DK1S10(NiosII), let me know.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Great to hear everything is working now. So now you play with scripting. E.g. -- 

automatically attempt an NFS download and execute the download on success, 

otherwise jump into flash ;-) 

 

Some notes: 

 

> I had originally set CFG_NIOS_TMRMS to 1 thinking I had to match the default hw. 

 

The timer stuff can be confusing. The two most important macros are: 

 

cfg_nios_tmrms -- number of milliseconds between each timer interrupt. 

cfg_hz -- the frequency of the timer interrupt. 

 

The two are of course redundant, but they&#39;re both defined to encourage using the 

preprocessor for divide/multiply where possible. 

 

Sine the Nios timer may be configured with/without the period registers, another 

macro, cfg_nios_tmrcnt is used. If this macro is defined, the value is 

written into the timer&#39;s period registers when u-boot starts, but is otherwise 

never referenced. If the macro is not defined, the period registers are never 

accessed, period. The intent of CFG_NIOS_TMRCNT is to allow users to slow down 

the interrupt rate when the period is programmable. A 1 ms rate is (normally) 

overkill in a boot monitor. 

 

Since I have a tendency to misplace the decimal point, I use the sleep command 

to do a sanity check. Try for example, "sleep 10" while looking at your watch ;-) 

 

BTW: the timer macros are (indirectly) used by most of the network protocol 

modules, and by the flash programming code. 

 

>I guess it does not matter that I have no cache.  

 

Correct, the cache instructions behave as NOP when no cache is configured -- so 

the bogus instructions do little more than add an unnecessary delay loop when they&#39;re 

left in the code. 

 

After downloading, u-boot invalidates the region that was loaded (both data and 

instruction caches) to ensure everything is coherent.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

For my custom board, I finally got around to putting u-boot and my C application both in the flash. With just u-boot in the flash, it would start up when the board was powered. With both in the flash, my app starts up instead - not what I expected.  

My flash is 0x0 to 0x800000. My sram is 0x800000 to 0xA00000. My reset vector is 0x0. My exception vector is 0x800020. 

u-boot is flashed at 0x0 and linked to run at 0x9d0000. My app image is flashed at 0x400000 and linked with the default NiosII bootstrap to run at 0x800000. I used u-boot to flash both images and verify the locations (not the IDE flash programmer), so I they should be where I think they are.  

 

The u-boot boot process seems to be start.S -> board_init() -> main_loop(). As far as I can tell, when I power cycle my board board_init() is never reached and my app is loaded and executed instead. If I erase the section of flash where my app resides, then u-boot begins normally again. I don&#39;t see anything in start.S that would explain this behavior. Somehow it is jumping to some location below the app image in flash (0x400000) and above the u-boot image in order to invoke the app bootstrap routine.  

 

To test, I load u-boot over jtag and made sure to clear sram before my tests so I am not accidentally re-executing previously loaded code. I can then try one of: 

==> go 0 ;starts u-boot (the go bug is fixed)  

==> reset ;starts u-boot 

(power cycle) ;app starts 

==> go 400000 ;app starts 

 

I see that u-boot has all kinds of options related to autobooting of images, but I don&#39;t think they are enabled. I should at least get to main_loop() and see some u-boot prompt before this happens anyway. I&#39;ve a few more things to try before I gut my project to make room for the hw debugger, but would appreciate any insight.
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

Hi tns1, 

 

> I can then try one of: 

> ==> go 0 ;starts u-boot (the go bug is fixed) 

> ==> reset ;starts u-boot 

> (power cycle) ;app starts 

> ==> go 400000 ;app starts 

 

This looks like your reset address is set to 0x40_0000. If &#39;go 0&#39; and &#39;reset&#39; 

correctly starts u-boot (they&#39;er basically the same) ... then a POR with the 

reset address set to 0 will behave identically. Better double-check your 

config in SOPC builder ... or better, your ptf file reset_slave/reset_offset. 

 

You might want to try flashing the app at 0 and u-boot 0x40_0000 as well. 

 

> I should at least get to main_loop() and see some u-boot prompt before 

> this happens anyway. 

 

Agreed ... that&#39;s why I don&#39;t think the u-boot entry point is being called at all 

for POR. 

 

BTW: Did you move to Quartus 4.2? Or are you still at 4.1? I haven&#39;t installed 

the upgrade yet ... too close to finishing a job ;-) 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,752 Views

I am sticking with Q4.2 and NiosII1.01 until the dust clears.  

 

SOPC says my reset address is in flash at 0x0 with offset 0x0. 

 

The ptf agrees with this.  

CPU_RESET_ADDRESS is 0x0,  

reset_slave = "flash/s1"; 

reset_offset = "0x00000000"; 

 

The board is working HW and has displayed no flakeyness while running, but POR is always special. 

 

I have created a stripped down project that includes the fs2 module which should allow me to step thru the flashed start.S.  

This required moving from the e core to the s core so now I have a cache to think about. I am hoping I will see an incorrect  

jump early in the code to explain this behavior. If the bug only occurs for a real power cycle and not a soft reset, I wont see it in the  

debugger and will instead have to probe the buses directly. I don&#39;t have debug headers for these buses - any signaltap gurus out there? 

I&#39;ll have to make sure to disable cache so all cycles are visible.  

 

I&#39;ll swap the code locations as you suggest before I dive in.
0 Kudos
Altera_Forum
Honored Contributor II
1,701 Views

whoops, i meant Q4.1, not Q4.2.

0 Kudos
Reply