资讯详情

OrangePIPC2---镜像制作

前言

本文主要介绍Orange PiPC2 启动镜像制作,包含内容,sunxi H5芯片的bootrom,以及spiflash镜像制作,tf卡的镜像制作等。 镜像制作的话和bootrom内容涉及密切联系。如果你不明白,你可以先看这篇文章OrangePIPC2—bootrom

sunxi(sunxi represents the family of ARM SoCs from Allwinner Technology) 引用https://linux-sunxi.org/BROM

本文针对sunxi的H5做下norflash和tf卡的镜像制作方法。 因为在bootrom中有对nor和tf卡的处理,所以如下在附上启动的特殊说明。eGON就是在bootrom代码代码。

大致的启动说明

在文件中uboot----\board\sunxi\README.sunxi64

Boot process ============ The on-die BROM code will try several methods to load and execute the firmware. On a typical board like the Pine64 this will result in the following boot order:  1) Reading 32KB from sector 16 (@8K) of the microSD card to SRAM A1. If the BROM finds the magic "eGON" header in the first bytes, it will execute that code. If not (no SD card at all or invalid magic), it will: 2) Try to read 32KB from sector 16 (@8K) of memory connected to the MMC2 controller, typically an on-board eMMC chip. If there is no eMMC or it does not contain a valid boot header, it will: 3) Initialize the SPI0 controller and try to access a NOR flash connected to it (using the CS0 pin). If a flash chip is found, the BROM will load the first 32KB (from offset 0) into SRAM A1. Now it checks for the magic eGON header and checksum and will execute the code upon finding it. If not, it will: 4) Initialize the USB OTG controller and will wait for a host to connect to it, speaking the Allwinner proprietary (but deciphered) "FEL" USB protocol.   To boot the Pine64 board, you can use U-Boot and any of the described methods. 
  1. 针对tf卡从16扇区(512)B)也就是8K的地方读32K带sdram中
  2. nor从0地址读32k到sdram中

uboot的debug默认打印不输出,只要在当前c文件的前面#define _DEBUG 1 debug()会打印出来

spl的bin编译后的文件uboot\spl目录下sunxi-spl.bin

nor启动

eGON 中对nor的处理

在bootrom在汇编文件中可以看到正确的nor处理就是这个函数 bootrom处理的代码 load_from_spinor 对于 SPI NOR 闪存引导,BROM 为 SPI0 设置 6 MHz时钟频率,然后发送一系列读取数据字节 (03h) 命令。第一条从地址命令 0 读取 256 字节。若识别有效 eGON 标头,接下来读两遍,第一次从0开始 读2048字节,第二次读2048字节。boot0镜像。 那他怎么知道我的呢?boot得益于0多大,boot0的头,也就是第一次读到的信息。然后跳转到boot0去运行。 在这里插入图片描述 几乎是对的,但这个plt信息有点不对,不知道为什么。

分析

前面镜像分析的读取地址由spl决定,他在spi本文件在介质中实现,spl_spi.c(common/spl) 在函数spl_spi_load_image在哪里读镜像?payload_offs变量决定。

根据代码分析 1.默认值为CONFIG_SYS_SPI_U_BOOT_OFFS 0x8000 2. 假如OF_CONTROL使能且OF_PLATDATA如果你不能,去设备树读这个值。他的名字叫u-boot,spl-payload-offset,假如不需要自己设置,H5 这个编译没进

在这里,他使用默认值0x从8000一般过程从CONFIG_SYS_SPI_U_BOOT_OFFS 开始读0x40,用于检测mkimage header 判断64字节是否包含,判断是否包含fdt,

依赖

首先上面的spl_spi.c由于配置需要修改,支持需要修改spl的makefile, obj-KaTeX parse error: Expected group after '_' at position 8: (CONFIG_?(SPL_TPL_)MMC_SUPPORT) = spl_mmc.o obj-KaTeX parse error: Expected group after '_' at position 8: (CONFIG_?(SPL_TPL_)SPI_LOAD) = spl_spi.o CONFIG_$(SPL_TPL_)SPI_LOAD 这个需要支持下(实际上不是这个文件)

这里有一个插曲。一开始我以为是这样。spl_spi.c看文件配置makefile没有这样的配置CONFIG,感觉很奇怪,搜索spl_spi才发现sunxi他没有必要自己实现这一点。

./arch/arm/mach-sunxi/spl_spi_sunxi.c:275:static int spl_spi_load_image(struct spl_image_info *spl_image, ./arch/arm/mach-sunxi/spl_spi_sunxi.c:312:SPL_LOAD_IMAGE_METHOD("sunxi SPI", 0, BOOT_DEVICE_SPI, spl_spi_load_image);  makefile: obj-$(CONFIG_SPL_SPI_SUNXI)  = spl_spi_sunxi.o 

方法:

  1. 看下这个CONFIG_SPL_SPI_SUNXI是否打开

这里有一个小问题

为啥spiflash就是运行spl_spi_sunxi.c而不是spl_nor.c,这里有说明 /* * Loading of the payload to SDRAM is done with skipping of * the mkimage header in this SPL NOR driver */ 他不会有mkinage的header,而且看load代码 先解析CONFIG_SYS_OS_BASE这个地方的header如果check成功而且是linux然后直接操作linux,若失败再分析CONFIG_SYS_UBOOT_BASE这个地方的header,进入uboot

走向

spl_spi_load_image  if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&    image_get_magic(header) == FDT_MAGIC) { 
          //根据u-boot.its中的images布局进行加载到相对应位置,不是uboot下的设备树,是另一个设备树文件 struct spl_load_info load; debug("Found FIT\n"); load.dev = flash; load.priv = NULL; load.filename = NULL; load.bl_len = 1; load.read = spl_spi_fit_read; err = spl_load_simple_fit(spl_image, &load, payload_offs, header); } 
  1. header读到的其实是boot.its的头,这个文件是个设备树格式的文件,所以他也有头,包含了这个设备树文件的大小
  2. spl_load_simple_fit函数中根据实际大小再次读完整的boot.its到内存中
  3. 根据解析将image搬到boot.its指定的ddr中
u-boot.its
/ { 
        
	description = "Configuration to load ATF before U-Boot";
	#address-cells = <1>;

	images { 
        
		uboot { 
        
			description = "U-Boot (64-bit)";
			data = /incbin/("u-boot-nodtb.bin");
			type = "standalone";
			arch = "arm64";
			compression = "none";
			load = <0x4a000000>;
		};
		atf { 
        
			description = "ARM Trusted Firmware";
			data = /incbin/("bl31.bin");
			type = "firmware";
			arch = "arm64";
			compression = "none";
			load = <0x44000>;
			entry = <0x44000>;
		};
		fdt_1 { 
        
			description = "sun50i-h5-orangepi-pc2";
			data = /incbin/("arch/arm/dts/sun50i-h5-orangepi-pc2.dtb");
			type = "flat_dt";
			compression = "none";
		};
	};
	configurations { 
        
		default = "config_1";

		config_1 { 
        
			description = "sun50i-h5-orangepi-pc2";
			firmware = "uboot";
			loadables = "atf";
			fdt = "fdt_1";
		};
	};
};

制作镜像

所以按照上面的bootrom的做法,那么久必须将boot0 也就是spl.bin烧写道flash 的0地址。那么,其他文件怎么办呢,boot1烧写的地址应该是由boot0来确定的,因为bootrom将boot0搬到sdram中后就由boot0来接管执行了。所以boot1的走向是boot0来确定的。 tftp sunxi-spl.bin sf erase 0 0x8000 sf write 0x42000000 0 0x8000 tftp u-boot.itb sf erase 0x8000 0x80000 sf write 0x42000000 0x8000 0x80000

  1. norflash的0地址烧写sunxi-spl.bin
  2. 把u-boot.itb烧写到0x8000位置

启动打印

resetting ...
INFO:    PSCI Affinity Map:
INFO:      AffInst: Level 0, MPID 0x0, State ON
INFO:      AffInst: Level 0, MPID 0x1, State OFF
INFO:      AffInst: Level 0, MPID 0x2, State OFF
INFO:      AffInst: Level 0, MPID 0x3, State OFF

U-Boot SPL 2018.03 (Jun 26 2022 - 20:31:13 +0800)
DRAM: 1024 MiB
>>spl:board_init_r()
Trying akk to boot from sunxi SPI
os :17
Jumping to U-Boot
SPL malloc() used lx bytes (0 KB)
loaded - jumping to U-Boot...
image entry point: 0x
NOTICE:  BL3-1: Running on H5 (1718) in SRAM A2 (@0x44000)
NOTICE:  Configuring SPC Controller
NOTICE:  BL3-1: v1.0(debug):ae787242
NOTICE:  BL3-1: Built : 20:43:27, Feb 21 2018
NOTICE:  DT: sun50i-h5-orangepi-pc2
NOTICE:  SCPI: dummy stub handler, implementation level: 000000
INFO:    BL3-1: Initializing runtime services
INFO:    BL3-1: Preparing for EL3 exit to normal world
INFO:    BL3-1: Next image address: 0x4a000000, SPSR: 0x3c9


U-Boot 2018.03 (Jun 26 2022 - 20:34:26 +0800) Allwinner Technology

CPU:   Allwinner H5 (SUN50I)
Model: OrangePi PC 2
DRAM:  1 GiB
MMC:   SUNXI SD/MMC: 0
Loading Environment from FAT... MMC: no card present
** Bad device mmc 0 **
Failed (-5)
Loading Environment from MMC... MMC: no card present
*** Warning - MMC init failed, using default environment

Failed (-5)
In:    serial
Out:   serial
Err:   serial
Net:   phy interface7
eth0: ethernet@1c30000
starting USB...
USB0:   PA: set_value: error: gpio PA0 not reserved
USB EHCI 1.00
USB1:   USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  0 
AK # 
AK # 

tf卡启动

对你写文章有帮助的贴纸http://t.zoukankan.com/emlslxl-p-5620007.html 这边文章也挺好https://zhuanlan.zhihu.com/p/391101179 参考文献SD布局

eGON 中对tf的处理

制作镜像

从上面bootrom行为来看他是从8K的地方开始检测boot0。 atf和uboot经过打包成 u-boot.itb(uboot目录下需要atf文件bl31.bin)这个文件烧写到0x50*512B的地方也就是40KB的位置

操作: spl 8K /512 == 0x10 16 0x8000 /512 == 0x30 tftp sunxi-spl.bin mmc write 0x42000000 10 40 tftp u-boot.itb 40K/256 == 0x50 mmc write 0x42000000 50 400

  1. spl.bin烧写在8KB的地址上
  2. u-boot.itb烧写在40KB的地址上

上电打印

U-Boot SPL 2018.03 (Jun 26 2022 - 20:31:13 +0800)
DRAM: 1024 MiB
>>spl:board_init_r()
Trying akk to boot from MMC1
spl: bootmomd: 1
os :17
Jumping to U-Boot
SPL malloc() used lx bytes (408 KB)
loaded - jumping to U-Boot...
image entry point: 0x
NOTICE:  BL3-1: Running on H5 (1718) in SRAM A2 (@0x44000)
NOTICE:  Configuring SPC Controller
NOTICE:  BL3-1: v1.0(debug):ae787242
NOTICE:  BL3-1: Built : 20:43:27, Feb 21 2018
NOTICE:  DT: sun50i-h5-orangepi-pc2
NOTICE:  SCPI: dummy stub handler, implementation level: 000000
INFO:    BL3-1: Initializing runtime services
INFO:    BL3-1: Preparing for EL3 exit to normal world
INFO:    BL3-1: Next image address: 0x4a000000, SPSR: 0x3c9


U-Boot 2018.03 (Jun 26 2022 - 20:34:26 +0800) Allwinner Technology

CPU:   Allwinner H5 (SUN50I)
Model: OrangePi PC 2
DRAM:  1 GiB
MMC:   SUNXI SD/MMC: 0
Loading Environment from FAT... Unable to use mmc 0:0... Failed (-5)
Loading Environment from MMC... *** Warning - bad CRC, using default environment

Failed (-5)
In:    serial
Out:   serial
Err:   serial
Net:   phy interface7
eth0: ethernet@1c30000
starting USB...
USB0:   PA: set_value: error: gpio PA0 not reserved
USB EHCI 1.00
USB1:   USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot:  0 
AK # 
AK # 

为什么是40KB这个地址这里解释下,前面分析这个地址应该是spl中去确定的,那么在spl中根据自己的启动介质会执行相对应的load_image函数经过调用分析,mmc(tf卡)他的调用关系是这样的 具体实现是这个文件common/spl/spl_mmc.c 依赖这个宏CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR

这个CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR的值就是0x50,在mmc中一个sector大小512B,那么实际地址就是40K的地方

uboot(spl.bin)-》board_init_r->boot_from_devices(确定boot src)-》spl_load_image-(函数指针,不同媒介指向函数不一样)-》tf卡 spl_mmc_load_image-》走的是MMCSD_MODE_RAW(mmc_load_image_raw_sector)

  1. mmc_load_image_raw_sector:有对镜像的头进行校验check这个头就是mkimage header 64字节
  2. 其中mmc_load_image_raw_sector的参数有指定其实mmc地址进行镜像读取,他的值就是CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR

标签: sunx电涡流位移传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台