您尚未登录。

楼主 # 2021-09-16 10:37:25

qianfan
会员
注册时间: 2019-11-29
已发帖子: 38
积分: 106.5

sunxi-fel直接启动u-boot fastboot

分享一个使用sunxi-fel直接启动u-boot的fastboot的方法.

sunxi-fel使用uboot命令下载u-boot-sunxi-with-spl.bin之后可以直接运行u-boot, 如果需要配置uboot工作在其他模式, 比如ums或者fastboot等, 需要手动在u-boot的控制台上输入指令, 麻烦的很, 不利于自动化运行. 下面介绍一个简单的方法.

$ cat fastboot.env
#=uEnv
bootdelay=0
bootcmd=fastboot usb 0
$ sudo sunxi-fel uboot u-boot-sunxi-with-spl.bin write 0x44000000 fastboot.env
$ fastboot version
version: 0.4
finished. total time: 0.001s

----------------------------------------

从代码上分析下该方式的实现:

1. sunxi-tools

使用sunxi-fel write固件的时候, 函数内部会对固件类型进行判断, 目前支持两种特殊的固件, 一是u-boot env, 以字符串"#=uEnv"开头. 另一个是u-boot scripts, 由mkimage生成的. 如果是这两种格式之一, 会将write的地址存放在spl header的fel_script_address中, 长度存放在fel_uEnv_length. u-boot scripts脚本的话, fel_uEnv_length为0.

/* private helper function, gets used for "write*" and "multi*" transfers */
static unsigned int file_upload(feldev_handle *dev, size_t count,
				size_t argc, char **argv, progress_cb_t callback)
{
	if (argc < count * 2)
		pr_fatal("error: too few arguments for uploading %zu files\n",
			 count);

	/* get all file sizes, keeping track of total bytes */
	size_t size = 0;
	unsigned int i;
	for (i = 0; i < count; i++)
		size += file_size(argv[i * 2 + 1]);

	progress_start(callback, size); /* set total size and progress callback */

	/* now transfer each file in turn */
	for (i = 0; i < count; i++) {
		void *buf = load_file(argv[i * 2 + 1], &size);
		if (size > 0) {
			uint32_t offset = strtoul(argv[i * 2], NULL, 0);
			aw_write_buffer(dev, buf, offset, size, callback != NULL);

			/* If we transferred a script, try to inform U-Boot about its address. */
			if (get_image_type(buf, size) == IH_TYPE_SCRIPT)
				pass_fel_information(dev, offset, 0);
			if (is_uEnv(buf, size)) /* uEnv-style data */
				pass_fel_information(dev, offset, size);
		}
		free(buf);
	}

	return i; /* return number of files that were processed */
}

2. u-boot的实现

u-boot relocated之后, 在初始化的后半部分调用misc_init_r, 其中执行parse_spl_header, 会对spl_header中sunxi-tools传递的信息进行处理.

/*
 * Check the SPL header for the "sunxi" variant. If found: parse values
 * that might have been passed by the loader ("fel" utility), and update
 * the environment accordingly.
 */
static void parse_spl_header(const uint32_t spl_addr)
{
	struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);

	if (spl == INVALID_SPL_HEADER)
		return;

	if (!spl->fel_script_address)
		return;

	if (spl->fel_uEnv_length != 0) {
		/*
		 * data is expected in uEnv.txt compatible format, so "env
		 * import -t" the string(s) at fel_script_address right away.
		 */
		himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
			  spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
		return;
	}
	/* otherwise assume .scr format (mkimage-type script) */
	env_set_hex("fel_scriptaddr", spl->fel_script_address);
}

这种实现方式真是因吹斯汀.

离线

#1 2021-09-16 11:30:54

memory
会员
注册时间: 2021-08-11
已发帖子: 483
积分: 459

Re: sunxi-fel直接启动u-boot fastboot

有点意思,这个 0x44000000  地址是怎么算出来的?

离线

楼主 #2 2021-09-16 12:01:11

qianfan
会员
注册时间: 2019-11-29
已发帖子: 38
积分: 106.5

Re: sunxi-fel直接启动u-boot fastboot

memory 说:

有点意思,这个 0x44000000  地址是怎么算出来的?

随便填个有效地址就行了

离线

#3 2021-09-16 12:51:12

cube
会员
注册时间: 2021-03-11
已发帖子: 288
积分: 202.5

Re: sunxi-fel直接启动u-boot fastboot

qianfan 说:
memory 说:

有点意思,这个 0x44000000  地址是怎么算出来的?

随便填个有效地址就行了

随便填怎么关联呢?

离线

楼主 #4 2021-09-16 14:32:07

qianfan
会员
注册时间: 2019-11-29
已发帖子: 38
积分: 106.5

Re: sunxi-fel直接启动u-boot fastboot

cube 说:
qianfan 说:
memory 说:

有点意思,这个 0x44000000  地址是怎么算出来的?

随便填个有效地址就行了

随便填怎么关联呢?

看上面贴出的sunxi-tools的代码, sunxi-tools会将这个地址, 也就是44000000放到spl的header中(fel_scripts_address), 等开机之后从spl header里面取到的.

离线

#5 2022-02-23 18:00:52

X3
会员
注册时间: 2020-04-08
已发帖子: 85
积分: 73.5

Re: sunxi-fel直接启动u-boot fastboot

这个操作不得不说有点骚!

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn