(原创)uCLinux在NiosII平台上的移植(基于Nios II的SOPC软硬件系统)(DE2)

 

uCLinuxNiosII平台上的移植

一、编译环境搭建

VMware上安装Ubuntu9.04*1

image

配置一些比较快的源

默认情况下,Ubuntu中的vi编辑器并不好用,左右键不正常,需先安装vim-full,但ubuntu-9.04-desktop-i386.iso中的默认的源无法访问了。sudo apt-get install 命令全都是“failed to fetch”的错误。

需要修改/etc/apt/sources.list源文件。可用gedit命令。

image

输入用户密码。

但若把源地址一项一项添加很费事,易出错,从windows环境下又无法向VMware中粘贴。

sshdvsftpd没有安装,share-folderUbuntu环境下无法使用。

现在,还有一种方法,可在VMware环境下,从外部的ftp服务器上把事先已传上去的sources.list文件下载下来。

 

先配置网

sudo vi /etc/network/interfaces

image

配置域名服务器

sudo vi /etc/resolv.conf

image

sudo /etc/init.d/networking restart

ftp上下载source.list文件,然后执行sudo mv sources.list /etc/apt 命令

image

之后, 

sudo apt-get update     //升级安装的软件包。

sudo apt-get install vim-full   //安装vim-full,便于以后的编辑

sudo apt-get install openssh-server  //安装sshd,便于远程登录

sudo apt-get install vsftpd   //安装vsftpd,便于以后与物理机间传送文件

sudo apt-get install chkconfig   //安装chkconfig,便于服务器的管理

 

接下来就参照http://www.nioswiki.com上所讲继续安装了。

二、TryOutLinux

在进行移植工作之前,可以先下载现成的配置文件和内核映像文件,下载到板子上看看效果。

nioswiki网站上下载DE2平台上已经编译好的DE2_NIOS_HOST_MOUSE_VGA.sofDE2_NIOS_HOST_MOUSE_VGA.ptf 以及zImage_DE2_NIOS_HOST_MOUSE_VGA_v1.6文件。

Configure the FPGA

[NiosII EDS]$ nios2-configure-sof   DE2_NIOS_HOST_MOUSE_VGA.sof

Download and run the kernel image,

[NiosII EDS]$ nios2-download -g  zImage_DE2_NIOS_HOST_MOUSE_VGA_v1.6

Open nios2 terminal

[NiosII EDS]$ nios2-terminal

 

三、InstallNios2Linux

安装或下载源码和编译工具。

image

在编译工具链之前,先安装以上这些工具。如若不安装完全,在后面的编译工具链和编制内核的时候可能出现错, Ncurses是一个能提供基于文本终端窗口功能的动态库。在Ubuntu安装的时候应注意,安装ncurses-dev库时可能会显示 ncurses-dev has no installation candidate”,如下图所示:

image

此时,可以安装libncurses5-dev

$ sudo apt-get install libncurses5-dev

在完成了上述库的安装后,可按下一条命令检查是否安装完全。

image

检查默认的shell是否是bash

image

如若不是,需改成bash

$ sudo rm /bin/sh

$ sudo ln -s bash /bin/sh

注销重新登录,检查’cc’是否链接向了’gcc’

image

如若不是,则需修改:

$ cd /usr/bin

$ ln -s gcc cc

20090703 需要gcc 4.2或者更高版本*2

ftp上下载nios2-linux-20090730.tar

image

sha1sum校验

image

nios2-linux-20090730.tar解压到指定的目录:

$ sudo tar nios2-linux-20090730.tar –C /media/sdb1/

切换到nios2-linux 目录,check out the source

image

nios2-linux中各个目录的作用。Nios2 uClinux 的源文件和gnu工具链。

image

以下这些命令是编译nios2-gcc工具链的整个过程

image

Ubuntu中编译需要注意的是:Ubuntu中并没有root用户,需用sudo的方式执行管理员操作,但是即使用sudo make仍会产生’permission denied’的错误。可能是sudo的有效区域的问题。可用以下方式解决:

image

出现的错误:

在安装好上文中所说的那些库后,在make的过程中仍有各种错误,便切换到nios2-linux目录update了一下。

再进行上述操作,会出现以下错误

cp: cannot stat `doc/gcc.1': No such file or directory

google上寻找解决方法如下,需修改gcc3目录下的Make-lang.in中的一句代码。

image

至此,在编译就没有错误了,tools chain的编译时间比较长,大概用了1个小时10分钟左右的时间。toolchain终于编译成功了。

 

也可以用编译好的BinaryToolchain

image

然后设一下PATH变量

$ vi ~/.bashrc

image

本文中,把编译好的BinaryToolchain放到/opt/nios2/bin目录下,把自行编译的tools-chain设在/media/sdb1/nios2-linux/toolchain-build/build/nios2/bin目录下。

重新登录后,查看nios2-linux-uclibc-gcc 是否可用

$ nios2-linux-uclibc-gcc -v

image

现在把编译环境完全在nios2-linux-20090929上来做。我在Ubuntu虚拟机上新加了一块8G的硬盘,在tar xf./checkoutmake toolchain之后居然空间不够了,还得把nios2-linux-20090929.tar的包删掉才行。由于nios2-linux项目使用git来管理的,所以在用的时候需要注意查看分支。如若不是在test-nios2分支上,切换过来吧。

image

依次检查每一个目录。其它与730的版本相同,而且不会出现编译工具链时的错误。

 

编一个测试程序:hello world

image

编译与检测

image

接下来,就可以配置和编译内核了。

切换到uClinux-dist目录下,执行

$ make menuconfig

image

回车进入Vendor/Product SelectionVendorAlteraProduct选择Altera Products(nios2)

image

Exit。选择Kernel/Library/Defaults Selection,单击回车进入。

image

选择Default all settings (lose changes)ExitExit

image

显示 Do you wish to save your new kernel configuration? 选择 Yes

 

可先从nioswiki网站上下载一个已配置好的系统 DE2_NIOS_HOST_MOUSE_VGA.ptf

DE2_NIOS_HOST_MOUSE_VGA.sof先做一下实验。

 

运行vendor_hwselect

$ make vendor_hwselect SYSPTF=/home/lunix/uclinux/DE2_NIOS_HOST_MOUSE_VGA.ptf

选择要使用的cpu,设置程序运行的存储器。

image

编译内核和程序

$ make

把生成的zImage文件cpvftpd配置的目录,在Windows环境中从虚拟机上下载。

启动nios2 command shell

$ nios2-configure-sof DE2_NIOS_HOST_MOUSE_VGA.sof

image

$ nios2-download –g zImage

-g 选项代表着是 下载后立即运行。

image

$ nios2-terminal

image

 

四、配置SOPC硬件系统平台

下面将配置一个SOPC系统,并自行裁剪linux内核

 

后记:没有认真阅读http://www.nioswiki.com/OperatingSystems/UClinux上的说明文档,想当然的配了个系统,浪费了大量的时间。

 

它的基本的硬件要求或建议是

  • Nios II fcore,带Hardware multipler
  • sdram(最小8M
  • 一个full feature的定时器timer
  • 一个jtag或者serialUART

除了定时器timer不要把中断号0irq 0)分配给任何器件

 

硬件设计

建立一个工程,名字为DE2_uClinux。器件设置如下。

加入一个Verilog HDL文件,文件名为DE2_uClinux.vSet as Top-Level Entity。此时可先不管DE2_uClinux.v中的内容,先建立一个SOPC系统。

 

image

调用Sopc Builder image 建立一个nios系统。起名字为DE2_lab1

image

添加On chip Memory,在Memorie and Memory Controllers->On-Chip->On-Chip Memory(RAM or ROM)

image

添加cpu,选择Nios II/e型,设置 复位和异常 向量。更正:此处应选Nios II/f

image

 

image

加入定时器timer,选择full-featured,在Peripherals->Microcontroller Peripherals->Interval Timer

image

加入JTAG_UARTUART,在Interface Protocols->Serial

image

加入sdram控制器,在Memories and Memory Controller->SDRAM->SDRAM Controller

image

 

加入sram,此处需注意

 

DE2光盘中找到demo工程的SRAM_16Bits_512K copyDE2-uClinux工程目录下,执行file->refresh system,可看到左侧system content栏中多了一个Terasic Technologies Inc组,组中的SRAM_16Bits_512K就是要加入的DE2上的sram控制器。



 

DM9000ASRAM_16Bit_512K加入

后记:

SOPC Component for DM9000

dm9000a_hw.tcl文件存放到工程目录,打开SOPC Builder,可看到一个新的“dm9000a”组件。

添加一个新的Avalon-MM tristate bridge,添加dm9000a组件,重命名为dm9000,连接到Avalon tristate bridge master,不需要Verilog或者VHDL文件,因为SOPC Builder会自动生成。不要把中断号0irq 0)分配给dm9000

 

DM9000A模块加入后,应命名为dm9000,并通过tristate-bridge与连接到系统上,且中断号不能为0。以下图的中未作修改,所有的dm9000a都应为dm9000

 

加入flash controllerMemories and Memory Controller->Flash->Flash Memeory Interface(CFI)

CFI flash通过tristate-bridgeAvalon MM总线连接,它是个速度较慢的器件。

 

配些开关和灯。开关和红灯18个,绿灯8个,按钮4个。

绿灯和按钮类似

 

先选这么多吧,最后结果

执行一些地址对齐,中断号分配的工作。注意中断号0。点击nextgenerate

把新生成的系统加到DE2_uCLinux工程中。

配置引脚

Assignments->Import Assignments, 选中DE2光盘中的DE2_pin_assignments.csv文件,导入。

Assignment->Device->Device and Pin Options->Unused pin 设为 As input tri-stated

Dual-purpose pin->nCEO 设置为Use as regular I/O

 

修改顶层文件DE2_uClinux

打开DE2光盘中的一个比较齐全的的Demo,此处用\DE2\DE2_demonstrations\DE2_NET。把里面的DE2_NET.v文件的内容考出,把内容copyDE2_uClinux.v中,把顶层module名改为DE2_uClinux。把不需要的部分进行裁剪。本文中裁剪如下。

                 ////////////////////    Clock Input         ////////////////////     

        CLOCK_27,                        //    On Board 27 MHz

        CLOCK_50,                        //    On Board 50 MHz

        ////////////////////    Push Button        ////////////////////

        KEY,                            //    Pushbutton[3:0]

        ////////////////////    DPDT Switch        ////////////////////

        SW,                                //    Toggle Switch[17:0]

        ////////////////////////    LED        ////////////////////////

        LEDG,                            //    LED Green[8:0]

        LEDR,                            //    LED Red[17:0]

        ////////////////////////    UART    ////////////////////////

        UART_TXD,                        //    UART Transmitter

        UART_RXD,                        //    UART Receiver

        /////////////////////    SDRAM Interface        ////////////////

        DRAM_DQ,                        //    SDRAM Data bus 16 Bits

        DRAM_ADDR,                        //    SDRAM Address bus 12 Bits

        DRAM_LDQM,                        //    SDRAM Low-byte Data Mask 

        DRAM_UDQM,                        //    SDRAM High-byte Data Mask

        DRAM_WE_N,                        //    SDRAM Write Enable

        DRAM_CAS_N,                        //    SDRAM Column Address Strobe

        DRAM_RAS_N,                        //    SDRAM Row Address Strobe

        DRAM_CS_N,                        //    SDRAM Chip Select

        DRAM_BA_0,                        //    SDRAM Bank Address 0

        DRAM_BA_1,                        //    SDRAM Bank Address 1

        DRAM_CLK,                        //    SDRAM Clock

        DRAM_CKE,                        //    SDRAM Clock Enable

        ////////////////////    Flash Interface        ////////////////

        FL_DQ,                            //    FLASH Data bus 8 Bits

        FL_ADDR,                        //    FLASH Address bus 20 Bits

        FL_WE_N,                        //    FLASH Write Enable

        FL_RST_N,                        //    FLASH Reset

        FL_OE_N,                        //    FLASH Output Enable

        FL_CE_N,                        //    FLASH Chip Enable

        ////////////////////    SRAM Interface        ////////////////

        SRAM_DQ,                        //    SRAM Data bus 16 Bits

        SRAM_ADDR,                        //    SRAM Address bus 18 Bits

        SRAM_UB_N,                        //    SRAM High-byte Data Mask

        SRAM_LB_N,                        //    SRAM Low-byte Data Mask  

        SRAM_WE_N,                        //    SRAM Write Enable

        SRAM_CE_N,                        //    SRAM Chip Enable

        SRAM_OE_N,                        //    SRAM Output Enable

        ////////////////////    USB JTAG link    ////////////////////

        TDI,                              //    CPLD -> FPGA (Data in)

        TCK,                              //    CPLD -> FPGA (Clock)

        TCS,                              //    CPLD -> FPGA (CS)

        TDO,                              //    FPGA -> CPLD (Data out)

        ////////////    Ethernet Interface    ////////////////////////

        ENET_DATA,                        //    DM9000A DATA bus 16Bits

        ENET_CMD,                        //    DM9000A Command/Data Select, 0 = Command, 1 = Data

        ENET_CS_N,                        //    DM9000A Chip Select

        ENET_WR_N,                        //    DM9000A Write

        ENET_RD_N,                        //    DM9000A Read

        ENET_RST_N,                        //    DM9000A Reset

        ENET_INT,                        //    DM9000A Interrupt

        ENET_CLK//,                        //    DM9000A Clock 25 MHz

文件中其它的部分与上些部分无关的代码去掉。

在生成的DE2_lab.v文件中把,把顶层模块DE2_lab复制到DE2_uClinux.v中修改如下

DE2_lab1 de2(

                  // 1) global signals:

                   .clk(CPU_CLK),

                   .reset_n(CPU_RESET),

 

                  // the_button_pio

                   .in_port_to_the_button_pio(KEY),

 

                  // the_dm9000a

         .cmd_to_the_dm9000(cmd_dm9000),

         .cs_n_to_the_dm9000(ENET_CS_N),

         .data_to_and_from_the_dm9000(ENET_DATA),

         .irq_from_the_dm9000(ENET_INT),

         .ior_n_to_the_dm9000(ENET_RD_N),

         .rst_n_to_the_dm9000(ENET_RST_N),

         .iow_n_to_the_dm9000(ENET_WR_N),

                  // the_led_green

                   .out_port_from_the_led_green(LEDG),

 

                  // the_led_red

                   .out_port_from_the_led_red(LEDR),

 

                  // the_sdram

                   .zs_addr_from_the_sdram(DRAM_ADDR),

                   .zs_ba_from_the_sdram({DRAM_BA_1,DRAM_BA_0}),

                   .zs_cas_n_from_the_sdram(DRAM_CAS_N),

                   .zs_cke_from_the_sdram(DRAM_CKE),

                   .zs_cs_n_from_the_sdram(DRAM_CS_N),

                   .zs_dq_to_and_from_the_sdram(DRAM_DQ),

                   .zs_dqm_from_the_sdram({DRAM_UDQM,DRAM_LDQM}),

                   .zs_ras_n_from_the_sdram(DRAM_RAS_N),

                   .zs_we_n_from_the_sdram(DRAM_WE_N),

 

                  // the_sram_16bit_512k

                   .SRAM_ADDR_from_the_sram_16bit_512k(SRAM_ADDR),

                   .SRAM_CE_N_from_the_sram_16bit_512k(SRAM_CE_N),

                   .SRAM_DQ_to_and_from_the_sram_16bit_512k(SRAM_DQ),

                   .SRAM_LB_N_from_the_sram_16bit_512k(SRAM_LB_N),

                   .SRAM_OE_N_from_the_sram_16bit_512k(SRAM_OE_N),

                   .SRAM_UB_N_from_the_sram_16bit_512k(SRAM_UB_N),

                   .SRAM_WE_N_from_the_sram_16bit_512k(SRAM_WE_N),

 

                  // the_switch_pio

                   .in_port_to_the_switch_pio(SW),

 

                  // the_tri_state_bridge_avalon_slave

                   .address_to_the_cfi_flash(FL_ADDR),

                   .data_to_and_from_the_cfi_flash(FL_DQ),

                   .read_n_to_the_cfi_flash(FL_OE_N),

                   .select_n_to_the_cfi_flash(FL_CE_N),

                   .write_n_to_the_cfi_flash(FL_WE_N),

 

                  // the_uart

                   .rxd_to_the_uart(UART_RXD),

                   .txd_from_the_uart(UART_TXD)

                )

 

关于dm9000的一些修改

                  // the_dm9000a

                     .cmd_to_the_dm9000(cmd_dm9000),

                      .cs_n_to_the_dm9000(ENET_CS_N),

                      .data_to_and_from_the_dm9000(ENET_DATA),

                      .irq_from_the_dm9000(ENET_INT),

                      .ior_n_to_the_dm9000(ENET_RD_N),

                      .rst_n_to_the_dm9000(ENET_RST_N),

                      .iow_n_to_the_dm9000(ENET_WR_N),

dm9000产生一个25MHz的时钟

// the_dm9000a

reg                            ENET_CLK;

 

always @(posedge CLOCK_50) ENET_CLK<= ~ENET_CLK;

wire [1:0] cmd_dm9000;

assign              ENET_CMD = cmd_dm9000[1];

 

DE2_NET例子的目录下把两个文件Reset_Delay.vSDRAM_PLL.v两个文件复制到当前工程目录下。并加上下两句代码。

Reset_Delay              delay1              (.iRST(KEY[0]),.iCLK(CLOCK_50),.oRESET(CPU_RESET));

SDRAM_PLL               PLL1              (.inclk0(CLOCK_50),.c0(DRAM_CLK),.c1(CPU_CLK),.c2(CLK_25));

 

Reset_Delay是个复位延迟文件。为了给Nios2提供有效宽度的复位信号。

 

SDRAM_PLL为系统及SDRAM提供时钟。可以自己配置。

SDRAM的时钟必须和SDRAM Controller的时钟频率相同,必须保证当时钟上升沿到来时,SDRAM芯片上的dataaddress,和Control信号已经稳定,这就需要SDRAM时钟和SDRAM Controller时钟之间有一个clock skewSDRAM的时钟上升沿到来的晚一些),所以需要PLL产生一个phase shiftSDRAM Controller core的说明文档中有计算公式,此处取demo中的经验值即可。

Inclk0 50M

Clk c0: output clock frequency: 50MHz, Clock phase shift -3.00 ns, Clock duty cycle %:50

sdram提供时钟

Clk c1: output clock frequency: 100MHz, Clock phase shift 0.00 ns, Clock duty cycle %:50

nios2系统提供时钟

Clk c2可以不设,在本系统中没有用到。

 

编译。显示Full Compilation was Successful!

生成DE2_uClinux.sofDE2_uClinux.ptf文件(成功后可以先用Nios II IDE编写一个小程序测试一下所生成的系统是否有错误),用这两个文件重做上面的实验。

五、配置编译uClinux内核

此次自定制裁剪uClinux内核,实现3个目的

Ø         hyperterminal作为控制终端

Ø         uClinux中运行hello world程序

Ø         调通网络

将上文中生成的hw文件cp$NIOS2LINUX/nios2-linux/uClinux-dist/romfs/

基本步骤与上文相同,仅列出需要注意的不同的步骤。

Kernel/Library/Defaults Selection à下选择Custom Kernel Setting向,其它不变,退出。

其实没有什么可以修改的,基本上默认即可

Processor type and features à Platform (Altera DE2 Development board support)

Device DriversàCharacter devicesàSerial driversàAltera UART console support

一定要把Altera JTAG UART console support关掉,不能用两个控制终端,这一点没有认真看文档,浪费了不少时间。

关于网络,默认即可

Network SupportàNetwork Optionsà选择如下

Device DriversàNetwork Device SupportàEthernet (10 or 100 Mbit)àDM9000 support

一路exityes

root@lunix-desktop:/media/sdc1/nios2-linux/uClinux-dist# make

配置超级终端UART

打开超级终端,将新核下载到板子上。

[Nios II EDS]$ nios2-confige-sof hw/DE2_uClinux.sof

[Nios II EDS]$ nios2-download g zImage_net

[Nios II EDS]$ nios2-terminal

在超级终端上显示:

执行ls命令,可看到文件系统中多了hw文件,这就是我们刚才加进去的。

执行./hw显示hello world!!!,运行成功了。

下面配一下网络

/> ifconfig eth0 down

/> ifconfig eth0 hw ether 00:00:11:22:33:44

/> ifconfig eth0 192.168.135.250 up

配置MAC地址时,前2个字节应该是00:00,其它随便配。

实验一下ftp

就到这吧

 

一点感触:之所以在这个实验上浪费了大量时间,是因为以前做过,以为很快就会做完。但现在的环境已经很多不一样了,一开始没仔细阅读nioswiki上关于uClinux的文档,导致一些配置不符合要求,死磕了不少时间。

 

*1 Ubuntu起源于debiandebian被认为是最“free”的,但实际上,很少被大企业采用作为标准平台,使用中会碰到各种各样的兼容性问题,建议以RHEL(CentOS)为基准,Ubuntu/fedora之类的,个人玩玩是可以的,但要与他人合作工作,不太合适

*2 有这种说法?一般讲,目前gcc稳定版本还是3.4.6,大多数系统特别是嵌入式系统,不会采用新版gcc特性;我跟着git服务器更新过,用的3.4.6编译工具链,没有任何问题



posted @ 2010-04-22 00:18  任怀鲁  阅读(8118)  评论(19编辑  收藏  举报