日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mkv210_image.c文件详解

發布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mkv210_image.c文件详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以下內容源于朱有鵬《物聯網大講堂》課程的學習,如有侵權,請告知刪除。


1、mkv210_image.c的使用演示

  • 裸機程序中的Makefile(實際上真正的項目的Makefile都是這樣的)是把程序的編譯和鏈接過程分開的。(平時我們用gcc a.c -o exe這種方式來編譯時,實際上把編譯和鏈接過程一步完成了。在內部實際上編譯和鏈接永遠是分開獨立進行的,編譯要使用編譯器gcc,鏈接要使用鏈接器ld)
  • 鏈接器得到led.elf其實就是我們的可執行程序,(如果是在操作系統下,這個led.elf就可以執行了)但是在嵌入式裸機中我們需要的是可以燒寫的文件(可燒寫的文件就叫鏡像image),因此我們需要用這個led.elf為原材料來制作鏡像,制作工具是交叉編譯工具鏈中的arm-linux-objcopy。
  • 我們使用arm-linux-objdump工具進行反編譯(反匯編),反匯編其實就是把編譯后的elf格式的可執行程序給反過來的到對應的匯編程序,的到它的匯編源代碼。我們使用反匯編主要是用來學習,見本部分最后一節。
  • mkv210_image.c這個程序其實最終不是在開發板上執行的,而是在主機linux(就是用來執行make對整個項目進行編譯的那個機器)中執行的,因此編譯這個程序用gcc而不是用arm-linux-gcc。這個.c文件編譯后得到一個可執行程序mkmini210,目的是通過執行這個mkmini210程序而由led.bin得到210.bin。(210.bin是通過SD卡啟動時的裸機鏡像,這個鏡像需要由led.bin來加工的到,加工的具體方法和原理要看mkv210_image.c)


2、背景知識:S5PV210的啟動過程回顧

  • 210啟動后先執行內部iROM中的BL0,BL0執行完后會根據OMpin的配置選擇一個外部設備來啟動(有很多,我們實際使用的有2個:usb啟動和SD卡啟動)。
  • 在usb啟動時,內部BL0讀取到BL1后不做校驗,直接從BL1的實質內部0xd0020010開始執行,因此usb啟動的景象led.bin不需要頭信息,因此我們從usb啟動時直接將鏡像下載到0xd0020010去執行即可,不管頭信息了。
  • 從SD啟動時,BL0會首先讀取sd卡得到完整的鏡像(完整指的是led.bin和16字節的頭),然后BL0會自己根據你的實際鏡像(指led.bin)來計算一個校驗和checksum,然后和你完整鏡像的頭部中的checksum來比對。如果對應則執行BL1,如果不對應則啟動失敗(會轉入執行2st啟動,即SD2啟動。如果這里已經是2st啟動了,這里校驗通不過就死定了)。(一開始計算出來的(之后被存儲在頭部16字節中),和BL0從sd卡讀取出來后重新計算的(可能由SD卡于機械特性出現錯誤),進行對比)


3、mkv210_image.c的作用:為BL1添加校驗頭

  • 編譯鏈接時只得到led.bin,由led.bin得到210.bin的過程是三星的S5PV210所特有的,因此需要我們自己去完成,為此我們寫了mkv210_image.c來完成。


4、整個程序工作流分析

  • 首先申請一個16KB大小的buffer,然后把所有內容按照各自的位置填充進去,最終把填充好的buffer寫入到一個文件(名叫210.bin)就形成了我們想要的鏡像。

5、代碼詳解

第1步:檢驗用戶傳參是不是3個。

第2步:分配16K Bbuffer并且填充為0.

第3步:·········

(1)main函數兩個形參的作用

  • main函數接收2個形參:argc和argv。
  • argc是用戶(通過命令行來)執行這個程序時,實際傳遞的參數個數。注意這個個數是包含程序執行本身的
  • argv是一個字符串數組,這個數組中存儲的字符串就是一個個的傳參。
  • 譬如我們執行程序時使用./mkx210 led.bin 210.bin,則argc = 3,則argv[0] = "./mkx210" ?argv[1] = led.bin ?argv[2] = 210.bin

(2)glibc讀寫文件接口

  • linux中要讀取一個文件,可以使用fopen打開文件,fread讀取文件,讀完之后fclose關閉文件。
  • 要寫文件用fwrite來寫。這些函數是glibc的庫函數,在linux中用man 3 可以查找。

(3)校驗和的計算方法

  • 校驗和其實就是需要校驗的內存區域中,所有內存中的內容按照字節為單位來進行相加,最終相加的和極為校驗和。


/** mkv210_image.c的主要作用就是由usb啟動時使用的led.bin制作得到由sd卡啟動的鏡像210.bin** 本文件來自于友善之臂的裸機教程,據友善之臂的文檔中講述,本文件是一個熱心網友提供,在此表示感謝。*/ /* 在BL0階段,Irom內固化的代碼讀取nandflash或SD卡前16K的內容,* 并比對前16字節中的校驗和(下面的代碼就是計算校驗和的,但對比是BL0來實現,與此代碼無關)是否正確,正確則繼續,錯誤則停止。*/ #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個參數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. 計算校驗和// 4.1 從第16byte開始統計buffer中共有幾個1// 4.1 從第16byte開始計算,把buffer中所有的字節數據加和起來得到的結果a = Buf + SPL_HEADER_SIZE;for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)checksum += (0x000000FF) & *a++;// 4.2 將校驗和保存在buffer[8~15]a = Buf + 8; // Buf是210.bin的起始地址,+8表示向后位移2個字,也就是說寫入到第3個字*( (unsigned int *)a ) = checksum;// 5. 拷貝buffer中的內容到目的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; }



總結

以上是生活随笔為你收集整理的mkv210_image.c文件详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。