记录Ok6410 sd 启动uboot

1\参考资料https://github.com/SeanXP/ARM-Tiny6410/tree/master/no-os/sd-no-os/u-boot

2\参考资料https://blog.csdn.net/xinxin_2011/article/details/85228961

3\编译sd ram128版本的uboot

make ARCH=arm CROSS_COMPILE=$(编译器路径)/arm-linux-  forlinx_sd_ram128_config

make ARCH=arm CROSS_COMPILE=$(编译器路径)/arm-linux-  all -j8

记录Ok6410 sd 启动uboot

4\操作编译出来的u-boot.bin

cat u-boot.bin >> temp
cat u-boot.bin >> temp
split -b 256k temp
mv xaa u-boot_256k.bin
split -b 8k u-boot.bin
mv xaa u-boot_8k.bin
cat u-boot_256k.bin >> u-boot_mmc.bin
cat u-boot_8k.bin >> u-boot_mmc.bin

5\根据写入位置信息,将u-boot写入sd卡中

dd if=u-boot_256k.bin of=/dev/sdc seek= 7625166 bs=512

dd if=u-boot_256k.bin of=/dev/sdc seek=7625166 bs=512

sync

记录Ok6410 sd 启动uboot

下面是参考的资料

前面讲了Uboot启动流程和如何修改调试串口,相信大家对Uboot已经有了初步的了解,今天来进行更深一点的分析。上篇文章 OK6410开发板Uboot学习总结----(二)修改调试打印串口 遗留一个问题:烧写文件时Uboot还是使用原串口0打印。这次我们就解决这个问题,制作自己的烧写Uboot。
S3C6410芯片SD卡启动流程可以参见《S3C6410_Internal_ROM_Booting.pdf》文档:

从图中可以看出,芯片上电后先执行BL0代码,这部分程序是写死在内部iROM中,出厂时厂家就烧写好了的。而设置SD卡启动后大致流程是先准备8K的引导代码在BL1(写在SD卡最后保留扇区中的那部分),它启动后用来初始化系统,时钟,串口,SDRAM等硬件,并且将SD卡中完整的Uboot(有效内容大小不能超过256K)拷贝到BL2上运行。
下面来分析拷贝的代码,在cpu/s3c64xx/start.S文件:

如果从NAND Flash启动,不需要拷贝,直接跳转到after_copy处;如果从SD启动,跳转到movi_bl2_copy实现Uboot拷贝到BL2的功能。这个函数在哪里了呢,这是一段C代码,在cpu/s3c64xx/movi.c文件中:

6410是有两个MMC通道的,OK6410使用的是通道0,如果板子使用其他通道的话,需要修改include/movi.h文件的HSMMC_CHANNEL宏:

计算偏移量和大小这里面涉及到的宏较多,重要的是MOVI_BL2_POS和BL2_BASE,都是在include/movi.h文件中定义的,BL2_BASE好分析,先来看它:

由于拷贝代码后才使能MMU单元,所以这个地址是映射前的物理地址,由TEXT_BASE决定。记得第一篇博文OK6410开发板Uboot学习总结----(一)Uboot启动分析 里面提到uboot1.1.6\board\samsung\smdk6410\u-boot.lds文件:

那么这个TEXT_BASE地址就是0x00000000吗,再看同目录下的Makefile文件:

在编译的时候包含了当前目录的config.mk文件,这里有对有TEXT_BASE的定义:

显示TEXT_BASE已经被更新为0x5FE00000了。再来看MOVI_BL2_POS宏定义:

可见MOVI_BL2_POS 是需要拷贝的数据位于SD的起始扇区位置,其计算需要依靠其他几个宏,也定义在movi.h文件:

这里定义SD卡扇区大小固定为512了,这也是为什么大容量的SD卡直接用于烧写是不行的(网上有说通过改写上位机SD卡制作程序才行,大扇区SD卡也得改为512来读写,以后有时间试试)。通过计算:

MOVI_LAST_BLKPOS = *((volatile unsigned int*)(TCM_BASE - 0x4))-((1 * 1024)/512)
MOVI_BL1_BLKCNT = (8*1024) / 512 = 16
MOVI_BL2_BLKCNT = (256 * 1024) / 512 = 512
MOVI_ENV_BLKCNT = 0x4000/512 = 32
1
2
3
4
MOVI_BL1_BLKCNT是BL1代码所占的大小(16x512=8K),MOVI_BL2_BLKCNT是BL2代码所占的大小(512x512=256K),这也解释了为什么Uboot代码不能超过256K了。目前只有MOVI_LAST_BLKPOS还没计算出来,大致看出了MOVI_BL2_POS的计算方式:
先得到这个SD的总扇区数TOTAL,再减去256K的BL2和8K的BL1所占的扇区数,最后减去0.5K 的eFuse和0.5K的保留区所占的扇区数。
看下图会更清楚,这也是为什么上位机制作烧写SD的工具需要操作最后的18个扇区:

程序中用到了寄存器地址TCM_BASE-4来获得SD卡的总容量的,具体怎么得到的呢?先看它在movi.h文件中定义:

TCM_BASE - 0x4就是0x0C003FFC,这块地址是干什么的呢,显然不是外设地址(外设是从0x70000000开始的),还是看手册吧:

手册里介绍这块属于内部SRAM地址范围,启动的时候该地址会被映射的,而其他的手册并没有介绍,还是看《S3C6410_Internal_ROM_Booting.pdf》文档:

终于找到这个既熟悉又陌生的地址了,它就代表SD卡的总容量块数,是芯片内部自动读取到的。这文档没有中文的啊,就乎看吧,要是有个英语好的妹子记得联系我啊,能助我一臂之力。唔,不说了,好害羞啊。。。
再回头去看movi_bl2_copy函数中CopyMovitoMem函数:

也是用这个地址+8,这个拷贝函数也是芯片自动实现的:

这个拷贝函数对于SDHC类型的卡有什么限制条件吗:

要求每块扇区大小是512字节,这就是为什么前面计算时扇区大小固定为512了,你要用大容量的SD卡,扇区不是512字节的就不行了,拷贝函数首先就不支持了。

分析完6410的SD卡启动流程,那么如何编译烧写用的mmc.bin文件呢,在uboot1.1.6/include/configs/smdk6410.h文件里有相关的宏定义:

可见是通过定义FORLINX_BOOT_NAND 和FORLINX_BOOT_SD来区分的,当定义FORLINX_BOOT_SD宏时,CONFIG_BOOT_MOVINAND宏也会被定义,而且CONFIG_BOOTCOMMAND就变为烧写u-boot.bin等一系列烧写命令了,这就是为什么SD卡启动的Uboot能自动实现烧写功能。
那么FORLINX_BOOT_NAND宏在哪里定义的呢?在uboot1.1.6/include/config.h文件中定义的:

注释上写得很清楚,这个是自动产生的,不需要我们自己编辑。编译前执行命令“make forlinx_nand_ram256_config”产生的这些宏定义,我们来看下Makefile文件:

下面的forlinx_sd_ram256_config标签就应该是配置SD卡启动的编译宏定义,二者区别只在于一个有“NAND”,一个有“SD”。分析一下这个命令,首先unconfig 命令是删除以前的配置文件,而后面的@$(MKCONFIG):
@表示不要echo这个命令到标准输出
$(MKCONFIG) 是个环境变量,对应脚本的名字是mkconfig
那么相当于执行“mkconfig smdk6410 arm s3c64xx…”命令,后面的内容以参数的形式传入了mkconfig脚本中,比如smdk6410对应的就是$1,依次推算,NAND或SD对应的是$7,那么看一下脚本文件:

如果是SD,就往config.h文件写入FORLINX_BOOT_SD宏,如果是NAND,就往config.h文件写入FORLINX_BOOT_NAND宏。由此可见,只要执行“make forlinx_sd_ram256_config”,就能完成支持SD卡启动Uboot的编译配置。但是编译完的u-boot.bin文件,大小并没有符合上面要求的256K+8K的条件,所以还得自己写个脚本:

cat u-boot.bin >> temp
cat u-boot.bin >> temp
split -b 256k temp
mv xaa u-boot_256k.bin
split -b 8k u-boot.bin
mv xaa u-boot_8k.bin
cat u-boot_256k.bin >> u-boot_mmc.bin
cat u-boot_8k.bin >> u-boot_mmc.bin
1
2
3
4
5
6
7
8
这个脚本负责把大小不足256K的u-boot.bin文件填充至256K,再在后面加上8K大小的BL1启动的Uboot程序。由于飞凌原来的mmc.bin文件大小就是280K(这可能与上位机烧写软件SD_Writer.exe写法有关),所以这里在256K的u-boot_256k.bin文件后面又添加了3个8K的u-boot_8k.bin,正好大小为280K。
把我们新生成的u-boot_mmc.bin文件用SD_Writer.exe程序写进SD卡中,烧写后,这下烧写用的Uboot调试串口也改为我们指定的串口3了,大功告成!!!
---------------------
作者:竹影云
来源:CSDN
原文:https://blog.csdn.net/xinxin_2011/article/details/85228961
版权声明:本文为博主原创文章,转载请附上博文链接!


上一篇:u-boot分析(四)---设置异常向量表|设置SVC模式


下一篇:学生管理系统(基于C++操作台)