Skip to content

Latest commit

 

History

History
109 lines (84 loc) · 4.03 KB

一些与全志D1启动相关的东西.md

File metadata and controls

109 lines (84 loc) · 4.03 KB

一些与全志D1启动相关的东西

前言

最近在看全志D1的SDK,一头雾水。整个打包过程太多脚本,搞不清楚执行过程。在经过好多天的奋斗后,把一下搞明白的东西记录下来。

SD卡启动镜像

首先SD启动镜像是一个GPT分区的硬盘镜像,在第一个分区之前存放了一些固件。

奇怪的MBR

尽管磁盘镜像是GPT,但依然有一份传统的MBR(分区表)。我的SD镜像来自伟东山的buildroot

➜  /tmp xxd -s 446 -l 64 disk.img 
000001be: 8032 1102 0c46 2006 e089 0000 0000 0100  .2...F .........
000001ce: 0046 2106 8304 1e46 e089 0100 00a0 0f00  .F!....F........
000001de: 0000 0200 ee21 0100 0100 0000 1f08 0000  .....!..........
000001ee: 0000 0000 0000 0000 0000 0000 0000 0000  ................

我尝试清除了sd卡中的MBR,发现不能从sd卡启动了。从sd卡启动是会卡在uboot,日志如下:

[00.442][mmc]: get sdc_type fail and use default host:tm1.
[00.449][mmc]: can't find node "mmc0",will add new node
[00.453][mmc]: fdt err returned <no error>
[00.457][mmc]: Using default timing para
[00.461][mmc]: SUNXI SDMMC Controller Version:0x50310
[00.489][mmc]: card_caps:0x3000000a
[00.492][mmc]: host_caps:0x3000003f
[00.509]set disp.dev2_output_type fail. using defval=0
[00.533]Get bootloader and boot-resource partition number fail!
[00.562]out of usb burn from boot: not need burn key

boot0

这个程序存放在磁盘镜像8K字节偏移量的位置,被称为boot0。它的代码位于官方SDK的lichee/brandy-2.0/spl目录。它被CPU内部的代码自动加载执行。它有一个头部用于记录一些参数,以及用于让CPU内部代码识别它是否为一个有效的boot0。这个头部比较复杂,相关代码参考官方SDK的lichee/brandy-2.0/spl/include/private_boot0.h。此程序的主体代码位于lichee/brandy-2.0/spl/nboot/main/boot0_main.c。它的主要工作为:初始化时钟、内存,并加载下一阶段的程序。

下一阶段的是一个程序包,被成为toc1

toc1

toc1存放在磁盘镜像的32800扇区,并且备份了一份在24576扇区。boot0会选择一个没有被破坏的toc1进行加载。toc1中存放了opensbi/uboot/dtb。toc1的格式:

最前面是一个toc1的头部,结构如下:

typedef struct sbrom_toc1_head_info
{
	char name[16]	;	//user can modify
	u32  magic	;	//must equal TOC_U32_MAGIC
	u32  add_sum	;

	u32  serial_num	;	//user can modify
	u32  status		;	//user can modify,such as TOC_MAIN_INFO_STATUS_ENCRYP_NOT_USED

	u32  items_nr;	//total entry number
	u32  valid_len;
	u32  reserved[5];	//reserved for future
	u32  end;
}
sbrom_toc1_head_info_t;

紧跟着头部是一些item head。这个用于描述item的位置,结构如下:

typedef struct sbrom_toc1_item_info
{
	char name[64];			//such as ITEM_NAME_SBROMSW_CERTIF
	u32  data_offset;
	u32  data_len;
	u32  encrypt;			//0: no aes   //1: aes
	u32  type;				//0: normal file, dont care  1: key certif  2: sign certif 3: bin file
	u32  run_addr;          //if it is a bin file, then run on this address; if not, it should be 0
	u32  index;             //if it is a bin file, this value shows the index to run; if not
	                       //if it is a certif file, it should equal to the bin file index
	                       //that they are in the same group
	                       //it should be 0 when it anyother data type
	u32  reserved[69];	   //reserved for future;
	u32  end;
}sbrom_toc1_item_info_t;

最后没一个镜像还有一个头部描述自己加载到何处

typedef struct _sunxi_image_head
{
	unsigned int  jump_instruction;
	unsigned char magic[MAGIC_SIZE];
	unsigned int  res1;
	unsigned int  res2;
	unsigned int  res3;
	unsigned int  res4;
	unsigned char res5[8];
	unsigned char res6[8];
	int           run_addr;
}sunxi_image_head;

加载完成后运行opensbi

杂项

opensbi是jmp类型的固件,dtb的加载地址,和uboot的加载地址都是通过精心设计的编译脚本控制的。