uClinux在Nios II平台上的移植

说起来网上关于如何在FPGA开发板上,对基于NIOS II软核的平台移植uClinux系统的资料真的很多,写下这篇文章,一是提到点自己测试的经验;二是整理资料,希望能有个更清晰明了的教程。

上次写魔兽插件的教程,越到最后觉得写得越仓促,主要是因为追求细节足够详细导致精力不够,毕竟写写东西也只是业余消遣。保证初学者有迹可循又简明扼要,的确不是容易办到的事情。这样冗长的技术教程,我会在给初学者留条小路的基础上尽量一针见血的说明事情。

对于开发板的选择,我也买错了,红色飓风这种板高不成低不就的,700块大洋花了真的一点都不值,至少在这次应用上,它的片上资源已经捉襟见肘。如果有可能,买块DE或者DE2的板,一块可以解决日后很多应用,我就是借用了实验室的DE2才得以继续进行下去的。

废话说完了,下面开始说正事。

移植实现思路

  1. 建立交叉编译开发环境
  2. SoPC Builder配置硬件资源
  3. 配置、编译内核
  4. 下载运行测试

这里采用Fedora 12为基础建立交叉编译环境,我是在Vmware虚拟机上安装的Fedora,如果可以推荐直接装在物理机上,装Ubuntu、CentOS之类的系统都可以。初学者请搜索“Vmware 安装linux”,自行学习基础,如果Vmware没有注册使用不了,为了版权的考虑,可以选用Virtual Box这样的开源虚拟机软件。

SoPC Builer是Quartus开发工具中的一部分,我使用的是Quartus 7.2版本,安装在物理机的Windows XP下

熟悉基本的Linux命令,以便后面解压源码等步骤使用

下载到板上测试,我使用的是NIOS Shell Command,所以要安装与Quartus同版本的NIOS开发工具,一样装在XP下。可以自行下载Linux版本的开发工具,这只是我懒得换版本而已。

搭建交叉编译环境

安装并配置linux系统

假设已经安装Fedora 12,要进行下一步开发,需要安装一些开发库。

在终端输入如下指令,可以一次性安装好本次开发需要的所有库:

$ sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

$sudo yum install git-all git-gui make gcc ncurses-devel bison \
byacc flex gawk gettext ccache zlib-devel gtk2-devel lzo-devel \
pax-utils libglade2-devel

如果是Ubuntu之类的其他Linux系统,请看NiosWiki的安装说明:<—猛击我—>

获取nios2-linux源码

要进行操作系统的移植,一要移植bootloader,二要移植内核,三是根文件系统,移植的编译需要交叉编译工具,这里可以下一个源码包,里面已经整合了我们需要的各种东西

在终端输入下载


$wget http://www.niosftp.com/pub/uclinux/nios2-linux-20090730.tar

把nios2-linux-20090730.tar解压到当前目录:


$tar nios2-linux-20090730.tar

切换到nios2-linux 目录,验证文件


$./checkout

下载交叉编译工具

获得nios2-linux源码之后,可以在toolchain-build目录下自行编译生成交叉编译工具,也可以从http://www.nioswiki.com/OperatingSystems/UClinux/BinaryToolchain这里下载编译好的BinaryToolchain。笔者试过以nios2-linux-20090730版本的源码加上Fedora的gcc 4.4.3尝试自行编译,但是提示出错,最后选用现成的交叉编译工具,节省研究时间。


$wget http://www.niosftp.com/pub/gnutools/nios2gcc-20080203.tar.bz2

之后解压该文档,交叉编译工具在/opt/nios2/bin下,Fedora 12默认建立用户一开始无法使用sudo请自行搜索“Fedora 无法使用sudo”


$sudo tar -jxf nios2gcc-20080203.tar.bz2 –C /

然后设一下Linux用户的PATH变量,这样才可以等会编译的时候才找的到交叉编译器


$ vi ~/.bashrc

根据ToolChain所在位置在.bashrc中添加一行并保存,其中的路径为刚才下载的交叉编译器的解压位置


PATH=$PATH:/opt/nios2/bin

重新登录linux用户后,查看nios2-linux-gcc 版本,验证编译器是否可用


$nios2-linux-gcc -v

SoPC Builder配置

根据NiosWiki的说明,要在NIOS上移植uClinux系统,硬件需要的最低标准如下:

  • Nios II f/s级别的核,必须要有硬件乘法器(推荐f级别,s级别是最低要求)
  • sdram(至少需要8M)
  • 一个full featured的计时器(IRQ为0)
  • 一个jtag/serial uart

假设你已经会使用SoPC Builder,然后根据上面的要求,建立一个最小系统。在移植uClinux之前你可以使用NIOS建立一些HelloWorld的程序测试一下,是否可以运行,测试通过了就可以跳过继续下一阶段了。

对于使用DE2或者一些资料比较齐全的开发板的童鞋,在第一次进行移植工作的时候,可以先使用附带的范例中现成的SoPC工程项目,可以简化操作,提高成功率,避免因为Sopc Builder中配置硬件不正确,导致后期移植系统出错却误以为是配置编译过程中操作不当。

  • 按照nioswiki上的资料表明,对nios平台移植uClinux系统,需要将一个Full Featured的Timer设置为IRQ 0,但是笔者试验证明,即使使用Custom模式的Timer,而且IRQ不设置为0,依然可以移植成功。但是IRQ 0是linux默认自动检测的一个中断号,为了避免不必要的麻烦,对于那些附带的范例中IRQ不为0的,笔者推荐还是手动稍微修改一下设置比较好。

在SoPC Builder工程的目录下找到如下2个文件:

  • {SoPC项目名称}.ptf
  • {Quartus项目名称}.sof

将其复制保存以供后面使用,前者用来配置uClinux目标板的基本信息,后者用来烧写FPGA。

配置编译内核

配置内核

切换到nios2-linux下的uClinux-dist,执行


$ make menuconfig

如果你已经安装了ncurses库,就可以进入内核配置的图形界面

然后分别对Vendor以及Kernel的下级菜单进行如下设置:

Vendor/Product Selection —>
— Select the Vendor you wish to target
Vendor (Altera)  —>

— Select the Product you wish to target
Altera Products (nios2)   —>

Kernel/Library/Defaults Selection —>
— Kernel is linux-2.6.x

Libc Version (None)  —>
[*] Default all settings (lose changes)
[ ] Customize Kernel Settings
[ ] Customize Vendor/User Settings
[ ] Update Default Vendor Settings

按Y为选中项目,N为取消,M是动态加载,按2次ESC为退出到上一级菜单,最后退出的时候会提示保存设置,根据上面设置并保存退出。

本文这里使用内核的默认设置,并为进行过多剪裁。实际上笔者发现该内核开发包可以很完善的支持DE2等一些官方认证的开发板,默认的设置都可以开始并使用网卡等设备,若无特殊要求,默认设置就可以胜任。

你可以选择Customize Kernel Setting,保存退出,然后又会进入新的配置界面,里面有详细的内核剪裁、配置选项,可以尝试着自己修改看看。东西都是折腾中学习出来了。

配置硬件信息

将之前SoPC Builder建立的ptf文件复制到某一文件夹下面,然后根据自己保存的路径与文件名输入


$ make vendor_hwselect SYSPTF=/home/lee/nios2-linux/system_0.ptf

之后选择对应的cpu以及供内核运行的存储器,cpu只有altera_nios2一个,但是板上的存储器类型很多,这里选择使用SDRAM来运行内核。

如果是物理机上的Linux系统,复制粘贴这个文件我就不说了,如果是Vmware的虚拟机安装Linux,Quartus又装在物理机的Windows下,有几种方法:

  • 使用虚拟网卡与主机相连,用Samba之类的共享文件,这种设置折腾折腾之后,你的Linux基本操作设置应该也都还可以了
  • 给虚拟机的Linux系统安装Vmware Tools,然后用虚拟机的共享文件夹功能来复制文件,不过Fedora 12这种新系统,Tools是不好安装成功的,如果是版本比较低的安装就很顺畅
  • 直接用优盘当中转,物理机把文件复制到优盘上,然后挂载到虚拟机中复制出来……很傻很简单很实在

这里配置这一步的作用,可以看NiosWiki-LinuxHWselect,说明的很详细,主要就是生成板上IO口以及存储器资源

编译

上面的步骤都没有错的话,直接输入


$make

第一次编译成功之后,可以在uClinux-dist的目录看到一个带有内核编号的文件夹,这里是linux-2.6.x,进去之后可以看到生成的一些相关文件与文件夹,在linux-2.6.x/arch/nios2/boot下,会有一个zImage的内核映像文件,这就是我们要的,按照上面的方法复制保存它,以供等会烧写使用。

这个uClinux-dist的开发包,默认设置就已经帮你把bootloader以及根文件系统配置好了,使用make的时候会对应一起生成。bootloader默认是u-boot,根文件系统是romfs。

下载运行测试

经过如上的操作,此刻我们会有2个文件,一个sof文件用于烧写FPGA芯片,一个zImage用于烧写uClinux内核。

打开NIOS II Command Shell,切换到文件保存的路径下,这里是优盘的盘符下,然后输入如下指令:


$ nios2-configure-sof DE2_NET.sof

看到下面的信息说明烧写成功

接着输入如下命令,-g是指下载后复位目标板,让内核立即运行,记得不要漏掉


$ nios2-download –g zImage

若成功会看到如下提示:

最后,输入


$ nios2-terminal

启动调试,就可以看到uClinux启动的画面

至此,最简单的一次移植我们已经都成功了,可以运行基本的linux命令,测试一下移植的uClinux系统。

我们这里只是在SDRAM上下载了内核映像,测试移植的话,这几个命令就可以了,但是每次断电之后,所有信息都会丢失。若你要真正烧写到flash之类的存储器上,你需要先将FPGA的下载方式改为AS,烧写FPGA芯片,然后接着才是烧写系统内核到flash上,对于第二步在这里转载gewanyong的文章,他已经说的很详细了,步骤如下:

(1)先把内核映像转换成可以直接烧到flash的文件,用以下命令:


$elf2flash --input=zImage --output=xx.flash --base=0x..... --reset=0x..... --end=0x.... --boot=xxxx.srec

其中:

  • zImage就是编译好的uClinux内核映像,
  • xx.flash是这条命令输出的文件,
  • –base和–end分别对应flash芯片的基地址和结束地址.–reset是CPU复位地址,一般和–base相同.
  • xxxx.srec是bootloader,可以从安装目录下的ip/altera_nios2下拷贝,名字是:boot_loader_cfi.srec,若不知具体位置可以搜索一下.

(2)把上面生成的xx.flash文件下载到目标板 flash中:


$nios2-flash-programmer -g -c usb-blaster --base=0x... --program xx.flash

usb- blaster是用到的下载电缆,-g表示下载后复位目标板,启动内核.

那几个地址可以从.ptf文件中得到.

添加简单程序

在第一次生成内核映像时,输入make之后会在uClinux-dist生成romfs这个文件夹,是对应根文件系统的编译内容文件夹,我们复制自己编写程序到其中,重新make一次,新产生的内核映像文件就包含了我们自己写的程序。

在这里笔者写了一个最简单的C语言的Hello World程序,测试自己编写程序移植的可能性。


#include <stdio.h>

int main(void)

{

printf("Hello,world!\n");

return 0;

}

将如上代码保存为.c文件,这里取名为test.c,然后输入编译命令


$ nios2-linux-gcc test.c –o test –elf2flt

由于uClinux没有MMU,所以不支持虚拟内存以及程序的相对地址运行,程序文件只能使用绝对物理地址的FLT格式,所以一定得加上-elf2flt参数,否则编译完的程序无法再uClinux上运行。

编译好可以使用如下命令验证是否是FLT格式


$ nios2-linux-flthdr test

检验成功后,在romfs下建立一个名为test的文件夹,把生成的test程序复制到其中,然后回到uClinux-dist下再次编译内核


$ make

之后重复之前的烧写步骤,直到进入uClinux系统,开始测试


$ cd test

$ ./test

到这里,我们也可以自行添加简单的程序了。当然你也可以配置好网卡跟ftp,使用ftp把编译好的程序传到板上运行,可以不用每次都重复一遍烧写过程,这个再google几下,就大概知道如何做了,甚至可以考虑改成NFS根文件系统,但是相对改动就大些,初学的时候,为了简单容易成功,麻烦就麻烦吧。

至于要再此基础上开发什么应用,那就任君选择了。

之前由于没有人在Nios平台上移植OpenCV,所以我自己尝试移植了一下,这几天有空我会整理出来,不过由于要发表到学术期刊上,所以可能会晚几天。

如果想深入学习,bootloader的自行修改,内核的剪裁以及驱动的编写都可以去了解下。

这次就说这么多吧,白白~~

Tagged , , ,

2 thoughts on “uClinux在Nios II平台上的移植

  1. [...] 对于第一步,给个自己写的文章当参考——《uClinux在Nios II平台上的移植》,我将从第二步开始说起 值得注意的是: [...]

  2. Keesha says:

    Unparalleled accuracy, unequivocal clarity, and undeniable impotrncae!

    [Reply]

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>