Sitara AM335x Bootload的流程分析 .pdf |
平台:AM335x
Linux SDK :PROCESSOR-SDK-LINUX-AM335X(v03.01)
此SDK下载网址: http://www.ti.com/tool/processor-sdk-am335x
文章面向对象:ARM的初学者 或 SDK新版本初级使用者
文章base操作:在Linux平台成功安装上述的Linux SDK以及uboot成功编译。
若在安装或者编译有问题,请参考以下关于文章基础操作的教程link:
http://processors.wiki.ti.com/index.php/Processor_SDK_Linux_Getting_Started_Guide
http://processors.wiki.ti.com/index.php/Processor_SDK_Linux_U-Boot
文章内容:第一部分概括移植Linux的启动整体步骤;
第二部分会描述出厂固化在am335x的ROM code的作用、引导模式和执行流程;
第三部分描述SPL和Uboot的运行的位置和一下基础性知识;
最后就是重点:SPL、Uboot的流程图,以及DDR的内容分布。
由于SPL、Uboot的代码冗长和某些函数实现的功能复杂,所以分析SPL、Uboot的流程图,我主要是以”全而简”(全过程+简单分析)的角度进
行介绍,这样做的目的主要是让大家比较清晰地知道bootload在哪里在哪个文件在哪个函数实现什么功能,可以方便地让大家随时随地定位你想要
了解的功能的位置。
若在细节上有任何疑问,可以根据我画的流程图方便查找和定位程序所在地,若仍然解决不了,欢迎大家可以在论坛上积极地提出来。谢谢!
dongdong qu:
具体的版本u-boot-201? 我用的最新版本ti-processor-sdk-linux-am335x-evm-03.03.00.04-Linux-x86-Install.bin 里面的u-boot-2016不一样 不知道在哪里可以下载你分析的版本
dongdong qu:
你好 我的板子是SD卡启动 用以前的版本 能启动u-boot 用最新的版本之后 插入SD卡之后就没反应 一点打印消息都没有 调试好几天了 不知道原因何在,拔掉SD卡后一直打印CCCCCC 望指点
Eggsy Pang:
回复 dongdong qu:
下载 :http://software-dl.ti.com/processor-sdk-linux/esd/AM335X/03_02_00_05/index_FDS.html
其实两个版本相差不大,我的分析流程仍然可以在你的下载的版本进行参考
Eggsy Pang:
回复 dongdong qu:
是自己做的板子还是TI EVM 板?参考我之前发过的帖子
http://www.deyisupport.com/question_answer/dsp_arm/sitara_arm/f/25/t/128026.aspx?pi239031348=1
govin huang:
请教AM335X基于StarterWare的启动问题,bootload 是否可以做成可以MMCSD卡和NAND启动?将启动设置00100,AM335X先检测从SD卡启动,如果没有SD卡后从NAND启动。bootload中PLO判断是否从SD卡启动,如果从SD卡启动就将PLO和app复制分别拷贝到nand的0地址和512*1024地址后,再拷贝到0x8000000启动,如果没有检测到SD卡就直接从nand启动。不知道是否已经有这样的启动方案,方便项目量产及程序升级!不知道这样是否行得通,请求给建议!
Eggsy Pang:
回复 govin huang:
你说的PLO是MLO吧
这个方案是可以的,记得初始化NAND,然后再拷贝
govin huang:
您好,就在原来的基础上加 nandInfo = BlNANDConfigure();初始化的NAND的函数,以后再添加了
/*** \brief – Write bytes to NAND.* \param – flashAddr – NAND Flash address.\n.* \param – size – Indicates the total size needs to be write to flash.\n.* \param – destAddr – Source address where data needs to be copy from.\n.** \return none**/void BlNANDWriteFlash (NandInfo_t *hNandInfo, unsigned int flashAddr, unsigned int size, unsigned char *srcAddr){ unsigned int currBlock = 0xFFFFFFFF; unsigned int currPage = 0xFFFFFFFF;
unsigned int pageSize = hNandInfo->pageSize; unsigned int blockSize = hNandInfo->blkSize; unsigned int bytesHasWrite = 0; unsigned int bytesToWrite = size;
NandStatus_t retVal; /* Convert the flashAddr to block, page numbers */ unsigned int blkNum = (flashAddr / blockSize); unsigned int pageNum = (flashAddr – (blkNum * blockSize)) / pageSize;
// Check the current block is whether GOOD until we are in a good block while (NANDBadBlockCheck(hNandInfo,blkNum) != NAND_BLOCK_GOOD) { blkNum += 1; pageNum = 0; }
currPage = pageNum; currBlock = blkNum; // Erase falsh first! retVal = NANDBlockErase( hNandInfo, currBlock); if (retVal != NAND_STATUS_PASSED) { while(1); }
// If we have one or more full blocks to copy, copy them directly // Any leftover data (partial page) gets copied via the memory buffer while (bytesHasWrite < bytesToWrite) { memcpy ((void *)txData,(unsigned char *)&srcAddr[bytesHasWrite],2048); //CacheDataCleanBuff( (unsigned int) txData, 2048); //2015-10-29 retVal = NANDPageWrite( hNandInfo, currBlock, currPage,txData, &eccData[0]); if(retVal != NAND_STATUS_PASSED) { while(1); }
bytesHasWrite += pageSize; currPage += 1;
// Check to see if curr page is at end of a block if (currPage >= hNandInfo->pagesPerBlk) { // If so, increment current block until we are in a good block do { currBlock += 1; } while (NANDBadBlockCheck(hNandInfo,currBlock)!= NAND_BLOCK_GOOD);
// Erase flash first! retVal = NANDBlockErase( hNandInfo, currBlock); if(retVal != NAND_STATUS_PASSED) { while(1); } currPage = 0; } }}
上面代码新加进去的,前面的拷贝都正常,我是现将MLO和app先拷贝到ddr里面,再调用上面函数拷贝到NAND的,
BlNANDWriteFlash (nandInfo, 0, mlo_size, (unsigned char *)mlo_ddr_addr);
但是每次到
retVal = NANDPageWrite( hNandInfo, currBlock, currPage,txData, &eccData[0]);这里就死了,什么情况都搞不明白!我使用IAR软件调试仿真的!
这里都没有进去就死了(我已经把编译成库的文件全部合到工程里面,就是不使用库调用了)
望赐教!谢谢!
govin huang:
回复 govin huang:
您好,就在原来的基础上加
BlPlatformNANDSetup();
nandInfo = BlNANDConfigure();
初始化的NAND的函数,以后再添加了
/*** \brief – Write bytes to NAND.* \param – flashAddr – NAND Flash address.\n.* \param – size – Indicates the total size needs to be write to flash.\n.* \param – destAddr – Source address where data needs to be copy from.\n.** \return none**/void BlNANDWriteFlash (NandInfo_t *hNandInfo, unsigned int flashAddr, unsigned int size, unsigned char *srcAddr){unsigned int currBlock = 0xFFFFFFFF;unsigned int currPage = 0xFFFFFFFF;
unsigned int pageSize = hNandInfo->pageSize;unsigned int blockSize = hNandInfo->blkSize;unsigned int bytesHasWrite = 0;unsigned int bytesToWrite = size;
NandStatus_t retVal;/* Convert the flashAddr to block, page numbers */unsigned int blkNum = (flashAddr / blockSize);unsigned int pageNum = (flashAddr – (blkNum * blockSize)) / pageSize;
// Check the current block is whether GOOD until we are in a good blockwhile (NANDBadBlockCheck(hNandInfo,blkNum) != NAND_BLOCK_GOOD){blkNum += 1;pageNum = 0;}
currPage = pageNum;currBlock = blkNum;// Erase falsh first!retVal = NANDBlockErase( hNandInfo, currBlock);if (retVal != NAND_STATUS_PASSED){while(1);}
// If we have one or more full blocks to copy, copy them directly// Any leftover data (partial page) gets copied via the memory bufferwhile (bytesHasWrite < bytesToWrite){memcpy ((void *)txData,(unsigned char *)&srcAddr[bytesHasWrite],2048);//CacheDataCleanBuff( (unsigned int) txData, 2048); //2015-10-29retVal = NANDPageWrite( hNandInfo, currBlock, currPage,txData, &eccData[0]);if(retVal != NAND_STATUS_PASSED){while(1);}
bytesHasWrite += pageSize;currPage += 1;
// Check to see if curr page is at end of a blockif (currPage >= hNandInfo->pagesPerBlk){// If so, increment current block until we are in a good blockdo{currBlock += 1;}while (NANDBadBlockCheck(hNandInfo,currBlock)!= NAND_BLOCK_GOOD);
// Erase flash first!retVal = NANDBlockErase( hNandInfo, currBlock);if(retVal != NAND_STATUS_PASSED){while(1);}currPage = 0;}}}
上面代码新加进去的,前面的拷贝都正常,我是现将MLO和app先拷贝到ddr里面,再调用上面函数拷贝到NAND的,
BlNANDWriteFlash (nandInfo, 0, mlo_size, (unsigned char *)mlo_ddr_addr);
但是每次到
retVal = NANDPageWrite( hNandInfo, currBlock, currPage,txData, &eccData[0]);这里就死了,什么情况都搞不明白!我使用IAR软件调试仿真的!
这里都没有进去就死了(我已经把编译成库的文件全部合到工程里面,就是不使用库调用了)
望赐教!谢谢!
user4750962:
回复 govin huang:
您好,您用nand启动的boot可以用吗,我也是使用startware的boot裸跑,不知道从nand启动的程序该如何写,向您请教下
user5306891:
我自己做的板子,下载了PROCESSOR-SDK-LINUX-AM335X06_00_00_07 的 uboot-spl.bin 之后没有打印uboot版本信息,什么打印都没有,配置了GPIO点灯也不亮。 下载 AM335xSDK08_00_00_00 版本的uboot-spl.bin 是没有问题的。是为什么呢?