全志H3uboot串口移植
由于硬件设计错误,需要把串口从uart0更改到uart2。本实验基于友善之臂的nanopi进行串口移植
移植前需要了解uboot以及uboot-spl的启动流程,这里参考:
tiny210(s5pv210)上电启动流程(BL0-BL2)
uboot流程——uboot-spl代码流程
uboot流程——uboot启动流程
SPL和Uboot
在更改串口之前,我们需要先了解一下spl和uboot分别做了什么:
- SPL:由IROM加载到SRAM,主要负责初始化DDR并加载+跳转uboot到DDR
- Uboot:由SPL加载到DDR,主要负责板级外设的初始化并加载+跳转Linux到DDR
SPL和Uboot在arch级的初始化步骤是一样的,差异集中在板级的初始化(串口的初始化就在板级)
串口移植
在更改串口前,我们先想一想使用一个串口需要做的准备:
- 串口的GPIO初始化
- 串口初始化
只要保证了这两步,一个串口的配置就算完成了。
所以我们的工作就可以分为SPL的串口配置和Uboot的串口配置,我们将从源码的角度来看看更改串口需要做哪些事情。
SPL串口移植
uart_init
SPL的串口初始化函数在board_init_f(arch/arm/mach-sunxi/board.c):
void board_init_f(ulong dummy)
{
spl_init();
preloader_console_init(); // 串口初始化
#ifdef CONFIG_SPL_I2C_SUPPORT
/* Needed early by sunxi_board_init if PMU is enabled */
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
sunxi_board_init();
#if (CONFIG_CONS_INDEX > 1) && defined(CONFIG_MACH_SUN8I_H3)
/* the sunxi kernel needs uart0 to be initialized by the bootloader */
/* configure uart0 GPIOs */
sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
/* initialize uart0 */
NS16550_init((NS16550_t)(SUNXI_UART0_BASE), CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
#endif
}
board_init_f进行了spl所需要的外设初始化,而我们的串口初始化就在preloader_console_init():
void preloader_console_init(void)
{
gd->baudrate = CONFIG_BAUDRATE;
serial_init(); /* serial communications setup */
gd->have_console = 1;
#if CONFIG_IS_ENABLED(BANNER_PRINT)
puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
U_BOOT_TIME " " U_BOOT_TZ ")\n");
#endif
#ifdef CONFIG_SPL_DISPLAY_PRINT
spl_display_print();
#endif
}
它会调用serial_inti(drivers/serial/serial.c)进行串口的初始化:
int serial_init(void)
{
gd->flags |= GD_FLG_SERIAL_READY;
return get_current()->start();
}
get_current()会调用default_serial_console(),最终返回一个串口设备,进入default_serial_console():
__weak struct serial_device *default_serial_console(void)
浙公网安备 33010602011771号