S3C6410 SD card启动过程分析

    技术2026-09-29  2

    S3C6410支持SD card启动,可以直接通过IROM_Fusing_tools将BootLoader烧录到SD card,然后通过启动的Bootloader来烧录新的Loader/Eboot/Os等到NandFlash,以后就可以从nand 启动了。

         通过IROM Fusing tool烧录IROM_SD_EBOOT.nb0文件到SD card后,在SD卡中是看不到文件的,因为它不是通过FAT写文件的方式,而是直接写入SD card扇区,这样S3C6410从SD card启动时,直接通过controller 读扇区。

           那么IROM_SD_EBOOT烧录在SD card的位置呢,从网上找到源代码中可以看到,当按下Start开始烧录时,程序如下:

    pMBRBuffer = ReadSector(0,1); // read MBR sector.  

    if (pMBRBuffer == NULL )  

    …..

         if (!GetTotalSector())  

           ….

    if (!m_fileImageFile.Open(m_strFilePath,CFile::modeRead)) 

    ….  

        m_dwStartWriteSector = m_dwTotalSector - EFUSE_RESEVED_SECTOR - SDHC_SHIFT_SECTOR - ((DWORD)m_fileImageFile.GetLength() / 512);  

        m_pbWriteBuffer = (char *)malloc((UINT)m_fileImageFile.GetLength());  

       ….

     

    从上面看出来,先读出MBR确认是不是FAT32系统,然后计算SD Card的sector数目,然后计算写入地址。

    #define EFUSE_RESEVED_SECTOR (2)  

    //#define SDHC_SHIFT_SECTOR (1024) // it's for SDHC card  

    #define SDHC_SHIFT_SECTOR (0)

    当是SD 时,写入的地址是 TotaolSector-2-(sizeof(ImageFile)/512)

    而是SDHC的card,写入地址是TotaolSector-1024-(sizeof(ImageFile)/512)

    而程序是默认为SD类型,所以最好是使用2G以内的SD CARD。如果改用SDHC卡,需要改程式重新编译一个新版本。

     

    用1G的SDcard作为示例,当写入成功后,通过Winhex打开SD card盘符可以看到,如下图所示。

     

    SD 烧录完成以后,那么6410启动的时候怎么找到这个位置并执行呢。从IROM_ApplicationNote中启动图示看到,

     

    CPU从SD card的最后18 sector后的16sector,正好8KB进入steppingstone空间。那么我烧录SD card的image size是512KB,远大于8K,那么那些什么时候加载呢,通过分析,我们看到,烧录档实际分为NBL2+NBL1两部分,NBL1正好是最后的8K空间。所以自动加载入CPU的是NBL1,而NBL2是由NBL1的code来加载的,

    打开NBL1的main.c文件,只有两个函数

    CopyMovitoMem(1,globalBlockSizeHide-18-EBOOT_NB0_SIZE, EBOOT_NB0_SIZE, (unsigned int *)LOAD_ADDRESS_PHYSICAL, 1);

    ((PFN_IMAGE_LAUNCH)(LOAD_ADDRESS_PHYSICAL))();

    第一个函数作用是,看上去应该是将SD card中的Loader从SD card中读出来,搬移到SDRAM里面。这个函数的主体是找不到的,在IROM_ApplicationNote文件中有叙述,这个是用于从SD card搬移数据的内置函数。可能是如果用户自己写入SD驱动再搬移,可能会产生size比较大,所以CPU提供内置的函数,仅仅对controller进行精简控制。

    而0x0C003FFC这个地址也是在文档中注明的。存储的是SD card的sector的数目。

     

     

    第二个函数是跳转到搬移后SDRAM的位置执行NBL2,

    #define EBOOT_NB0_SIZE (0x80000/0x200)

    #define globalBlockSizeHide             (*((volatile unsigned int*)( 0x0C003FFC)))

    #define CopyMovitoMem(z,a,b,c,e) (((int(*)(int, unsigned int, unsigned short, unsigned int*, int))(*((unsigned int *)0x0C004008)))(z,a,b,c,e))

     

    这样就可以将NBL2加载到SDRAM并执行。然后再NBL2中加载EBOOT,EBOOT再加载OS。

    最新回复(0)