前面我们已经实现从SPI Flash启动orpmon和u-boot,并利用orpmon和u-boot的tftp服务最终启动了linux。看似大功告成,其实不然。
由于SPI Flash的容量有限(2MB),无法从SPI Flash直接启动linux,如果想启动linux的话必须先启动bootloader,这就要求linux的启动过程需要人为的参与,而这是我们不想看到的。
那如何才能上电直接启动linux,并且不需要人为操作呢?
前面说过,ML501的CFI FLash是32MB,容量够大,能不能从CFI Flash启动软件呢?
本小节就以从CFI Flash启动u-boot为例,来介绍从CFI Flash启动软件的方法。
编译生成针对ML501并附带sizeword信息的u-boot.szbin文件,然后制作用来将u-boot.szbin烧到CF卡里面的烧写工具(cfi_ctrl_programmer.elf),通过or32-elf-gdb将cfi_ctrl_programmer.elf下载到内存,执行cfi_ctrl_programmer.elf,根据其提供的命令将u-boot烧到CF卡。
修改ORPSoC的启动地址,修改为从CF卡启动。上电即可直接从CF卡启动u-boot。
a,下载u-boot源码到/home/openrisc目录下。
http://opencores.org/or1k/U-Boot
或者
http://git.openrisc.net/cgit.cgi/stefan/u-boot/commit/
b,解压并编译
tar xvf u-boot-master.tar.gz make ml501_config make
用bin2binsizeword小工具,生成u-boot.szbin文件。
cd ~/soc-design/orpsocv2/sw/apps/cfi_ctrl_programmer make cfi_ctrl_programmer.elf PROGRAMMINGFILE=~/u-boot-master/u-boot.szbin BOARD=xilinx/ml501
a,下载
要想让cfi_ctrl_programmer运行,首先必须要将其load到内存。主要有两种方式:
第一,先将cfi_ctrl_programmer.elf文件利用or32-elf-objcopy转成bin格式的文件(cfi_ctrl_programmer.bin)。然后利用orpmon或者u-boot将bin文件load到内存。
第二,直接用or32-elf-gdb将cfi_ctrl_programmer.elf文件load到内存。
如果你的debug系统还没搭好的话,只能采用第一种方式。如果debug系统搭好了,第二种方式无疑更方便快捷。
利用or32-elf-gdb向ML501的DDR2 RAM中load程序,前面已经介绍过,如有疑问,请参考:(http://blog.csdn.net/rill_zhen/article/details/17011957)。
执行结果,如下所示:
(gdb) load cfi_ctrl_programmer.elf Loading section .vectors, size 0xe1c lma 0x0 Loading section .text, size 0x598c lma 0x1000 Loading section .rodata, size 0x8f8 lma 0x698c Loading section .data, size 0xf0 lma 0x7284 Loading section .userprogram, size 0x2c454 lma 0x9374 Start address 0x100, load size 210404 Transfer rate: 68 KB/sec, 3896 bytes/write. (gdb) spr npc 0x100 SYS.NPC (SPR0_16) set to 256 (0x100), was: 256 (0x100) (gdb) c Continuing. Remote connection closed (gdb)
b,运行
cfi_ctrl_programmer一旦开始运行之后,我们就可以在串口终端看到输出信息。
输入‘h’,查看帮助命令,根据帮助提示,先后输入‘p’和‘v’,就能完成u-boot的CF卡烧写和校验,
在烧写完成后,按‘ESC’,即可启动u-boot,如下所示:
cfi_ctrl flash programming app type 'h' for help menu > h Usage: [p]rogram erase req. blocks, write image to flash [o]ffset set page offset to write to [v]erify verify written program [s]tatus print status of CFI flash [e]rase erase block of CFI flash [r]ead read, browse page of CFI flash [i]nspect inspect page of image in RAM [R]eset reset CFI flash controller [ESC] reset by jumping to 0xf0000100 > > p Erasing blocks (0 - 1) Erasing block 0 Erasing block 1 Erase complete Programming 181332 bytes Programming 181332 bytes complete > > v Verifying 181332 bytes of image from 0x00000000 Image verified. Press esacpe to boot from 0xf0000100. >
要想上电直接从CF卡启动,而不是从bootrom启动,就必须修改ORPSoC的默认PC值。
首先我们需要确定CF卡控制器的wishbone总线地址:0xf0000000
orpsocv2/boards/xilinx/ml501/rtl/verilog/include/orpsc-params.v
然后,我们就可以修改默认PC值了:
orpsocv2/boards/xilinx/ml501/rtl/verilog/include/or1200_defines.v :
修改完成后,在确认一下CF卡控制器的引脚分配:ml501.ucf,如果没问题的话,综合生成orpsoc.bit文件。
将生成的orpsoc.bit文件用iMPACT烧到FPGA里面,即可从串口看到u-boot的启动信息:
U-Boot 2011.09-rc2-00000-geeab5fa-dirty (Oct 22 2011 - 18:49:33) CPU: OpenRISC BOARD : ml501 2 erase regions found, only 1 used
具体内容如下图所示:
将vmlinux.szbin替换u-boot.szbin文件,按照上述步骤,即可从CF卡启动linux,如果不能启动的话,可能需要在linux中增加从CF卡copy自身到内存的相关代码。
下面是我试图从CF卡直接启动linux的情况:
此外,还可以通过u-boot将linux镜像烧写到CF卡里,然后修改u-boot的启动参数(从CF卡copy linux到RAM,并启动linux),这样也可以实现linux的启动。本小节,我们实现了从CF卡启动软件,如果受SPI Flash的容量限制,不能启动较大程序时,从CF卡启动将是一个不错的选择。