mkv210_image.c文件详解(为BL1添加校验头)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

1、mkv210_image.c的使用演示

裸机程序中的Makefile是把程序的编译和链接过程分开的。实际上真正的项目的Makefile也是这样的,只是平时我们用gcc a.c -o exe这种方式编译时,把编译和链接过程一步完成了,但在内部,编译和链接是分开独立进行的,编译要使用编译器gcc,链接要使用链接器ld。

链接器得到的 led.elf 文件,其实就是我们的可执行程序。如果是在操作系统中,这个led.elf就可以执行了,但是在嵌入式裸机中,我们需要的是可以烧写的镜像文件,因此我们需要以这个led.elf文件为原材料来制作镜像,制作工具是交叉编译工具链中的arm-linux-objcopy。

我们使用arm-linux-objdump工具进行反汇编。反汇编,其实就是把编译后的.elf格式的可执行程序,转换成对应的汇编程序。我们使用反汇编主要是用来学习,见本部分最后一节。

mkv210_image.c这个程序不是在开发板上执行的,而是在主机linux(就是用来执行make对整个项目进行编译的那个机器)中执行的,因此编译这个程序用gcc而不是用arm-linux-gcc。

这个mkv210_image.c文件编译后得到一个可执行程序mkmini210,通过执行mkmini210,可以将led.bin文件加工得到SD卡启动时的裸机镜像文件,即210.bin文件。

2、S5PV210的启动过程

S5PV210启动后先执行内部iROM中的BL0,BL0执行完后会根据OMpin的配置选择一个外部设备来启动。启动方式有很多,我们实际使用的有2个,即usb启动和SD卡启动。

在usb启动时,内部BL0读取到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这个SoC所特有的,因此需要我们自己去完成,为此我们写了mkv210_image.c来完成。

4、代码详解

首先申请一个16KB大小的buffer,然后把所有内容按照各自的位置填充进去,最终把填充好的buffer写入到一个文件(名叫210.bin)就形成了我们想要的镜像。

(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读取文件,fwrite来写文件,读写完之后fclose关闭文件。这些函数是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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

和菜鸟一起学linux之bluez学习记录2

这里主要摘取对于hci&#xff0c;l2cap&#xff0c;sdp和rfcomm的一些应用编程。 关于hci 一、HCI层协议概述 1、HCI Command Packets 详见bluez源码&#xff1a;lib/hci.h /* Link Control */ #define OGF_LINK_CTL 0x01 #define OCF_INQUIRY 0x0001 #define OCF_…

AppDelegate.h

2019独角兽企业重金招聘Python工程师标准>>> #ifndef __APP_DELEGATE_H__ #define __APP_DELEGATE_H__#include "CCApplication.h" //CCApplication.h能根据平台打开对应的平台头文件 /** brief The cocos2d Application.The reason for implement as …

wamp替换mysql_将wamp集成的mysql替换成安装版的

替换原因&#xff1a;wamp集成的mysql错误提示乱码。修改文件&#xff1a;路径C:\wamp下的wampmanager.conf&#xff0c;wampmanager.ini&#xff0c;uninstall_services.bat路径C:\wamp\bin\mysql\mysql5.6.17下的wampserver.conf步骤&#xff1a;1.安装wamp和mysql&#xff0…

关于uboot的简介——uboot的一些常识介绍

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、uboot的由来 1、uboot从哪里来的&#xff1f; uboot是SourceForge上的开源项目。uboot项目的作者&#xff1a;一个德国人最早发起的项目。uboot就是由一个人发起&#xff0c;然后由整个网络上所…

有目标

生活就是每一天都有一个目标&#xff0c;不管大或者小&#xff0c;只要很好的完成了&#xff0c;都会觉得很有成就感&#xff01;转载于:https://www.cnblogs.com/jackychua/archive/2013/04/01/2994434.html

虚拟机上网以及互ping问题

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 虚拟机设置静态IP和上网问题 &#xff08;1&#xff09;在“虚拟机——设置——网络适配器”中选择桥接模式&#xff1b; &#xff08;2&#xff09;在“编辑——虚拟网络编辑器”中&#xff0c;选择桥接到有…

php定时执行原理

即使关掉浏览器也能继续执行 ignore_user_abort(); //即使Client断开(如关掉浏览器)&#xff0c;PHP脚本也可以继续执行. set_time_limit(0); // 执行时间为无限制&#xff0c;php默认的执行时间是30秒&#xff0c;通过set_time_limit(0)可以让程序无限制的执行下去 转载于:htt…

php递归无限极分类

递归无限级分类有几种形式&#xff0c;我这里仅仅举例比較经常使用的三种&#xff1a; 第一种&#xff1a;返回有排序的数组&#xff1a; <?php$data array(1 > array(id > 1,pid > 0,user_name > one,),2 > array(id > 2,pid > 1,user_name > tw…

qt 飞扬青云_R语言学习——实例标识符

> patientID> age> diabetes> status> patientdata> #在上述创建的病例数据框中&#xff0c;病人编号(patientID)用于区分数据中的不同个体&#xff0c;在R中实例标识符(case identifier)可以通过数据框操作函数中的rowname选项指定&#xff0c;如下代码&…

Makefile中的赋值符号:=、:=、?=、+=

参考博客&#xff1a; Makefile赋值符号的使用——"" ":" "?" ""_秦伟H的博客-CSDN博客 1、“”&#xff0c;是最基本的赋值 make将整个Makefile展开后再决定变量的值&#xff0c;变量的值等于Makefile中最后给这个变量所指定的值&am…

fck java_FCkjava三种调用方法

测试FCK方法一:toolbarSet "Default" >默认内容测试方法二:FCKeditor oFCKeditor ;oFCKeditor new FCKeditor(request,"content") ;oFCKeditor.setBasePath( "/db/fckeditor/" ) ;oFCKeditor.setWidth("600");oFCKeditor.setHeig…

Spring 容器(Spring 的上下文)

为什么80%的码农都做不了架构师&#xff1f;>>> 最近在做项目时牵扯到有关父子上下文的概念。 何为父子上下文呢&#xff1f; 父上下文&#xff1a; 使用listener监听器来加载配置文件&#xff0c;如下&#xff1a; <listener> <listener-class>org.…

file_operations结构体

以下读书笔记内容摘自宋宝华《Linux设备驱动开发详解》一书。 file_operations结构体在字符设备驱动的地位 file_operations结构体的定义 此结构体定义在x210kernel/include/linux/fs.h文件中。 struct file_operations {struct module *owner;loff_t (*llseek) (struct file …

FlashCC学习札记

前段时间项目中有一个功能模块用到了FlashCC&#xff0c;将C的代码编译成swc文件&#xff0c;以便在Flash工程中使用。开发过程中遇到一些问题&#xff0c;现在记录下来&#xff0c;以便日后查阅。 一、开发环境搭建 说明:本文所使用的FlashCC版本为1.0.1&#xff0c; 操作系统…

Java制作报表系统流程_基于JAVA报表生成系统设计与实现.doc

基于JAVA报表生成系统设计与实现摘 要现在是信息社会&#xff0c;各种信息都需要处理并直观展现&#xff0c;如股票&#xff0c;物价等信息都需要通过数据报表来展现、分析&#xff0c;因此高质量报表软件系统具有重要的实际意义。本论文课题研究探索了报表系统的开发方法与技术…

”凉凉“ 的故事

某一天&#xff0c;我在给数据匹配编码的时候发现一个数据匹配不到编码&#xff0c;我怀疑是码表问题&#xff0c;终于发现一个非常奇妙的事情&#xff1a;两个一模一样的字符串竟然不相等&#xff1f;&#xff1f;&#xff1f; 屌爆了&#xff0c;我上下左右看遍了也没看出这2…

struct file 结构体

该结构体在x210kernel/include/linux/fs.h文件中定义。 struct file {/** fu_list becomes invalid after file_free is called and queued via* fu_rcuhead for RCU freeing*/union {struct list_head fu_list;struct rcu_head fu_rcuhead;} f_u;struct path f_path; #def…

左右替换循环

$i1; while($i<5){$i;if(($i%2)0){echo 文字在左&#xff0c;<img src"img/logo_sports.png"><br /><br />;}else{echo <img src"logo_sports.png">&#xff0c;文字在右<br /><br />;} } 转载于:https://www.cnbl…

面向对象理论概述

2019独角兽企业重金招聘Python工程师标准>>> 转载自&#xff1a;http://my.oschina.net/brucelee80/blog 面向对象与面向过程的区别 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候一个一个依次调用就…

网络设备驱动介绍

以下内容源于朱有鹏《物联网大讲堂》课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 一、网络设备驱动概述 1、什么是网络设备 &#xff08;1&#xff09;网络设备&#xff1a;物理网卡在linux中形成的体系软件表现。 &#xff08;2&#xff09;物理网卡&#xff…