Jump to content

    
Sign in to follow this  
doom13

U-Boot + BareMetal application

Recommended Posts

 
Quote

Приветствую.

Не могу понять возможно ли это (платформа ZynqMP), хочу при помощи U-Boot грузить BareMetal прошивки на отдельные ядра. Для начала хотелось бы хотя бы одну. Команды bootelf и go не работают, вроде бы пишет, что стартует приложение по такому-то адресу, но ничего не происходит.

Нужен совет в каком направлении копать.

Спасибо.

 

Share this post


Link to post
Share on other sites
5 часов назад, doom13 сказал:

хочу при помощи U-Boot грузить BareMetal прошивки

Смысл убута для BareMetal?  Просто сразу загрузить прошивку?

5 часов назад, doom13 сказал:

пишет, что стартует приложение по такому-то адресу, но ничего не происходит

А прога скомпилирована по этому адресу? Смотрели конфиг линкера?

Share this post


Link to post
Share on other sites
10 hours ago, doom13 said:

платформа ZynqMP

 

u-boot какой версии ? elf64 он относительно недавно стал поддерживать

http://git.denx.de/?p=u-boot.git;a=commitdiff;h=839c4e9c5bb09ac1ef2c129c7082a15b9cbd3a8a

Share this post


Link to post
Share on other sites
18 hours ago, mantech said:

Смысл убута для BareMetal?  Просто сразу загрузить прошивку? 

Он уже умеет лить прошивку по TFTP в RAM, писать во flash, и вроде как должен уметь стартануть elf/bin, то что мне и необходимо. Лень делать то, что уже сделано.

18 hours ago, mantech said:

А прога скомпилирована по этому адресу? Смотрели конфиг линкера?

С этим всё норм. По JTAG всё льётся и работает.

14 hours ago, sasamy said:

u-boot какой версии ? elf64 он относительно недавно стал поддерживать

Сливалась с git где-то в марте, т.е. почти свежая. В elf.c нахожу такое:

/*
 * A very simple ELF64 loader, assumes the image is valid, returns the
 * entry point address.
 *
 * Note if U-Boot is 32-bit, the loader assumes the to segment's
 * physical address and size is within the lower 32-bit address space.
 */
static unsigned long load_elf64_image_phdr(unsigned long addr)
{
	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
	Elf64_Phdr *phdr; /* Program header structure pointer */
	int i;

	ehdr = (Elf64_Ehdr *)addr;
	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);

	/* Load each program header */
	for (i = 0; i < ehdr->e_phnum; ++i) {
		void *dst = (void *)(ulong)phdr->p_paddr;
		void *src = (void *)addr + phdr->p_offset;

		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
		      i, dst, (ulong)phdr->p_filesz);
		if (phdr->p_filesz)
			memcpy(dst, src, phdr->p_filesz);
		if (phdr->p_filesz != phdr->p_memsz)
			memset(dst + phdr->p_filesz, 0x00,
			       phdr->p_memsz - phdr->p_filesz);
		flush_cache((unsigned long)dst, phdr->p_filesz);
		++phdr;
	}

	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
					    EF_PPC64_ELFV1_ABI)) {
		/*
		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
		 * descriptor pointer with the first double word being the
		 * address of the entry point of the function.
		 */
		uintptr_t addr = ehdr->e_entry;

		return *(Elf64_Addr *)addr;
	}

	return ehdr->e_entry;
}

 

17 hours ago, gosha-z said:

U-Boot сам вроде как не релокейтит .elf, в случае с цинком этим явно занимается bootgen

Вот не получается стартануть моего elf-a из u-boot. Пробовал команду bootelf для elf, перегнал elf в bin и пробовал те же bootelf и go, попробовал переконвертить bin в img и стартануть при помощи bootm, но всё не то, пишет что стартую приложение по такому-то адресу и опа. Исходники u-boot поковырял - делаю вывод, что и не может оно стартануть приложение с EL3.

Для go вызывает такую вот функцию

unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
			 char * const argv[])
{
	int ret = 0;

	printf ("2. In file zynqmp.c\n");

	if (current_el() > 1) {
		printf ("EL = %d\n", current_el());
		smp_kick_all_cpus();
		dcache_disable();
		armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
				    ES_TO_AARCH64);
	} else {
		printf("FAIL: current EL is not above EL1\n");
		ret = EINVAL;
	}
	return ret;
}

т.е. перед стартом на EL1 переключается.

Посмотрел asm, что работает при старте прошивы и вижу, что там похоже и дохнет, EL не совпадает с тем что SDK генерит. В BSP есть настройка для супервизора EL1, но это как понял совсем не мой случай.

Попробовал u-boot стартануть с настройкой для BIF-файла EL3 - не стартует. Стартует и нормально работает только с BL31 в EL3 и u-boot в EL2, все другие варианты - тишина.

Что посоветуете? Пилить свой загрузчик?

Share this post


Link to post
Share on other sites
5 minutes ago, gosha-z said:

Естественно, U-Boot работает на EL2, как ему (и не только ему) положено.

Что можете сказать по этому поводу: link

Или это ерунда какая-то

Share this post


Link to post
Share on other sites
1 minute ago, gosha-z said:

А чем вам так критичен EL3??

Пока вижу в нем проблему не запуска BareMetal, bsp которого компилится под EL3, и поменять это малой кровью я не могу.

Аналогичная проблема без ответа.

Возможно ли в U-Boot при переходе на BareMeta переключать EL в положение 3?

Share this post


Link to post
Share on other sites
2 minutes ago, gosha-z said:

А что конкретно он хочет от EL3? Прямого доступа к портам?

Я тут пока сам не пойму. Например для go U-boot выполняет:

unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
			 char * const argv[])
{
	int ret = 0;

	printf ("2. In file zynqmp.c\n");

	if (current_el() > 1) {
		printf ("EL = %d\n", current_el());
		smp_kick_all_cpus();
		dcache_disable();
		armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
				    ES_TO_AARCH64);
	} else {
		printf("FAIL: current EL is not above EL1\n");
		ret = EINVAL;
	}
	return ret;
}

т.е. переключает на EL1 и переходит на мой адрес старта boot.S, а там уже EL не совпадает и:

_prestart:
_boot:
	mov      x0, #0
	mov      x1, #0
	mov      x2, #0
	mov      x3, #0
	mov      x4, #0
	mov      x5, #0
	mov      x6, #0
	mov      x7, #0
	mov      x8, #0
	mov      x9, #0
	mov      x10, #0
	mov      x11, #0
	mov      x12, #0
	mov      x13, #0
	mov      x14, #0
	mov      x15, #0
	mov      x16, #0
	mov      x17, #0
	mov      x18, #0
	mov      x19, #0
	mov      x20, #0
	mov      x21, #0
	mov      x22, #0
	mov      x23, #0
	mov      x24, #0
	mov      x25, #0
	mov      x26, #0
	mov      x27, #0
	mov      x28, #0
	mov      x29, #0
	mov      x30, #0
#if 0 //dont put other a53 cpus in wfi
   //Which core am I
   // ----------------
	mrs      x0, MPIDR_EL1
	and      x0, x0, #0xFF                        //Mask off to leave Aff0
	cbz      x0, OKToRun                          //If core 0, run the primary init code
EndlessLoop0:
	wfi
	b        EndlessLoop0
#endif
OKToRun:

	mrs	x0, currentEL
	cmp	x0, #0xC
	beq	InitEL3

	cmp	x0, #0x4
	beq	InitEL1

	b 	error

и как понимаю, вероятнее всего попадает на error и там висит (такой результат работы наблюдаю, если BSP сгенерить под гипервизор с EL1, будет висеть на error)

Share this post


Link to post
Share on other sites

Для bootelf последовательность такая:

/* Interpreter command to boot an arbitrary ELF image from memory */
int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	unsigned long addr; /* Address of the ELF image */
	unsigned long rc; /* Return value from user code */
	char *sload = NULL;
	const char *ep = env_get("autostart");
	int rcode = 0;

	/* Consume 'bootelf' */
	argc--; argv++;

	/* Check for flag. */
	if (argc >= 1 && (argv[0][0] == '-' && \
				(argv[0][1] == 'p' || argv[0][1] == 's'))) {
		sload = argv[0];
		/* Consume flag. */
		argc--; argv++;
	}
	/* Check for address. */
	if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) {
		/* Consume address */
		argc--; argv++;
	} else
		addr = load_addr;

	if (!valid_elf_image(addr))
		return 1;

	if (sload && sload[1] == 'p')
		addr = load_elf_image_phdr(addr);
	else
		addr = load_elf_image_shdr(addr);

	if (ep && !strcmp(ep, "no"))
		return rcode;

	printf("## Starting application at 0x%08lx ...\n", addr);

	/*
	 * pass address parameter as argv[0] (aka command name),
	 * and all remaining args
	 */
	rc = do_bootelf_exec((void *)addr, argc, argv);
	if (rc != 0)
		rcode = 1;

	printf("## Application terminated, rc = 0x%lx\n", rc);

	return rcode;
}


/* Allow ports to override the default behavior */
static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
				     int argc, char * const argv[])
{
	unsigned long ret;

	/*
	 * pass address parameter as argv[0] (aka command name),
	 * and all remaining args
	 */
	ret = entry(argc, argv);

	return ret;
}

как понимаю, парсит elf и идёт на entry point, тут похоже останется в EL2, но мой BareMetal опять же хочет видеть EL3.

Тут тогда вопрос: может ли BL31 стартануть U-Boot c EL3? Тогда bootelf возможно и сработала бы.

Но у меня система с U-Boot стартует только если формирую бинарник таким образом:

//arch = zynqmp; split = false; format = BIN
the_ROM_image:
{
	[fsbl_config]a53_x64
	[bootloader]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.sdk/fsbl_a530/Debug/fsbl_a530.elf
	[pmufw_image]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.sdk/pmufw/Debug/pmufw.elf
	[destination_device = pl]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.runs/impl_1/xczu9eg.bit
	[destination_cpu = a53-0, exception_level = el-3, trustzone]/home/andrei/workspace/ZynqMP/linux/images/linux/bl31.elf
	[destination_cpu = a53-0, exception_level = el-2]/home/andrei/workspace/ZynqMP/u-boot-xlnx/u-boot.elf
}

 

Share this post


Link to post
Share on other sites
10 hours ago, doom13 said:

может ли BL31 стартануть U-Boot c EL3?

 

Если пропатчить - почему нет. Тут описание и патч для другой платформы, но переделать думаю не проблема

https://forum.armbian.com/topic/4165-re-buildingupdating-arm-trusted-firmware-and-u-boot-only/?tab=comments#comment-36024

Share this post


Link to post
Share on other sites

Нашёл, на форуме Xilinx это.

Каким-то чудом BareMetal стал стартовать по команде go с настройкой EL1 для BSP (предварительно правда пересобрал bl31). Пока так и не понял, что именно ему помогло запуститься. Остался вопрос с проектом под FreeRTOS, в этом случае в BSP не могу найти опцию для EL1.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this