背景:项目进行到最后阶段,所有的启动都需要放到NAND Flash芯片上。但是由于硬件设计,没有添加网络和JTAG模块,所以常见的NFS和JTAG烧写方式失效。于是,我们需要寻找可行的烧录方式。
平台:
操作系统:Ubuntu 10.04
开发板:DM368
工具:TI旗下的某些工具(下面用到了就会具体解释)和串口调试工具
开发板启动模式,在这里只列出3种:
BTSE[2:0] = 000:NAND启动
BTSE[2:0] = 010:SD卡启动
BTSE[2:0] = 011:串口启动
BTSEL[2:0]是来控制DM368释义何种方式启动的,最终决定RBL的代码如何执行。
相关知识:
总体:采用串口启动和NAND启动,配合完成整个系统的启动。
通过串口启动烧写UBL和U-Boot。
RBL:ARM ROM Boot Loader,TI固化在ROM中的bootloader。上电后会先运行RBL,然后由RBL去引导UBL。
UBL:User Boot Loader,UBL来引导uboot的加载。一级boot loader。大小有限制。
Uboot:用来引导加载linux内核。二级boot loader。
具体操作:
首先,选择板子启动模式为串口启动,以便于将UBL和U-Boot烧写到Flash中去。这里需要注意,虚拟机连接主机的USB串口。使用:
dmesg | grep ttyUSB*
查看串口信息。
其次,我们需要找到:
烧写工具:sfh_DM36x.exe,
UBL文件:UBL_DM36x_NAND_ARM432_DDR340_OSC24.bin,
u-boot文件:u-boot.bin
位置:
psp/board_utilities/serial_flash/dm365/ psp/u-boot-2010.12-rc2-psp03.01.01.39/u-boot.bin
最好是把这三个文件拷贝到同一个文件夹,然后再去执行命令。
下载UBL和Uboot:
- 首先需要擦写flash
/home/davinci/test/sfh_DM36x.exe –nanderase –v –p /dev/ttyUSB0
注意:由于TI软件问题,执行两次才会成功。
- 烧写flash:
/home/davinci/test/sfh_DM36x.exe –nandflash /home/davinci/test/UBL_DM36x_NAND_ARM432_DDR340_OSC24.bin /home/davinci/test/u-boot.bin –v –p /dev/ttyUSB0
注意:由于TI软件问题,执行两次才会成功。
以上两个操作,都出现Operation completed successfully才算烧写成功。
完成以上操作以后,断开板子电源,把板子启动模式改成NAND启动,串口作为打印功能。进入DM36x Leopard # 命令提示符。这就是uboot模式,然后在这个模式中完成kernel和文件系统的烧写。
接下来解释一些U-Boot的nand命令:
nand read InAddr FIAddr size
InAddr:从nand flash中读取,然后存放的目的内存地址
FIAddr:nand flash读取起始地址
size:读取的内容大小
一句话解释上面命令:从Nand Flash芯片的FIAddr地址读取size大小内容存放到地址为InAddr的内存中。
nand write InAddr FIAddr size
InAddr:写到nand flash中的资源在内存中的起始地址
FIAddr:nand flash的起始地址
size:数据的大小
一句话解释上面命令:从地址为InAddr的内存中读取size大小的内容写入到Nand Flash芯片的FIAddr地址处
bootm 内存地址:内核从改地址启动
一句话解释上面命令:从指定的内存地址开始加载内核。也就是第一条中read的InAddr的值。
下面贴一张Nand Flash芯片大小分配的图片:
可以计算出:
UBL的大小是:20 * 128KB(bootloader)
U-Boot大小是:20 * 128KB(params)
kernel的大小:4M
filesystem1: 128M + 64M
filesystem2: 剩下
在这里,我需要说几个常识:
2的10次方个byte等于1KB;
2的20次方个byte等于1MB;
2的30次方个byte等于1GB。
比如:
128KB = 131072bytes
20 * 128KB = 2621440bytes
然而在Nand Flash芯片里面,都是使用十六进制表示的。
于是:
2621440=0x00280000
也就是说UBL在Nand Flash芯片上存储的物理地址就是:
0x00000000--0x00280000
依次可以计算得到:
0x00280000--0x00500000//U-Boot的地址范围
0x00500000--0x00900000//kernel的地址范围
注意:Nand Flash的物理地址分配了这么多空间给各个部分,但是不一定非要使用这么大的空间。但是,如果使用的空间大于这个值,则需要重新分区。
再就是,我们通过串口已经把UBL和U-Boot烧录到Nand Flash中去了,我们现在就只需烧录kernel就好。
---------------------------分割线-------------------------------
在U-Boot模式下,完成Nand Flash的kernel烧写。
- 插入装有uImage的sd卡;
- 执行如下命令
mmc init//初始化sd卡
mmc rescan 0//把sd卡挂到U-Boot上面
fatload mmc 0 0x81000000 uImage//把uImage读到内存中
如果没有错误的话,会出现一个数字,单位是bytes。
假设,我现在的这个数字是:1919704bytes。一定要牢记这个数字。
这个数字代表,我们uImage(内核)的大小,它将会在内存中占据的空间,同样当我们把它写入到Nand Flash芯片中的时候占据的空间大小。
根据上面的计算原理:
1919704bytes占据的地址长度就是这个数字的十六进制形式:0x001D4AD8。
现在,我们需要执行:
//把内存中的uImage写到Nand Flash芯片中
nand write 0x81000000 0x00500000 0x001D4AD8
如果没有错的话,会提示写入成功。
此刻剩下的就是测试内核是否会被成功加载?
断电,拔出sd卡,上电,执行下面命令:
//Nand Flash芯片地址0x05000000开始,size为0x001D4AD8的内核内容读到内存地址0x81000000中
nand read 0x81000000 0x0050000 0x001D4AD8
//从内存地址0x81000000处启动
bootm 0x81000000
如果没有错误,会看到内核的解压缩打印信息。
写到这里,已经完成了Nand Flash启动的3/4的工作量。
下一遍笔记将会完成文件系统的nand烧写。