引言
经过前面的分析和介绍,我们对ORPSoC的启动过程(http://blog.csdn.net/rill_zhen/article/details/8855743)和
ORpSoC的debug子系统(http://blog.csdn.net/rill_zhen/article/details/9045837)有了初步的了解,
但是对于启动和debug前的工作还没有仔细分析过。比如FPGA是怎么config的,orpmon是怎么load的,是如何事先烧到外部的flash里的,等等。
本小节就解决这个问题。
1,系统的setup
1>回顾
根据前面的分析,我们知道了ORPSoC复位之后的操作,简单整理如下:
1》首先从0xf0000100(rom0的wishbone地址)这个地址取出rom0的内容(bootrom.S),并执行之。
2》bootrom.S中会通过地址为0xb000_0000(simple-spi的wishbone地址)的控制器从0xc0000(sizeword的地址)地址取出需要copy的内容的大小(sizeword)
3》根据sizeword的大小将0xc0004~0xc0004+sizeword的内容copy到SDRAM的0x0的位置。
4》copy完成后,产生一个reset中断,中断入口为0x100。
5》从SDRAM的0x100取指令,启动整个程序。
以上内容可以从
orpsocv2\boards\altera\ordb2a-ep4ce22\sw\board\include\board.h
orpsocv2\sw\bootrom\bootrom.S
中分析获得。
2>数据流向(data flow),从flash启动。
上面说了ORPSoC复位后的操作,但是在复位之前呢,如下图:一种颜色代表一条data path。
上面的机制可以通过schematic来进一步验证:
说明:
1》我们之前的实验都是通过jtag工具将svf文件,经FPGA本身的JTAG模块将ORPSoC配置到FPGA,然后通过or32-elf-gdb工具将可执行bin文件,经ORPSoC中的jtag_tap模块load到SDRAM中,再通过spr npc 0x100,设置启动地址,最终启动helloworld.HW ,orpmon和linux。最后通过picocom工具接受uart16550的内容,显示出来。
2》上面的过程,断电之后是不保存的,所以每次上电需要重新操作一遍才行。如果想上电自动执行,就需要将ORPSoC和需要执行的软件实现烧到外部的flash或者EEPROM或者SD card里面。
3》要想烧写外部的flash,首先需要将spi_fwd模块通过jtag工具将spoi_fwd.svf配置到FPGA里面,然后通关过spiflash-program工具将对应的rbf文件(ORPSoC的fpga bit文件),将orpmon.sizebin(前4字节是文件大小)/vmlinux.sizebin烧到0xc0000地址。这样上电之后,FPGA自动配置ORPSoC,然后or1200通过rom0中的bootrom.S经simple-spi模块和serialflashloader模块将flash中的软件copy到SDRAM,并运行之。
注:
1》spi_fwd和jtag_tap两个模块都是用户逻辑,并且两个模块对应的FPGA的引脚是一样的,两个模块对应的驱动工具分别是spiflash-program和or32-debug-proxy。ubuntu本地和官网svn有对应的c语言source code。感兴趣的可以下载下来看一下。
2》一般综合ORPSoC的工程后会自动生成rbf文件如果不能生成,需要手动生成,具体操作步骤,请参考后面的附录。
3>数据流向,从SD card启动。
上面分析了从外部flash启动的数据流向路径,要想从SDcard启动怎么办呢?步骤如下:
1》rbf文件仍然需要烧到外部的flash。这样上电之后FPGA本身的config模块才会自动load rbf文件内容来实现配置FPGA。
2》将软件事先通过PC烧到SDcard里面(起始地址要记住)。
3》修改bootrom.S代码,实现SD card controller的驱动,并将软件从SDcard copy到SDRAM。
2,program spi flash
步骤如下:
1>配置spi_fwd模块到FPGA芯片
$ cd ~/program-spi-flash
$ jtag ./program_spi.jtag
2>擦除flash
$ ./spiflash/spiflash-program -e
3>将ORPSoC的rbf文件烧到flash的0x0地址
$ ./spiflash/spiflash-program -p /home/openrisc/fpga_dev_board/ordb2a-ep4ce22/output_file.rbf
4>将booloader/vmlinux的sizebin文件烧到flash的0xc0000地址,具体烧什么要看你的板子的flash的大小而定(板子后面的U6和U7的型号),如果太小可以自己换一个大的(up to 8M bytes)。
$ ./spiflash/spiflash-program -a 0xc0000 -P /home/openrisc/program-spi-flash/vmlinux.sizebin
或者
$ ./spiflash/spiflash-program -a 0xc0000 -P /home/openrisc/program-spi-flash/orpmon.or32.sizebin
注:上面的2-4步可以通过一条命令实现:文件路径需要修改正确。
spiflash-program -e -p output_file.rbf -a 0xc0000 -P orpmon.or32.sizebin
5>重新插拔USB线
6>打开串口工具picocom
$ picocom --b 115200 --p n --d 8 --f xon /dev/ttyUSB2
7>应该能看到orpmon的输出信息,如下图(注:下图是我刚买回板子后用win7下的hyperterminal测试的截屏,不是这次实验的截屏。)
3,问题的解决
经过努力,终于可以完成烧写外部spi flash的工作了。上面的步骤没问题,问题出在工具上(spiflash-program),这个工具在ubuntu的镜像中针对的flash是64Mbit的,但是官网的板子出厂默认焊的是8Mbit的,所以就需要修改一下对应的spiflash-program.c,然后重新编译,然后重复上面的步骤即可。具体的代码修改,请参考附录。如果还没成功的话可以用‘-a addr -l size -r read.data’参数将flash的addr地址的size大小的内容读到read.data文件,和打算烧录的文件进行对比,进一步查找问题。
下面是截屏:可以看到orpmon的输出信息。
4,小结
本小节介绍了ORPSoC的系统setup过程,并尝试烧写外部的flash。这样的话,每次上电就可以自动运行了。
附录A 生成rbf文件
如下图,根据sof文件生成rbf文件:用quartus_cpf工具生成。如果连sof文件都没有,可以用programmer工具根据svf文件生成sof文件。
附录B ORPSoC运行软件实验参考文档
===========================================================
Running Software on Hardware
============