ubl的程序设计,相对uboot、kernel、rootfs、设备驱动、dsp开发来说,还是比较简单。我们先从davinci的启动说起,了解ubl在davin系统中的位置和作用。对于固件程序烧写在nand flash 的davinci dm644x嵌入式系统, 上电启动的过程如下:
rbl(arm rom boot loader)在芯片出厂的时候就已经烧写到rom里了,这不需要大家关心,上电后,rbl会自动从emifa em_cs2 memory space (0x0200 0000). 执行指令,这个地址就是nand flash 或nor flash的片选起始地址。当你的系统设置为nand boot的时候,ubl(user boot loader)是必不可少的,否则rbl不能直接把uboot给boot起来,因为rbl只支持14k nand flash 的 boot程序,而uboot编译出来后的bin文件一般都大于80k,特别是版本越高,uboot的代码越大,所以这时候就需要写一个ubl。ubl 从nand flash 读取uboot,然后把uboot copy 到 ddr2(ram)的相关地址上,然后把uboot 给boot 起来。根据ti davin rbl的规定,不同型号的nand flash,ubl保存的地址是不同的,512字节page 的nand(即small page),保存的地址是:0x00004000;2048字节page的nand (即large page)保存的地址是:0x20000。至于如何通过xds560仿真器烧写ubl或通过uart boot烧写ubl,本人放在davinci uboot移植的文章介绍。(提示:rbl和ubl不要混淆!多看看boot的顺序图。)
ubl的移植,比较简单,当然,前提条件你已经搭好交叉编译环境。进入ubl文件包最上层的文件夹,使用make 就可以编译出:ubl_davinci_nand.bin。ubl主要有: ubl.c dm644x.c util.c nand.c nandboot.c nor.c norboot.c uart.c uartboot.c ubl_davinci.lds 相关的*.h 文件和两个makefile文件。如果最上层的makefile选择$(make) -c src flash=nand,表示使用arm nand flash boot模式,这时nor,uart boot模式相关的c文件不会编译。 介绍一下: ubl_davinci.lds: 指定ubl的sections及ubl本身的入口地址; ubl.c:从selfcopy函数开始运行,copy自己到ram,然后跳到正常入口地址,执行boot(),main()等函数,调用dm644xinit(),copy uboot到ram相关地址,最后执行uboot的入口地址(entrypoint),这时uboot就可以运行了。 dm644x.c:主要配置最小系统,比如关中断、pll1、pll2设置、ddr2 时序设置、uart设置,等等。 util.c:是一些相关的malloc等公共函数。 nand.c:主要是nand flash的驱动; nandboot.c:主要是实现nand_copy,把uboot从nand copy到相应的ddr2(ram)里。 ubl要移植的东西不是很多,主要是在dm644x.c里要定义好: uint32 pll1_mult = 22; // dsp=594 mhz for dm6446,dm6441一般使用uint32 pll1_mult = 19; // dsp=513 mhz。在pll2init()函数里,使用不同型号的ddr,要设置不同的参数,即时序参数等,这是关键的地方。 nand.c及nand.h主要移植就是定义好uboot在nand的存储地址,不同型号的nand flash ,比如small page(512字节)和large page(2048字节)这些都要修改除非你的nand的类型和ti evm 兼容。 nandboot.c主要任务就是如何把u-boot.bin或带有头的u-boot.img正确copy到ddr里,这里最容易出问题,编译出来的u-boot文件一般带有valid magic number(magic_number_valid),入口地址entrypaoit,这些信息不对都使uboot 运行不起来,建议看一下或copy uboot的image.h。 本人在自己设计的开发板上实现ubl的移植。ubl把uboot运行起来,很多事情都可以做了,linux kernel,rootfs,nfs,dsp,设备驱动,应用等等,都可开始按部就班开发。