1.通过阅读iROM_Application_note可以获取关于启动的全部信息
2.记录下代码
制作SD卡启动的代码,即添加校验和的
#include <strings.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define BL1SIZE (16*1024) #define HEADSIZE (16) static void sys_err(char *str) { perror(str); exit(1); } int main(int argc, char **argv) { if (argc != 3) { printf("format: a.out [infile] [outfile]\n"); return -1; } int fd; if ((fd = open(argv[1], O_RDONLY)) < 0) sys_err("open"); int filesize = 0; if ((filesize = lseek(fd, 0, SEEK_END)) < 0) sys_err("lseek"); if ((lseek(fd, 0, SEEK_SET)) < 0) sys_err("lseek 2"); int newfilesize = 0; char *newfile = NULL; if (filesize < BL1SIZE) { newfilesize = BL1SIZE + HEADSIZE; } else { newfilesize = filesize + HEADSIZE; } if ((newfile = (char *)malloc(newfilesize)) == NULL) sys_err("malloc newfile"); bzero(newfile, newfilesize); int ncount; if ((ncount = read(fd, newfile + HEADSIZE, filesize)) < 0) sys_err("read err"); if (ncount != filesize) { printf("read err 2\n"); exit(1); } char *checksum = newfile + 8; char *getsum = newfile + HEADSIZE; unsigned int sum = 0, count = 0; for (; count < BL1SIZE - HEADSIZE; count++) { sum += getsum[count] & 0xff; } *(unsigned int *)checksum = sum; int newfd; if ((newfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) sys_err("open outfile"); if ((ncount = write(newfd, newfile, newfilesize)) < 0) sys_err("write outfile"); if (ncount != newfilesize) { printf("write outfile err\n"); exit(1); } return 0; }
使用 dd 命令,将SD卡启动代码拷贝到 SD 的 block1
#/bin/sh sudo dd iflag=dsync oflag=dsync if=./sd.bin of=/dev/sdb seek=1
使用iROM中的库将SD卡中的代码考到DDR上
typedef unsigned int bool; typedef bool (*pfunc_t) (int , unsigned int , unsigned short, unsigned int* , bool ); /** * This Function copy MMC(MoviNAND/iNand) Card Data to memory. * Always use EPLL source clock. * This function works at 20Mhz. * @param u32 StartBlkAddress : Source card(MoviNAND/iNand MMC)) Address.(It must block address.) * @param u16 blockSize : Number of blocks to copy. * @param u32* memoryPtr : Buffer to copy from. * @param bool with_init : determined card initialization. * @return bool(u8) - Success or failure. */ #define channel 2 #define StartBlkAddress 1 #define blockSize 50 #define memoryPtr 0x20000000 #define with_init 0 void sd_relcate() { pfunc_t pfunc = (pfunc_t)(*(unsigned int *)0xD0037F98); if (!pfunc(channel, StartBlkAddress, blockSize, memoryPtr, with_init)) printf("sd_relcate err\n"); else printf("sd_relcate success\n"); }
在汇编中,使用长跳转,跳转到DDR上的main
bl sdram_asm_init bl sd_relcate ldr sp, =0x2E000000 // 在DDR上重新设置栈 ldr pc, =main