QNX调试笔记[IMX6Q/TQIMX6Q]---SD启动卡制作

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 查看本文章

猜你喜欢

转载自blog.csdn.net/werweqg/article/details/82223236