关于s3c6410的SD卡启动

来源:互联网 发布:淘宝买的丰胸贴有用吗 编辑:程序博客网 时间:2024/05/05 01:47

要研究裸机程序的编写,必须要有一个“全裸”的环境。友善提供的superboot可以提供执行用户自定义程序的能力,但其实这样运行的程序环境还是依赖于superboot的, 那些内存初始化、时钟初始化,串口初始化等工作都已经由superboot做了。tiny6410支持nandflash和sd卡启动两种模式,nandflash的烧写还是依赖superboot,所以比较简便的方法是通过sd卡启动,superboot本身也是通过sd卡启动的。

      从网上搜了一下这方面的资料,主要参考文章来来去去就几篇, 三星的S3C6410_Internal_Rom_Booting.pdf是一份比较有用的资料,当然还有其中一些文章也比较有用,例如djyos的sd卡启动试验。这些文章描述s3c6410的要点总结如下:
      (1) s3c6410启动过程分成BL0, BL1, BL2几个阶段, 其中BL0是固化在s3c6410内部的IROM中的, 该段程序根据所选择的启动模式从存储介质加载BL1. s3c6410支持从多种存储介质中启动,nandflash, sd卡,sdhc卡,OneNand, MoviNand.... BL1和BL2存储于这些存储介质中。这里我主要关注sd和sdhc卡.
      (2) BL0在加载BL1前已经做了很多工作,sd控制器初始化,关闭看门狗等。
      (3) 对于sd卡, BL1位于 (totalSector - 18) 的扇区;对于sdhc卡,BL1位于(totalSector-1042)的扇区。BL1由BL0加载到 0x0C000000处运行,大小为8K.
       
  
   
      知道了上面几点,就可以制作sd启动卡了,可以将所编写的裸机程序放到BL1的位置。下面编写一个最简单的点灯程序(LED1~LED4全亮):
///// led.s:
       .text
       .code 32
       .global _start
       _start:
           ldr r0,=0x7f008800
           ldr r1,=0x11111111
           str r1,[r0]
           ldr r0,=0x7f008808
           ldr r2,=0xff0f
           str r2,[r0]
       loop:
           b loop

//// makefile:       

      CC=arm-linux-gcc
      LD=arm-linux-ld
      OBJCOPY=arm-linux-objcopy
      CFLAG=-c
      LDFLAG=-e _start -Ttext 0x0c000000

      led.bin: led 
          $(OBJCOPY) -O binary $< $@

      led: led.o
           $(LD) $(LDFLAG) $? -o $@

      led.o:led.s           $(CC) $(CFLAG) $< -o $@

      clean:
            rm *.o
            rm led
            rm led.bin

      下面要将led.bin写入BL1.使用的是2G的sd卡,所以应该写到 -512 * 18处。网上的文章都说用WinHex写入,我使用的是linux环境,没有WinHex可用,不过其实dd命令就可以对绝对磁盘扇区做读写。还有一个问题就是要知道sd卡的大小, 用fdisk命令就可以了:
 $ sudo fdisk -l /dev/sdb

Disk /dev/sdb: 2059 MB, 2059403264 bytes
207 heads, 37 sectors/track, 525 cylinders
Units = cylinders of 7659 * 512 = 3921408 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xb2a60e0e

Device Boot Start End Blocks Id System
/dev/sdb1 1 525 2010469 b W95 FAT32

      所以要写入的地址为 2059403264 - 18 * 512 = 2059394048
      然后用dd命令写入led.bin :
      $ sudo dd if=./led.bin of=/dev/sdb seek=2059394048 bs=1
      至此一张可启动的sd卡就完成了,插入tiny6410, 选择sd卡启动模式,就可以看到板子启动时4灯全亮。
      注:友善宣称它提供的SDFlasher.exe可以不论sd和sdhc卡都可以支持,从而优于三星提供的IROM_Flushing_Tool, 三星的要选择是sd还是sdhc。其实原理很简单,SDFlasher.exe写入时不论是-18扇区还是-1042扇区都写入。
 
 
1、资料上说SD卡分两种,一种是普通的SD卡,一种是SDHC卡,主要区别是后者支持大容量,高速;但是文件系统必须都是FAT32,所以无法格式化为FAT32文件系统的卡是无法使用的,这主要是为了兼容SDHC卡,因为只有FAT32的系统才能管理大容量的存储设备,所以SDHC卡都必须使用FAT32,但是s3c6410有一个缺点,就是在识别SDHC卡的时候会忽略后面的1024的块,也就是512K的空间,所以在往SDHC卡内部存储程序时只能抛弃后面的512K的空间,这个地方要注意啦,磁盘格式化仅仅是删除的文件目录区,实际数据还在,而文件目录还有一个备份,这就是为什么删除的文件可以恢复的原因,但是烧写软件可是不知道你的卡是不是SDHC,只会一味的按照你的选择往不同的地址烧写程序,所以说如果你的卡是普通SD卡,而你又烧写过程序,而且你的文件总的大小小于512K,那么即使你再次烧写普通的SD卡的时候选择了SDHC卡,那么还是可以启动的,因为你以前的程序还在,所以会让人误认为随便一个卡用两种方式烧写都可以,
所以切记,使用之前要知道你的卡是什么卡,因为有的不正规的SDHC卡是不会给标示的。
    2、关于boot的启动流程,分为三段:BL0,BL1,BL2,BL0被厂商固化到了处理器当中,启动会先执行这一段代码,具体做什么请看数据手册,他会将BL1拷贝到内部SRAM中,这里就是体现启动方式的时候了,因为处理器会根据你的选择模式去到指定位置加载程序,这里比如选择了SD卡,那么处理器就会到SD中的倒数第18个块开始取数据,这里指出,如果是SDHC卡,其实是到1024+18个块处取程序,因为处理器根本就看不到最后的1024个块,这应该是6410内部固化代码存在的bug或者是故意为之,SD卡一个块是512个字节,所以18个块就是9K,但是6410要求最后必须空出来1K,不知道用意何在,也许是为了以后的产品升级吧,所以正好是从倒是第18个块开始取8K的数据到内部的SRAM中,在前8K当中一定要做一件很重要的事情,就是将整个uboot的加载和重定位到SDRAM当中去最后跳转到绝对地址运行,这样即使你的BL1还没执行完,也可以到SDRAM中继续干活啦,前面是汇编,在重定位之前必须是位置无关代码,至于什么是位置无关,请百度吧,这一段完成一些基本初始化,最主要就是要加载和重定位,另外就是堆栈的初始化,因为后面的C语言阶段是需要堆栈的,具体每个阶段都需要完成哪些东西,根据具体情况会有差别,当然第二阶段加载内核和参数传递时必须有的,其实这些就好像我们的系统一样,有最小系统之说,基本必须的一定要有,其他都是根据具体情况而定。所以我们有的人会认为BL1是汇编部分,BL2是C语言部分,其实不对,更合适的理解应该是这是UBOOT代码的完成任务的两个阶段。BL0在完成一些低级初始化之后就是将BL1拷贝到SRAM,BL1在完成一些初始化之后将uboot代码拷贝到SDRAM中,重定位到编译器编译指定是位置,然后跳转,BL2就是完成一些复杂的初始化,以及很多辅助调试功能,比如网络命令,usb命令,nand命令等等,最后执行你的bootcmd,将内核加载到指定位置,将bootargs放到指定位置,传递给内核mach_type,bootargs的存放地址,然后跳转到内核执行,到这里uboot就完成使命然后消失了。所以说BLx我们可以认为是uboot功能的几个阶段,其实如果只是基本功能的话,完全可以将代码压缩到8K以内,那么就不需要重定位。编译的时候直接从0地址开始就行了。
    3、另外有一个误区,我们在使用SD卡启动的时候,这个代码必须是拼接够256K然后再接上BL1的8K,形成一个264K的代码,然后通过软件烧写到SD卡中,其实这个都是由于三星官网提供的UBOOt代码给忽悠的,因为代码里面前8K在重新加载完整UBOOT代码的时候是从256K+8K开始,然后加载256K到SDRAM,其实我们不能决定的地址只有那个8K的位置,因为这是BL0决定的,我们无法改变,但是拷贝BL2我们是可以自己决定的,也不一定必须是256K,不需要去拼接代码,我们可以放到整个SD卡的任何位置,另外我们还可以放一些其他的东西,比如开始动画,logo啥的,只要你在UBOOT里面配置一下这个地址就行啦。
原创粉丝点击