S5PV210--1---210启动方式和代码前16字节

按照三星《S5PV210_UM_REV1.1》手册上说明的启动流程为:S5PV210上电将从IROM(interal ROM)处执行固化的启动代码,它对时钟等初始化、对启动设备进行判断,并从启动设备中复制BL1(最大16KB)到IRAM0xd002_0000处,其中0xd002_0010之前的16个字节储存的BL1的校验信息和BL1尺寸)中,并对BL1进行校验,校验OK转入BL1进行执行

首先解释一下我认为的BL0BL1BL2

(1)BL0:是指S5PV210IROM中固化的启动代码
(2)BL1:是指在IRAM自动从外扩存储器(nand /sd/usb)中拷贝的uboot.bin二进制文件的头最大16K代码;

(3)BL2:是指在代码重定向后在内存中执行的的UBOOT的完整代码;

(4)三者之间关系是:(Interal ROM固话代码)BL0BL1(bootloader的前16kB)加载到iRAMBL1然后在iRAM中运行将BL2(其实整个bootloader)加载到SDRAMDDR);BL2加载内核;BL就是bootloader的简写;


刚开始的搞210时,我们编译的代码都必须通过一个工具xxx210.xxx(如mktiny210.exe),这个是为什么呢,它的作用就是在我们生成的bin文件前面加上16个字节, 下面就说说前16字节的内容是什么:

S5PV210iRAM的地址范围0xD002_0000~0xD003_FFFF,而上电后我们的iROM执行完固化的代码,并将boot设备中的代码拷贝到iRAM中,并跳转到0xD002_0010处执行,问题就在0xD002_0000~0xD002_0010这16字节数据该填写什么?

16字节头部信息,排列格式如下:

_____________________________

|0x0地址:BL1 size            |

|0x4地址:必须设置为0 (是规定)|

|0x8地址:CheckSum      |

|0xc地址:必须设置为0 (是规定)|

但是为什么要加上16字节呢,其实理解为了ECC校验用的就行了;

上面16字节的内容不是乱加的哦,下面给出uboot中参考代码,可以用的:

[cpp]  view plain copy
  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <stdlib.h>   
  4.   
  5. #define SEEK_SET           0 /* 文件开头的标记 */   
  6. #define SEEK_CUR    1 /* 当前位置的标记 */   
  7. #define SEEK_END    2 /* 文件末尾的标记 */   
  8.   
  9. #define BUFSIZE                 (24*1024)   
  10. #define IMG_SIZE                (24*1024)   
  11. #define SPL_HEADER_SIZE         16   
  12. #define SPL_HEADER              "S5PC110 HEADER  "   
  13.   
  14. int main (int argc, char *argv[])  
  15. {  
  16.     FILE        *fp;    /* 定义一个文件指针 */  
  17.     char        *Buf, *a;  
  18.     int     BufLen;  
  19.     int     nbytes, fileLen;  
  20.     unsigned int    checksum, count;  
  21.     int     i;  
  22.   
  23.     if (argc != 3) /* 如果参数个数错误,打印帮助信息,只能有两个参数*/  
  24.     {  
  25.         /* 应用工具时,格式必须是 ./mktiny210spl.exe old.bin new.bin */  
  26.         printf("Usage: mkbl1 <source file> <destination file>\n");  
  27.         return -1;  
  28.     }//这一点大家要注意,main函数其实也是可以接收参数的,argc就表示了参数的个数,   
  29. //argv就是参数的内容;   
  30.   
  31.     BufLen = BUFSIZE;  
  32.     Buf = (char *)malloc(BufLen); /* 动态分配一段24k的内存空间 */  
  33.     if (!Buf) /* 分配失败,将返回0 */  
  34.     {  
  35.         printf("Alloc buffer failed!\n");  
  36.         return -1;  
  37.     }  
  38.   
  39.     memset(Buf, 0x00, BufLen); /* 将上面分配的空间清零 */  
  40.   
  41.     fp = fopen(argv[1], "rb"); /* 以读二进制的方式打开没有头部信号的old.bin文件 */  
  42.     if( fp == NULL)  
  43.     {  
  44.         printf("source file open error\n");  
  45.         free(Buf); /* 如果打开失败,释放掉原来分配的内存,否则会造成内存泄漏 */  
  46.         return -1;  
  47.     }  
  48.   
  49.     fseek(fp, 0L, SEEK_END); /* 让文件位置指针指向文件末尾,便于下行的统计大小的操作 */  
  50.     fileLen = ftell(fp); /* 用于得到文件位置指针当前位置相对于文件首的偏移字节数,即文件大小*/  
  51.     fseek(fp, 0L, SEEK_SET); /* 让文件位置指针指向文件开始 */  
  52.   
  53.     /* 如果old.bin文件的大小小于规定的最大大小,则count等于该文件的大小,否则等于最大大小 */  
  54.     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))  
  55.         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);  
  56.   
  57.     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE); /* 拷贝16字节的数据到Buf中,即初始化头部信息的位置 */  
  58.   
  59.     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp); /* 将编译生成的old.bin文件拷贝到buf中,紧接着头部信息开始拷贝 */  
  60.   
  61.     if ( nbytes != count ) /* 返回值等于拷贝的元素的个数 */  
  62.     {  
  63.         printf("source file read error\n"); /* 如果个数和实际的不相等,则失败 */  
  64.         free(Buf); /* 释放内存 */  
  65.         fclose(fp); /* 关闭文件 */  
  66.         return -1;  
  67.     }  
  68.   
  69.     fclose(fp); /* 关闭文件 */  
  70.   
  71.     /* 以下三行,用于动态生成checksum,公式见上面的尝试一 */  
  72.     a = Buf + SPL_HEADER_SIZE;  
  73.     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)  
  74.         checksum += (0x000000FF) & *a++;  
  75.   
  76.     /* 将checksum写入buf的第三个字节处,即该是checksum的位置处 */  
  77.     a = Buf + 8;  
  78.     *( (unsigned int *)a ) = checksum;  
  79.   
  80.     fp = fopen(argv[2], "wb"); /* 以二进制写的方式创建一个新的二进制文件 */  
  81.     if (fp == NULL)  
  82.     {  
  83.         printf("destination file open error\n");  
  84.         free(Buf); /* 释放内存 */  
  85.         return -1;  
  86.     }  
  87.   
  88.     a = Buf; /* 指向内存的首地址 */  
  89.     nbytes  = fwrite( a, 1, BufLen, fp); /* 把buf中的数据写入新创建的bin文件 */  
  90.   
  91.     if ( nbytes != BufLen ) /* 返回值等于写入的元素的个数 */  
  92.     {  
  93.         printf("destination file write error\n");  
  94.         free(Buf); /* 释放内存 */  
  95.         fclose(fp);/* 关闭文件 */  
  96.         return -1;  
  97.     }  
  98.   
  99.     free(Buf); /* 释放内存 */  
  100.     fclose(fp);/* 关闭文件 */  
  101.   
  102.     return 0;  
  103. }  
[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4.   
  5. #define SEEK_SET           0 /* 文件开头的标记 */  
  6. #define SEEK_CUR    1 /* 当前位置的标记 */  
  7. #define SEEK_END    2 /* 文件末尾的标记 */  
  8.   
  9. #define BUFSIZE                 (24*1024)  
  10. #define IMG_SIZE                (24*1024)  
  11. #define SPL_HEADER_SIZE         16  
  12. #define SPL_HEADER              "S5PC110 HEADER  "  
  13.   
  14. int main (int argc, char *argv[])  
  15. {  
  16.     FILE        *fp;    /* 定义一个文件指针 */  
  17.     char        *Buf, *a;  
  18.     int     BufLen;  
  19.     int     nbytes, fileLen;  
  20.     unsigned int    checksum, count;  
  21.     int     i;  
  22.   
  23.     if (argc != 3) /* 如果参数个数错误,打印帮助信息,只能有两个参数*/  
  24.     {  
  25.         /* 应用工具时,格式必须是 ./mktiny210spl.exe old.bin new.bin */  
  26.         printf("Usage: mkbl1 <source file> <destination file>\n");  
  27.         return -1;  
  28.     }//这一点大家要注意,main函数其实也是可以接收参数的,argc就表示了参数的个数,  
  29. //argv就是参数的内容;  
  30.   
  31.     BufLen = BUFSIZE;  
  32.     Buf = (char *)malloc(BufLen); /* 动态分配一段24k的内存空间 */  
  33.     if (!Buf) /* 分配失败,将返回0 */  
  34.     {  
  35.         printf("Alloc buffer failed!\n");  
  36.         return -1;  
  37.     }  
  38.   
  39.     memset(Buf, 0x00, BufLen); /* 将上面分配的空间清零 */  
  40.   
  41.     fp = fopen(argv[1], "rb"); /* 以读二进制的方式打开没有头部信号的old.bin文件 */  
  42.     if( fp == NULL)  
  43.     {  
  44.         printf("source file open error\n");  
  45.         free(Buf); /* 如果打开失败,释放掉原来分配的内存,否则会造成内存泄漏 */  
  46.         return -1;  
  47.     }  
  48.   
  49.     fseek(fp, 0L, SEEK_END); /* 让文件位置指针指向文件末尾,便于下行的统计大小的操作 */  
  50.     fileLen = ftell(fp); /* 用于得到文件位置指针当前位置相对于文件首的偏移字节数,即文件大小*/  
  51.     fseek(fp, 0L, SEEK_SET); /* 让文件位置指针指向文件开始 */  
  52.   
  53.     /* 如果old.bin文件的大小小于规定的最大大小,则count等于该文件的大小,否则等于最大大小 */  
  54.     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))  
  55.         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);  
  56.   
  57.     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE); /* 拷贝16字节的数据到Buf中,即初始化头部信息的位置 */  
  58.   
  59.     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp); /* 将编译生成的old.bin文件拷贝到buf中,紧接着头部信息开始拷贝 */  
  60.   
  61.     if ( nbytes != count ) /* 返回值等于拷贝的元素的个数 */  
  62.     {  
  63.         printf("source file read error\n"); /* 如果个数和实际的不相等,则失败 */  
  64.         free(Buf); /* 释放内存 */  
  65.         fclose(fp); /* 关闭文件 */  
  66.         return -1;  
  67.     }  
  68.   
  69.     fclose(fp); /* 关闭文件 */  
  70.   
  71.     /* 以下三行,用于动态生成checksum,公式见上面的尝试一 */  
  72.     a = Buf + SPL_HEADER_SIZE;  
  73.     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)  
  74.         checksum += (0x000000FF) & *a++;  
  75.   
  76.     /* 将checksum写入buf的第三个字节处,即该是checksum的位置处 */  
  77.     a = Buf + 8;  
  78.     *( (unsigned int *)a ) = checksum;  
  79.   
  80.     fp = fopen(argv[2], "wb"); /* 以二进制写的方式创建一个新的二进制文件 */  
  81.     if (fp == NULL)  
  82.     {  
  83.         printf("destination file open error\n");  
  84.         free(Buf); /* 释放内存 */  
  85.         return -1;  
  86.     }  
  87.   
  88.     a = Buf; /* 指向内存的首地址 */  
  89.     nbytes  = fwrite( a, 1, BufLen, fp); /* 把buf中的数据写入新创建的bin文件 */  
  90.   
  91.     if ( nbytes != BufLen ) /* 返回值等于写入的元素的个数 */  
  92.     {  
  93.         printf("destination file write error\n");  
  94.         free(Buf); /* 释放内存 */  
  95.         fclose(fp);/* 关闭文件 */  
  96.         return -1;  
  97.     }  
  98.   
  99.     free(Buf); /* 释放内存 */  
  100.     fclose(fp);/* 关闭文件 */  
  101.   
  102.     return 0;  
  103. }  

这个代码怎么用呢,在vc或者gcc,甚至Tc中编译,生成一个xxx.exe文件,我生成的是 stepmk210.exe ,然后按照下面的格式编译bin文件,生成的新bin文件就是我们要用的;

./stepmk210.exe led.bin led1.bin


OK,如果还有不理解,请留言,大家互相了交流~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值