Nios II Legacy SDK Support

The Nios® II development kit version 5.1 and prior include support for software development kit (SDK) generation. Legacy SDK support is not available in Nios II Embedded Design Suite (EDS) version 6.0 and later.

SDK generation provided backward compatibility for Nios (as opposed to Nios II) users who did not wish to alter their source code to be compatible with the hardware abstraction layer (HAL) support provided natively in Nios II processors. New features introduced in Nios II processors, associated peripherals and tools, and SOPC Builder are not available in the legacy SDK. Only Nios features are carried forward. New peripherals such as the JTAG UART, hardware mutex, and the SOPC Builder Component Editor have no legacy SDK support.

Altera strongly encourages Nios II users to migrate their software source code to the HAL using the instructions provided in Upgrading Nios Processor Systems to the Nios II Processor (PDF).

GERMS Monitor for Nios II

This Nios II software template provides the Nios Go-Erase-Relocate-Memory-S-record (GERMS) monitor functionality for Nios II users. GERMS is a simple, compact program that can serve as monitor for Nios II systems that include:

  • A UART (JTAG or Serial)
  • 1Kbyte of on-chip memory implemented in M4K or M512 blocks
  • The reset address set to the memory in which the GERMS monitor will reside

The GERMS monitor for Nios II is available in the Downloads -> Post Your Own IP Section of the Nios Forum.

Known Issues & Workarounds

For those with projects still using the Nios II legacy SDK, the known problems and workarounds to these problems are described below.

C "Stub" Routines

The Nios SDK included C “stubs” with low-level routines that are usually provided independently of the GNU toolchain/library distribution. A comprehensive list of these routines appears below. In Nios II processors, the routines were omitted. In lieu of this, the nios2-build linking method used the GNU toolchain’s “nosys” libraries providing basic (if not empty) implementations of these routines.

C “stub” routines present in Nios SDK and not present in Nios II legacy SDK:

  • write
  • read
  • sbrk
  • :malloc_lock
  • :malloc_unlock
  • :env_lock
  • :env_unlock
  • isatty
  • lseek
  • _exit
  • close
  • fstat
  • kill
  • getpid

The following operations will not operate properly in the Nios II legacy SDK:

Please note that many users with simple source code will see little if any impact as a result of this issue. In fact, all of the examples provided with the legacy SDK will function without these stubs.

The Nios SDK support for these stubs did not include complete stub implementations. Many of these routines were “do nothing and return zero” implementations provided only to ensure no linker warnings. Notable exceptions include read() and write() that were implemented to communicate with the Avalon™ UART peripheral only, to provide minimal support for routines such as printf and scanf, and sbrk to support bounds checking when malloc was called.

Note: The intent of the Nios II HAL is to provide a much more comprehensive set of these stubs for true UNIX-style I/O to a wide range of peripherals.


The Legacy SDK Patch contains C library “stubs” containing most of the functionality present in the Nios SDK. The only exception is sbrk, which is implemented, but without memory bounds checking. The patch includes an updated nios2-build script and example makefile illustrating the linker changes required for this fix. Refer to the patch_readme.txt for instructions on applying the patch.

Download Legacy SDK Patch

The patch also corrects three other issues described below:

Note: This patch will provide no support of C stubs beyond what existed in the original Nios SDK. If additional support is needed in this area it is recommended that you migrate to the Nios II HAL. Refer to Upgrading Nios Processor Systems to the Nios II Processor for details.



When building applications using nios2-build or the peripheral_test application’s example Makefile, libraries to be included for linking are specified as follows: “-l <library name>” (note the space between –l and the library name). The GNU linker documentation does not recommend including this space. While this operation is violating recommended practices, no known issues have been reported because of it to date.


The Legacy SDK Patch modifies nios2-build and the peripheral_test example application’s Makefile to link. Refer to the patch_readme.txt for instructions on applying the patch.

Legacy SDK Patch


The sbrk() routine supplied with the legacy SDK “nosys” library does not support bounds checking. This means that an application’s call to malloc() requesting more memory than is physically available may successfully return a pointer, rather than NULL as malloc() should. This issue will affect users who rely on malloc() to see whether a requested memory buffer size is available.

  • Users can write their own sbrk() implementation and use that with the Legacy SDK Patch.
  • The excalibur.h and excalibur.s files included in the legacy SDK have start/end addresses of data memory. You can calculate, at runtime, the amount of system memory available so that malloc() is not called requesting “too much” memory. If you use this workaround, you must check the size of your program using nios2-elf-size and calculate the amount of stack space your application will consume prior to using this workaround. The amount of stack space consumed must be subtracted from the total data memory.

The software engineer may call malloc() with care and with a knowledge of the memory available in the system. Calling malloc() will work correctly provided that the amount of memory requested is available between stack and heap at runtime.


Nios II Legacy SDK Flow & Reset Address

Legacy SDK systems may fail to boot when developing systems that will boot automatically, or power up where Nios II CPU reset is held pending program memory initialization. This occurs because the linker script generated by the legacy SDK, using the default legacy SDK settings presented in SOPC Builder, will not place boot code at the CPU reset address automatically.

This issue affects systems that boot automatically and is not likely to be seen in the early stages of development or debug where code is downloaded and jumped to with nios2-run or nios2-download utilities.


A simple workaround that directs the legacy SDK to link boot-code to the reset address can be performed in SOPC Builder as follows:

  1. Navigate to the “More <Nios II CPU name> Settings” tab in SOPC Builder
  2. Place the Nios II CPU’s reset address at the base of the memory where you wish to boot from.
  3. Place program memory at the base of the above memory.
  4. Place your exception address at the top of your memory minus 0x80.

The above settings mimic the memory map used in the Nios SDK and allow the legacy SDK linker script to place boot memory at the reset address of the CPU as desired. A warning message has been added to SOPC Builder when the legacy SDK is enabled, advising you to perform the above steps.

SPI Peripheral Register Definitions & Drivers

Legacy SDK systems that include one or more instantiated Avalon SPI peripherals will not have the SPI register definitions defined automatically in excalibur.h or excalibur.s. In addition, the legacy SDK drivers to send and receive SPI data are not present in the SDK/lib folder. As a result, Nios code that used the supplied SPI drivers will not function.

  • To enable SPI register access as present in excalibur.h, copy the spi_struct.h (for C/C++ development) or spi_struct.s (for assembly development) file from the <Nios II installation>/components/altera_avalon_spi/sdk folder to the folder containing your source code, and then include the file in your source code. A struct can then be created as usual, pointing to your SPI peripheral’s base address as defined in excalibur.h/excalibur.s
  • To utilize the SPI driver routines present in Nios processors, the assembly files defining these drivers must be re-written, as Nios II processors are not instruction-set compatible with the Nios processor. The drivers are located in the <Nios II installation>/components/altera_avalon_spi/sdk/lib folder. Alternatively, check for the patch resolving this issue for updated Nios II processor-compatible drivers.
  • Migrate to the Nios II HAL, which supports the SPI peripheral and includes device drivers.


“Full” printf()

The legacy SDK includes support for two forms of printf():

  • nr_printf(): a small version designed for low memory use that does not support printing floating point numbers
  • Full GNU printf()

The excalibur.h and excalibur.s files “re-map” (via #define) nr_printf() to printf(), so that calling printf() in user application code will call the “small” printf().

Due to the lack of C stub routines, the low-level read() and write() routines necessary for “full” printf() to send output to STDIO (the UART peripheral) are not present. As a result, users who wish to use the full GNU printf() will not see any output on STDOUT.


The patch below corrects this problem by providing the read() and write() routines as part of the SDK. With these routines present, “full” printf() functions normally. Refer to the patch_readme.txt for instructions on applying the patch.

Legacy SDK Patch

C++ Constructor

Calling a C++ constructor locally (in a subroutine) will generate build warnings and the constructor will not be called as intended. Consider the following example:

a a1(1);

int main(void)
printf("This is a cpp test\r");

a a2(2);

a1.print(); /* This call will print out “1” correctly */
a2.print(); /* This call will not print out “2” correctly */


To work around this issue, declare your C++ constructors globally. For example , the code above could be modified to the following:

a a1(1);

a a2(2);

int main(void)
printf("This is a cpp test\r");

a1.print(); /* This call will print out “1” correctly */
a2.print(); /* This call will print out “2” correctly */


Insight Debugger Displays Incorrect Values

During a debug session, pausing or halting the processor at a breakpoint causes a debug monitor to execute on the CPU. This monitor uses (and restores upon completion) the content of the r25, r30, and bstatus registers. Therefore, while debugging, the contents of these registers should be ignored.

This problem is not specific to the legacy SDK. It applies for debugging HAL-based systems in Nios II IDE as well.


Developers debugging assembly code should avoid the above registers. In addition, the Nios II application binary interface discusses which registers may be used by the assembly developer.

Insight Debugger Unable to Find Source for Some Library Functions

During a debug session, stepping into certain GNU library functions may result in an error because the source file cannot be located. This is because certain paths are omitted from the script that initializes the GDB debugger. However, the most library functions can be debugged, including the most commonly used routines.


No workaround is currently available.