uClinux/Linux for NIOS


There is a web page http://www.alterawiki.com/ where you can find nice description about running Linux or uClinux on NIOS processor but for me-not experienced Linux user it was paint-full to run Linux fast as I want. So, I will try to show my steps in two branches successful and not successful.

At the beginning I was confused about differences between uClinux and Linux for NIOS as you see later they seems to be using the same uClinux-dist directory to make image. For experiment I used Terasic DE0 development board it has 8-Mbyte SDRAM quite enough. Operating system is CentOs-6  and gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) (try command in terminal: gcc -v) and Quartus 11 (without SP1).

At first place you may need to install Quartus (I used Subscription Edition) and NIOS II Embedded Design Suite (this one I used for test purposes). Personally I am using Virtual Box installed in to Windows XP, thus you may nod need to install Quartus on Linux, but I suppose it is worth to forget Windows and stay in Linux.

First I downloaded  http://www.niosftp.com/pub/linux/nios2-linux-20100621.tar this file which contains necessary sources and tried to compile Linux with MMU as desribed in http://www.alterawiki.com/ , but at the end of  building NIOS processor an error appears:

CC arch/nios2/lib/libgcc.o
In file included from /home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c:13:
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/longlong.h:1237:2: warning: #warning “Default c-implementation of umul_ppm”
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/longlong.h:1264:2: warning: #warning “Default c-implementation of __umulsidi3″
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/longlong.h:1327:2: warning: #warning “Using count_leading_zeroes in C”
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c: In function ‘__ashldi3′:
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c:52: warning: ISO C90 forbids mixed declarations and code
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c: In function ‘__ashrdi3′:
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c:78: warning: ISO C90 forbids mixed declarations and code
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c: In function ‘__lshrdi3′:
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c:105: warning: ISO C90 forbids mixed declarations and code
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c: In function ‘__udivmoddi4′:
/home/darka/nios2-linux/linux-2.6/arch/nios2/lib/libgcc.c:351: warning: ISO C90 forbids mixed declarations and code
CC arch/nios2/lib/memcpy.o
CC arch/nios2/lib/string.o
AR arch/nios2/lib/lib.a
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
/home/darka/nios2-linux/toolchain-mmu/x86-linux2/bin/nios2-linux-gnu-ld:arch/nios2/kernel/vmlinux.lds:173: ignoring invalid character `#’ in expression
/home/darka/nios2-linux/toolchain-mmu/x86-linux2/bin/nios2-linux-gnu-ld:arch/nios2/kernel/vmlinux.lds:173: syntax error
make[2]: *** [.tmp_vmlinux1] Error 1
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory `/home/darka/nios2-linux/linux-2.6′
make: *** [linux] Error 1

At the moment I do not know what to do, so I passed it by and tried to compile uClinux.

So there is some news: recently I was successful and compiled Toolchain of  nios2-linux-20100621. I have swich from Centos to Ubuntu 11.10 version and problem seems to be was in:

make gcc elf2flt gdb-host

Try to seperate make process of gcc, elf2flt and gdb-host:

make gcc      make elf2flt        make gdb-host

After building of toolchain go to through these  steps:

cd /home/user/altera/11.0/nios2-linux/linux-2.6
git fetch origin
git branch nios2 origin/nios2
git checkout -f nios
git clean -f -x -d

cd /home/user/altera/11.0/nios2-linux/uClinux-dist
git fetch origin
git branch trunk origin/trunk
git checkout -f trunk
git clean -f -x -d

Do not forget to set path to toolchain, just entering path in nios2-di
PATH=$PATH:/home/USER_NAME/nios2-linux/toolchain-build/build/nios2/bin

in other way you probably will get an error:  nios2-linux-uclibc-gcc : command not found; perhaps you need to fix PATH?
and check it with: nios2-linux-uclibc-gcc -v

Also you can get other error similar to shown:  nios2-linux-gnu-gcc : command not found; perhaps you need to fix PATH?
you may fix it by entering path in terminal to this tool in: PATH=$PATH:~/nios2-linux/toolchain-mmu/x86-linux2/bin

 

 Will be some pictures!

 

First I am groining to use NIOS processor without MMU. Below is listed an error which appears by compiling linux image:

kernel/built-in.o(.text+0x1064): In function `get_update_sysctl_factor':
: undefined reference to `____ilog2_NaN’
kernel/built-in.o(.text+0x1064): In function `get_update_sysctl_factor':
: relocation truncated to fit: R_NIOS2_CALL26 ____ilog2_NaN
make[2]: *** [.tmp_vmlinux1] Error 1
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory `/home/darka/nios2-linux/linux-2.6′
make: *** [linux] Error 1

This error appears because of  a bug in the nios2nommu toolchain here is description, how to solve it.

Do not forget to follow  5th and 6th steps. Moreover modify  config.linux-2.6.x file and change CONFIG_DTB_SOURCE=” path to your DTS  file ” line, by entering path to your DTS file created by sopc2dts. Example:
CONFIG_DTB_SOURCE=”/home/USER_NAME/my_nios2_fpga.dts”

Then enter make menuconfig - change vendor to Altera ( Fig. 3 ) and Kernel/Library/Defaults to Default all settings (lose changes). Then you will be asked to enter base address and size of your SDRAM:

Also I suppose you need to confirm Compilation of device tree. Other stuff except to you..

 

I am still getting trouble… cant compile because of another error in “sched_init_smp”:

LD .tmp_vmlinux1
kernel/built-in.o(.init.text+0x54c): In function `sched_init_smp':
/home/darka/nios2-linux/linux-2.6/kernel/sched.c:5989: undefined reference to `____ilog2_NaN’
kernel/built-in.o(.init.text+0x54c):/home/darka/nios2-linux/linux-2.6/kernel/sched.c:5989: relocation truncated to fit: R_NIOS2_CALL26 ____ilog2_NaN
make[2]: *** [.tmp_vmlinux1] Error 1
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory `/home/darka/nios2-linux/linux-2.6′
make: *** [linux] Error 1

 Will be updated!

 

uClinux 

In Altera forum I found  older version nios2-linux-20090929. So to compile uClinux I passed these steps:

Step 1.

After installation of Quartus and Nios II I was forced to fix patches manually because installation by some reason did not did what it must. So run terminal in Linux and enter:

Fig. 1 An example of supervisor mode

Then you need to find hidden bash_profile it is located in directory /home/user_name/ (user_name – this is your account name in Linux), to view all files you can use command: ls -a
You can open this file with some text editor, I used emacs:

Fig. 2  bash_profile editing by emacs for modification of  user environment

Enter paths to installed Altera’s software:

QUARTUS_ROOTDIR=/home/darka/altera/11.0/quartus
export QUARTUS_ROOTDIR

QUARTUS=/home/darka/altera/11.0/quartus
export QUARTUS

NIOS2EDS=/home/darka/altera/11.0/nios2eds
export NIOS2EDS
SOPC_KIT_NIOS2=/home/darka/altera/11.0/nios2eds
export SOPC_KIT_NIOS2

NIOS2LINUX=/home/darka/nios2-linux
export NIOS2LINUX

PATH=$QUARTUS/bin:$QUARTUS/linux:$QUARTUS/sopc_builder/bin:$NIOS2EDS/bin:$NIOS2EDS/bin/nios2-gnutools/H-i686-pc-linux-gnu/bin:$NIOS2LINUX/toolchain-mmu/x86-linux2/bin:/usr/bin:$PATH

Save it – Log Out  and Login again. After that you will be able to use JTAG programmers and other Quartus and NIOS II Embedded Design Suite tools.

Step 2: Downloading Linux Distribution for NIOS http://www.alterawiki.com/..

In terminal enter these commands:
wget http://www.niosftp.com/pub/linux/nios2-linux- 20090929 .tar

After download untar it:
tar xf nios2-linux- 20090929 .tar

Goto nios2-linux directory:
cd nios2-linux

And enter:
./checkout

It will take several minutes. Note: do not update this distribution using ./update

Step 3.

After the ./checkout
cd to /nios2-linux/linux-2.6
git checkout test-nios2

Step 4. 
cd to /nios2-linux/uClinux-dist
git checkout test-nios2

Wait until finish.

 Step 5. Toolchain

Now you need to get Toolchain . You can try to compile, goto to nios2-linux/toolchain-build/ by enter to terminal:

cd  nios2-linux/toolchain-build/
git clean -f -x -d # clean on restart
make gcc elf2flt gdb-host 

If you lucky you will compile it. Unfortunately after hours of trying I was forced to use  already compiled binary Toolchain nios2gcc-20080203.tar.bz2.

Download it and untar it in your user directory and do not forget add path PATH=$PATH:/opt/nios2/bin to  bash_profile file (After changes of this file you need to Log out and Log in in order to use changes).

After Login go to terminal and enter as supervisor (su and password). Go to nios2-linux/uClinux-dist/ directory and type: make menuconfig then configuration window should appear:

Fig. 3 An example of configuration window

Go to  Vendor/Product Selection and select Altera, then goto Kernel/Library/Defaults Selection and set Default all settings (lose changes):

Fig. 4 An example of configuration window for Kernel configuration

Save your changes by Exiting and when window close in terminal enter:  make . After this command in terminal you should be asked to use hwselect for PTF file, which contains your NIOS structure.

Hardware of NIOS processor is quite simple:

Fig. 5 An example of NIOS processor structure

SDRAM on DE0 development board needs PLL to form specific clock, in pictures below you can see how clocks of PLL c0, c1 are organized:

Fig. 6 An organization of pll.C0 clock

 


Fig. 7
An organization of pll.C1 clock , note that phase is shifted by -60 deg

 

Nios processor core for this experiment was designed without MMU:


Fig. 8
NIOS cpu configuration pointing reset vector to SDRAM


  Fig. 9 NIOS cpu Caches and Memory Interfaces can be set to default

Other Nios components depends on you, except Timer it must be set to FULL FEATURED and  note that IRQ must be set to 0. Here you can download Quartus project of this example.
In this example you can find NIOS_proc.ptf file. In terminal use:  make vendor_hwselect SYSPTF=/enter path to ptf file/ NIOS_proc.ptf 

If you  have compiled toolchain or used older already compiled (wrote before) you should be able use  make vendor_hwselect SYSPTF command. If not you will be unable to compile uCLinux for NIOS.

After assertion of  make vendor_hwselect SYSPTF=/enter path to ptf file/ NIOS_proc.ptf you will be asked to enter some parameters:

 

Fig. 10 An example of hwselect procedure, processor selection (top) and Kernel loading device (bottom)

Next step is to start by typing: make

 uClinux compilation will take several minutes and should go without errors. When compilation is complete type the command:  nios2-download -g images/zImage



Fig. 11 An example software download to DE0 development boards

To run uClinux just type in terminal and press enter:  nios2-terminal and with NIOS terminal uClinux will start:

  Fig. 12 uClinux started

The end!

During process of compiling uClinux, I faced with error:

[root@localhost uClinux-dist]# nios2-download -g images/zImage
Using cable “USB-Blaster [1-2]”, device 1, instance 0x01
Processor is already paused
Initializing CPU cache (if present)
OK
Downloaded 1348KB in 1.6s (842.5KB/s)
Verified OK
Starting processor at address 0x10500000
nios2-gdb-server-wrapped: nios2debug.cpp:578: virtual ADI_ERROR NIOS2DEBUG::leave_debug_mode(): Assertion `m_state == STATE_DEBUG’ failed.
/home/darka/altera/11.0/nios2eds/bin/nios2-download: line 609: 3268 Aborted (core dumped) nios2-gdb-server –go –tcpport none –write-pid ./images/nios2-download.pid ./images/zImage.srec
[root@localhost uClinux-dist]#

The main problem was, that I created NIOS processor with MMU and tried to run uClinux which is designed for NIOS without MMU. Hope it will help for some one!

Running your application

The next step with uCLinux is to run some application to print hello world and blink some LEDs on board. In Altera Wiki available nice description how to compile simple hello world code. Using “Add hello apps to uClinux-dist” steps I was unable to compile my code because of error in Make file:

make[3]: Nothing to be done for `all’.
make[3]: Leaving directory `/home/darka/nios2-linux/uClinux-dist/user/ftpd’
[ ! -d “games” ] || ( touch games/.sgbuilt_user && make -C games ) || exit $?
make[3]: Entering directory `/home/darka/nios2-linux/uClinux-dist/user/games’
for i in dummy ; do \
[ $i = dummy ] || make -C $i || exit ; \
done
make[3]: Leaving directory `/home/darka/nios2-linux/uClinux-dist/user/games’
[ ! -d “hello” ] || ( touch hello/.sgbuilt_user && make -C hello ) || exit $?
make[3]: Entering directory `/home/darka/nios2-linux/uClinux-dist/user/hello’
Makefile:7: *** missing separator. Stop.
make[3]: Leaving directory `/home/darka/nios2-linux/uClinux-dist/user/hello’
make[2]: *** [hello] Error 2
make[2]: Leaving directory `/home/darka/nios2-linux/uClinux-dist/user’
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/darka/nios2-linux/uClinux-dist/user’
make: *** [subdirs] Error 1

I am going to find out what is wrong later.

So at the moment the second method “Compile without adding to uClinux-dist” works fine. You can use this code to print and blink LEDs:

#include <stdio.h>
#include <asm/io.h>  // inlcude for outl()
#include <asm/unistd.h> // include for usleep()
#define PIO_0_BASE 0x11840 // This is your PIO adress

int main(void)
{
printf(“Hello\n”);
while(1)
{outl(0xF, PIO_0_BASE); // direct output to PIO
usleep(1000000);
outl(0x0, PIO_0_BASE);
usleep(1000000);
}
}

You need to compile your code with:
nios2-linux-uclibc-gcc hello.c -o hello -elf2flt
and copy compiled file  manually to /nios2-linux/uClinux-dist/romfs/bin directory. Next step is to Make you uClinux image and download it to board and run NIOS terminal (Fig. 11 and Fig. 12).  When uCinux starts enter hello and your application should start by printing “Hello” message and blinking diodes. If you want to run your application in background enter hello &. 

To run application when uCLinux starts, you need to modify rc file in  /nios2-linux/uClinux-dist/vendors/Altera/nios2 directory by entering path to you program in uCLinux:


Fig. 13 Adding path to your application in rc file, symbol & in the end of path runs application in background

Thus Make your uClinux image and download it to board.

Running SD Card on DE0 board (download Quartus Project)

Firs read Altera wiki about using SD card. There are files in the bottom you can use it if you want. In this example I tried to use Altera SPI to read and write to SD card. So you need to add SPI core to CPU (Fig. 5):

 
Fig. 14 An example of added SPI (mmc_spi) core to NIOS CPU

Change its name to mmc_spi and set its parameters:  

Fig. 15 An example of SPI parameters for managing of SD card (enter PSI clock: 2 MHz .. <20 MHz)

If you get an error:  FAT: codepage cp437 not found it seems that you forgot to set language support (in make menuconfig):

File System ->Native language support :


Fig. 16  Native language support example (Top) and file system vfat support (Bottom) FileSystem->DOS/FAT/NT FIlesystems

Fig. 17 An example of MMC and Altera SPI support configuration (Top, Bottom)

 

Do not forget to use make vendor_hwselect. Then make kernel image and load it to development board. When uClinux is loading you should see notice about mmc_spi:

 

 Fig. 18 SD card on uClinux, as seen there is shown size of SD card

Then mount SD card to created sd directory:

mkdir /mnt/sd
mount -t vfat /dev/mmcblk0 /mnt/sd

Fig. 19  An example of SD card mounting in uClinux

If you want to see files use:  mount -t vfat /dev/mmcblk0p1 /mnt/sd
Using Altera SPI to read SD card seems to be quite slow, but it works.

By building this example I faced to strange problems:

nios2-terminal: connected to hardware target using JTAG UART on cable
nios2-terminal: “USB-Blaster [1-2]”, device 1, instance 0

nios2-terminal: Warning: The JTAG cable you are using is not supported for Nios
nios2-terminal: II systems. You may experience intermittent JTAG communication
nios2-terminal: failures with this cable. Please use a USB Blaster revision B
nios2-terminal: cable or another supported cable. Please refer to the file
nios2-terminal: errata.txt included in the Nios II development kit documents
nios2-terminal: directory for more information.

nios2-terminal: (Use the IDE stop button or Ctrl-C to terminate)

Uncompressing Linux… Ok, booting the kernel.

At this point uClinux is stopped to start..  This my be related with drivers between Linux and Oracle VM VirtualBox. After resetting of development board and reloading .sof and image –  uClinux has started.

Another problem was related to this error:
mmc0: error -110 whilst  initialising SD card

It is some how related to SD card type, because with one card I had problems quite often, when using another card there was no problem at all.

 

The next step is to use UART instead of JTAG UART

To use UART instead of JTAG uart to view uClinux, you need to go to /nios2-linux/uClinux-dist/vendors/Altera/nios2/ and find file named inittab, open it and uncomment this line (Fig. 20):  

Fig. 20 An example of structure of inittab file

Then - make menuconfig select Customize Kernel Settings then disable JTAG UART in Device Drivers->Character Devices ->Serial Drivers:


Fig. 21
Disabling Altera JTAG UART


Then make kernel and download it to development board. In other side of UART use some terminal:

Fig. 22 uClinux messages on HyperTerminal

 

The problem with this mode is that sometimes in terminal appears a message:
/mnt> init: /bin/agetty respawning too fast 

Need find some solution for it.

 

Will be more!!

  1. #1 by Socrates on November 1, 2011 - 22:44

    Great! Did You try Nios-MMU design?

  2. #2 by admin on November 7, 2011 - 00:56

    I tried, at the moment I am not successful.. I am able to compile but there wrong memory address and have not time to figure out.

(will not be published)