|
Helper2416-08——裸机第二弹——制作可从SD卡启动的bin文件(附上源码包)
[复制链接]
本帖最后由 yuanlai2010 于 2014-7-14 08:19 编辑
裸机第二弹——制作可从SD卡启动的bin文件
参与Helper2416开发板助学计划心得 07-14 应网友要求 已附上源码包 欢迎下载 直接make就行了
在上一篇帖子裸机第一弹——点亮LED+SD启动中为了让直接编译生成的bin文件可以从SD卡运行,我是使用网友分享的一个小软件把bin文件处理了一下,但是有点麻烦。所以今天就为大家分享一下我自己编写的这C程序,在mekefile里面调用它来生成可直接在SD启动的bin文件,那是相当的方便!
首先讲解下原理:
在BL0阶段,IROM内固化的代码读取SD卡内特定位置的8K内容(BL1),
IROM_Fusing_tools从TOTAL_SECTOR – 2 - SIZE_OF_IMAGE/512扇区开始烧写;
其中TOTAl_SECTOR是这个磁盘总的扇区数目,它是通过读取磁盘的MBR扇区判断是否为FAT32格式然后获得
TOTAl_SECTOR的(这也是为什么SD卡必须为FAT32格式),
SIZE_OF_IMAGE/512是这个bin文件将要占据的扇区数
(这里是以
512Byte为扇区大小的,如果SD卡的扇区大小非512Byte,就需要重新计算和修改程序了)
以下是 SD/MMC 的卡的存储结构 从6410的一篇文档
CHxx_IROM_ApplicationNote_Rev0.2_080618.pdf
(201.7 KB, 下载次数: 49)
中截取的,2416同样适用。
SD/MMC 1Block = 512 Byte
在SD启动方式下,S3C2416内部的IROM程序BL0首先运行,并将SD中的最后18个扇区开始的16个扇区内容复制到片内 的8K SRAM,也就是SteppingStone,接着跳转到这块SRAM的开始地址开始运行,现在玩裸机的话程序暂时没超过8K 就先让它在SteppingStone运行就行,后续使用上SDRAM就可运行更大的程序了。所以就先让我们的裸机程序放在这8K里面咯!
附上源码及重新编写的makefile文件
mk2416sdbin.c
- /***************************************************************************************
- 文件:mk2416sdbin.c
- 作者:yuanlai2010
- 版本:2014-07-11
- NOTE:
- 在BL0阶段,Irom内固化的代码读取SD卡内特定位置的8K内容(BL1),
- IROM_Fusing_tools从TOTAL_SECTOR – 2 - SIZE_OF_IMAGE/512扇区开始烧写;
- 其中TOTAl_SECTOR是这个磁盘总的扇区数目;SIZE_OF_IMAGE/512是这个bin文件将要占据的扇区数
- (这里是以512为扇区大小的)
- 以下 SD/MMC 的卡的存储结构
- SD/MMC 1Block = 512 Byte
- =========================================================================================
- | SD/MMC Device |
- =========================================================================================
- | | Recommendation | Mandatory |
- | User File System |=====================================================================
- | | Kernel | BL2 | BL1(8K) | Signature(512Byte) | Reserved(512Byte) |
- | | | | 16 Block | 1 Block | 1 Block |
- =========================================================================================
- *****************************************************************************************/
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define BUFSIZE (8*1024)
- #define IMG_SIZE (8*1024)
- int main (int argc, char *argv[])
- {
- FILE *in_fp, *out_fp;
- char *Buf, *tmp;
- int BufLen, nbytes, fileLen;
- unsigned int count;
-
- // 1. 判断是否是三个参数(mkbl1 <source file> <destination file>)
- if (argc != 3)
- {
- printf("Usage: mkbl1 <source file> <destination file>\n");
- return -1;
- }
- // 2. 分配8K的buffer
- BufLen = BUFSIZE;
- Buf = (char *)malloc(BufLen);
- if (!Buf)
- {
- printf("Alloc buffer failed!\n");
- return -1;
- }
- memset(Buf, 0x00, BufLen);
- // 3. 读源bin到buffer
- // 3.1 打开源bin
- in_fp = fopen(argv[1], "rb");
- if( in_fp == NULL)
- {
- printf("source file open error\n");
- free(Buf);
- return -1;
- }
- // 3.2 获取源bin长度
- fseek(in_fp, 0L, SEEK_END);
- fileLen = ftell(in_fp);
- fseek(in_fp, 0L, SEEK_SET);
- // 3.3 源bin长度不得超过8K
- count = (fileLen < IMG_SIZE)
- ? fileLen : IMG_SIZE;
- // 3.4 读源bin到buffer
- nbytes = fread(Buf, 1, count, in_fp);
- if ( nbytes != count )
- {
- printf("source file read error\n");
- free(Buf);
- fclose(in_fp);
- return -1;
- }
- fclose(in_fp);
- // 4. 拷贝buffer中的内容到目的bin
- // 4.1 打开目的bin
- out_fp = fopen(argv[2], "wb");
- if (out_fp == NULL)
- {
- printf("destination file open error\n");
- free(Buf);
- return -1;
- }
- // 4.2 将8k的buffer拷贝到目的bin中
- tmp = Buf;
- nbytes = fwrite( tmp, 1, BufLen, out_fp);
- if ( nbytes != BufLen )
- {
- printf("destination file write error\n");
- free(Buf);
- fclose(out_fp);
- return -1;
- }
- free(Buf);
- fclose(out_fp);
- return 0;
- }
复制代码
makefile
- led_on.bin : led_on.o
- arm-linux-ld -Ttext 0x40000000 -o led_on.elf $^
- arm-linux-objdump -D led_on.elf > led_on_elf.dis
- arm-linux-objcopy -O binary -S led_on.elf led_on.bin
- gcc mk2416sdbin.c -o mk2416sdbin
- ./mk2416sdbin led_on.bin app.bin
- %.o : %.S
- arm-linux-gcc -o $@ [ DISCUZ_CODE_211 ]lt; -c
- %.o : %.c
- arm-linux-gcc -o $@ [ DISCUZ_CODE_211 ]lt; -c
-
- clean:
- rm -f mk2416sdbin led_on.elf led_on_elf.dis *.bin *.o
复制代码 附上昨天的led_on.S
- @******************************************************************************
- @ File:led_on.S
- @ 功能:LED点灯程序,关闭看门狗,点亮D8
- @******************************************************************************
- .text
- .global _start
- _start:
- LDR R0, =0x53000000 @R0设为WTCON寄存器
- LDR R1, [R0] @把WTCOM寄存器的值读入到R1
- BIC R1, R1, #0x01 @清除最低位
- STR R1, [R0] @把值写入WTCON寄存器关闭看门狗
-
- LDR R0, =0x4c000034 @R0设为PCLKCON 寄存器
- LDR R1, =0xffffffff
- STR R1, [R0] @把值写入PCLKCON寄存器开启所有PHB上的外设时钟
-
- LDR R0, =0x56000010 @ R0设为GPBCON寄存器。此寄存器
- @ 用于选择端口B各引脚的功能:
- @ 是输出、是输入、还是其他
- MOV R1, #0x00000004
- STR R1, [R0] @ 设置GPB1为输出口, 位[3:2]=0b01
-
- LDR R0, =0x56000014 @ R0设为GPBDAT寄存器。此寄存器
- @ 用于读/写端口B各引脚的数据
- MOV R1, #0x00000000 @ 此值改为0x00000002,
- @ 可让D8熄灭
- STR R1, [R0] @ GPB5输出0,D8点亮
-
- MAIN_LOOP:
- B MAIN_LOOP
-
- .end
复制代码
编译运行后生成app.bin 按我上一篇帖子的方法直接烧写到SD卡就可以lo!
在此感谢BOSS昨天的指点!
不知道我的帖子什么时候能加精啊
论坛ID:yuanlai2010
发表时间:2014-07-11
|
赞赏
-
2
查看全部赞赏
-
|