Jump to content

    

Разрешение консольного UART в device tree для SPL

Recommended Posts

Roberto_Tolas

Здравствуйте, уважаемые форумчане!

Возникла проблема при инициализации консольного UART в SPL.

Имеется плата собственной разработки, основанная на процессоре NXP i.MX6 SoloX. Произвожу сборку U-boot с SPL, полученный файл гружу через USB с помощью программы imx_usb_loader. Но плата после попытки инициализации консольного UART сбрасывается.

Код функции board_init_f файла spl.c для моей платы:

void board_init_f(ulong dummy)
{
	ccgr_init();	

	/* setup AIPS and disable watchdog */
	arch_cpu_init();	

	/* setup GP timer */
	timer_init();	

	/* UART clocks enabled and gd valid - init serial console */
	preloader_console_init();	// <--- после вызова этой функции плата сбрасывается

	/* DDR initialization */
	spl_dram_init();		

	/* Clear the BSS. */
	memset(__bss_start, 0, __bss_end - __bss_start);

	/* load/boot image from boot device */
	board_init_r(NULL, 0);
}

Как я понимаю, сброс происходит из-за того, что не получается найти UART для консольного вывода. В дереве устройств я определяю UART3 как порт для консоли (stdout-path), разрешаю его работу (status = okay), и указываю что он мне пригодится в SPL (u-boot, dm-spl).

Вот моё дерево устройств:

/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "imx6sx.dtsi"

/ {
	model = "Freescale i.MX6 SoloX MY Board";
	compatible = "fsl,imx6sx-myboard", "fsl,imx6sx";

	chosen {						
		stdout-path = &uart3;
	};

    [email protected] {
		device_type = "memory";
		reg = <0x80000000 0x40000000>;
	};
};

&uart3 {
	u-boot,dm-spl;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart3>;
	status = "okay";
};

&iomuxc {
	imx6x-mypins {
        pinctrl_uart3: uart3grp {			
			u-boot,dm-spl;
			fsl,pins = <
				MX6SX_PAD_QSPI1B_SCLK__UART3_DCE_RX		0x1b0b1
				MX6SX_PAD_QSPI1B_SS0_B__UART3_DCE_TX	0x1b0b1
			>;
		};		
    };
};

В default config для платы разрешаю SPL и SPL_DM (OF_CONTROL). Вот полный код конфига:

CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_SYS_TEXT_BASE=0x87800000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=8
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xE0000
CONFIG_MX6SX=y
CONFIG_TARGET_MYBOARD_IMX6SOLOX=y
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx6sx-myboard"
CONFIG_SPL_TEXT_BASE=0x00909000
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL=y
# CONFIG_CMD_BMODE is not set
# CONFIG_LEGACY_IMAGE_FORMAT is not set
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=20
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL_SHOW_ERRORS=y
CONFIG_SPL_WATCHDOG=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_DEV=2
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
# CONFIG_NET is not set
CONFIG_SPL_DM=y
CONFIG_DM_DEBUG=y
CONFIG_BOUNCE_BUFFER=y
# CONFIG_I2C is not set
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_TRACE=y
CONFIG_FSL_USDHC=y
CONFIG_MTD=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_IMX6=y
CONFIG_IMX_THERMAL=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_SHA1=y
CONFIG_SHA256=y
CONFIG_MD5=y

Если через make menuconfig отключить опцию "Provide a serial driver in SPL", то плата не сбрасывается, но и вывод в консоль на данный UART я не наблюдаю.

Что я упустил или не правильно понял из документации и примеров кода для других плат?

Share this post


Link to post
Share on other sites

Tarbal

Если не получается найти device то сброса не будет. Сброс будет от использования неинициализированного указателя.
Попробуйте продебагировать вашу функцию preloader_console_init. Добавьте в нее принтов и посмотрите где она падает.

В u-boot не ручаюсь. С первого раза подумал, что речь о ядре идет. Но все равно добавьте в функцию принты и посмотрите что происходит. Так раз за разом добавляя и проверяя дойдете до проблемы.

Share this post


Link to post
Share on other sites

Roberto_Tolas
4 hours ago, Tarbal said:

Если не получается найти device то сброса не будет. Сброс будет от использования неинициализированного указателя.
Попробуйте продебагировать вашу функцию preloader_console_init. Добавьте в нее принтов и посмотрите где она падает.

В u-boot не ручаюсь. С первого раза подумал, что речь о ядре идет. Но все равно добавьте в функцию принты и посмотрите что происходит. Так раз за разом добавляя и проверяя дойдете до проблемы.

Здравствуйте! Спасибо за отклик!

Я прошёл по вызываемым функциям в preloader_console_init, одной из последних функций там вызывается serial_find_console_or_panic, дойдя до конца которой (в случае, если не было найдено ни одного порта), вызывается функция panic_str, которая вызывает do_reset. Думаю здесь он и сбрасывается.

Сейчас пробую не создавать новый код для платы, а взял уже готовый для платы udoo_neo_basic. Удалил все оттуда лишнее, привёл к тому же виду, что и у меня. Результат получше, хотя бы есть вывод в консоль (правда в чем отличие от моего кода я пока не понял, сейчас буду более детально сверять default_config).

Не подскажите как мне лучше сделать дальше: необходимо продолжить загрузку - перейти к загрузке U-Boot. Думал продолжить загрузку через SD-карту, но опять не понимаю что происходит с деревом устройств. Добавил описание пинов, разрешил интерфейс, к которому подведена SD-карта, все это указал чтобы можно было использовать в SPL, но каких либо попыток загрузиться с SD-карты я не наблюдаю. Кроме вывода в консоль: Trying to boot from MMC1. Такое ощущение, что не инициализируется тактовая для интерфейса usdhc1. В коде для некоторых плат находил функцию board_mmc_init(struct bd_info *bis) (функция вызывается из mmc_probe) с кодом:

usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);

ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
if (ret) {
	printf("Warning: failed to initialize mmc dev %d\n", 0);
	return ret;
}

Но, как я понял, она вызывается только при отключенном DM_MMC. Не подскажите, как мне убедиться, что то, что я описываю в дереве устройств используется в SPL и используется правильно? У меня ощущение что я что-то не до конца понимаю, не подскажите что можно почитать про SPL?

Share this post


Link to post
Share on other sites

Tarbal
40 minutes ago, Roberto_Tolas said:

serial_find_console_or_panic, дойдя до конца которой (в случае, если не было найдено ни одного порта), вызывается функция panic_str, которая вызывает do_reset. ие что я что-то не до конца понимаю, не подскажите что можно почитать про SPL?

Если reset происходит в этой функции Значит вы были правы. Проблема в том, что порт консоли не был обнаружен.

Share this post


Link to post
Share on other sites

sasamy
	chosen {						
		stdout-path = &uart3;
	};

попробуйте так

        chosen {
                stdout-path = "serial2:115200n8";
        };

и в DT помоему надо добавлять для uarta

u-boot,dm-pre-reloc;

 

https://wiki.st.com/stm32mpu/wiki/How_to_configure_U-Boot_for_your_board#Device_tree

Share this post


Link to post
Share on other sites

Roberto_Tolas

Я отключил использование DM для SERIAL_PORT, появился консольный вывод. И вот что он мне сообщает:

Quote

U-Boot SPL 2021.10-rc3-00054-g4412fd8ba2-dirty (Sep 10 2021 - 08:45:54 +0300)
Board: MyBoard imx6SoloX Board
Missing DTB

Получается он не видит дререво устройств вообще?

Я проверил, собирается ли SPL с деревом устройств - после сборки в папке spl два файла: u-boot-spl-nodtb.bin и u-boot-spl-dtb.bin, отличающиеся размером как раз на размер файла dt-spl.dtb из папки spl\dts. Для формирования файла SPL, исходя из .SPL.cmd, используется файл u-boot-spl.bin. Файл u-boot-spl.bin и u-boot-spl-dtb.bin одинаковые. Следовательно, я сделал вывод, что SPL собирается с деревом устройств.

Может быть проблема заключается в том, что я гружу SPL через usb? Содержимое конфигурационных файлов программы imx_usb_loader не менял. Может быть там что-то надо поменять?

Вывод процесса загрузки:

config file <.//imx_usb.conf>
vid=0x066f pid=0x3780 file_name=mx23_usb_work.conf
vid=0x15a2 pid=0x004f file_name=mx28_usb_work.conf
vid=0x15a2 pid=0x0052 file_name=mx50_usb_work.conf
vid=0x15a2 pid=0x0054 file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x0061 file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x0063 file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x0071 file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x007d file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x0080 file_name=mx6_usb_work.conf
vid=0x1fc9 pid=0x0128 file_name=mx6_usb_work.conf
vid=0x15a2 pid=0x0076 file_name=mx7_usb_work.conf
vid=0x1fc9 pid=0x0126 file_name=mx7ulp_usb_work.conf
vid=0x15a2 pid=0x0041 file_name=mx51_usb_work.conf
vid=0x15a2 pid=0x004e file_name=mx53_usb_work.conf
vid=0x15a2 pid=0x006a file_name=vybrid_usb_work.conf
vid=0x066f pid=0x37ff file_name=linux_gadget.conf
vid=0x1b67 pid=0x4fff file_name=mx6_usb_sdp_spl.conf
vid=0x0525 pid=0xb4a4 file_name=mx6_usb_sdp_spl.conf
config file <.//mx6_usb_work.conf>
parse .//mx6_usb_work.conf
Trying to open device vid=0x15a2 pid=0x0071
Interface 0 claimed
HAB security state: development mode (0x56787856)
== work item
filename ./SPL
load_size 0 bytes
load_addr 0x00000000
dcd 1
clear_dcd 0
plug 1
jump_mode 2
jump_addr 0x00000000
== end work item
No dcd table, barker=402000d1

loading binary file(./SPL) to 00907400, skip=0, fsize=8c00 type=aa

<<<35840, 35840 bytes>>>
succeeded (security 0x56787856, status 0x88888888)
jumping to 0x00907400

 

Edited by Roberto_Tolas

Share this post


Link to post
Share on other sites

Roberto_Tolas

Продолжаю попытки запустить плату с использованием дерева устройств.

Добавил в .config: CONFIG_SPL_SEPARATE_BSS=y

После чего получил в вывод следующее:

Quote

bind node chosen
Device 'chosen' has no compatible string
bind node aliases
Device 'aliases' has no compatible string
bind node soc
Device 'soc' has no compatible string

Вывод в консоль сейчас использую без DM для Serial Port.

Мне кажется какая-то проблема с памятью, а именно с областью bss. Я добавил строку

printf("pointer to bss = 0x%08X, size bss = 0x%08X\n", (unsigned int)__bss_start, (unsigned int)(__bss_end - __bss_start));

перед очисткой области bss в файле spl.c в функции board_init_f. И получил следующий вывод:

pointer to bss = 0x00000000, size bss = 0x00000000

Содержимое файла  u-boot-spl.lds:

MEMORY { .sram : ORIGIN = 0x00908000, LENGTH = 0x10000 }
MEMORY { .sdram : ORIGIN = 0x88200000, LENGTH = 0x100000 }
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
 .text :
 {
  __start = .;
  *(.vectors)
  arch/arm/cpu/armv7/start.o (.text*)
  *(.text*)
 } >.sram
 . = ALIGN(4);
 .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
 . = ALIGN(4);
 .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
 . = ALIGN(4);
 .u_boot_list : {
  KEEP(*(SORT(.u_boot_list*)));
 } >.sram
 . = ALIGN(4);
 __image_copy_end = .;
 .end :
 {
  *(.__end)
 }
 _image_binary_end = .;
 .bss :
 {
  . = ALIGN(4);
  __bss_start = .;
  *(.bss*)
  . = ALIGN(4);
  __bss_end = .;
 } >.sdram
}

Правильно ли я понимаю, что pointer to bss должен был быть равен 0x88200000? Почему мог обнулиться данный адрес?

И, теперь, как я понимаю, все глобальные переменные указывают на null, что может привести (и скорее всего приводит) к странной работе программы SPL?

Share this post


Link to post
Share on other sites

Roberto_Tolas

Добавлю вывод выполнения команды dtc ./dt-spl.dtb (в первый вариант добавил еще usdhc)

<stdout>: Warning (reg_format): /soc/aips-[email protected]/[email protected]:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
<stdout>: Warning (reg_format): /soc/aips-[email protected]/[email protected]:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
<stdout>: Warning (reg_format): /soc/aips-[email protected]/[email protected]:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
<stdout>: Warning (unit_address_vs_reg): /soc/aips-[email protected]: node has a unit name, but no reg property
<stdout>: Warning (unit_address_vs_reg): /soc/aips-[email protected]: node has a unit name, but no reg property
<stdout>: Warning (pci_device_reg): Failed prerequisite 'reg_format'
<stdout>: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
<stdout>: Warning (simple_bus_reg): Failed prerequisite 'reg_format'
<stdout>: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
<stdout>: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #address-cells value
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #size-cells value
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #address-cells value
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #size-cells value
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #address-cells value
<stdout>: Warning (avoid_default_addr_size): /soc/aips-[email protected]/[email protected]: Relying on default #size-cells value
<stdout>: Warning (avoid_unnecessary_addr_size): Failed prerequisite 'avoid_default_addr_size'
<stdout>: Warning (unique_unit_address): Failed prerequisite 'avoid_default_addr_size'
<stdout>: Warning (dmas_property): /soc/aips-[email protected]/[email protected]:dmas: Could not get phandle node for (cell 0)
<stdout>: Warning (gpios_property): /soc/aips-[email protected]/[email protected]:cd-gpios: Could not get phandle node for (cell 0)
/dts-v1/;

/ {
	#address-cells = <0x01>;
	#size-cells = <0x01>;
	model = "Freescale i.MX6 SoloX MY Board";
	compatible = "fsl,imx6sx";

	chosen {
		stdout-path = "/soc/[email protected]/[email protected]";
	};

	aliases {
		mmc0 = "/soc/[email protected]/[email protected]";
		serial2 = "/soc/[email protected]/[email protected]";
	};

	soc {

		aips-[email protected] {

			[email protected] {
				compatible = "fsl,imx6sx-iomuxc";
				reg = <0x20e0000 0x4000>;
				phandle = <0x0e>;

				imx6x-mypins {

					uart3grp {
						fsl,pins = <0x1b4 0x4fc 0x840 0x01 0x04 0x1b0b1 0x1b8 0x500 0x00 0x01 0x00 0x1b0b1>;
						phandle = <0x1d>;
					};
				};
			};
		};

		aips-[email protected] {

			[email protected] {
				compatible = "fsl,imx6sx-usdhc\0fsl,imx6sl-usdhc";
				reg = <0x2190000 0x4000>;
				bus-width = <0x04>;
				status = "okay";
				cd-gpios = <0x1c 0x02 0x01>;
				no-1-8-v;
				keep-power-in-suspend;
				wakeup-source;
			};

			[email protected] {
				compatible = "fsl,imx6sx-uart\0fsl,imx6q-uart\0fsl,imx21-uart";
				reg = <0x21ec000 0x4000>;
				dmas = <0x0c 0x1d 0x04 0x00 0x0c 0x1e 0x04 0x00>;
				dma-names = "rx\0tx";
				status = "okay";
			};
		};
	};
};

 

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.