开发板(S5PV210)刷机以及简单Makefile学习记录还有mkv210_image.c文件学习

开发板刷机

线怎么连接

1.usb转串口接uart2(secureCRT用)
2.otg线(fastboot用)

刷机步骤

一、等开发板自己倒计时入uboot,然后粘贴那段代码(破坏bootloader)

题外话:
为什么这么做?
因为设计的原因,大概说是默认SD0启动,但是SD0接了EMMC

什么是EMMC?
EMMC,embedded multimedia card
细分有inand,movinand,onenand,这些都是EMMC

顺便讲下SD卡:SD,secure digital card
TF卡,mmc卡都是SD卡

二、fastboot进行烧录

windows CMD secureCTR
进入fastboot .exe ,用fastboot devices,连上了会有开发板型号 倒计时之前回车,然后fastboot
fastboot flash bootloader dir (dir是镜像路径) uboot
fastboot flash kernel dir
fastboot flash system dir …img
fastboot reboot 每一项完成之后都有complete或者看开发板上面进度条

Makefile简单学习

Makefile有三个要素,分别是目标、依赖、命令
下面两个图标对照看即可

111: a.c b.c
	gcc a.c b.c -o 111

clean:
	rm 111
目标: 依赖1 依赖2
	命令

目标:
	命令 //命令之前是一个tab的间隔

mkv210_image.c文件学习

一些背景知识

摘录自 S5PV210_IROM_APPLICATION NOTE_REV 0.3 三星的
操作顺序如下
在这里插入图片描述
全部的boot-up图如上图所示

BL1 / BL2 : It can be variable size copied from boot device to
internal SRAM area. BL1 max. size is 16KB. BL2 max. size is 80KB

BL:BootLoader,不是那个BL(=。=)
BL1和BL2都是可以从引导设备里面复制到internal SRAM里面的,BL1最大16KB,BL2最大80KB

在这里插入图片描述
以下是大概翻译
1.iROM(这里的iROM是BL0)可以做初始化的引导工作:初始化系统时钟、设备特定的控制器和引导设备
2.iROM的引导代码会把BootLoader加载到SRAM里面,这个BootLoader叫做BL1,然后iROM就会核实BL1的完整性,在安全启动模式下
3.BL1会被执行,BL1就会load剩下的BootLoader(也就是BL2,已经复制到了SRAM里面的),然后BL1又去核实BL2的完整性
4.BL2会被执行,BL2就初始化动态的RAM控制器,初始化完之后了把OS加载到S(synchronous)DRAM里面
5.最终,就会跳到操作系统的开始地址,完成了用系统之前的一个要做的环境工作。

As BL1 doesn’t need header information through UART/USB boot mode, BL1’s code base address is
0xd002_0000. In other cases except UART/USB boot mode, BL1 should have header information and It’s code
base address is 0xd0020010.

因为在UART/和USB的模式模式下,BL1不需要头文件,所以BL1的代码基地址是0xd0020000,在其他除了上述两种驱动模式下的其他模式情况下,BL1(bootloader)就需要头文件并且代码基地址是0xd0020010。

这里对比一下,0xd0020010 - 0xd0020000 相差了一个10,也就是进了一个位,这里是计算机内存的进位,16进制,也就是16个字节,所以头文件就是16byte。

总结:
1.usb/uart引导模式下:BL1前面没有头文件,基地址是0xd0020000
2.在除了上述模式下:BL1前面要塞一个头文件,基地址是0xd0020010
3.头文件占的长度是0x10,十六进制,所以头文件是16字节。

整个代码文件

	所有的思考、注释、原型已经加上去了,可能有点乱,慢慢看还是可以的
/*
 * mkv210_image.c的主要作用就是由usb启动时使用的led.bin制作得到由sd卡启动的镜像210.bin
 *
 * 本文件来自于友善之臂的裸机教程,据友善之臂的文档中讲述,本文件是一个热心网友提供,在此表示感谢。
 */
/* 在BL0阶段,Irom内固化的代码读取nandflash或SD卡前16K的内容,
 * 并比对前16字节中的校验和是否正确,正确则继续,错误则停止。
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
											//宏定义
#define BUFSIZE                 (16*1024) 	//16*1024byte = 16KB
#define IMG_SIZE                (16*1024)	//镜像大小16KB  
#define SPL_HEADER_SIZE         16			//头文件大小16byte
//#define SPL_HEADER              "S5PC110 HEADER  "
#define SPL_HEADER              "****************"  //16byte

int main (int argc, char *argv[])
{
	FILE		*fp;      	//定义一个FILE* 类型的指针fp
	char		*Buf, *a;	//定义一个char*类型的Buf,和一个char*类型的a
	int		BufLen;			//定义一个int类型的变量BufLen 
	int		nbytes, fileLen;//定义int类型变量nbytes和int类型变量fileLen
	unsigned int	checksum, count;	//定义无符号int类型的checksum和无符号int型count
	int		i;				//定义int类型i
	
	// 1. 3个参数
	// 要传进去三个参数,第一个参数argc[0]是mk210_image.c本身
	//					 第二个参数argc[1]是源文件
	//					 第三个参数argc[2]是目标文件
	if (argc != 3)
	{
		printf("Usage: %s <source file> <destination file>\n", argv[0]);
		//		用法:mk210_image.c 源文件 目标文件
		return -1;
	}

	// 2. 分配16K的buffer
	BufLen = BUFSIZE;	//BUFSIZE = 16*1024bytes,
	//The  malloc()  function  allocates !!size bytes!! and returns a pointer tothe allocated memory. 	
	Buf = (char *)malloc(BufLen); //memory allocate 内存分配,是byte单位,Buf是char*,也一一对应。
	//通过malloc分配出了BUFSIZE这么多字节的内存空间,
	
	//这里判断是否分配正常
	if (!Buf) //正常来说Buf是一个指针变量,进行!运算之后等于0,if就不会执行了,但是如果分配到0地址就证明出错了,然后if就执行了
	{
		printf("Alloc buffer failed!\n");
		return -1;
	}

	memset(Buf, 0x00, BufLen);//通过memset对分配的空间进行初始化

	// 3. 读源bin到buffer
	// 3.1 打开源bin
	
	// fopen的原型 FILE *fopen(const char *pathname, const char *mode);
	// mode位设置了r代表只读,r后面加了b代表adding the 'b' may be a good idea if you do I/O to a binary file
	fp = fopen(argv[1], "rb");  //返回值是一个file pointer 简称fp
	
	/* 	Upon successful completion fopen(), fdopen() and  freopen()  return  a
       FILE  pointer.   Otherwise, NULL is returned and errno is set to indi‐
       cate the error. */
	if( fp == NULL)
	{
		printf("source file open error\n");
		free(Buf);//如果源文件打开失败的话之前分配的buf也没用了,所以要free掉,malloc和free是一起搭配用的。
		return -1;
	}
	// 3.2 获取源bin长度
	fseek(fp, 0L, SEEK_END);								// 定位到文件尾 L是长整型的意思
	
/* 	The ftell() function obtains the current value of  the  file  position indicator for the stream 
	pointed to by stream. 
	获得当前的由stream指向的file position indicator的值,那之前已经定位到文件尾巴了,所以从头开始算得到文件长度。 
	//最后pointed to by stream 的这个file position indicator 就是之前fopen得到的file pointer(fp)
	long ftell(FILE *stream);  
	*/
	fileLen = ftell(fp);									// 得到文件长度 返回值是long 
	fseek(fp, 0L, SEEK_SET);								// 再次定位到文件头
	// 3.3 源bin长度不得超过16K-16byte
	count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))  //c=a<b?a:b 如果是(a<b)则c=a; 否(a>b)则c=b
		? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);
	
	// 3.4 buffer[0~15]存放"****************"
	/* 	void *memcpy(void *dest, const void *src, size_t n);
	The  memcpy()  function  copies n bytes from memory area src to memory area dest.  */
	memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);//从SPL_HEADER里面复制SPL_HEADER_SIZE(16)个byte的东西到Buf里面
	// 3.5 读源bin到buffer[16]
	/* The  function fread() reads nmemb items of data, each size bytes long,
       from the stream pointed to by stream, storing  them  at  the  location
       given by ptr.
	   On  success,  fread()  and fwrite() return the number of items read or
       written.  
	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);*/
	//前面count计算了文件长度,现在通过fread来从fp里面读取count那么多个字节的东西,1字节1字节地读Buf基地址
	//存储在Buf基地址+16的地址上(也就是顺着之前的0-15的位置后面放,不要覆盖它)
	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;
	//前面的16个字节算好了,现在是从第16字节开始校验后面16K-16byte的东西
	for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)
		checksum += (0x000000FF) & *a++; 
	/*
		checksum = checksum = *a++的东西,每一次的*a都与0x000000FF
		(8个1进行于运算,取出这8个位,一个字节8个位)再加起来
	*/	
	// 4.2 将校验和保存在buffer[8~15]
	a = Buf + 8;	// Buf是210.bin的起始地址,+8表示向后位移2个字,也就是说写入到第3个字
	//加8的原因是要往后移动8个字节,因为在iROM application Note里讲到
	//checksum是user write的,起始地址是从头文件开始(也就是buf的地址加上0x8),所以要加上8.
	//所以a其实只是个公用的char*类型的指针变量而已。
	*( (unsigned int *)a ) = checksum;//因为a本来是char*类型的指针变量
									  //现在是把checksum的值放到合适的位置
									  //这位置就是指针变量a所指向的地址。

	// 5. 拷贝buffer中的内容到目的bin
	// 5.1 打开目的bin
	fp = fopen(argv[2], "wb"); 
	/* //w	Truncate file to zero length or create text file  for  writing.
			The stream is positioned at the beginning of the file. */if (fp == NULL)
	{
		printf("destination file open error\n");
		free(Buf);
		return -1;
	}
	// 5.2 将16k的buffer拷贝到目的bin中
	a = Buf;		//这里Buf相当于是一个基地址了
	/* size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
	 *****obtaining  them  from  the location given by ***ptr***.** */
	//这个prt是个地址,Buf是一个指针变量,对得上的。
	   
	nbytes	= fwrite( a, 1, BufLen, fp); //从基地址写到你fopen了的文件流fp里面,
									//也就是写到argv[2]里面,argv[2]是destination file
	if ( nbytes != BufLen )
	{
		printf("destination file write error\n");
		free(Buf);
		fclose(fp);
		return -1;
	}

	free(Buf);
	fclose(fp);

	return 0;
}

发布了38 篇原创文章 · 获赞 1 · 访问量 1034

猜你喜欢

转载自blog.csdn.net/qq_40897531/article/details/104262211