This example is built on and requires Nios II 5.0 and Quartus II 5.0.
WARNING: This example probably does not work with later versions!
This example illustrates a boot loader methodology that does not adhere exactly to the default tool flow of the Altera Nios II IDE for application development.While every effort has been made to maintain the default flow, this boot loader example does require some minor manual manipulation outside the IDE in order to post process flash images for the example.
If you are not already familiar with the default application build proceedures and results for the Nios II IDE, I suggest that you read the Nios II Software and Hardware handbooks, run thru the software tutorials and familiarize yourself with the default operation of the enviroment before confusing yourself with this example that steps outside that default flow, and may be doing things that you have no interest in, and may confuse your understanding of how to use the default environment.
This example is intended for experienced Nios II users that may wish to create a more customized boot loader to start their systems with, and provide functionality beyond Altera's default environment.While this example attempts to identify and address most of the challenges with creating such a loader, do not assume that it covers all possible issues that may arise.
This example is packaged with the following materials:
1 - Source code for the boot loader application.
2 - Source code for a test application that the loader can load.
3 - Scripts for processing the application ELF image into an enhanced flash image.
4 - A PowerPoint slide set with some high level pictures representing the memory utilization throughout the execution of the example.
5 - This readme file.
All of these materials are heavily commented, and those comments are inherently part of the documentation of this example.
Simply put, this example creates a boot loader targeted to execute from external flash memory.Once the FPGA configures, the Nios II cpu jumps into the boot loader code in external flash memory.The boot loader examines flash memory at two specific offsets, 1M and 2M, looking for a special header that has been prepended to an application program for loading.If the special header is located in these images, then the loader will choose the latest revision image that is valid, and load that image into system memory and jump to it.The special header looks like this:
signature = 32-bit word, user assigned, intended to hold a signature used
to locate the header in flash memory
version = 32-bit word, user assigned, inteneded to hold a binary encoded
version identifier for the application
timestamp = 32-bit word, script generated, assigns the current time value,
the standard C time integer value, seconds since JAN 01, 1970
data length = 32-bit word, script generated, assigns the byte length of the
application data contained in the file
data crc = 32-bit word, script generated, assigns the crc32 calculated
across the entire application data
res1 = 32-bit word, user assigned, use is unspecified
res2 = 32-bit word, user assigned, use is unspecified
header crc = 32-bit word, script generated, assigns the crc32 calculeted
across the other 28-bytes of the header data
The scripts provided with this example will generate this header and prepend it to the application image, to make it a flash image.
Creating the Example
The following steps are how you can take this example and build up a system that runs it on a Nios II development board.
1 - Choose your favorite Nios II development board, connect a USB Blaster to it and power it up. (this exampel generally assumes that your dev board has an SDRAM like memory, along with a CFI flash memory, as most standard Nios II development boards should)
2 - Install the Nios II 5.0 and Quartus II 5.0 tools.
3 - Locate the "Standard" Nios II reference design for the dev board that you have.Copy the "standard" reference design to a new location so that you can modify it and build this example on it.
4 - Open the quartus project file for your copy of the standard reference design.
5 - Open the SOPC system in the project.
6 - This step has been omitted.
7 - This step has been omitted.
8 - Add a JTAG UART peripheral, accept the default settings.The name of this peripheral is very critical because there are references in the source code that rely on this name.The name I used is "download_jtag_uart".
9 - Select the Nios II More CPU Settings tab and verify that the reset vector points at the external flash memory with offset 0, and the exception vector points at the SDRAM with offset 0x20.You don't really need this to be offset 0x20, but there's no harm in it, and it creates a memory void that you could use for some interesting purposes as well.
10 - Now click Generate to generate the SOPC system.
11 - After the system generates, click on the Run Nios II IDE button in the System Generation tab of SOPC Builder.
12 - This should launch the Nios II IDE, create a new software project, Altera Nios II, C/C++ Application.
13 - Choose the "Hello World Small" template.
13 - Make sure that the Target Hardware selection is pointing to the PTF file for the system that we just generated.
14 - Choose a name for this project, I used "boot_loader_flash".
15 - Now click finish to create the software project for the boot loader.
16 - Open the software project directory and delete the "hello_world_small.c" source file.
17 - Copy the source file from this example into the software project directory.The file in this example is "boot_loader_src/flash_boot_loader.c", you can drag this file from an Explorer window and drop it on the project directory in the IDE while holding the CTRL key down, and this will copy the file for you.
18 - Open the properties page for system library and choose the "system library" section to edit.
19 - In the "system library" section we just need to adjust the memory sections and enable the system clock timer.The memory sections first, setup the memory sections like this: .text should go in "ext_flash", .rodata should go in "ext_flash" and .rwdata, heap and stack should go in "sdram".Now select the sys_clk_timer as the system clock timer.Ensure that the original jtag_uart is selected for the stdio device, not the download_jtag_uart that we added.
20 - Once the memory sections and system clock timer are changed you can close the properties page.
21 - Go ahead and build the boot loader software project, we need to get the auto generated alt_sys_init.c file for our own purposes.
22 - After you build the software project the first time, you should have an error complaining about not finding the function "my_sys_init".To fix this we copy the alt_sys_init.c file from the system library directory into our boot loader project directory.Drag and drop it with the CTRL key down from the "syslib/Release/system_description/alt_sys_init.c" location.
23 - Rename the alt_sys_init.c file to my_sys_init.c, in the boot loader project directory.
24 - Open your copy of my_sys_init.c and change the name of the function defined in there to my_sys_init from alt_sys_init.Then comment out all of the initialization and instance lines for all the peripherals except two, the SYS_CLK_TIMER and JTAG_UART.
25 - Close the my_sys_init.c file, saving the changes.
26 - Build the boot loader project again, this time the build should complete with no errors.
27 - Now go back to the SOPC Builder window and exit SOPC Builder.
28 - Go back to the quartus window, update the symbol, and compile the design.
29 - After the design compiles, you can close quartus.
30 - Go back to the Nios II IDE window, create a new software project, Altera Nios II, C/C++ Application.
31 - Choose the "Hello World" template.
32 - Make sure that the Target Hardware selection is pointing to the PTF file for the system that we just generated.
33 - Choose a name for this project, I used "loader_test".
34 - Now click finish to create the software project for the test application.
35 - Open the software project directory and delete the "hello_world.c" source file.
36 - Copy the source file from this example into the software project directory.The file in this example is "test_application_src/loaded_application.c", you can drag this file from an Explorer window and drop it on the project directory in the IDE while holding the CTRL key down, and this will copy the file for you.
37 - Go ahead and build the test application software project.It should build with no errors.The syslib properties should select the SDRAM memory for all code sections and the jtag_uart for the STDIO as well as setting the sys_clk_timer by default.If these settings are not set like this by default, then this example will not work as expected.
38 - Now to make things easier, we need to copy the directory from this example "flash_image_scripts" into the "Debug" directory of the test application project directory.The test application project directory will be in the Quartus project directory at "software/loader_test/Debug" assuming you chose the defaults and named your project "loader_test".Just use Explorer to make a copy of the scripts directory into that location.
38 - Now start a Nios II SDK shell and change directories to that same directory "<quartus_project_directory>/software/loader_test/Debug".
39 - Actually change directories into the scripts folder "cd flash_image_scripts" inside that directory.
40 - Now run the make_flash_image_script.sh script to convert the elf file into a binary flash image.Like this:
[SOPC Builder]$ ./make_flash_image_script.sh ../loader_test.elf
41 - After that script runs, you should see the files ../loader_test.elf.flash.bin and ../loader_test.elf.flash.srec in the directory above the scripts directory, i.e. Debug directory.
42 - If you'd like to see the structure of this binary file that was created, you can use the read_flash_image.pl script like this:
[SOPC Builder]$ ./read_flash_image.pl ../loader_test.elf.flash.bin
43 - Now we're ready to program the images into the board.Go back to the Nios II IDE window.
44 - Click on the original boot loader project in the project pane.
45 - Now run the Nios II Flash Programmer.Tools->Flash Programmer
46 - Click the NEW button to create a new Flash programmer configuration.It should automatically pickup the name of your boot loader project.
47 - Check the "Program software project into flash memory" option, we want to program the boot loader application into flash.Click the checkbox for "Program FPGA Configuration data into hardware-image region of flash memory", we want to put this image in the hardware configuration area so we have the right hardware for our software to run on.Then click the checkbox for "Program a file into flash memory", and browse for the loader_test.elf.flash.bin file that we created with the script.This binary file should be programmed at offset 0x00100000 in the flash.
48 - Now program the flash.
49 - After the flash programmer finishes, you can press the board reconfig switch.And the boot loader should boot and start blinking led 0.
50 - The boot loader and the test_application both print status messages out the JTAG UART.If you'd like to see that, go back to the Nios II SDK shell window and run nios2-terminal like this:
[SOPC Builder]$ nios2-terminal --cable=1 --device=1 --instance=1
51 - If you'd like to download a new binary flash image to the test application, you can start a second Nios II SDK shell window and change directory to a directory with a binary flash image in it, you can reuse the one we originally programmed, or create a new one if you'd like, a new one would be more interesting since the timestamp will make it look like a newer version.Then when the application prints it's startup message the next time, you can type this command to download a new flash image:
[SOPC Builder]$ cat -B loader_test.elf.flash.bin | nios2-terminal --cable=1 --device=1 --instance=0
This opens the binary file with the cat utility, and pipes it to the nios2-terminal program which connects to the download_jtag_uart instance and sends the data into the application.
The material in this wiki page or document is provided AS-IS and is not supported by Altera Corporation.