linux下SD卡烧录程序
1.文件mkv210_image.c詳解
?
分析啟動(dòng)過程可知:
210 啟動(dòng)后先執(zhí)行內(nèi)部iROM中的BL0,BL0執(zhí)行完后會(huì)根據(jù)OMpin 的配置選擇一個(gè)外部設(shè)備來啟動(dòng)(有很多,我們實(shí)際使用的有2個(gè):usb 啟動(dòng)和SD卡 啟動(dòng))。在 usb 啟動(dòng)時(shí)內(nèi)部 BL0 讀取到 BL1 后不做校驗(yàn),直接從 BL1 的實(shí)質(zhì)內(nèi)部 0xd0020010 開始執(zhí)行,因此 usb 啟動(dòng)的景象 led.bin 不需要頭信息,因此我們從 usb啟動(dòng)時(shí)直接將鏡像下載到 0xd0020010 去執(zhí)行即可,不管頭信息了;從 SD 啟動(dòng)時(shí),BL0 會(huì)首先讀取 SD卡 得到完整的鏡像(完整指的是 led.bin 和 16字節(jié) 的頭),然后BL0 會(huì)自己根據(jù)你的實(shí)際鏡像(指led.bin)來計(jì)算一個(gè)校驗(yàn)和 checksum,然后和你完整鏡像的頭部中的 checksum 來比對(duì)。如果對(duì)應(yīng)則執(zhí)行 BL1,如果不對(duì)應(yīng)則啟動(dòng)失敗。
mkv210_image.c的作用:
為BL1添加校驗(yàn)頭,我們編譯鏈接時(shí)只得到了led.bin,這個(gè)210.bin的得到和交叉編譯工具鏈?zhǔn)峭耆珶o關(guān)的。由led.bin得到210.bin的過程是三星的S5PV210所特有的,因此需要我們自己去完成,為此我們寫了mkv210_image.c來完成。
整個(gè)程序工作流分析:
整個(gè)程序中首先申請(qǐng)一個(gè)16KB大小的buffer,然后把所有內(nèi)容按照各自的位置填充進(jìn)去,最終把填充好的buffer寫入到一個(gè)文件(名叫210.bin)就形成了我們想要的鏡像。
/** mkv210_image.c的主要作用就是由usb啟動(dòng)時(shí)使用的led.bin制作得到由sd卡啟動(dòng)的鏡像210.bin** 本文件來自于友善之臂的裸機(jī)教程,據(jù)友善之臂的文檔中講述,本文件是一個(gè)熱心網(wǎng)友提供,在此表示感謝。*/ /* 在BL0階段,Irom內(nèi)固化的代碼讀取nandflash或SD卡前16K的內(nèi)容,* 并比對(duì)前16字節(jié)中的校驗(yàn)和是否正確,正確則繼續(xù),錯(cuò)誤則停止。** */ #include <stdio.h> #include <string.h> #include <stdlib.h>#define BUFSIZE (16*1024) #define IMG_SIZE (16*1024) #define SPL_HEADER_SIZE 16 //#define SPL_HEADER "S5PC110 HEADER " #define SPL_HEADER "****************"int main (int argc, char *argv[]) {FILE *fp;char *Buf, *a;int BufLen;int nbytes, fileLen;unsigned int checksum, count;int i;// 1. 3個(gè)參數(shù)if (argc != 3){printf("Usage: %s <source file> <destination file>\n", argv[0]);return -1;}// 2. 分配16K的bufferBufLen = BUFSIZE;Buf = (char *)malloc(BufLen);if (!Buf){printf("Alloc buffer failed!\n");return -1;}memset(Buf, 0x00, BufLen);// 3. 讀源bin到buffer// 3.1 打開源binfp = fopen(argv[1], "rb");if( fp == NULL){printf("source file open error\n");free(Buf);return -1;}// 3.2 獲取源bin長度fseek(fp, 0L, SEEK_END); // 定位到文件尾fileLen = ftell(fp); // 得到文件長度fseek(fp, 0L, SEEK_SET); // 再次定位到文件頭// 3.3 源bin長度不得超過16K-16bytecount = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);// 3.4 buffer[0~15]存放"S5PC110 HEADER "memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);// 3.5 讀源bin到buffer[16]nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp);if ( nbytes != count ){printf("source file read error\n");free(Buf);fclose(fp);return -1;}fclose(fp);// 4. 計(jì)算校驗(yàn)和// 4.1 從第16byte開始統(tǒng)計(jì)buffer中共有幾個(gè)1// 4.1 從第16byte開始計(jì)算,把buffer中所有的字節(jié)數(shù)據(jù)加和起來得到的結(jié)果a = Buf + SPL_HEADER_SIZE;for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)checksum += (0x000000FF) & *a++;// 4.2 將校驗(yàn)和保存在buffer[8~15]a = Buf + 8; // Buf是210.bin的起始地址,+8表示向后位移2個(gè)字,也就是說寫入到第3個(gè)字*( (unsigned int *)a ) = checksum;// 5. 拷貝buffer中的內(nèi)容到目的bin// 5.1 打開目的binfp = fopen(argv[2], "wb");if (fp == NULL){printf("destination file open error\n");free(Buf);return -1;}// 5.2 將16k的buffer拷貝到目的bin中a = Buf;nbytes = fwrite( a, 1, BufLen, fp);if ( nbytes != BufLen ){printf("destination file write error\n");free(Buf);fclose(fp);return -1;}free(Buf);fclose(fp);return 0; }?
?
2.dd命令
?
dd命令作用:指定大小的塊拷貝一個(gè)文件,并在拷貝的同時(shí)進(jìn)行指定的轉(zhuǎn)換,起到一個(gè)初始化磁盤的作用
dd?的主要選項(xiàng):
if=file?
輸入文件名,缺省為標(biāo)準(zhǔn)輸入。
of=file?
輸出文件名,缺省為標(biāo)準(zhǔn)輸出。
ibs=bytes?
一次讀入 bytes 個(gè)字節(jié)(即一個(gè)塊大小為 bytes 個(gè)字節(jié))。
obs=bytes?
一次寫出 bytes 個(gè)字節(jié)(即一個(gè)塊大小為 bytes 個(gè)字節(jié))。
bs=bytes?
同時(shí)設(shè)置讀寫塊的大小為 bytes ,可代替 ibs 和 obs 。
cbs=bytes?
一次轉(zhuǎn)換 bytes 個(gè)字節(jié),即轉(zhuǎn)換緩沖區(qū)大小。
skip=blocks?
從輸入文件開頭跳過 blocks 個(gè)塊后再開始復(fù)制。
seek=blocks?
從輸出文件開頭跳過 blocks 個(gè)塊后再開始復(fù)制。(通常只有當(dāng)輸出文件是磁盤或磁帶時(shí)才有效)。
count=blocks?
僅拷貝 blocks 個(gè)塊,塊大小等于 ibs 指定的字節(jié)數(shù)。
conv=conversion[,conversion...]?
用指定的參數(shù)轉(zhuǎn)換文件。
轉(zhuǎn)換參數(shù):?
ascii 轉(zhuǎn)換 EBCDIC 為 ASCII。
ebcdic?轉(zhuǎn)換 ASCII 為 EBCDIC。
ibm?轉(zhuǎn)換 ASCII 為?alternate EBCDIC.?
block 把每一行轉(zhuǎn)換為長度為 cbs 的記錄,不足部分用空格填充。
unblock?使每一行的長度都為 cbs ,不足部分用空格填充。
lcase?把大寫字符轉(zhuǎn)換為小寫字符。
ucase?把小寫字符轉(zhuǎn)換為大寫字符。
swab?交換輸入的每對(duì)字節(jié)。??
noerror 出錯(cuò)時(shí)不停止。
notrunc?不截短輸出文件。 不取整指令
sync?把每個(gè)輸入塊填充到ibs個(gè)字節(jié),不足部分用空(NUL)字符補(bǔ)齊。
?
?
3.使用方法
比如:使用SD卡燒錄led.bin到s5pv210中
1)編譯mkv210_image.c文件生成mkmini210? ? ? ? ? ? ? ? ? ? ? ? ? ? gcc mkv210_image.c -o mkmini210
2)使用mkmini210對(duì)led.bin進(jìn)行加頭部處理生成210.bin? ? ? ? ? ?./mkmini210 led.bin 210.bin
3)使用dd命令將210.bin文件燒錄到SD中? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sudo dd iflag=dsync oflag=dsync if=210.bin of=/dev/sdb seek=1
4)將SD卡插入卡槽,s5pv210選擇為SD卡啟動(dòng)方式
總結(jié)
以上是生活随笔為你收集整理的linux下SD卡烧录程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Simulink之三相桥式半控整流电路
- 下一篇: 爬虫小工具合集|不会编程也能爬数据