author:tianming1992
E-mail: [email protected]
采用QNX7.0和sabreARD BSP,主要工作在于制作bootloader。
1.IPL制作
IPL时QNX特有的bootloader,类似于u-boot。
mx6x BSP的IPL代码位于src/ipl/boards/mx6x-sabreARD目录下,观察其main函数,基本可以理解为一个裸奔的单片机程序,作用是初始化串口,SD卡,比通过读取SD卡文件,将系统镜像读入内存中,并最终将控制权交给镜像的start-up模块。
int main()
{
unsigned image = QNX_LOAD_ADDR;
init_aips();
init_clocks();
init_regulator_settings();
if ( get_imx6_type() == MX6_CHIP_TYPE_QUAD_OR_DUAL)
{
if ( get_imx6_rev() == MX6_CHIP_REV_2_0 )
{
//DDR配置相关
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quadplus);
}
else
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quad);
}
//pin mux set!! 引脚配置
init_pinmux_quad_dual();
}
else if (get_imx6_type() == MX6_CHIP_TYPE_DUAL_LITE_OR_SOLO)
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_solo);
init_pinmux_dual_lite_solo();
}
else
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quad);
init_pinmux_quad_dual();
}
/* Init serial interface 串口配置*/
init_serial_mx6x();
ser_putstr("\nQNX Neutrino Initial Program Loader for the NXP i.MX6 Quad/Dual/DualLite/Solo/QuadPlus Sabre-ARD RevB (ARM Cortex-A9 MPCore)\n");
ser_putstr("BeiJing Leadgen.AI\n");
if ( get_imx6_type() == MX6_CHIP_TYPE_QUAD_OR_DUAL)
{
if ( get_imx6_rev() == MX6_CHIP_REV_2_0)
{
ser_putstr("\ni.MX6 Quad Plus CPU detected.\n\n");
}
else
{
ser_putstr("\ni.MX6 Quad or Dual CPU detected.\n\n");
}
}
else if (get_imx6_type() == MX6_CHIP_TYPE_DUAL_LITE_OR_SOLO)
{
ser_putstr("\ni.MX6 Dual Lite or Solo CPU detected.\n\n");
}
else
{
ser_putstr("\ni.MX6 unknown CPU type.\n\n");
ser_putstr("CHIP ID = ");
ser_puthex(get_imx6_type());
}
ser_putstr("SDMMC download...\n");
if (sdmmc_load_file(image, "QNX-IFS") == 0) {
ser_putstr("load image done.\n");
/* Proceed to image scan */
image = image_scan(image, image + 0x200);
if (image != 0xffffffff) {
ser_putstr("Found image @ 0x");
ser_puthex(image);
ser_putstr("\n");
image_setup(image);
ser_putstr("Jumping to startup @ 0x");
ser_puthex(startup_hdr.startup_vaddr);
ser_putstr("\n\n");
image_start(image);
/* Never reach here */
return 0;
}
}
while (1) {
ser_putstr("Command:\n");
ser_putstr("Press 'D' for serial download, using the 'sendnto' utility\n");
ser_putstr("Press 'M' for SDMMC download, IFS filename MUST be 'QNX-IFS'.\n");
switch (ser_getchar()) {
case 'D':
case 'd':
ser_putstr("send image now...\n");
if (image_download_ser(image)) {
ser_putstr("download failed...\n");
continue;
}
else
ser_putstr("download OK...\n");
break;
case 'M':
case 'm':
ser_putstr("SDMMC download...\n");
if (sdmmc_load_file(image, "QNX-IFS") == 0) {
ser_putstr("load image done.\n");
/* Proceed to image scan */
break;
}
else
{
ser_putstr("Load image failed.\n");
continue;
}
default:
ser_putstr("Unknown command.\n");
continue;
}
image = image_scan(image, image + 0x200);
if (image != 0xffffffff) {
ser_putstr("Found image @ 0x");
ser_puthex(image);
ser_putstr("\n");
image_setup(image);
ser_putstr("Jumping to startup @ 0x");
ser_puthex(startup_hdr.startup_vaddr);
ser_putstr("\n\n");
image_start(image);
/* Never reach here */
return 0;
}
ser_putstr("Image_scan failed...\n");
}
return 0;
}
对于IPL移植,最重要的在引脚配置部分,根据TQIMX6Q原理图,修改如下
init_pinmux_quad_dual()
{
//tqimx6 -----uart1-------------------------
//tx
set_mux_cfg(SWMUX_SD3_DAT7, MUX_CTL_MUX_MODE_ALT1);
set_pad_cfg(SWPAD_SD3_DAT7, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RXD_MUX, 0x02);
//RX
set_mux_cfg(SWMUX_SD3_DAT6, MUX_CTL_MUX_MODE_ALT1);
set_pad_cfg(SWPAD_SD3_DAT6, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RXD_MUX, 0x03);
//cts
set_mux_cfg(SWMUX_EIM_D19, MUX_CTL_MUX_MODE_ALT4);
set_pad_cfg(SWPAD_EIM_D19, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RTS_B, 0x00);
//rts
set_mux_cfg(SWMUX_EIM_D20, MUX_CTL_MUX_MODE_ALT4);
set_pad_cfg(SWPAD_EIM_D20, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RTS_B, 0x01);
}
/* SD2 CLK */
set_mux_cfg(SWMUX_SD2_CLK, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_CLK, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 CMD */
set_mux_cfg(SWMUX_SD2_CMD, MUX_CTL_MUX_MODE_ALT0 | MUX_CTL_SION);
set_pad_cfg(SWPAD_SD2_CMD, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT0 */
set_mux_cfg(SWMUX_SD2_DAT0, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT0, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT1 */
set_mux_cfg(SWMUX_SD2_DAT1, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT1, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT2 */
set_mux_cfg(SWMUX_SD2_DAT2, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT2, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT3 */
set_mux_cfg(SWMUX_SD2_DAT3, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT3, MX6Q_PAD_SETTINGS_USDHC);
/* SD2 Card Detect - configure GPIO4[1] as an input */
set_mux_cfg(SWMUX_GPIO_4, MUX_CTL_MUX_MODE_ALT5);
out32(MX6X_GPIO4_BASE + MX6X_GPIO_GDIR, in32(MX6X_GPIO4_BASE + MX6X_GPIO_GDIR) & ~(1<<1));
/* SD2 Write Protect - configure GPIO5[20] as an input */
set_mux_cfg(SWMUX_GPIO_2, MUX_CTL_MUX_MODE_ALT5);
out32(MX6X_GPIO2_BASE + MX6X_GPIO_GDIR, in32(MX6X_GPIO2_BASE + MX6X_GPIO_GDIR) & ~(1<<20));
此外,串口配置的宏也要更改
#define MXC_CONSOLE_BASE MX6X_UART1_BASE
SD卡部分类似。
2.SD卡烧写
这个部分都是通用的,制作一张FAT32的活动主分区SD卡,利用
sudo dd if=ipl-mx6q-sabresmart.bin of=/dev/sdd bs=512 seek=2
skip=2
将IPL写入SD中即可。
3.其他坑
在前面改IPL源码的时候,发现不管怎么改,最终生成的IPL竟然时一样的,最终发现这个BSP根目录下的makefile竟然遗漏了make install,如下:
install: $(if $(wildcard prebuilt/*),prebuilt)
$(MAKE) -Csrc hinstall
$(MAKE) -Csrc
增加install后,总算正常了:
install: $(if $(wildcard prebuilt/*),prebuilt)
$(MAKE) -Csrc hinstall
$(MAKE) -Csrc install
结结实实被QNX工程师坑了一把。
扫描二维码关注公众号,回复:
2966323 查看本文章